Module: Mesa Branch: main Commit: 08f851f4361cfbdb211dc70d03cf3ebff331c3ee URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=08f851f4361cfbdb211dc70d03cf3ebff331c3ee
Author: José Roberto de Souza <jose.so...@intel.com> Date: Tue Aug 15 13:45:26 2023 -0700 anv: Bring back the non optimized version of build_load_render_surface_state_address() Commit 50c29e1ffa1c ("anv: simplify buffer address+size loads from descriptor buffer") is making use of AuxiliarySurfaceBaseAddress field to store buffer lenght as it was not used but a LNL workaround will make use of it so we need to bring back this non optimized version of build_load_render_surface_state_address(). There is some conflicts so a simple revert do not works. Signed-off-by: José Roberto de Souza <jose.so...@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26152> --- src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 108 ++++++++++++++++++++++- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index dc39affe05f..6aad6fe2fe5 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -355,9 +355,9 @@ build_load_descriptor_mem(nir_builder *b, * buffer size and just load a vec4. */ static nir_def * -build_load_render_surface_state_address(nir_builder *b, - nir_def *desc_addr, - struct apply_pipeline_layout_state *state) +build_optimized_load_render_surface_state_address(nir_builder *b, + nir_def *desc_addr, + struct apply_pipeline_layout_state *state) { const struct intel_device_info *devinfo = &state->pdevice->info; @@ -373,6 +373,108 @@ build_load_render_surface_state_address(nir_builder *b, return nir_vec4(b, addr_ldw, addr_udw, length, nir_imm_int(b, 0)); } +/* When using direct descriptor, we do not have a structure to read in memory + * like anv_address_range_descriptor where all the fields match perfectly the + * vec4 address format we need to generate for A64 messages. Instead we need + * to build the vec4 from parsing the RENDER_SURFACE_STATE structure. Easy + * enough for the surface address, lot less fun for the size. + */ +static nir_def * +build_non_optimized_load_render_surface_state_address(nir_builder *b, + nir_def *desc_addr, + struct apply_pipeline_layout_state *state) + +{ + const struct intel_device_info *devinfo = &state->pdevice->info; + + assert(((RENDER_SURFACE_STATE_SurfaceBaseAddress_start(devinfo) + + RENDER_SURFACE_STATE_SurfaceBaseAddress_bits(devinfo) - 1) - + RENDER_SURFACE_STATE_Width_start(devinfo)) / 8 <= 32); + + nir_def *surface_addr = + build_load_descriptor_mem(b, desc_addr, + RENDER_SURFACE_STATE_SurfaceBaseAddress_start(devinfo) / 8, + DIV_ROUND_UP(RENDER_SURFACE_STATE_SurfaceBaseAddress_bits(devinfo), 32), + 32, state); + nir_def *addr_ldw = nir_channel(b, surface_addr, 0); + nir_def *addr_udw = nir_channel(b, surface_addr, 1); + + /* Take all the RENDER_SURFACE_STATE fields from the beginning of the + * structure up to the Depth field. + */ + const uint32_t type_sizes_dwords = + DIV_ROUND_UP(RENDER_SURFACE_STATE_Depth_start(devinfo) + + RENDER_SURFACE_STATE_Depth_bits(devinfo), 32); + nir_def *type_sizes = + build_load_descriptor_mem(b, desc_addr, 0, type_sizes_dwords, 32, state); + + const unsigned width_start = RENDER_SURFACE_STATE_Width_start(devinfo); + /* SKL PRMs, Volume 2d: Command Reference: Structures, RENDER_SURFACE_STATE + * + * Width: "bits [6:0] of the number of entries in the buffer - 1" + * Height: "bits [20:7] of the number of entries in the buffer - 1" + * Depth: "bits [31:21] of the number of entries in the buffer - 1" + */ + const unsigned width_bits = 7; + nir_def *width = + nir_iand_imm(b, + nir_ishr_imm(b, + nir_channel(b, type_sizes, width_start / 32), + width_start % 32), + (1u << width_bits) - 1); + + const unsigned height_start = RENDER_SURFACE_STATE_Height_start(devinfo); + const unsigned height_bits = RENDER_SURFACE_STATE_Height_bits(devinfo); + nir_def *height = + nir_iand_imm(b, + nir_ishr_imm(b, + nir_channel(b, type_sizes, height_start / 32), + height_start % 32), + (1u << height_bits) - 1); + + const unsigned depth_start = RENDER_SURFACE_STATE_Depth_start(devinfo); + const unsigned depth_bits = RENDER_SURFACE_STATE_Depth_bits(devinfo); + nir_def *depth = + nir_iand_imm(b, + nir_ishr_imm(b, + nir_channel(b, type_sizes, depth_start / 32), + depth_start % 32), + (1u << depth_bits) - 1); + + nir_def *length = width; + length = nir_ior(b, length, nir_ishl_imm(b, height, width_bits)); + length = nir_ior(b, length, nir_ishl_imm(b, depth, width_bits + height_bits)); + length = nir_iadd_imm(b, length, 1); + + /* Check the surface type, if it's SURFTYPE_NULL, set the length of the + * buffer to 0. + */ + const unsigned type_start = RENDER_SURFACE_STATE_SurfaceType_start(devinfo); + const unsigned type_dw = type_start / 32; + nir_def *type = + nir_iand_imm(b, + nir_ishr_imm(b, + nir_channel(b, type_sizes, type_dw), + type_start % 32), + (1u << RENDER_SURFACE_STATE_SurfaceType_bits(devinfo)) - 1); + + length = nir_bcsel(b, + nir_ieq_imm(b, type, 7 /* SURFTYPE_NULL */), + nir_imm_int(b, 0), length); + + return nir_vec4(b, addr_ldw, addr_udw, length, nir_imm_int(b, 0)); +} + +static inline nir_def * +build_load_render_surface_state_address(nir_builder *b, + nir_def *desc_addr, + struct apply_pipeline_layout_state *state) +{ + if (state->pdevice->isl_dev.buffer_length_in_aux_addr) + return build_optimized_load_render_surface_state_address(b, desc_addr, state); + return build_non_optimized_load_render_surface_state_address(b, desc_addr, state); +} + /* Load the depth of a 3D storage image. * * Either by reading the indirect descriptor value, or reading the value from