Mesa (staging/21.1): radv: Handle unnormalized samplers in YCbCr lowering

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 17 19:00:34 UTC 2021


Module: Mesa
Branch: staging/21.1
Commit: 8a1f8951284cd16c5c0e6bc6b8d83de7f0c15054
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8a1f8951284cd16c5c0e6bc6b8d83de7f0c15054

Author: Joshua Ashton <joshua at froggi.es>
Date:   Sat May 15 14:43:14 2021 +0100

radv: Handle unnormalized samplers in YCbCr lowering

We need to divide these by their divisors and special-case COSITED_EVEN.

Fixes NV12 compositing in Gamescope.

Fixes: 91702374 ("radv: Add ycbcr lowering pass.")
Cc: mesa-stable
Signed-off-by: Joshua Ashton <joshua at froggi.es>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10816>
(cherry picked from commit 855cb78d4631afeb51291cf1f2f936841d52e8d4)

---

 .pick_status.json                              |  2 +-
 src/amd/vulkan/radv_nir_lower_ycbcr_textures.c | 41 ++++++++++++++++++++------
 2 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 0e0efe4e52a..6801687788f 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -31,7 +31,7 @@
         "description": "radv: Handle unnormalized samplers in YCbCr lowering",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": "91702374d5d70296c967c324fff1844cc2933dd4"
     },
diff --git a/src/amd/vulkan/radv_nir_lower_ycbcr_textures.c b/src/amd/vulkan/radv_nir_lower_ycbcr_textures.c
index a42852faac8..0a517dd5da0 100644
--- a/src/amd/vulkan/radv_nir_lower_ycbcr_textures.c
+++ b/src/amd/vulkan/radv_nir_lower_ycbcr_textures.c
@@ -34,6 +34,7 @@ struct ycbcr_state {
    nir_tex_instr *origin_tex;
    nir_deref_instr *tex_deref;
    const struct radv_sampler_ycbcr_conversion *conversion;
+   bool unnormalized_coordinates;
 };
 
 static nir_ssa_def *
@@ -67,6 +68,14 @@ implicit_downsampled_coord(nir_builder *b, nir_ssa_def *value, nir_ssa_def *max_
       nir_fdiv(b, nir_imm_float(b, 1.0f), nir_fmul(b, nir_imm_float(b, div_scale), max_value)));
 }
 
+static nir_ssa_def *
+implicit_downsampled_coord_unnormalized(nir_builder *b, nir_ssa_def *value, int div_scale)
+{
+   return nir_fadd(
+      b, value,
+      nir_imm_float(b, 1.0f / (float)div_scale));
+}
+
 static nir_ssa_def *
 implicit_downsampled_coords(struct ycbcr_state *state, nir_ssa_def *old_coords)
 {
@@ -82,15 +91,22 @@ implicit_downsampled_coords(struct ycbcr_state *state, nir_ssa_def *old_coords)
                                  chroma_format <= PIPE_VIDEO_CHROMA_FORMAT_420 ? 2 : 1};
 
    for (int c = 0; c < old_coords->num_components; c++) {
-      if (c < ARRAY_SIZE(divisors) && divisors[c] > 1 &&
-          conversion->chroma_offsets[c] == VK_CHROMA_LOCATION_COSITED_EVEN) {
-         if (!image_size)
-            image_size = get_texture_size(state, state->tex_deref);
-
-         comp[c] = implicit_downsampled_coord(b, nir_channel(b, old_coords, c),
-                                              nir_channel(b, image_size, c), divisors[c]);
-      } else {
-         comp[c] = nir_channel(b, old_coords, c);
+      comp[c] = nir_channel(b, old_coords, c);
+
+      if (c < ARRAY_SIZE(divisors) && divisors[c] > 1) {
+         if (state->unnormalized_coordinates)
+            comp[c] = nir_fdiv(b, comp[c], nir_imm_float(b, divisors[c]));
+
+         if (conversion->chroma_offsets[c] == VK_CHROMA_LOCATION_COSITED_EVEN) {
+            if (state->unnormalized_coordinates) {
+               comp[c] = implicit_downsampled_coord_unnormalized(b, comp[c], divisors[c]);
+            } else {
+               if (!image_size)
+                  image_size = get_texture_size(state, state->tex_deref);
+
+               comp[c] = implicit_downsampled_coord(b, comp[c], nir_channel(b, image_size, c), divisors[c]);
+            }
+         }
       }
    }
 
@@ -220,6 +236,10 @@ try_lower_tex_ycbcr(const struct radv_pipeline_layout *layout, nir_builder *buil
    if (!ycbcr_samplers)
       return false;
 
+   assert(binding->immutable_samplers_offset);
+   const uint32_t *immutable_samplers =
+      radv_immutable_samplers(set_layout, binding);
+
    /* For the following instructions, we don't apply any change and let the
     * instruction apply to the first plane.
     */
@@ -240,11 +260,14 @@ try_lower_tex_ycbcr(const struct radv_pipeline_layout *layout, nir_builder *buil
    if (ycbcr_sampler->format == VK_FORMAT_UNDEFINED)
       return false;
 
+   bool unnormalized_coordinates = immutable_samplers[4 * array_index + 0] & S_008F30_FORCE_UNNORMALIZED(1);
+
    struct ycbcr_state state = {
       .builder = builder,
       .origin_tex = tex,
       .tex_deref = deref,
       .conversion = ycbcr_sampler,
+      .unnormalized_coordinates = unnormalized_coordinates,
    };
 
    builder->cursor = nir_before_instr(&tex->instr);



More information about the mesa-commit mailing list