diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 242f9577cf7..2d7f3b3916f 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -858,6 +858,17 @@ dri2_update_tex_buffer(struct dri_drawable *drawable, /* no-op */ } +static const struct dri2_format_mapping r8_g8_b8_mapping = { + DRM_FORMAT_YUV420, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, + PIPE_FORMAT_R8_G8_B8_420_UNORM, + 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 }, + { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 } } +}; + static const struct dri2_format_mapping r8_g8b8_mapping = { DRM_FORMAT_NV12, __DRI_IMAGE_FORMAT_NONE, @@ -953,6 +964,15 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } + /* For I420, see if we have support for sampling r8_g8_b8 */ + if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV && + map->dri_fourcc == DRM_FORMAT_YUV420 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r8_g8_b8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + /* If the hardware supports R8G8_R8B8 style subsampled RGB formats, these * can be used for YUYV and UYVY formats. */ diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 9f04aac98ee..4157a105c0d 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -298,6 +298,10 @@ update_shader_samplers(struct st_context *st, states[extra] = sampler; break; case PIPE_FORMAT_IYUV: + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + /* no additional views needed */ + break; + } /* we need two additional samplers: */ extra = u_bit_scan(&free_slots); states[extra] = sampler; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index f816dbdaa40..ed3e0d8bc0e 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -210,6 +210,10 @@ st_get_sampler_views(struct st_context *st, pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); break; case PIPE_FORMAT_IYUV: + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) + /* no additional views needed */ + break; + /* we need two additional R8 views: */ tmpl.format = PIPE_FORMAT_R8_UNORM; extra = u_bit_scan(&free_slots); diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 4b0a639c48a..6156d00f76e 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -194,6 +194,24 @@ is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *ou return false; } +static bool +is_i420_as_r8_g8_b8_420_supported(struct pipe_screen *screen, + struct st_egl_image *out, + unsigned usage, bool *native_supported) +{ + if (out->format == PIPE_FORMAT_IYUV && + out->texture->format == PIPE_FORMAT_R8_G8_B8_420_UNORM && + screen->is_format_supported(screen, PIPE_FORMAT_R8_G8_B8_420_UNORM, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + + return false; +} /** * Return the gallium texture of an EGLImage. @@ -218,6 +236,7 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle, } if (!is_nv12_as_r8_g8b8_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, native_supported)) { @@ -372,8 +391,13 @@ st_bind_egl_image(struct gl_context *ctx, texObj->RequiredTextureImageUnits = 1; break; case PIPE_FORMAT_IYUV: - texFormat = MESA_FORMAT_R_UNORM8; - texObj->RequiredTextureImageUnits = 3; + if (stimg->texture->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + texFormat = MESA_FORMAT_R8G8B8X8_UNORM; + texObj->RequiredTextureImageUnits = 1; + } else { + texFormat = MESA_FORMAT_R_UNORM8; + texObj->RequiredTextureImageUnits = 3; + } break; case PIPE_FORMAT_YUYV: case PIPE_FORMAT_YVYU: diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index ea35fe5c87a..7a826f832fd 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -104,6 +104,10 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) key.lower_nv21 |= (1 << unit); break; case PIPE_FORMAT_IYUV: + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + key.lower_yuv |= (1 << unit); + break; + } key.lower_iyuv |= (1 << unit); break; case PIPE_FORMAT_YUYV: diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 59df3922c78..753b67733f2 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -393,6 +393,10 @@ st_get_sampler_view_format(const struct st_context *st, } FALLTHROUGH; case PIPE_FORMAT_IYUV: + if (texObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + format = PIPE_FORMAT_R8_G8_B8_420_UNORM; + break; + } format = PIPE_FORMAT_R8_UNORM; break; case PIPE_FORMAT_P010: diff --git a/src/util/format/u_format.csv b/src/util/format/u_format.csv index cbb39ba16a2..93517cec310 100644 --- a/src/util/format/u_format.csv +++ b/src/util/format/u_format.csv @@ -407,6 +407,7 @@ PIPE_FORMAT_Y8_400_UNORM , other , 1, 1, 1, un8, , , , x0 # multiplane textures but needs color-space conversion in the shader. PIPE_FORMAT_R8_G8B8_420_UNORM , planar2, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_G8_B8R8_420_UNORM , planar2, 1, 1, 1, un8, , , , xyzw, rgb +PIPE_FORMAT_R8_G8_B8_420_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_G8_B8_R8_420_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_R8_G8_B8_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index 84d0e21ee95..8427760a2a4 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -114,6 +114,7 @@ def has_access(format): 'y16_u16_v16_444_unorm', 'r8_g8b8_420_unorm', 'g8_b8r8_420_unorm', + 'r8_g8_b8_420_unorm', 'g8_b8_r8_420_unorm', 'r8_g8_b8_unorm', 'y8_unorm', diff --git a/src/util/format/u_formats.h b/src/util/format/u_formats.h index 935e8bc2bbc..45af123b9ef 100644 --- a/src/util/format/u_formats.h +++ b/src/util/format/u_formats.h @@ -512,6 +512,7 @@ enum pipe_format { PIPE_FORMAT_R8_G8B8_420_UNORM, PIPE_FORMAT_G8_B8R8_420_UNORM, + PIPE_FORMAT_R8_G8_B8_420_UNORM, PIPE_FORMAT_G8_B8_R8_420_UNORM, PIPE_FORMAT_R8_G8_B8_UNORM, PIPE_FORMAT_Y8_UNORM,