diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index abab8c9edbc..a31d7c58080 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -2332,6 +2332,9 @@ dri2_num_fourcc_format_planes(EGLint format) case DRM_FORMAT_NV21: case DRM_FORMAT_NV16: case DRM_FORMAT_NV61: + case DRM_FORMAT_NV15: + case DRM_FORMAT_NV20: + case DRM_FORMAT_NV30: case DRM_FORMAT_P010: case DRM_FORMAT_P012: case DRM_FORMAT_P016: diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 54ce3cf78c5..4c97c045354 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -856,6 +856,26 @@ static const struct dri2_format_mapping g8r8_b8r8_mapping = { { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }; +static const struct dri2_format_mapping r10_g10b10_mapping = { + DRM_FORMAT_NV15, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, + PIPE_FORMAT_R10_G10B10_420_UNORM, + 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_NONE } } +}; + +static const struct dri2_format_mapping r10_g10b10_mapping_422 = { + DRM_FORMAT_NV20, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, + PIPE_FORMAT_R10_G10B10_422_UNORM, + 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE }, + { 1, 1, 0, __DRI_IMAGE_FORMAT_NONE } } +}; + static enum __DRIFixedRateCompression to_dri_compression_rate(uint32_t rate) { @@ -944,6 +964,21 @@ dri_create_image_from_winsys(struct dri_screen *screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } + /* For NV15, see if we have support for sampling r10_g10b10 */ + if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV15 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r10_g10b10_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + + if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV20 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_422_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r10_g10b10_mapping_422; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + /* For YV12 and I420, see if we have support for sampling r8_b8_g8 or r8_g8_b8 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV) { if (map->dri_fourcc == DRM_FORMAT_YUV420 && diff --git a/src/gallium/frontends/dri/dri_helpers.c b/src/gallium/frontends/dri/dri_helpers.c index c5bdd3aa5b3..c3e91fb8b49 100644 --- a/src/gallium/frontends/dri/dri_helpers.c +++ b/src/gallium/frontends/dri/dri_helpers.c @@ -550,6 +550,18 @@ static const struct dri2_format_mapping dri2_format_table[] = { { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }, + /* 10 bit 4:2:0 and 4:2:2 formats; the components + are tightly packed, so the planes don't correspond + to any native DRI format */ + { DRM_FORMAT_NV15, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV15, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_NONE } } }, + { DRM_FORMAT_NV20, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV20, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE }, + { 1, 1, 0, __DRI_IMAGE_FORMAT_NONE } } }, + { DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE, __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P010, 2, { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index f1294d70d9d..ab7cdd97875 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -167,7 +167,7 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, } static bool -is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *out, +is_fmt_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *out, unsigned usage, bool *native_supported) { if (out->format == PIPE_FORMAT_NV12 && @@ -205,6 +205,33 @@ is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *ou return false; } +static bool +is_fmt_as_r10_g10b10_supported(struct pipe_screen *screen, struct st_egl_image *out, + unsigned usage, bool *native_supported) +{ + if (out->format == PIPE_FORMAT_NV15 && + out->texture->format == PIPE_FORMAT_R10_G10B10_420_UNORM && + screen->is_format_supported(screen, PIPE_FORMAT_R10_G10B10_420_UNORM, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + if (out->format == PIPE_FORMAT_NV20 && + out->texture->format == PIPE_FORMAT_R10_G10B10_422_UNORM && + screen->is_format_supported(screen, PIPE_FORMAT_R10_G10B10_422_UNORM, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + return false; +} + static bool is_i420_as_r8_g8_b8_420_supported(struct pipe_screen *screen, struct st_egl_image *out, @@ -257,7 +284,8 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle, return false; } - if (!is_nv12_as_r8_g8b8_supported(screen, out, usage, native_supported) && + if (!is_fmt_as_r8_g8b8_supported(screen, out, usage, native_supported) && + !is_fmt_as_r10_g10b10_supported(screen, out, usage, native_supported) && !is_i420_as_r8_g8_b8_420_supported(screen, out, usage, native_supported) && !is_format_supported(screen, out->format, out->texture->nr_samples, out->texture->nr_storage_samples, usage, @@ -404,6 +432,22 @@ st_bind_egl_image(struct gl_context *ctx, texObj->RequiredTextureImageUnits = 2; } break; + case PIPE_FORMAT_NV15: + if (stimg->texture->format == PIPE_FORMAT_R10_G10B10_420_UNORM) { + texFormat = MESA_FORMAT_R10G10B10X2_UNORM; + texObj->RequiredTextureImageUnits = 1; + } else { + unreachable("NV15 emulation requires R10_G10B10_420_UNORM support"); + } + break; + case PIPE_FORMAT_NV20: + if (stimg->texture->format == PIPE_FORMAT_R10_G10B10_422_UNORM) { + texFormat = MESA_FORMAT_R10G10B10X2_UNORM; + texObj->RequiredTextureImageUnits = 1; + } else { + unreachable("NV20 emulation requires R10_G10B10_422_UNORM support"); + } + break; case PIPE_FORMAT_P010: case PIPE_FORMAT_P012: case PIPE_FORMAT_P016: diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 5358d176483..b81770afc9f 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -96,6 +96,12 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) break; } FALLTHROUGH; + case PIPE_FORMAT_NV15: + if (stObj->pt->format == PIPE_FORMAT_R10_G10B10_420_UNORM) { + key.lower_yuv |= (1 << unit); + break; + } + FALLTHROUGH; case PIPE_FORMAT_P010: case PIPE_FORMAT_P012: case PIPE_FORMAT_P016: @@ -109,6 +115,12 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) } key.lower_nv21 |= (1 << unit); break; + case PIPE_FORMAT_NV20: + if (stObj->pt->format == PIPE_FORMAT_R10_G10B10_422_UNORM) { + key.lower_yuv |= (1 << unit); + break; + } + FALLTHROUGH; case PIPE_FORMAT_IYUV: if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || stObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) { diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 4b94397f8df..89e89fd103d 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -415,6 +415,18 @@ st_get_sampler_view_format(const struct st_context *st, } format = PIPE_FORMAT_R8_UNORM; break; + case PIPE_FORMAT_NV15: + if (texObj->pt->format == PIPE_FORMAT_R10_G10B10_420_UNORM) { + format = PIPE_FORMAT_R10_G10B10_420_UNORM; + break; + } + FALLTHROUGH; + case PIPE_FORMAT_NV20: + if (texObj->pt->format == PIPE_FORMAT_R10_G10B10_422_UNORM) { + format = PIPE_FORMAT_R10_G10B10_422_UNORM; + break; + } + FALLTHROUGH; case PIPE_FORMAT_P010: case PIPE_FORMAT_P012: case PIPE_FORMAT_P016: diff --git a/src/util/format/u_format.yaml b/src/util/format/u_format.yaml index 30913dd1e02..c0f46eb89f4 100644 --- a/src/util/format/u_format.yaml +++ b/src/util/format/u_format.yaml @@ -1900,7 +1900,18 @@ block: {width: 1, height: 1, depth: 1} channels: [UN8] swizzles: [X, 0, 0, 1] - +- name: NV15 + layout: planar2 + colorspace: YUV + block: {width: 1, height: 1, depth: 1} + channels: [] + swizzles: [X, Y, Z, W] +- name: NV20 + layout: planar2 + colorspace: YUV + block: {width: 1, height: 1, depth: 1} + channels: [] + swizzles: [X, Y, Z, W] # RGB versions of NV12, YV12, P010, and P012 for hardware that supports sampling # from multiplane textures but needs color-space conversion in the shader. @@ -1922,6 +1933,18 @@ block: {width: 1, height: 1, depth: 1} channels: [UN8] swizzles: [X, Y, Z, W] +- name: R10_G10B10_420_UNORM + layout: planar2 + colorspace: RGB + block: {width: 4, height: 1, depth: 1} + channels: [UN40] + swizzles: [X, Y, Z, W] +- name: R10_G10B10_422_UNORM + layout: planar2 + colorspace: RGB + block: {width: 4, height: 1, depth: 1} + channels: [UN40] + swizzles: [X, Y, Z, W] - name: R8_G8_B8_420_UNORM layout: planar3 colorspace: RGB diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index fda24594002..4a3873d2e9b 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -86,6 +86,8 @@ def has_access(format): 'nv12', 'nv16', 'nv21', + 'nv15', + 'nv20', 'p010', 'p012', 'p016', @@ -118,6 +120,8 @@ def has_access(format): 'r8_g8b8_420_unorm', 'r8_b8g8_420_unorm', 'g8_b8r8_420_unorm', + 'r10_g10b10_420_unorm', + 'r10_g10b10_422_unorm', 'r8_g8_b8_420_unorm', 'r8_b8_g8_420_unorm', 'g8_b8_r8_420_unorm', diff --git a/src/util/format/u_formats.h b/src/util/format/u_formats.h index 677691a2a35..7b6e7d8f7c8 100644 --- a/src/util/format/u_formats.h +++ b/src/util/format/u_formats.h @@ -306,6 +306,8 @@ enum pipe_format { PIPE_FORMAT_NV12, PIPE_FORMAT_NV21, PIPE_FORMAT_NV16, + PIPE_FORMAT_NV15, + PIPE_FORMAT_NV20, PIPE_FORMAT_Y8_400_UNORM, /* PIPE_FORMAT_Y8_U8_V8_420_UNORM = IYUV */ @@ -526,6 +528,8 @@ enum pipe_format { PIPE_FORMAT_R8_G8B8_420_UNORM, PIPE_FORMAT_R8_B8G8_420_UNORM, PIPE_FORMAT_G8_B8R8_420_UNORM, + PIPE_FORMAT_R10_G10B10_420_UNORM, + PIPE_FORMAT_R10_G10B10_422_UNORM, PIPE_FORMAT_R8_G8_B8_420_UNORM, PIPE_FORMAT_R8_B8_G8_420_UNORM, PIPE_FORMAT_G8_B8_R8_420_UNORM,