diff options
author | Mike Blumenkrantz <[email protected]> | 2019-05-29 17:14:32 -0400 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2019-07-31 09:50:06 -0700 |
commit | 7404833c2e3227b61f53ad93b0e3a1a4d545c05f (patch) | |
tree | 05ca13aada923987187442d9137b62d2b4b747f7 /src/mesa | |
parent | 338a29b08fe69aa91ad0318d54da1670f40307f0 (diff) |
gallium: add handling for YUV planar surfaces
st/dri:
this adds a table (similar to the one in i965) which provides
mappings for turning various planar formats into multiple sampler views.
whereas only NV12 and IYUV were supported, now many more formats are
supported here:
* P0XX
* YUV4XX
* YVU4XX
* AYUV
* XYUV
* YUYV
* UYVY
the table is used directly to handle image creation, simplifying
a lot of code and resolving related TODO/FIXME items where workarounds were
previously in place to manage NV12 and IYUV formats exclusively
st/mesa:
the changes here relate to setting up samplers for the planar formats.
this requires:
* checking for driver support for all the sampler formats
* creating the samplers with the corresponding formats and swizzling
* running nir_lower_tex with the appropriate options to trigger the lowering
for each plane->sampler
fixes kwg/mesa#36
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_atom_sampler.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_texture.c | 26 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_eglimage.c | 61 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 21 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 18 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_sampler_view.c | 13 |
6 files changed, 135 insertions, 7 deletions
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 27e4da31581..758ace10b8a 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -309,6 +309,9 @@ update_shader_samplers(struct st_context *st, switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_P016: + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: /* we need one additional sampler: */ 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 ce7755f0c58..8a881c24fb3 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -191,6 +191,14 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); break; + case PIPE_FORMAT_P016: + /* we need one additional R16G16 view: */ + tmpl.format = PIPE_FORMAT_RG1616_UNORM; + tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R16 */ + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; case PIPE_FORMAT_IYUV: /* we need two additional R8 views: */ tmpl.format = PIPE_FORMAT_R8_UNORM; @@ -201,6 +209,24 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl); break; + case PIPE_FORMAT_YUYV: + /* we need one additional BGRA8888 view: */ + tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; + case PIPE_FORMAT_UYVY: + /* we need one additional RGBA8888 view: */ + tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; default: break; } diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 08697c42dfa..77abe55cfb2 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -54,17 +54,56 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, * a shader variant that converts. */ if ((usage == PIPE_BIND_SAMPLER_VIEW) && !supported) { - if (format == PIPE_FORMAT_IYUV) { + switch (format) { + case PIPE_FORMAT_IYUV: supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage); - } else if (format == PIPE_FORMAT_NV12) { + break; + case PIPE_FORMAT_NV12: supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage) && screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage); + break; + case PIPE_FORMAT_P016: + supported = screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_YUYV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_UYVY: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_AYUV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + case PIPE_FORMAT_XYUV: + supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBX8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage); + break; + default: + break; } } @@ -204,10 +243,28 @@ st_bind_egl_image(struct gl_context *ctx, texFormat = MESA_FORMAT_R_UNORM8; texObj->RequiredTextureImageUnits = 2; break; + case PIPE_FORMAT_P016: + texFormat = MESA_FORMAT_R_UNORM16; + texObj->RequiredTextureImageUnits = 2; + break; case PIPE_FORMAT_IYUV: texFormat = MESA_FORMAT_R_UNORM8; texObj->RequiredTextureImageUnits = 3; break; + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: + texFormat = MESA_FORMAT_R8G8_UNORM; + texObj->RequiredTextureImageUnits = 2; + break; + case PIPE_FORMAT_AYUV: + texFormat = MESA_FORMAT_R8G8B8A8_UNORM; + internalFormat = GL_RGBA; + texObj->RequiredTextureImageUnits = 1; + break; + case PIPE_FORMAT_XYUV: + texFormat = MESA_FORMAT_R8G8B8X8_UNORM; + texObj->RequiredTextureImageUnits = 1; + break; default: texFormat = st_pipe_format_to_mesa_format(stimg->format); break; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 7d1ed5634eb..81065612adb 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1201,20 +1201,28 @@ st_create_fp_variant(struct st_context *st, NIR_PASS_V(tgsi.ir.nir, nir_lower_drawpixels, &options); } - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv || + key->external.lower_ayuv || key->external.lower_xyuv)) { nir_lower_tex_options options = {0}; options.lower_y_uv_external = key->external.lower_nv12; options.lower_y_u_v_external = key->external.lower_iyuv; + options.lower_xy_uxvx_external = key->external.lower_xy_uxvx; + options.lower_yx_xuxv_external = key->external.lower_yx_xuxv; + options.lower_ayuv_external = key->external.lower_ayuv; + options.lower_xyuv_external = key->external.lower_xyuv; NIR_PASS_V(tgsi.ir.nir, nir_lower_tex, &options); } st_finalize_nir(st, &stfp->Base, stfp->shader_program, tgsi.ir.nir); - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv)) { /* This pass needs to happen *after* nir_lower_sampler */ NIR_PASS_V(tgsi.ir.nir, st_nir_lower_tex_src_plane, ~stfp->Base.SamplersUsed, - key->external.lower_nv12, + key->external.lower_nv12 || key->external.lower_xy_uxvx || + key->external.lower_yx_xuxv, key->external.lower_iyuv); } @@ -1318,7 +1326,8 @@ st_create_fp_variant(struct st_context *st, fprintf(stderr, "mesa: cannot create a shader for glDrawPixels\n"); } - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) { + if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + key->external.lower_xy_uxvx || key->external.lower_yx_xuxv)) { const struct tgsi_token *tokens; /* samplers inserted would conflict, but this should be unpossible: */ @@ -1326,7 +1335,9 @@ st_create_fp_variant(struct st_context *st, tokens = st_tgsi_lower_yuv(tgsi.tokens, ~stfp->Base.SamplersUsed, - key->external.lower_nv12, + key->external.lower_nv12 || + key->external.lower_xy_uxvx || + key->external.lower_yx_xuxv, key->external.lower_iyuv); if (tokens) { if (tgsi.tokens != stfp->tgsi.tokens) diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 59a60368039..caaa779287a 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -53,6 +53,10 @@ struct st_external_sampler_key { GLuint lower_nv12; /**< bitmask of 2 plane YUV samplers */ GLuint lower_iyuv; /**< bitmask of 3 plane YUV samplers */ + GLuint lower_xy_uxvx; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_yx_xuxv; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_ayuv; + GLuint lower_xyuv; }; static inline struct st_external_sampler_key @@ -70,12 +74,26 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_P016: key.lower_nv12 |= (1 << unit); break; case PIPE_FORMAT_IYUV: key.lower_iyuv |= (1 << unit); break; + case PIPE_FORMAT_YUYV: + key.lower_yx_xuxv |= (1 << unit); + break; + case PIPE_FORMAT_UYVY: + key.lower_xy_uxvx |= (1 << unit); + break; + case PIPE_FORMAT_AYUV: + key.lower_ayuv |= (1 << unit); + break; + case PIPE_FORMAT_XYUV: + key.lower_xyuv |= (1 << unit); + break; default: + printf("unhandled %u\n", st_get_view_format(stObj)); break; } } diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 9c45de6032d..2fa08815085 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -495,6 +495,19 @@ get_sampler_view_format(struct st_context *st, case PIPE_FORMAT_IYUV: format = PIPE_FORMAT_R8_UNORM; break; + case PIPE_FORMAT_P016: + format = PIPE_FORMAT_R16_UNORM; + break; + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: + format = PIPE_FORMAT_R8G8_UNORM; + break; + case PIPE_FORMAT_AYUV: + format = PIPE_FORMAT_RGBA8888_UNORM; + break; + case PIPE_FORMAT_XYUV: + format = PIPE_FORMAT_RGBX8888_UNORM; + break; default: break; } |