diff --git a/src/intel/genxml/meson.build b/src/intel/genxml/meson.build index cb06e30ebc7..43d94b9913d 100644 --- a/src/intel/genxml/meson.build +++ b/src/intel/genxml/meson.build @@ -57,6 +57,7 @@ genX_bits_included_symbols = [ # structures 'RENDER_SURFACE_STATE::Surface Base Address', 'RENDER_SURFACE_STATE::Surface Pitch', + 'RENDER_SURFACE_STATE::Surface QPitch', 'RENDER_SURFACE_STATE::Auxiliary Surface Base Address', 'RENDER_SURFACE_STATE::Auxiliary Surface Pitch', 'RENDER_SURFACE_STATE::Clear Value Address', @@ -69,6 +70,7 @@ genX_bits_included_symbols = [ 'RENDER_SURFACE_STATE::Depth', 'RENDER_SURFACE_STATE::Surface Type', 'RENDER_SURFACE_STATE::Render Target View Extent', + 'RENDER_SURFACE_STATE::Tile Mode', 'CLEAR_COLOR', 'VERTEX_BUFFER_STATE::Buffer Starting Address', 'CPS_STATE', diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index 6c95c416ded..66b5250f216 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -2258,6 +2258,15 @@ anv_descriptor_set_write_image_view(struct anv_device *device, device->physical, anv_image_view_storage_surface_state(image_view)->state), .image_depth = image_view->vk.storage.z_slice_count, + .image_address = (anv_image_is_sparse(image_view->image) ? + image_view->image->bindings[ + ANV_IMAGE_MEMORY_BINDING_MAIN].sparse_data.address : + anv_address_physical( + image_view->image->bindings[ + ANV_IMAGE_MEMORY_BINDING_MAIN].address)), + .tile_mode = image_view->image->planes[0].primary_surface.isl.tiling == ISL_TILING_LINEAR ? 0 : 0xffffffff, + .row_pitch_B = image_view->image->planes[0].primary_surface.isl.row_pitch_B, + .qpitch = image_view->image->planes[0].primary_surface.isl.array_pitch_el_rows, }; memcpy(desc_surface_map, &desc_data, sizeof(desc_data)); } else { @@ -2392,6 +2401,8 @@ anv_descriptor_set_write_buffer_view(struct anv_device *device, struct anv_storage_image_descriptor desc_data = { .vanilla = anv_surface_state_to_handle( device->physical, buffer_view->storage.state), + .image_address = anv_address_physical(buffer_view->address), + /* tile_mode, row_pitch_B, qpitch = 0 */ }; memcpy(desc_map, &desc_data, sizeof(desc_data)); } diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index 14e07d3b5f7..896099f49e4 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -1661,6 +1661,121 @@ lower_get_ssbo_size(nir_builder *b, nir_intrinsic_instr *intrin, return true; } +static bool +lower_image_load_intel_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, + struct apply_pipeline_layout_state *state) +{ + nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); + nir_variable *var = nir_deref_instr_get_variable(deref); + + unsigned set = var->data.descriptor_set; + unsigned binding = var->data.binding; + + b->cursor = nir_instr_remove(&intrin->instr); + + nir_def *array_index; + if (deref->deref_type != nir_deref_type_var) { + assert(deref->deref_type == nir_deref_type_array); + assert(nir_deref_instr_parent(deref)->deref_type == nir_deref_type_var); + array_index = deref->arr.index.ssa; + } else { + array_index = nir_imm_int(b, 0); + } + + nir_def *desc_addr = build_desc_addr_for_binding( + b, set, binding, array_index, 0 /* plane */, state); + + nir_def *desc; + + if (state->layout->type == ANV_PIPELINE_DESCRIPTOR_SET_LAYOUT_TYPE_INDIRECT) { + switch (nir_intrinsic_base(intrin)) { + case ISL_SURF_PARAM_BASE_ADDRESSS: + desc = build_load_descriptor_mem( + b, desc_addr, + offsetof(struct anv_storage_image_descriptor, image_address), + 1, 64, state); + break; + case ISL_SURF_PARAM_TILE_MODE: + desc = build_load_descriptor_mem( + b, desc_addr, + offsetof(struct anv_storage_image_descriptor, tile_mode), + 1, 32, state); + break; + case ISL_SURF_PARAM_PITCH: + desc = build_load_descriptor_mem( + b, desc_addr, + offsetof(struct anv_storage_image_descriptor, row_pitch_B), + 1, 32, state); + break; + case ISL_SURF_PARAM_QPITCH: + desc = build_load_descriptor_mem( + b, desc_addr, + offsetof(struct anv_storage_image_descriptor, qpitch), + 1, 32, state); + break; + default: + unreachable("Invalid surface parameter"); + } + } else { + const struct intel_device_info *devinfo = &state->pdevice->info; + + switch (nir_intrinsic_base(intrin)) { + case ISL_SURF_PARAM_BASE_ADDRESSS: { + desc = build_load_descriptor_mem( + b, desc_addr, + RENDER_SURFACE_STATE_SurfaceBaseAddress_start(devinfo) / 8, + intrin->def.num_components, + intrin->def.bit_size, state); + break; + } + case ISL_SURF_PARAM_TILE_MODE: { + // tile mode [13:12] is in the first dword + const unsigned tile_mode_bits = + RENDER_SURFACE_STATE_TileMode_bits(devinfo); + const unsigned tile_mode_start = + RENDER_SURFACE_STATE_TileMode_start(devinfo); + + nir_def *dword = + build_load_descriptor_mem(b, desc_addr, tile_mode_start / 32, 1, 32, state); + + desc = nir_iand_imm(b, + nir_ishr_imm(b, dword, tile_mode_start % 32), + (1u << tile_mode_bits) - 1); + break; + } + case ISL_SURF_PARAM_PITCH: { + assert(RENDER_SURFACE_STATE_SurfacePitch_start(devinfo) % 32 == 0); + const unsigned surfPitch_bits = + RENDER_SURFACE_STATE_SurfacePitch_bits(devinfo); + nir_def *pitch_dword = build_load_descriptor_mem( + b, desc_addr, + RENDER_SURFACE_STATE_SurfacePitch_start(devinfo) / 8, + 1, 32, state); + desc = nir_iand_imm(b, pitch_dword, (1u << surfPitch_bits) - 1); + desc = nir_iadd_imm(b, desc, 1); + break; + } + case ISL_SURF_PARAM_QPITCH: { + assert(RENDER_SURFACE_STATE_SurfaceQPitch_start(devinfo) % 32 == 0); + const unsigned surfQPitch_bits = + RENDER_SURFACE_STATE_SurfaceQPitch_bits(devinfo); + nir_def *pitch_dword = build_load_descriptor_mem( + b, desc_addr, + RENDER_SURFACE_STATE_SurfaceQPitch_start(devinfo) / 8, + 1, 32, state); + desc = nir_iand_imm(b, pitch_dword, (1u << surfQPitch_bits) - 1); + desc = nir_ishl_imm(b, desc, 2); + break; + } + default: + unreachable("Invalid surface parameter"); + } + } + + nir_def_rewrite_uses(&intrin->def, desc); + return true; +} + static bool lower_image_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, struct apply_pipeline_layout_state *state) @@ -1955,11 +2070,12 @@ apply_pipeline_layout(nir_builder *b, nir_instr *instr, void *_state) case nir_intrinsic_image_deref_atomic: case nir_intrinsic_image_deref_atomic_swap: case nir_intrinsic_image_deref_samples: - case nir_intrinsic_image_deref_load_param_intel: case nir_intrinsic_image_deref_load_raw_intel: case nir_intrinsic_image_deref_store_raw_intel: case nir_intrinsic_image_deref_sparse_load: return lower_image_intrinsic(b, intrin, state); + case nir_intrinsic_image_deref_load_param_intel: + return lower_image_load_intel_intrinsic(b, intrin, state); case nir_intrinsic_image_deref_size: return lower_image_size_intrinsic(b, intrin, state); case nir_intrinsic_load_constant: diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 76b081c256e..979cadfee10 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2776,6 +2776,21 @@ struct anv_storage_image_descriptor { * RESINFO result. */ uint32_t image_depth; + + /** Image address */ + uint64_t image_address; + + /** Image tiling mode + * + * 0 for linear, ~0 otherwise. + */ + uint32_t tile_mode; + + /** Image row pitch in bytes */ + uint32_t row_pitch_B; + + /** Image Q pitch (rows between array slices) */ + uint32_t qpitch; }; /** Struct representing a address/range descriptor