anv: Use bindless handles for images
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
parent
83af92e593
commit
c0d9926df7
|
@ -121,6 +121,8 @@ bool brw_nir_lower_image_load_store(nir_shader *nir,
|
|||
const struct gen_device_info *devinfo);
|
||||
void brw_nir_rewrite_image_intrinsic(nir_intrinsic_instr *intrin,
|
||||
nir_ssa_def *index);
|
||||
void brw_nir_rewrite_bindless_image_intrinsic(nir_intrinsic_instr *intrin,
|
||||
nir_ssa_def *handle);
|
||||
|
||||
bool brw_nir_lower_mem_access_bit_sizes(nir_shader *shader);
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ anv_descriptor_data_for_type(const struct anv_physical_device *device,
|
|||
data = ANV_DESCRIPTOR_SURFACE_STATE;
|
||||
if (device->info.gen < 9)
|
||||
data |= ANV_DESCRIPTOR_IMAGE_PARAM;
|
||||
if (device->has_bindless_images)
|
||||
data |= ANV_DESCRIPTOR_STORAGE_IMAGE;
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
|
@ -112,6 +114,9 @@ anv_descriptor_data_size(enum anv_descriptor_data data)
|
|||
if (data & ANV_DESCRIPTOR_SAMPLED_IMAGE)
|
||||
size += sizeof(struct anv_sampled_image_descriptor);
|
||||
|
||||
if (data & ANV_DESCRIPTOR_STORAGE_IMAGE)
|
||||
size += sizeof(struct anv_storage_image_descriptor);
|
||||
|
||||
if (data & ANV_DESCRIPTOR_IMAGE_PARAM)
|
||||
size += BRW_IMAGE_PARAM_SIZE * 4;
|
||||
|
||||
|
@ -178,6 +183,11 @@ anv_descriptor_data_supports_bindless(const struct anv_physical_device *pdevice,
|
|||
pdevice->has_bindless_images;
|
||||
}
|
||||
|
||||
if (data & ANV_DESCRIPTOR_STORAGE_IMAGE) {
|
||||
assert(pdevice->has_bindless_images);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1135,6 +1145,18 @@ anv_descriptor_set_write_image_view(struct anv_device *device,
|
|||
MAX2(1, bind_layout->max_plane_count) * sizeof(desc_data[0]));
|
||||
}
|
||||
|
||||
if (bind_layout->data & ANV_DESCRIPTOR_STORAGE_IMAGE) {
|
||||
assert(!(bind_layout->data & ANV_DESCRIPTOR_IMAGE_PARAM));
|
||||
assert(image_view->n_planes == 1);
|
||||
struct anv_storage_image_descriptor desc_data = {
|
||||
.read_write = anv_surface_state_to_handle(
|
||||
image_view->planes[0].storage_surface_state.state),
|
||||
.write_only = anv_surface_state_to_handle(
|
||||
image_view->planes[0].writeonly_storage_surface_state.state),
|
||||
};
|
||||
memcpy(desc_map, &desc_data, sizeof(desc_data));
|
||||
}
|
||||
|
||||
if (bind_layout->data & ANV_DESCRIPTOR_IMAGE_PARAM) {
|
||||
/* Storage images can only ever have one plane */
|
||||
assert(image_view->n_planes == 1);
|
||||
|
@ -1175,6 +1197,17 @@ anv_descriptor_set_write_buffer_view(struct anv_device *device,
|
|||
memcpy(desc_map, &desc_data, sizeof(desc_data));
|
||||
}
|
||||
|
||||
if (bind_layout->data & ANV_DESCRIPTOR_STORAGE_IMAGE) {
|
||||
assert(!(bind_layout->data & ANV_DESCRIPTOR_IMAGE_PARAM));
|
||||
struct anv_storage_image_descriptor desc_data = {
|
||||
.read_write = anv_surface_state_to_handle(
|
||||
buffer_view->storage_surface_state),
|
||||
.write_only = anv_surface_state_to_handle(
|
||||
buffer_view->writeonly_storage_surface_state),
|
||||
};
|
||||
memcpy(desc_map, &desc_data, sizeof(desc_data));
|
||||
}
|
||||
|
||||
if (bind_layout->data & ANV_DESCRIPTOR_IMAGE_PARAM) {
|
||||
anv_descriptor_set_write_image_param(desc_map,
|
||||
&buffer_view->storage_image_param);
|
||||
|
|
|
@ -1136,6 +1136,8 @@ void anv_GetPhysicalDeviceProperties(
|
|||
const uint32_t max_samplers =
|
||||
pdevice->has_bindless_samplers ? UINT16_MAX :
|
||||
(devinfo->gen >= 8 || devinfo->is_haswell) ? 128 : 16;
|
||||
const uint32_t max_images =
|
||||
pdevice->has_bindless_images ? UINT16_MAX : MAX_IMAGES;
|
||||
|
||||
/* The moment we have anything bindless, claim a high per-stage limit */
|
||||
const uint32_t max_per_stage =
|
||||
|
@ -1165,7 +1167,7 @@ void anv_GetPhysicalDeviceProperties(
|
|||
.maxPerStageDescriptorUniformBuffers = 64,
|
||||
.maxPerStageDescriptorStorageBuffers = max_ssbos,
|
||||
.maxPerStageDescriptorSampledImages = max_textures,
|
||||
.maxPerStageDescriptorStorageImages = MAX_IMAGES,
|
||||
.maxPerStageDescriptorStorageImages = max_images,
|
||||
.maxPerStageDescriptorInputAttachments = 64,
|
||||
.maxPerStageResources = max_per_stage,
|
||||
.maxDescriptorSetSamplers = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSamplers */
|
||||
|
@ -1174,7 +1176,7 @@ void anv_GetPhysicalDeviceProperties(
|
|||
.maxDescriptorSetStorageBuffers = 6 * max_ssbos, /* number of stages * maxPerStageDescriptorStorageBuffers */
|
||||
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
|
||||
.maxDescriptorSetSampledImages = 6 * max_textures, /* number of stages * maxPerStageDescriptorSampledImages */
|
||||
.maxDescriptorSetStorageImages = 6 * MAX_IMAGES, /* number of stages * maxPerStageDescriptorStorageImages */
|
||||
.maxDescriptorSetStorageImages = 6 * max_images, /* number of stages * maxPerStageDescriptorStorageImages */
|
||||
.maxDescriptorSetInputAttachments = 256,
|
||||
.maxVertexInputAttributes = MAX_VBS,
|
||||
.maxVertexInputBindings = MAX_VBS,
|
||||
|
|
|
@ -677,13 +677,17 @@ lower_image_intrinsic(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);
|
||||
|
||||
nir_builder *b = &state->builder;
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
|
||||
const bool use_bindless = state->pdevice->has_bindless_images;
|
||||
|
||||
if (intrin->intrinsic == nir_intrinsic_image_deref_load_param_intel) {
|
||||
b->cursor = nir_instr_remove(&intrin->instr);
|
||||
|
||||
assert(!use_bindless); /* Otherwise our offsets would be wrong */
|
||||
const unsigned param = nir_intrinsic_base(intrin);
|
||||
|
||||
nir_ssa_def *desc =
|
||||
|
@ -692,9 +696,14 @@ lower_image_intrinsic(nir_intrinsic_instr *intrin,
|
|||
intrin->dest.ssa.bit_size, state);
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(desc));
|
||||
} else if (use_bindless) {
|
||||
const bool write_only =
|
||||
(var->data.image.access & ACCESS_NON_READABLE) != 0;
|
||||
nir_ssa_def *desc =
|
||||
build_descriptor_load(deref, 0, 2, 32, state);
|
||||
nir_ssa_def *handle = nir_channel(b, desc, write_only ? 1 : 0);
|
||||
nir_rewrite_image_intrinsic(intrin, handle, true);
|
||||
} else {
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
|
||||
unsigned set = var->data.descriptor_set;
|
||||
unsigned binding = var->data.binding;
|
||||
unsigned binding_offset = state->set[set].surface_offsets[binding];
|
||||
|
|
|
@ -1546,6 +1546,17 @@ struct anv_sampled_image_descriptor {
|
|||
uint32_t sampler;
|
||||
};
|
||||
|
||||
/** Struct representing a storage image descriptor */
|
||||
struct anv_storage_image_descriptor {
|
||||
/** Bindless image handles
|
||||
*
|
||||
* These are expected to already be shifted such that the 20-bit
|
||||
* SURFACE_STATE table index is in the top 20 bits.
|
||||
*/
|
||||
uint32_t read_write;
|
||||
uint32_t write_only;
|
||||
};
|
||||
|
||||
/** Struct representing a address/range descriptor
|
||||
*
|
||||
* The fields of this struct correspond directly to the data layout of
|
||||
|
@ -1574,6 +1585,8 @@ enum anv_descriptor_data {
|
|||
ANV_DESCRIPTOR_ADDRESS_RANGE = (1 << 5),
|
||||
/** Bindless surface handle */
|
||||
ANV_DESCRIPTOR_SAMPLED_IMAGE = (1 << 6),
|
||||
/** Storage image handles */
|
||||
ANV_DESCRIPTOR_STORAGE_IMAGE = (1 << 7),
|
||||
};
|
||||
|
||||
struct anv_descriptor_set_binding_layout {
|
||||
|
|
Loading…
Reference in New Issue