summaryrefslogtreecommitdiff
path: root/src/amd
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2021-05-15 14:43:14 +0100
committerEric Engestrom <eric@engestrom.ch>2021-05-18 23:02:27 +0200
commit3514ef15ba264b16abe35f19eed938a20ba97da2 (patch)
tree0d18f1b91e5821bd1d21dbfef91571c97f665f46 /src/amd
parent85822fb7c11cc908fd220633008f4c868581fd29 (diff)
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@froggi.es> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10816> (cherry picked from commit 855cb78d4631afeb51291cf1f2f936841d52e8d4)
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/vulkan/radv_nir_lower_ycbcr_textures.c41
1 files changed, 32 insertions, 9 deletions
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 *
@@ -68,6 +69,14 @@ implicit_downsampled_coord(nir_builder *b, nir_ssa_def *value, nir_ssa_def *max_
}
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)
{
nir_builder *b = state->builder;
@@ -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);