Skip to content
Snippets Groups Projects
Commit 855cb78d authored by Autumn Ashton's avatar Autumn Ashton :frog: Committed by Marge Bot
Browse files

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: default avatarJoshua Ashton <joshua@froggi.es>
Reviewed-by: default avatarBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <mesa/mesa!10816>
parent fc765d6a
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment