Module: Mesa Branch: main Commit: ae171458827bb8fceb232b3a13f61920e87a0d3a URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ae171458827bb8fceb232b3a13f61920e87a0d3a
Author: Mary Guillemard <mary.guillem...@collabora.com> Date: Wed Oct 11 18:51:04 2023 +0200 nak: Rewrite nir_intrinsic_load_sample_pos and implement nir_intrinsic_load_barycentric_at_sample nir_intrinsic_load_sample_pos was causing failures on barycentric CTS tests. Signed-off-by: Mary Guillemard <mary.guillem...@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26239> --- src/nouveau/compiler/nak.h | 8 +++++ src/nouveau/compiler/nak_nir.c | 53 ++++++++++++++++++++++++++---- src/nouveau/vulkan/nvk_graphics_pipeline.c | 4 +++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/nouveau/compiler/nak.h b/src/nouveau/compiler/nak.h index 14a8ca76f43..fa07cdac380 100644 --- a/src/nouveau/compiler/nak.h +++ b/src/nouveau/compiler/nak.h @@ -39,6 +39,14 @@ struct nak_fs_key { * VkPipelineMultisampleStateCreateInfo::minSampleShading */ bool force_sample_shading; + + /** + * The constant buffer index and offset at which the sample locations table lives. + * Each sample location is two 4-bit unorm values packed into an 8-bit value + * with the bottom 4 bits for x and the top 4 bits for y. + */ + uint8_t sample_locations_cb; + uint32_t sample_locations_offset; }; void nak_postprocess_nir(nir_shader *nir, const struct nak_compiler *nak, diff --git a/src/nouveau/compiler/nak_nir.c b/src/nouveau/compiler/nak_nir.c index d3c7ffb1742..a6639eabd7b 100644 --- a/src/nouveau/compiler/nak_nir.c +++ b/src/nouveau/compiler/nak_nir.c @@ -610,6 +610,27 @@ load_interpolated_input(nir_builder *b, unsigned num_components, uint32_t addr, } } +static nir_def * +load_sample_pos_at(nir_builder *b, nir_def *sample_id, + const struct nak_fs_key *fs_key) +{ + nir_def *loc = nir_load_ubo(b, 1, 64, + nir_imm_int(b, fs_key->sample_locations_cb), + nir_imm_int(b, fs_key->sample_locations_offset), + .align_mul = 8, + .align_offset = 0, + .range = fs_key->sample_locations_offset + 8); + + /* Yay little endian */ + loc = nir_ushr(b, loc, nir_imul_imm(b, sample_id, 8)); + nir_def *loc_x_u4 = nir_iand_imm(b, loc, 0xf); + nir_def *loc_y_u4 = nir_iand_imm(b, nir_ushr_imm(b, loc, 4), 0xf); + nir_def *loc_u4 = nir_vec2(b, loc_x_u4, loc_y_u4); + nir_def *result = nir_fmul_imm(b, nir_i2f32(b, loc_u4), 1.0 / 16.0); + + return result; +} + struct lower_fs_input_ctx { const struct nak_compiler *nak; const struct nak_fs_key *fs_key; @@ -630,8 +651,7 @@ lower_fs_input_intrin(nir_builder *b, nir_intrinsic_instr *intrin, void *data) } case nir_intrinsic_load_frag_coord: - case nir_intrinsic_load_point_coord: - case nir_intrinsic_load_sample_pos: { + case nir_intrinsic_load_point_coord: { b->cursor = nir_before_instr(&intrin->instr); const enum nak_interp_loc interp_loc = @@ -655,9 +675,6 @@ lower_fs_input_intrin(nir_builder *b, nir_intrinsic_instr *intrin, void *data) break; case nir_intrinsic_load_point_coord: break; - case nir_intrinsic_load_sample_pos: - coord = nir_ffract(b, coord); - break; default: unreachable("Unknown intrinsic"); } @@ -715,10 +732,20 @@ lower_fs_input_intrin(nir_builder *b, nir_intrinsic_instr *intrin, void *data) nir_def *offset = NULL; enum nak_interp_loc interp_loc; switch (bary->intrinsic) { - case nir_intrinsic_load_barycentric_at_offset: { + case nir_intrinsic_load_barycentric_at_offset: + case nir_intrinsic_load_barycentric_at_sample: { interp_loc = NAK_INTERP_LOC_OFFSET; - nir_def *offset_f = bary->src[0].ssa; + nir_def *offset_f; + + if (bary->intrinsic == nir_intrinsic_load_barycentric_at_sample) { + nir_def *sample_id = bary->src[0].ssa; + nir_def *sample_pos = load_sample_pos_at(b, sample_id, ctx->fs_key); + offset_f = nir_fadd_imm(b, sample_pos, -0.5); + } else { + offset_f = bary->src[0].ssa; + } + offset_f = nir_fclamp(b, offset_f, nir_imm_float(b, -0.5), nir_imm_float(b, 0.437500)); nir_def *offset_fixed = @@ -773,6 +800,18 @@ lower_fs_input_intrin(nir_builder *b, nir_intrinsic_instr *intrin, void *data) return true; } + case nir_intrinsic_load_sample_pos: { + b->cursor = nir_before_instr(&intrin->instr); + + nir_def *sample_id = nir_load_sample_id(b); + nir_def *sample_pos = load_sample_pos_at(b, sample_id, ctx->fs_key); + + nir_def_rewrite_uses(&intrin->def, sample_pos); + nir_instr_remove(&intrin->instr); + + return true; + } + default: return false; } diff --git a/src/nouveau/vulkan/nvk_graphics_pipeline.c b/src/nouveau/vulkan/nvk_graphics_pipeline.c index 4213f229aeb..0ce98cf809e 100644 --- a/src/nouveau/vulkan/nvk_graphics_pipeline.c +++ b/src/nouveau/vulkan/nvk_graphics_pipeline.c @@ -4,6 +4,7 @@ */ #include "nvk_pipeline.h" +#include "nvk_cmd_buffer.h" #include "nvk_device.h" #include "nvk_physical_device.h" #include "nvk_shader.h" @@ -48,6 +49,9 @@ nvk_populate_fs_key(struct nak_fs_key *key, { memset(key, 0, sizeof(*key)); + key->sample_locations_cb = 0; + key->sample_locations_offset = nvk_root_descriptor_offset(draw.sample_locations); + if (state->pipeline_flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT) key->zs_self_dep = true;