libobs/graphics: Add NV12 texture support

This commit is contained in:
jp9000
2018-10-05 03:15:13 -07:00
parent b64d7d71d0
commit 93fc61fa82
8 changed files with 237 additions and 8 deletions

View File

@@ -171,6 +171,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT(gs_shader_set_default);
GRAPHICS_IMPORT(gs_shader_set_next_sampler);
GRAPHICS_IMPORT_OPTIONAL(device_nv12_available);
/* OSX/Cocoa specific functions */
#ifdef __APPLE__
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_from_iosurface);
@@ -192,6 +194,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT_OPTIONAL(device_texture_get_shared_handle);
GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync);
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
#endif
return success;

View File

@@ -232,6 +232,8 @@ struct gs_exports {
void (*gs_shader_set_next_sampler)(gs_sparam_t *param,
gs_samplerstate_t *sampler);
bool (*device_nv12_available)(gs_device_t *device);
#ifdef __APPLE__
/* OSX/Cocoa specific functions */
gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev,
@@ -265,6 +267,12 @@ struct gs_exports {
int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key,
uint32_t ms);
int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key);
bool (*device_texture_create_nv12)(gs_device_t *device,
gs_texture_t **tex_y, gs_texture_t **tex_uv,
uint32_t width, uint32_t height, uint32_t flags);
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
uint32_t width, uint32_t height);
#endif
};

View File

@@ -2545,6 +2545,18 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer)
return thread_graphics->exports.gs_indexbuffer_get_type(indexbuffer);
}
bool gs_nv12_available(void)
{
if (!gs_valid("gs_nv12_available"))
return false;
if (!thread_graphics->exports.device_nv12_available)
return false;
return thread_graphics->exports.device_nv12_available(
thread_graphics->device);
}
#ifdef __APPLE__
/** Platform specific functions */
@@ -2726,4 +2738,64 @@ int gs_texture_release_sync(gs_texture_t *tex, uint64_t key)
return -1;
}
bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
uint32_t width, uint32_t height, uint32_t flags)
{
graphics_t *graphics = thread_graphics;
bool success = false;
if (!gs_valid("gs_texture_create_nv12"))
return false;
if ((width & 1) == 1 || (height & 1) == 1) {
blog(LOG_ERROR, "NV12 textures must have dimensions "
"divisible by 2.");
return false;
}
if (graphics->exports.device_texture_create_nv12) {
success = graphics->exports.device_texture_create_nv12(
graphics->device, tex_y, tex_uv,
width, height, flags);
if (success)
return true;
}
*tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags);
*tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL,
flags);
if (!*tex_y || !*tex_uv) {
if (*tex_y)
gs_texture_destroy(*tex_y);
if (*tex_uv)
gs_texture_destroy(*tex_uv);
*tex_y = NULL;
*tex_uv = NULL;
return false;
}
return true;
}
gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_stagesurface_create_nv12"))
return NULL;
if ((width & 1) == 1 || (height & 1) == 1) {
blog(LOG_ERROR, "NV12 textures must have dimensions "
"divisible by 2.");
return NULL;
}
if (graphics->exports.device_stagesurface_create_nv12)
return graphics->exports.device_stagesurface_create_nv12(
graphics->device, width, height);
return NULL;
}
#endif

View File

@@ -71,7 +71,8 @@ enum gs_color_format {
GS_R32F,
GS_DXT1,
GS_DXT3,
GS_DXT5
GS_DXT5,
GS_R8G8,
};
enum gs_zstencil_format {
@@ -758,6 +759,8 @@ EXPORT size_t gs_indexbuffer_get_num_indices(
EXPORT enum gs_index_type gs_indexbuffer_get_type(
const gs_indexbuffer_t *indexbuffer);
EXPORT bool gs_nv12_available(void);
#ifdef __APPLE__
/** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures
@@ -814,6 +817,12 @@ EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms)
*/
EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key);
EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
uint32_t width, uint32_t height, uint32_t flags);
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(
uint32_t width, uint32_t height);
#endif
/* inline functions used by modules */
@@ -838,6 +847,7 @@ static inline uint32_t gs_get_format_bpp(enum gs_color_format format)
case GS_DXT1: return 4;
case GS_DXT3: return 8;
case GS_DXT5: return 8;
case GS_R8G8: return 16;
case GS_UNKNOWN: return 0;
}