diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.h b/src/nouveau/vulkan/nvk_cmd_buffer.h index 4e62c63490c..8db415a4a10 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.h +++ b/src/nouveau/vulkan/nvk_cmd_buffer.h @@ -23,6 +23,11 @@ struct nvk_cmd_pool; struct nvk_image_view; struct nvk_push_descriptor_set; +struct nvk_sample_location { + uint8_t x_u4:4; + uint8_t y_u4:4; +}; + /** Root descriptor table. This gets pushed to the GPU directly */ struct nvk_root_descriptor_table { uint64_t root_desc_addr; @@ -33,7 +38,7 @@ struct nvk_root_descriptor_table { uint32_t base_instance; uint32_t draw_id; uint32_t view_index; - uint32_t _pad[2]; + struct nvk_sample_location sample_locations[8]; } draw; struct { uint32_t base_group[3]; diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index 051603a4179..7aaaf072918 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -1203,11 +1203,6 @@ vk_sample_location(const struct vk_sample_locations_state *sl, return sl->locations[(x + y * sl->grid_size.width) * sl->per_pixel + s]; } -struct nvk_sample_location { - uint8_t x_u4:4; - uint8_t y_u4:4; -}; - static struct nvk_sample_location vk_to_nvk_sample_location(VkSampleLocationEXT loc) { @@ -1220,6 +1215,7 @@ vk_to_nvk_sample_location(VkSampleLocationEXT loc) static void nvk_flush_ms_state(struct nvk_cmd_buffer *cmd) { + struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors; const struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state; @@ -1232,6 +1228,11 @@ nvk_flush_ms_state(struct nvk_cmd_buffer *cmd) sl = vk_standard_sample_locations_state(dyn->ms.rasterization_samples); } + for (uint32_t i = 0; i < sl->per_pixel; i++) { + desc->root.draw.sample_locations[i] = + vk_to_nvk_sample_location(sl->locations[i]); + } + if (nvk_cmd_buffer_3d_cls(cmd) >= MAXWELL_B) { struct nvk_sample_location loc[16]; for (uint32_t n = 0; n < ARRAY_SIZE(loc); n++) { diff --git a/src/nouveau/vulkan/nvk_nir_lower_descriptors.c b/src/nouveau/vulkan/nvk_nir_lower_descriptors.c index 2633fdb7d32..d3d98667b4c 100644 --- a/src/nouveau/vulkan/nvk_nir_lower_descriptors.c +++ b/src/nouveau/vulkan/nvk_nir_lower_descriptors.c @@ -307,6 +307,39 @@ lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin, return true; } +static bool +lower_interp_at_sample(nir_builder *b, nir_intrinsic_instr *interp, + const struct lower_descriptors_ctx *ctx) +{ + const uint32_t root_table_offset = + nvk_root_descriptor_offset(draw.sample_locations); + + nir_def *sample = interp->src[1].ssa; + + b->cursor = nir_before_instr(&interp->instr); + + nir_def *loc = nir_load_ubo(b, 1, 64, + nir_imm_int(b, 0), /* Root table */ + nir_imm_int(b, root_table_offset), + .align_mul = 8, + .align_offset = 0, + .range = root_table_offset + 8); + + /* Yay little endian */ + loc = nir_ushr(b, loc, nir_imul_imm(b, sample, 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 *loc_f = nir_fmul_imm(b, nir_i2f32(b, loc_u4), 1.0 / 16.0); + nir_def *offset = nir_fadd_imm(b, loc_f, -0.5); + + assert(interp->intrinsic == nir_intrinsic_interp_deref_at_sample); + interp->intrinsic = nir_intrinsic_interp_deref_at_offset; + nir_src_rewrite(&interp->src[1], offset); + + return true; +} + static bool try_lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin, const struct lower_descriptors_ctx *ctx) @@ -341,6 +374,9 @@ try_lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin, case nir_intrinsic_image_deref_store_raw_intel: return lower_image_intrin(b, intrin, ctx); + case nir_intrinsic_interp_deref_at_sample: + return lower_interp_at_sample(b, intrin, ctx); + default: return false; }