mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
anv: add dynamic buffer offsets support with independent sets
With independent sets, we're not able to compute immediate values for the index at which to read anv_push_constants::dynamic_offsets to get the offset of a dynamic buffer. This is because the pipeline layout may not have all the descriptor set layouts when we compile the shader. To solve that issue, we insert a layer of indirection. This reworks the dynamic buffer offset storage with a 2D array in anv_cmd_pipeline_state : dynamic_offsets[MAX_SETS][MAX_DYN_BUFFERS] When the pipeline or the dynamic buffer offsets are updated, we flatten that array into the anv_push_constants::dynamic_offsets[MAX_DYN_BUFFERS] array. For shaders compiled with independent sets, the bottom 6 bits of element X in anv_push_constants::desc_sets[] is used to specify the base offsets into the anv_push_constants::dynamic_offsets[] for the set X. The computation in the shader is now something like : base_dyn_buffer_set_idx = anv_push_constants::desc_sets[set_idx] & 0x3f dyn_buffer_offset = anv_push_constants::dynamic_offsets[base_dyn_buffer_set_idx + dynamic_buffer_idx] It was suggested by Faith to use a different push constant buffer with dynamic_offsets prepared for each stage when using independent sets instead, but it feels easier to understand this way. And there is some room for optimization if you are set X and that you know all the sets in the range [0, X], then you can still avoid the indirection. Separate push constant allocations per stage do have a CPU cost. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15637>
This commit is contained in:
parent
16c7c37718
commit
0b8a2de2a1
11 changed files with 384 additions and 100 deletions
|
|
@ -434,7 +434,8 @@ visit_intrinsic(nir_shader *shader, nir_intrinsic_instr *instr)
|
||||||
case nir_intrinsic_image_load_raw_intel:
|
case nir_intrinsic_image_load_raw_intel:
|
||||||
case nir_intrinsic_get_ubo_size:
|
case nir_intrinsic_get_ubo_size:
|
||||||
case nir_intrinsic_load_ssbo_address:
|
case nir_intrinsic_load_ssbo_address:
|
||||||
case nir_intrinsic_load_desc_set_address_intel: {
|
case nir_intrinsic_load_desc_set_address_intel:
|
||||||
|
case nir_intrinsic_load_desc_set_dynamic_index_intel: {
|
||||||
unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
|
unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
|
||||||
for (unsigned i = 0; i < num_srcs; i++) {
|
for (unsigned i = 0; i < num_srcs; i++) {
|
||||||
if (instr->src[i].ssa->divergent) {
|
if (instr->src[i].ssa->divergent) {
|
||||||
|
|
|
||||||
|
|
@ -1741,6 +1741,11 @@ intrinsic("load_reloc_const_intel", dest_comp=1, bit_sizes=[32],
|
||||||
intrinsic("load_desc_set_address_intel", dest_comp=1, bit_sizes=[64],
|
intrinsic("load_desc_set_address_intel", dest_comp=1, bit_sizes=[64],
|
||||||
src_comp=[1], flags=[CAN_ELIMINATE, CAN_REORDER])
|
src_comp=[1], flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||||
|
|
||||||
|
# Base offset for a given set in the flatten array of dynamic offsets
|
||||||
|
# src[0] = { set }
|
||||||
|
intrinsic("load_desc_set_dynamic_index_intel", dest_comp=1, bit_sizes=[32],
|
||||||
|
src_comp=[1], flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||||
|
|
||||||
# OpSubgroupBlockReadINTEL and OpSubgroupBlockWriteINTEL from SPV_INTEL_subgroups.
|
# OpSubgroupBlockReadINTEL and OpSubgroupBlockWriteINTEL from SPV_INTEL_subgroups.
|
||||||
intrinsic("load_deref_block_intel", dest_comp=0, src_comp=[-1],
|
intrinsic("load_deref_block_intel", dest_comp=0, src_comp=[-1],
|
||||||
indices=[ACCESS], flags=[CAN_ELIMINATE])
|
indices=[ACCESS], flags=[CAN_ELIMINATE])
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,32 @@ void anv_CmdBindPipeline(
|
||||||
|
|
||||||
state = &cmd_buffer->state.gfx.base;
|
state = &cmd_buffer->state.gfx.base;
|
||||||
stages = gfx_pipeline->base.active_stages;
|
stages = gfx_pipeline->base.active_stages;
|
||||||
|
|
||||||
|
/* When the pipeline is using independent states and dynamic buffers,
|
||||||
|
* this will trigger an update of anv_push_constants::dynamic_base_index
|
||||||
|
* & anv_push_constants::dynamic_offsets.
|
||||||
|
*/
|
||||||
|
struct anv_push_constants *push =
|
||||||
|
&cmd_buffer->state.gfx.base.push_constants;
|
||||||
|
struct anv_pipeline_sets_layout *layout = &gfx_pipeline->base.base.layout;
|
||||||
|
if (layout->independent_sets && layout->num_dynamic_buffers > 0) {
|
||||||
|
bool modified = false;
|
||||||
|
for (uint32_t s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (layout->set[s].layout == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(layout->set[s].dynamic_offset_start < MAX_DYNAMIC_BUFFERS);
|
||||||
|
if (layout->set[s].layout->dynamic_offset_count > 0 &&
|
||||||
|
(push->desc_sets[s] & ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK) != layout->set[s].dynamic_offset_start) {
|
||||||
|
push->desc_sets[s] &= ~ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK;
|
||||||
|
push->desc_sets[s] |= (layout->set[s].dynamic_offset_start &
|
||||||
|
ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (modified)
|
||||||
|
cmd_buffer->state.push_constants_dirty |= stages;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,7 +464,7 @@ void anv_CmdBindPipeline(
|
||||||
static void
|
static void
|
||||||
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||||
VkPipelineBindPoint bind_point,
|
VkPipelineBindPoint bind_point,
|
||||||
struct anv_pipeline_layout *layout,
|
struct anv_pipeline_sets_layout *layout,
|
||||||
uint32_t set_index,
|
uint32_t set_index,
|
||||||
struct anv_descriptor_set *set,
|
struct anv_descriptor_set *set,
|
||||||
uint32_t *dynamic_offset_count,
|
uint32_t *dynamic_offset_count,
|
||||||
|
|
@ -516,7 +542,9 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||||
struct anv_push_constants *push = &pipe_state->push_constants;
|
struct anv_push_constants *push = &pipe_state->push_constants;
|
||||||
|
|
||||||
struct anv_address addr = anv_descriptor_set_address(set);
|
struct anv_address addr = anv_descriptor_set_address(set);
|
||||||
push->desc_sets[set_index] = anv_address_physical(addr);
|
push->desc_sets[set_index] &= ~ANV_DESCRIPTOR_SET_ADDRESS_MASK;
|
||||||
|
push->desc_sets[set_index] |= (anv_address_physical(addr) &
|
||||||
|
ANV_DESCRIPTOR_SET_ADDRESS_MASK);
|
||||||
|
|
||||||
if (addr.bo) {
|
if (addr.bo) {
|
||||||
anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
|
anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
|
||||||
|
|
@ -536,6 +564,11 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||||
uint32_t *push_offsets =
|
uint32_t *push_offsets =
|
||||||
&push->dynamic_offsets[dynamic_offset_start];
|
&push->dynamic_offsets[dynamic_offset_start];
|
||||||
|
|
||||||
|
memcpy(pipe_state->dynamic_offsets[set_index].offsets,
|
||||||
|
*dynamic_offsets,
|
||||||
|
sizeof(uint32_t) * MIN2(*dynamic_offset_count,
|
||||||
|
set_layout->dynamic_offset_count));
|
||||||
|
|
||||||
/* Assert that everything is in range */
|
/* Assert that everything is in range */
|
||||||
assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
|
assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
|
||||||
assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
|
assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
|
||||||
|
|
@ -543,7 +576,8 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||||
|
|
||||||
for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
|
for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
|
||||||
if (push_offsets[i] != (*dynamic_offsets)[i]) {
|
if (push_offsets[i] != (*dynamic_offsets)[i]) {
|
||||||
push_offsets[i] = (*dynamic_offsets)[i];
|
pipe_state->dynamic_offsets[set_index].offsets[i] =
|
||||||
|
push_offsets[i] = (*dynamic_offsets)[i];
|
||||||
/* dynamic_offset_stages[] elements could contain blanket
|
/* dynamic_offset_stages[] elements could contain blanket
|
||||||
* values like VK_SHADER_STAGE_ALL, so limit this to the
|
* values like VK_SHADER_STAGE_ALL, so limit this to the
|
||||||
* binding point's bits.
|
* binding point's bits.
|
||||||
|
|
@ -575,12 +609,15 @@ void anv_CmdBindDescriptorSets(
|
||||||
const uint32_t* pDynamicOffsets)
|
const uint32_t* pDynamicOffsets)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _layout);
|
||||||
|
struct anv_pipeline_sets_layout *layout = &pipeline_layout->sets_layout;
|
||||||
|
|
||||||
assert(firstSet + descriptorSetCount <= MAX_SETS);
|
assert(firstSet + descriptorSetCount <= MAX_SETS);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < descriptorSetCount; i++) {
|
for (uint32_t i = 0; i < descriptorSetCount; i++) {
|
||||||
ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
|
ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
|
||||||
|
if (set == NULL)
|
||||||
|
continue;
|
||||||
anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
|
anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
|
||||||
layout, firstSet + i, set,
|
layout, firstSet + i, set,
|
||||||
&dynamicOffsetCount,
|
&dynamicOffsetCount,
|
||||||
|
|
@ -728,8 +765,8 @@ struct anv_state
|
||||||
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
|
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
|
||||||
{
|
{
|
||||||
const struct intel_device_info *devinfo = cmd_buffer->device->info;
|
const struct intel_device_info *devinfo = cmd_buffer->device->info;
|
||||||
struct anv_push_constants *data =
|
struct anv_cmd_pipeline_state *pipe_state = &cmd_buffer->state.compute.base;
|
||||||
&cmd_buffer->state.compute.base.push_constants;
|
struct anv_push_constants *data = &pipe_state->push_constants;
|
||||||
struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
|
struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
|
||||||
const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
|
const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
|
||||||
const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
|
const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
|
||||||
|
|
@ -906,7 +943,8 @@ void anv_CmdPushDescriptorSetKHR(
|
||||||
const VkWriteDescriptorSet* pDescriptorWrites)
|
const VkWriteDescriptorSet* pDescriptorWrites)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _layout);
|
||||||
|
struct anv_pipeline_sets_layout *layout = &pipeline_layout->sets_layout;
|
||||||
|
|
||||||
assert(_set < MAX_SETS);
|
assert(_set < MAX_SETS);
|
||||||
|
|
||||||
|
|
@ -1003,7 +1041,8 @@ void anv_CmdPushDescriptorSetWithTemplateKHR(
|
||||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
VK_FROM_HANDLE(vk_descriptor_update_template, template,
|
VK_FROM_HANDLE(vk_descriptor_update_template, template,
|
||||||
descriptorUpdateTemplate);
|
descriptorUpdateTemplate);
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _layout);
|
||||||
|
struct anv_pipeline_sets_layout *layout = &pipeline_layout->sets_layout;
|
||||||
|
|
||||||
assert(_set < MAX_PUSH_DESCRIPTORS);
|
assert(_set < MAX_PUSH_DESCRIPTORS);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -647,6 +647,12 @@ set_layout_buffer_view_count(const struct anv_descriptor_set_layout *set_layout,
|
||||||
return set_layout->buffer_view_count - shrink;
|
return set_layout->buffer_view_count - shrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
anv_descriptor_set_layout_empty(const struct anv_descriptor_set_layout *set_layout)
|
||||||
|
{
|
||||||
|
return set_layout->binding_count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
anv_descriptor_set_layout_descriptor_buffer_size(const struct anv_descriptor_set_layout *set_layout,
|
anv_descriptor_set_layout_descriptor_buffer_size(const struct anv_descriptor_set_layout *set_layout,
|
||||||
uint32_t var_desc_count)
|
uint32_t var_desc_count)
|
||||||
|
|
@ -740,6 +746,83 @@ sha1_update_descriptor_set_layout(struct mesa_sha1 *ctx,
|
||||||
* just multiple descriptor set layouts pasted together
|
* just multiple descriptor set layouts pasted together
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
anv_pipeline_sets_layout_init(struct anv_pipeline_sets_layout *layout,
|
||||||
|
struct anv_device *device,
|
||||||
|
bool independent_sets)
|
||||||
|
{
|
||||||
|
memset(layout, 0, sizeof(*layout));
|
||||||
|
|
||||||
|
layout->device = device;
|
||||||
|
layout->independent_sets = independent_sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
anv_pipeline_sets_layout_add(struct anv_pipeline_sets_layout *layout,
|
||||||
|
uint32_t set_idx,
|
||||||
|
struct anv_descriptor_set_layout *set_layout)
|
||||||
|
{
|
||||||
|
if (layout->set[set_idx].layout)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Workaround CTS : Internal CTS issue 3584 */
|
||||||
|
if (layout->independent_sets && anv_descriptor_set_layout_empty(set_layout))
|
||||||
|
return;
|
||||||
|
|
||||||
|
layout->num_sets = MAX2(set_idx + 1, layout->num_sets);
|
||||||
|
|
||||||
|
layout->set[set_idx].layout =
|
||||||
|
anv_descriptor_set_layout_ref(set_layout);
|
||||||
|
|
||||||
|
layout->set[set_idx].dynamic_offset_start = layout->num_dynamic_buffers;
|
||||||
|
layout->num_dynamic_buffers += set_layout->dynamic_offset_count;
|
||||||
|
|
||||||
|
assert(layout->num_dynamic_buffers < MAX_DYNAMIC_BUFFERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
anv_pipeline_sets_layout_hash(struct anv_pipeline_sets_layout *layout)
|
||||||
|
{
|
||||||
|
struct mesa_sha1 ctx;
|
||||||
|
_mesa_sha1_init(&ctx);
|
||||||
|
for (unsigned s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (!layout->set[s].layout)
|
||||||
|
continue;
|
||||||
|
sha1_update_descriptor_set_layout(&ctx, layout->set[s].layout);
|
||||||
|
_mesa_sha1_update(&ctx, &layout->set[s].dynamic_offset_start,
|
||||||
|
sizeof(layout->set[s].dynamic_offset_start));
|
||||||
|
}
|
||||||
|
_mesa_sha1_update(&ctx, &layout->num_sets, sizeof(layout->num_sets));
|
||||||
|
_mesa_sha1_final(&ctx, layout->sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
anv_pipeline_sets_layout_fini(struct anv_pipeline_sets_layout *layout)
|
||||||
|
{
|
||||||
|
for (unsigned s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (!layout->set[s].layout)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
anv_descriptor_set_layout_unref(layout->device, layout->set[s].layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
anv_pipeline_sets_layout_print(const struct anv_pipeline_sets_layout *layout)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "layout: dyn_count=%u sets=%u ind=%u\n",
|
||||||
|
layout->num_dynamic_buffers,
|
||||||
|
layout->num_sets,
|
||||||
|
layout->independent_sets);
|
||||||
|
for (unsigned s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (!layout->set[s].layout)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fprintf(stderr, " set%i: dyn_start=%u flags=0x%x\n",
|
||||||
|
s, layout->set[s].dynamic_offset_start, layout->set[s].layout->flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkResult anv_CreatePipelineLayout(
|
VkResult anv_CreatePipelineLayout(
|
||||||
VkDevice _device,
|
VkDevice _device,
|
||||||
const VkPipelineLayoutCreateInfo* pCreateInfo,
|
const VkPipelineLayoutCreateInfo* pCreateInfo,
|
||||||
|
|
@ -756,30 +839,28 @@ VkResult anv_CreatePipelineLayout(
|
||||||
if (layout == NULL)
|
if (layout == NULL)
|
||||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
layout->num_sets = pCreateInfo->setLayoutCount;
|
anv_pipeline_sets_layout_init(&layout->sets_layout, device,
|
||||||
|
pCreateInfo->flags & VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
|
||||||
unsigned dynamic_offset_count = 0;
|
|
||||||
|
|
||||||
for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
|
for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
|
||||||
ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
|
ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
|
||||||
pCreateInfo->pSetLayouts[set]);
|
pCreateInfo->pSetLayouts[set]);
|
||||||
layout->set[set].layout = set_layout;
|
|
||||||
anv_descriptor_set_layout_ref(set_layout);
|
|
||||||
|
|
||||||
layout->set[set].dynamic_offset_start = dynamic_offset_count;
|
/* VUID-VkPipelineLayoutCreateInfo-graphicsPipelineLibrary-06753
|
||||||
dynamic_offset_count += set_layout->dynamic_offset_count;
|
*
|
||||||
}
|
* "If graphicsPipelineLibrary is not enabled, elements of
|
||||||
assert(dynamic_offset_count < MAX_DYNAMIC_BUFFERS);
|
* pSetLayouts must be valid VkDescriptorSetLayout objects"
|
||||||
|
*
|
||||||
|
* As a result of supporting graphicsPipelineLibrary, we need to allow
|
||||||
|
* null descriptor set layouts.
|
||||||
|
*/
|
||||||
|
if (set_layout == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
struct mesa_sha1 ctx;
|
anv_pipeline_sets_layout_add(&layout->sets_layout, set, set_layout);
|
||||||
_mesa_sha1_init(&ctx);
|
|
||||||
for (unsigned s = 0; s < layout->num_sets; s++) {
|
|
||||||
sha1_update_descriptor_set_layout(&ctx, layout->set[s].layout);
|
|
||||||
_mesa_sha1_update(&ctx, &layout->set[s].dynamic_offset_start,
|
|
||||||
sizeof(layout->set[s].dynamic_offset_start));
|
|
||||||
}
|
}
|
||||||
_mesa_sha1_update(&ctx, &layout->num_sets, sizeof(layout->num_sets));
|
|
||||||
_mesa_sha1_final(&ctx, layout->sha1);
|
anv_pipeline_sets_layout_hash(&layout->sets_layout);
|
||||||
|
|
||||||
*pPipelineLayout = anv_pipeline_layout_to_handle(layout);
|
*pPipelineLayout = anv_pipeline_layout_to_handle(layout);
|
||||||
|
|
||||||
|
|
@ -792,15 +873,14 @@ void anv_DestroyPipelineLayout(
|
||||||
const VkAllocationCallbacks* pAllocator)
|
const VkAllocationCallbacks* pAllocator)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _pipelineLayout);
|
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _pipelineLayout);
|
||||||
|
|
||||||
if (!pipeline_layout)
|
if (!layout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pipeline_layout->num_sets; i++)
|
anv_pipeline_sets_layout_fini(&layout->sets_layout);
|
||||||
anv_descriptor_set_layout_unref(device, pipeline_layout->set[i].layout);
|
|
||||||
|
|
||||||
vk_object_free(&device->vk, pAllocator, pipeline_layout);
|
vk_object_free(&device->vk, pAllocator, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ bool anv_nir_lower_multiview(nir_shader *shader, uint32_t view_mask,
|
||||||
bool use_primitive_replication);
|
bool use_primitive_replication);
|
||||||
|
|
||||||
bool anv_nir_lower_ycbcr_textures(nir_shader *shader,
|
bool anv_nir_lower_ycbcr_textures(nir_shader *shader,
|
||||||
const struct anv_pipeline_layout *layout);
|
const struct anv_pipeline_sets_layout *layout);
|
||||||
|
|
||||||
static inline nir_address_format
|
static inline nir_address_format
|
||||||
anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
|
anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
|
||||||
|
|
@ -67,7 +67,8 @@ bool anv_nir_lower_ubo_loads(nir_shader *shader);
|
||||||
void anv_nir_apply_pipeline_layout(nir_shader *shader,
|
void anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
const struct anv_physical_device *pdevice,
|
const struct anv_physical_device *pdevice,
|
||||||
bool robust_buffer_access,
|
bool robust_buffer_access,
|
||||||
const struct anv_pipeline_layout *layout,
|
bool independent_sets,
|
||||||
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
struct anv_pipeline_bind_map *map);
|
struct anv_pipeline_bind_map *map);
|
||||||
|
|
||||||
void anv_nir_compute_push_layout(nir_shader *nir,
|
void anv_nir_compute_push_layout(nir_shader *nir,
|
||||||
|
|
@ -83,14 +84,14 @@ void anv_nir_validate_push_layout(struct brw_stage_prog_data *prog_data,
|
||||||
bool anv_nir_add_base_work_group_id(nir_shader *shader);
|
bool anv_nir_add_base_work_group_id(nir_shader *shader);
|
||||||
|
|
||||||
uint32_t anv_nir_compute_used_push_descriptors(nir_shader *shader,
|
uint32_t anv_nir_compute_used_push_descriptors(nir_shader *shader,
|
||||||
const struct anv_pipeline_layout *layout);
|
const struct anv_pipeline_sets_layout *layout);
|
||||||
|
|
||||||
bool anv_nir_loads_push_desc_buffer(nir_shader *nir,
|
bool anv_nir_loads_push_desc_buffer(nir_shader *nir,
|
||||||
const struct anv_pipeline_layout *layout,
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
const struct anv_pipeline_bind_map *bind_map);
|
const struct anv_pipeline_bind_map *bind_map);
|
||||||
|
|
||||||
uint32_t anv_nir_push_desc_ubo_fully_promoted(nir_shader *nir,
|
uint32_t anv_nir_push_desc_ubo_fully_promoted(nir_shader *nir,
|
||||||
const struct anv_pipeline_layout *layout,
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
const struct anv_pipeline_bind_map *bind_map);
|
const struct anv_pipeline_bind_map *bind_map);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
struct apply_pipeline_layout_state {
|
struct apply_pipeline_layout_state {
|
||||||
const struct anv_physical_device *pdevice;
|
const struct anv_physical_device *pdevice;
|
||||||
|
|
||||||
const struct anv_pipeline_layout *layout;
|
const struct anv_pipeline_sets_layout *layout;
|
||||||
bool add_bounds_checks;
|
bool add_bounds_checks;
|
||||||
nir_address_format desc_addr_format;
|
nir_address_format desc_addr_format;
|
||||||
nir_address_format ssbo_addr_format;
|
nir_address_format ssbo_addr_format;
|
||||||
|
|
@ -50,6 +50,7 @@ struct apply_pipeline_layout_state {
|
||||||
|
|
||||||
bool uses_constants;
|
bool uses_constants;
|
||||||
bool has_dynamic_buffers;
|
bool has_dynamic_buffers;
|
||||||
|
bool has_independent_sets;
|
||||||
uint8_t constants_offset;
|
uint8_t constants_offset;
|
||||||
struct {
|
struct {
|
||||||
bool desc_buffer_used;
|
bool desc_buffer_used;
|
||||||
|
|
@ -89,6 +90,9 @@ add_binding(struct apply_pipeline_layout_state *state,
|
||||||
const struct anv_descriptor_set_binding_layout *bind_layout =
|
const struct anv_descriptor_set_binding_layout *bind_layout =
|
||||||
&state->layout->set[set].layout->binding[binding];
|
&state->layout->set[set].layout->binding[binding];
|
||||||
|
|
||||||
|
assert(set < state->layout->num_sets);
|
||||||
|
assert(binding < state->layout->set[set].layout->binding_count);
|
||||||
|
|
||||||
if (state->set[set].use_count[binding] < UINT8_MAX)
|
if (state->set[set].use_count[binding] < UINT8_MAX)
|
||||||
state->set[set].use_count[binding]++;
|
state->set[set].use_count[binding]++;
|
||||||
|
|
||||||
|
|
@ -331,16 +335,30 @@ build_res_index(nir_builder *b, uint32_t set, uint32_t binding,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bind_layout->dynamic_offset_index < MAX_DYNAMIC_BUFFERS);
|
assert(bind_layout->dynamic_offset_index < MAX_DYNAMIC_BUFFERS);
|
||||||
uint32_t dynamic_offset_index = 0xff; /* No dynamic offset */
|
nir_ssa_def *dynamic_offset_index;
|
||||||
if (bind_layout->dynamic_offset_index >= 0) {
|
if (bind_layout->dynamic_offset_index >= 0) {
|
||||||
dynamic_offset_index =
|
if (state->has_independent_sets) {
|
||||||
state->layout->set[set].dynamic_offset_start +
|
nir_ssa_def *dynamic_offset_start =
|
||||||
bind_layout->dynamic_offset_index;
|
nir_load_desc_set_dynamic_index_intel(b, nir_imm_int(b, set));
|
||||||
|
dynamic_offset_index =
|
||||||
|
nir_iadd_imm(b, dynamic_offset_start,
|
||||||
|
bind_layout->dynamic_offset_index);
|
||||||
|
} else {
|
||||||
|
dynamic_offset_index =
|
||||||
|
nir_imm_int(b,
|
||||||
|
state->layout->set[set].dynamic_offset_start +
|
||||||
|
bind_layout->dynamic_offset_index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dynamic_offset_index = nir_imm_int(b, 0xff); /* No dynamic offset */
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t packed = (bind_layout->descriptor_stride << 16 ) | (set_idx << 8) | dynamic_offset_index;
|
nir_ssa_def *packed =
|
||||||
|
nir_ior_imm(b,
|
||||||
|
dynamic_offset_index,
|
||||||
|
(bind_layout->descriptor_stride << 16 ) | (set_idx << 8));
|
||||||
|
|
||||||
return nir_vec4(b, nir_imm_int(b, packed),
|
return nir_vec4(b, packed,
|
||||||
nir_imm_int(b, bind_layout->descriptor_offset),
|
nir_imm_int(b, bind_layout->descriptor_offset),
|
||||||
nir_imm_int(b, array_size - 1),
|
nir_imm_int(b, array_size - 1),
|
||||||
array_index);
|
array_index);
|
||||||
|
|
@ -1278,15 +1296,49 @@ compare_binding_infos(const void *_a, const void *_b)
|
||||||
return a->binding - b->binding;
|
return a->binding - b->binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static void
|
||||||
|
anv_validate_pipeline_layout(const struct anv_pipeline_sets_layout *layout,
|
||||||
|
nir_shader *shader)
|
||||||
|
{
|
||||||
|
nir_foreach_function(function, shader) {
|
||||||
|
if (!function->impl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nir_foreach_block(block, function->impl) {
|
||||||
|
nir_foreach_instr(instr, block) {
|
||||||
|
if (instr->type != nir_instr_type_intrinsic)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||||
|
if (intrin->intrinsic != nir_intrinsic_vulkan_resource_index)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned set = nir_intrinsic_desc_set(intrin);
|
||||||
|
assert(layout->set[set].layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
anv_nir_apply_pipeline_layout(nir_shader *shader,
|
anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
const struct anv_physical_device *pdevice,
|
const struct anv_physical_device *pdevice,
|
||||||
bool robust_buffer_access,
|
bool robust_buffer_access,
|
||||||
const struct anv_pipeline_layout *layout,
|
bool independent_sets,
|
||||||
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
struct anv_pipeline_bind_map *map)
|
struct anv_pipeline_bind_map *map)
|
||||||
{
|
{
|
||||||
void *mem_ctx = ralloc_context(NULL);
|
void *mem_ctx = ralloc_context(NULL);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* We should not have have any reference to a descriptor set that is not
|
||||||
|
* given through the pipeline layout (layout->set[set].layout = NULL).
|
||||||
|
*/
|
||||||
|
anv_validate_pipeline_layout(layout, shader);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct apply_pipeline_layout_state state = {
|
struct apply_pipeline_layout_state state = {
|
||||||
.pdevice = pdevice,
|
.pdevice = pdevice,
|
||||||
.layout = layout,
|
.layout = layout,
|
||||||
|
|
@ -1298,9 +1350,13 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access),
|
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access),
|
||||||
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_buffer_access),
|
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_buffer_access),
|
||||||
.lowered_instrs = _mesa_pointer_set_create(mem_ctx),
|
.lowered_instrs = _mesa_pointer_set_create(mem_ctx),
|
||||||
|
.has_independent_sets = independent_sets,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (unsigned s = 0; s < layout->num_sets; s++) {
|
for (unsigned s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (!layout->set[s].layout)
|
||||||
|
continue;
|
||||||
|
|
||||||
const unsigned count = layout->set[s].layout->binding_count;
|
const unsigned count = layout->set[s].layout->binding_count;
|
||||||
state.set[s].use_count = rzalloc_array(mem_ctx, uint8_t, count);
|
state.set[s].use_count = rzalloc_array(mem_ctx, uint8_t, count);
|
||||||
state.set[s].surface_offsets = rzalloc_array(mem_ctx, uint8_t, count);
|
state.set[s].surface_offsets = rzalloc_array(mem_ctx, uint8_t, count);
|
||||||
|
|
@ -1328,6 +1384,9 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
unsigned used_binding_count = 0;
|
unsigned used_binding_count = 0;
|
||||||
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
||||||
struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
||||||
|
if (!set_layout)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (unsigned b = 0; b < set_layout->binding_count; b++) {
|
for (unsigned b = 0; b < set_layout->binding_count; b++) {
|
||||||
if (state.set[set].use_count[b] == 0)
|
if (state.set[set].use_count[b] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1341,6 +1400,9 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
used_binding_count = 0;
|
used_binding_count = 0;
|
||||||
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
||||||
const struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
const struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
||||||
|
if (!set_layout)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (unsigned b = 0; b < set_layout->binding_count; b++) {
|
for (unsigned b = 0; b < set_layout->binding_count; b++) {
|
||||||
if (state.set[set].use_count[b] == 0)
|
if (state.set[set].use_count[b] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1380,6 +1442,7 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
|
|
||||||
for (unsigned i = 0; i < used_binding_count; i++) {
|
for (unsigned i = 0; i < used_binding_count; i++) {
|
||||||
unsigned set = infos[i].set, b = infos[i].binding;
|
unsigned set = infos[i].set, b = infos[i].binding;
|
||||||
|
assert(layout->set[set].layout);
|
||||||
const struct anv_descriptor_set_binding_layout *binding =
|
const struct anv_descriptor_set_binding_layout *binding =
|
||||||
&layout->set[set].layout->binding[b];
|
&layout->set[set].layout->binding[b];
|
||||||
|
|
||||||
|
|
@ -1421,7 +1484,6 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
|
||||||
.binding = b,
|
.binding = b,
|
||||||
.index = binding->descriptor_index + i,
|
.index = binding->descriptor_index + i,
|
||||||
.dynamic_offset_index =
|
.dynamic_offset_index =
|
||||||
layout->set[set].dynamic_offset_start +
|
|
||||||
binding->dynamic_offset_index + i,
|
binding->dynamic_offset_index + i,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
|
||||||
}
|
}
|
||||||
|
|
||||||
case nir_intrinsic_load_desc_set_address_intel:
|
case nir_intrinsic_load_desc_set_address_intel:
|
||||||
|
case nir_intrinsic_load_desc_set_dynamic_index_intel:
|
||||||
push_start = MIN2(push_start,
|
push_start = MIN2(push_start,
|
||||||
offsetof(struct anv_push_constants, desc_sets));
|
offsetof(struct anv_push_constants, desc_sets));
|
||||||
push_end = MAX2(push_end, push_start +
|
push_end = MAX2(push_end, push_start +
|
||||||
|
|
@ -171,6 +172,22 @@ anv_nir_compute_push_layout(nir_shader *nir,
|
||||||
.base = offsetof(struct anv_push_constants, desc_sets),
|
.base = offsetof(struct anv_push_constants, desc_sets),
|
||||||
.range = sizeof_field(struct anv_push_constants, desc_sets),
|
.range = sizeof_field(struct anv_push_constants, desc_sets),
|
||||||
.dest_type = nir_type_uint64);
|
.dest_type = nir_type_uint64);
|
||||||
|
pc_load = nir_iand_imm(b, pc_load, ANV_DESCRIPTOR_SET_ADDRESS_MASK);
|
||||||
|
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nir_intrinsic_load_desc_set_dynamic_index_intel: {
|
||||||
|
b->cursor = nir_before_instr(&intrin->instr);
|
||||||
|
nir_ssa_def *pc_load = nir_load_uniform(b, 1, 64,
|
||||||
|
nir_imul_imm(b, intrin->src[0].ssa, sizeof(uint64_t)),
|
||||||
|
.base = offsetof(struct anv_push_constants, desc_sets),
|
||||||
|
.range = sizeof_field(struct anv_push_constants, desc_sets),
|
||||||
|
.dest_type = nir_type_uint64);
|
||||||
|
pc_load = nir_i2i32(
|
||||||
|
b,
|
||||||
|
nir_iand_imm(
|
||||||
|
b, pc_load, ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK));
|
||||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load);
|
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, pc_load);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include "anv_nir.h"
|
#include "anv_nir.h"
|
||||||
|
|
||||||
const struct anv_descriptor_set_layout *
|
const struct anv_descriptor_set_layout *
|
||||||
anv_pipeline_layout_get_push_set(const struct anv_pipeline_layout *layout,
|
anv_pipeline_layout_get_push_set(const struct anv_pipeline_sets_layout *layout,
|
||||||
uint8_t *set_idx)
|
uint8_t *set_idx)
|
||||||
{
|
{
|
||||||
for (unsigned s = 0; s < ARRAY_SIZE(layout->set); s++) {
|
for (unsigned s = 0; s < ARRAY_SIZE(layout->set); s++) {
|
||||||
|
|
@ -51,7 +51,7 @@ anv_pipeline_layout_get_push_set(const struct anv_pipeline_layout *layout,
|
||||||
*/
|
*/
|
||||||
uint32_t
|
uint32_t
|
||||||
anv_nir_compute_used_push_descriptors(nir_shader *shader,
|
anv_nir_compute_used_push_descriptors(nir_shader *shader,
|
||||||
const struct anv_pipeline_layout *layout)
|
const struct anv_pipeline_sets_layout *layout)
|
||||||
{
|
{
|
||||||
uint8_t push_set;
|
uint8_t push_set;
|
||||||
const struct anv_descriptor_set_layout *push_set_layout =
|
const struct anv_descriptor_set_layout *push_set_layout =
|
||||||
|
|
@ -108,7 +108,7 @@ anv_nir_compute_used_push_descriptors(nir_shader *shader,
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
anv_nir_loads_push_desc_buffer(nir_shader *nir,
|
anv_nir_loads_push_desc_buffer(nir_shader *nir,
|
||||||
const struct anv_pipeline_layout *layout,
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
const struct anv_pipeline_bind_map *bind_map)
|
const struct anv_pipeline_bind_map *bind_map)
|
||||||
{
|
{
|
||||||
uint8_t push_set;
|
uint8_t push_set;
|
||||||
|
|
@ -157,7 +157,7 @@ anv_nir_loads_push_desc_buffer(nir_shader *nir,
|
||||||
*/
|
*/
|
||||||
uint32_t
|
uint32_t
|
||||||
anv_nir_push_desc_ubo_fully_promoted(nir_shader *nir,
|
anv_nir_push_desc_ubo_fully_promoted(nir_shader *nir,
|
||||||
const struct anv_pipeline_layout *layout,
|
const struct anv_pipeline_sets_layout *layout,
|
||||||
const struct anv_pipeline_bind_map *bind_map)
|
const struct anv_pipeline_bind_map *bind_map)
|
||||||
{
|
{
|
||||||
uint8_t push_set;
|
uint8_t push_set;
|
||||||
|
|
|
||||||
|
|
@ -279,14 +279,40 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
|
||||||
|
|
||||||
util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
|
util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
|
||||||
|
|
||||||
|
anv_pipeline_sets_layout_init(&pipeline->layout, device,
|
||||||
|
false /* independent_sets */);
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
anv_pipeline_init_layout(struct anv_pipeline *pipeline,
|
||||||
|
struct anv_pipeline_layout *pipeline_layout)
|
||||||
|
{
|
||||||
|
if (pipeline_layout) {
|
||||||
|
struct anv_pipeline_sets_layout *layout = &pipeline_layout->sets_layout;
|
||||||
|
for (uint32_t s = 0; s < layout->num_sets; s++) {
|
||||||
|
if (layout->set[s].layout == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
anv_pipeline_sets_layout_add(&pipeline->layout, s,
|
||||||
|
layout->set[s].layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
anv_pipeline_sets_layout_hash(&pipeline->layout);
|
||||||
|
assert(!pipeline_layout ||
|
||||||
|
!memcmp(pipeline->layout.sha1,
|
||||||
|
pipeline_layout->sets_layout.sha1,
|
||||||
|
sizeof(pipeline_layout->sets_layout.sha1)));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
anv_pipeline_finish(struct anv_pipeline *pipeline,
|
anv_pipeline_finish(struct anv_pipeline *pipeline,
|
||||||
struct anv_device *device,
|
struct anv_device *device,
|
||||||
const VkAllocationCallbacks *pAllocator)
|
const VkAllocationCallbacks *pAllocator)
|
||||||
{
|
{
|
||||||
|
anv_pipeline_sets_layout_fini(&pipeline->layout);
|
||||||
anv_reloc_list_finish(&pipeline->batch_relocs,
|
anv_reloc_list_finish(&pipeline->batch_relocs,
|
||||||
pAllocator ? pAllocator : &device->vk.alloc);
|
pAllocator ? pAllocator : &device->vk.alloc);
|
||||||
ralloc_free(pipeline->mem_ctx);
|
ralloc_free(pipeline->mem_ctx);
|
||||||
|
|
@ -606,7 +632,6 @@ struct anv_pipeline_stage {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline *pipeline,
|
anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline *pipeline,
|
||||||
struct anv_pipeline_layout *layout,
|
|
||||||
struct anv_pipeline_stage *stages,
|
struct anv_pipeline_stage *stages,
|
||||||
uint32_t view_mask,
|
uint32_t view_mask,
|
||||||
unsigned char *sha1_out)
|
unsigned char *sha1_out)
|
||||||
|
|
@ -616,8 +641,8 @@ anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline *pipeline,
|
||||||
|
|
||||||
_mesa_sha1_update(&ctx, &view_mask, sizeof(view_mask));
|
_mesa_sha1_update(&ctx, &view_mask, sizeof(view_mask));
|
||||||
|
|
||||||
if (layout)
|
_mesa_sha1_update(&ctx, pipeline->base.layout.sha1,
|
||||||
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
|
sizeof(pipeline->base.layout.sha1));
|
||||||
|
|
||||||
const struct anv_device *device = pipeline->base.device;
|
const struct anv_device *device = pipeline->base.device;
|
||||||
|
|
||||||
|
|
@ -642,15 +667,14 @@ anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline *pipeline,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
anv_pipeline_hash_compute(struct anv_compute_pipeline *pipeline,
|
anv_pipeline_hash_compute(struct anv_compute_pipeline *pipeline,
|
||||||
struct anv_pipeline_layout *layout,
|
|
||||||
struct anv_pipeline_stage *stage,
|
struct anv_pipeline_stage *stage,
|
||||||
unsigned char *sha1_out)
|
unsigned char *sha1_out)
|
||||||
{
|
{
|
||||||
struct mesa_sha1 ctx;
|
struct mesa_sha1 ctx;
|
||||||
_mesa_sha1_init(&ctx);
|
_mesa_sha1_init(&ctx);
|
||||||
|
|
||||||
if (layout)
|
_mesa_sha1_update(&ctx, pipeline->base.layout.sha1,
|
||||||
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
|
sizeof(pipeline->base.layout.sha1));
|
||||||
|
|
||||||
const struct anv_device *device = pipeline->base.device;
|
const struct anv_device *device = pipeline->base.device;
|
||||||
|
|
||||||
|
|
@ -669,15 +693,14 @@ anv_pipeline_hash_compute(struct anv_compute_pipeline *pipeline,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
anv_pipeline_hash_ray_tracing_shader(struct anv_ray_tracing_pipeline *pipeline,
|
anv_pipeline_hash_ray_tracing_shader(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
struct anv_pipeline_layout *layout,
|
|
||||||
struct anv_pipeline_stage *stage,
|
struct anv_pipeline_stage *stage,
|
||||||
unsigned char *sha1_out)
|
unsigned char *sha1_out)
|
||||||
{
|
{
|
||||||
struct mesa_sha1 ctx;
|
struct mesa_sha1 ctx;
|
||||||
_mesa_sha1_init(&ctx);
|
_mesa_sha1_init(&ctx);
|
||||||
|
|
||||||
if (layout != NULL)
|
_mesa_sha1_update(&ctx, pipeline->base.layout.sha1,
|
||||||
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
|
sizeof(pipeline->base.layout.sha1));
|
||||||
|
|
||||||
const bool rba = pipeline->base.device->vk.enabled_features.robustBufferAccess;
|
const bool rba = pipeline->base.device->vk.enabled_features.robustBufferAccess;
|
||||||
_mesa_sha1_update(&ctx, &rba, sizeof(rba));
|
_mesa_sha1_update(&ctx, &rba, sizeof(rba));
|
||||||
|
|
@ -690,7 +713,6 @@ anv_pipeline_hash_ray_tracing_shader(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline *pipeline,
|
anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
struct anv_pipeline_layout *layout,
|
|
||||||
struct anv_pipeline_stage *intersection,
|
struct anv_pipeline_stage *intersection,
|
||||||
struct anv_pipeline_stage *any_hit,
|
struct anv_pipeline_stage *any_hit,
|
||||||
unsigned char *sha1_out)
|
unsigned char *sha1_out)
|
||||||
|
|
@ -698,8 +720,8 @@ anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline *p
|
||||||
struct mesa_sha1 ctx;
|
struct mesa_sha1 ctx;
|
||||||
_mesa_sha1_init(&ctx);
|
_mesa_sha1_init(&ctx);
|
||||||
|
|
||||||
if (layout != NULL)
|
_mesa_sha1_update(&ctx, pipeline->base.layout.sha1,
|
||||||
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
|
sizeof(pipeline->base.layout.sha1));
|
||||||
|
|
||||||
const bool rba = pipeline->base.device->vk.enabled_features.robustBufferAccess;
|
const bool rba = pipeline->base.device->vk.enabled_features.robustBufferAccess;
|
||||||
_mesa_sha1_update(&ctx, &rba, sizeof(rba));
|
_mesa_sha1_update(&ctx, &rba, sizeof(rba));
|
||||||
|
|
@ -743,15 +765,15 @@ anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct vk_ycbcr_conversion_state *
|
static const struct vk_ycbcr_conversion_state *
|
||||||
lookup_ycbcr_conversion(const void *_pipeline_layout, uint32_t set,
|
lookup_ycbcr_conversion(const void *_sets_layout, uint32_t set,
|
||||||
uint32_t binding, uint32_t array_index)
|
uint32_t binding, uint32_t array_index)
|
||||||
{
|
{
|
||||||
const struct anv_pipeline_layout *pipeline_layout = _pipeline_layout;
|
const struct anv_pipeline_sets_layout *sets_layout = _sets_layout;
|
||||||
|
|
||||||
assert(set < MAX_SETS);
|
assert(set < MAX_SETS);
|
||||||
assert(binding < pipeline_layout->set[set].layout->binding_count);
|
assert(binding < sets_layout->set[set].layout->binding_count);
|
||||||
const struct anv_descriptor_set_binding_layout *bind_layout =
|
const struct anv_descriptor_set_binding_layout *bind_layout =
|
||||||
&pipeline_layout->set[set].layout->binding[binding];
|
&sets_layout->set[set].layout->binding[binding];
|
||||||
|
|
||||||
if (bind_layout->immutable_samplers == NULL)
|
if (bind_layout->immutable_samplers == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -780,12 +802,12 @@ static void
|
||||||
anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
|
anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
|
||||||
void *mem_ctx,
|
void *mem_ctx,
|
||||||
struct anv_pipeline_stage *stage,
|
struct anv_pipeline_stage *stage,
|
||||||
struct anv_pipeline_layout *layout,
|
|
||||||
uint32_t view_mask,
|
uint32_t view_mask,
|
||||||
bool use_primitive_replication)
|
bool use_primitive_replication)
|
||||||
{
|
{
|
||||||
const struct anv_physical_device *pdevice = pipeline->device->physical;
|
const struct anv_physical_device *pdevice = pipeline->device->physical;
|
||||||
const struct brw_compiler *compiler = pdevice->compiler;
|
const struct brw_compiler *compiler = pdevice->compiler;
|
||||||
|
struct anv_pipeline_sets_layout *layout = &pipeline->layout;
|
||||||
|
|
||||||
struct brw_stage_prog_data *prog_data = &stage->prog_data.base;
|
struct brw_stage_prog_data *prog_data = &stage->prog_data.base;
|
||||||
nir_shader *nir = stage->nir;
|
nir_shader *nir = stage->nir;
|
||||||
|
|
@ -839,6 +861,7 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
|
||||||
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
|
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
|
||||||
NIR_PASS_V(nir, anv_nir_apply_pipeline_layout,
|
NIR_PASS_V(nir, anv_nir_apply_pipeline_layout,
|
||||||
pdevice, pipeline->device->vk.enabled_features.robustBufferAccess,
|
pdevice, pipeline->device->vk.enabled_features.robustBufferAccess,
|
||||||
|
layout->independent_sets,
|
||||||
layout, &stage->bind_map);
|
layout, &stage->bind_map);
|
||||||
|
|
||||||
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo,
|
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo,
|
||||||
|
|
@ -1686,7 +1709,6 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
|
||||||
const VkGraphicsPipelineCreateInfo *info,
|
const VkGraphicsPipelineCreateInfo *info,
|
||||||
const struct vk_graphics_pipeline_state *state)
|
const struct vk_graphics_pipeline_state *state)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
|
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
VkPipelineCreationFeedbackEXT pipeline_feedback = {
|
VkPipelineCreationFeedbackEXT pipeline_feedback = {
|
||||||
|
|
@ -1707,7 +1729,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
|
||||||
anv_graphics_pipeline_init_keys(pipeline, state, stages);
|
anv_graphics_pipeline_init_keys(pipeline, state, stages);
|
||||||
|
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
anv_pipeline_hash_graphics(pipeline, layout, stages, state->rp->view_mask, sha1);
|
anv_pipeline_hash_graphics(pipeline, stages, state->rp->view_mask, sha1);
|
||||||
|
|
||||||
for (unsigned s = 0; s < ARRAY_SIZE(stages); s++) {
|
for (unsigned s = 0; s < ARRAY_SIZE(stages); s++) {
|
||||||
if (!stages[s].info)
|
if (!stages[s].info)
|
||||||
|
|
@ -1815,7 +1837,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
|
||||||
|
|
||||||
int64_t stage_start = os_time_get_nano();
|
int64_t stage_start = os_time_get_nano();
|
||||||
|
|
||||||
anv_pipeline_lower_nir(&pipeline->base, pipeline_ctx, stage, layout,
|
anv_pipeline_lower_nir(&pipeline->base, pipeline_ctx, stage,
|
||||||
state->rp->view_mask, use_primitive_replication);
|
state->rp->view_mask, use_primitive_replication);
|
||||||
|
|
||||||
struct shader_info *cur_info = &stage->nir->info;
|
struct shader_info *cur_info = &stage->nir->info;
|
||||||
|
|
@ -2025,12 +2047,10 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
|
||||||
|
|
||||||
populate_cs_prog_key(device, device->vk.enabled_features.robustBufferAccess, &stage.key.cs);
|
populate_cs_prog_key(device, device->vk.enabled_features.robustBufferAccess, &stage.key.cs);
|
||||||
|
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
|
|
||||||
|
|
||||||
const bool skip_cache_lookup =
|
const bool skip_cache_lookup =
|
||||||
(pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
|
(pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
|
||||||
|
|
||||||
anv_pipeline_hash_compute(pipeline, layout, &stage, stage.cache_key.sha1);
|
anv_pipeline_hash_compute(pipeline, &stage, stage.cache_key.sha1);
|
||||||
|
|
||||||
bool cache_hit = false;
|
bool cache_hit = false;
|
||||||
if (!skip_cache_lookup) {
|
if (!skip_cache_lookup) {
|
||||||
|
|
@ -2068,7 +2088,7 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
|
||||||
|
|
||||||
anv_pipeline_nir_preprocess(&pipeline->base, stage.nir);
|
anv_pipeline_nir_preprocess(&pipeline->base, stage.nir);
|
||||||
|
|
||||||
anv_pipeline_lower_nir(&pipeline->base, mem_ctx, &stage, layout,
|
anv_pipeline_lower_nir(&pipeline->base, mem_ctx, &stage,
|
||||||
0 /* view_mask */,
|
0 /* view_mask */,
|
||||||
false /* use_primitive_replication */);
|
false /* use_primitive_replication */);
|
||||||
|
|
||||||
|
|
@ -2169,6 +2189,9 @@ anv_compute_pipeline_create(struct anv_device *device,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||||
|
anv_pipeline_init_layout(&pipeline->base, pipeline_layout);
|
||||||
|
|
||||||
anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
|
anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
|
||||||
pipeline->batch_data, sizeof(pipeline->batch_data));
|
pipeline->batch_data, sizeof(pipeline->batch_data));
|
||||||
|
|
||||||
|
|
@ -2295,6 +2318,9 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
|
||||||
|
|
||||||
pipeline->view_mask = state->rp->view_mask;
|
pipeline->view_mask = state->rp->view_mask;
|
||||||
|
|
||||||
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||||
|
anv_pipeline_init_layout(&pipeline->base.base, pipeline_layout);
|
||||||
|
|
||||||
result = anv_graphics_pipeline_compile(&pipeline->base, cache, pCreateInfo, state);
|
result = anv_graphics_pipeline_compile(&pipeline->base, cache, pCreateInfo, state);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
anv_pipeline_finish(&pipeline->base.base, device, alloc);
|
anv_pipeline_finish(&pipeline->base.base, device, alloc);
|
||||||
|
|
@ -2593,8 +2619,6 @@ anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
const VkRayTracingPipelineCreateInfoKHR *info,
|
const VkRayTracingPipelineCreateInfoKHR *info,
|
||||||
void *pipeline_ctx)
|
void *pipeline_ctx)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
|
|
||||||
|
|
||||||
/* Create enough stage entries for all shader modules plus potential
|
/* Create enough stage entries for all shader modules plus potential
|
||||||
* combinaisons in the groups.
|
* combinaisons in the groups.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2630,7 +2654,7 @@ anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
vk_pipeline_hash_shader_stage(sinfo, NULL, stages[i].shader_sha1);
|
vk_pipeline_hash_shader_stage(sinfo, NULL, stages[i].shader_sha1);
|
||||||
|
|
||||||
if (stages[i].stage != MESA_SHADER_INTERSECTION) {
|
if (stages[i].stage != MESA_SHADER_INTERSECTION) {
|
||||||
anv_pipeline_hash_ray_tracing_shader(pipeline, layout, &stages[i],
|
anv_pipeline_hash_ray_tracing_shader(pipeline, &stages[i],
|
||||||
stages[i].cache_key.sha1);
|
stages[i].cache_key.sha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2652,12 +2676,11 @@ anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
if (any_hit_idx != VK_SHADER_UNUSED_KHR) {
|
if (any_hit_idx != VK_SHADER_UNUSED_KHR) {
|
||||||
assert(any_hit_idx < info->stageCount);
|
assert(any_hit_idx < info->stageCount);
|
||||||
anv_pipeline_hash_ray_tracing_combined_shader(pipeline,
|
anv_pipeline_hash_ray_tracing_combined_shader(pipeline,
|
||||||
layout,
|
|
||||||
&stages[intersection_idx],
|
&stages[intersection_idx],
|
||||||
&stages[any_hit_idx],
|
&stages[any_hit_idx],
|
||||||
stages[intersection_idx].cache_key.sha1);
|
stages[intersection_idx].cache_key.sha1);
|
||||||
} else {
|
} else {
|
||||||
anv_pipeline_hash_ray_tracing_shader(pipeline, layout,
|
anv_pipeline_hash_ray_tracing_shader(pipeline,
|
||||||
&stages[intersection_idx],
|
&stages[intersection_idx],
|
||||||
stages[intersection_idx].cache_key.sha1);
|
stages[intersection_idx].cache_key.sha1);
|
||||||
}
|
}
|
||||||
|
|
@ -2729,8 +2752,6 @@ anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
struct anv_pipeline_stage *stages =
|
struct anv_pipeline_stage *stages =
|
||||||
anv_pipeline_init_ray_tracing_stages(pipeline, info, pipeline_ctx);
|
anv_pipeline_init_ray_tracing_stages(pipeline, info, pipeline_ctx);
|
||||||
|
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
|
|
||||||
|
|
||||||
const bool skip_cache_lookup =
|
const bool skip_cache_lookup =
|
||||||
(pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
|
(pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
|
||||||
|
|
||||||
|
|
@ -2765,7 +2786,7 @@ anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
anv_pipeline_nir_preprocess(&pipeline->base, stages[i].nir);
|
anv_pipeline_nir_preprocess(&pipeline->base, stages[i].nir);
|
||||||
|
|
||||||
anv_pipeline_lower_nir(&pipeline->base, pipeline_ctx, &stages[i],
|
anv_pipeline_lower_nir(&pipeline->base, pipeline_ctx, &stages[i],
|
||||||
layout, 0 /* view_mask */,
|
0 /* view_mask */,
|
||||||
false /* use_primitive_replication */);
|
false /* use_primitive_replication */);
|
||||||
|
|
||||||
stages[i].feedback.duration += os_time_get_nano() - stage_start;
|
stages[i].feedback.duration += os_time_get_nano() - stage_start;
|
||||||
|
|
@ -3065,6 +3086,9 @@ anv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline *pipeline,
|
||||||
|
|
||||||
util_dynarray_init(&pipeline->shaders, pipeline->base.mem_ctx);
|
util_dynarray_init(&pipeline->shaders, pipeline->base.mem_ctx);
|
||||||
|
|
||||||
|
ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||||
|
anv_pipeline_init_layout(&pipeline->base, pipeline_layout);
|
||||||
|
|
||||||
result = anv_pipeline_compile_ray_tracing(pipeline, cache, pCreateInfo);
|
result = anv_pipeline_compile_ray_tracing(pipeline, cache, pCreateInfo);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -1675,7 +1675,9 @@ struct anv_descriptor_set_binding_layout {
|
||||||
/* Index into the flattened descriptor set */
|
/* Index into the flattened descriptor set */
|
||||||
uint32_t descriptor_index;
|
uint32_t descriptor_index;
|
||||||
|
|
||||||
/* Index into the dynamic state array for a dynamic buffer */
|
/* Index into the dynamic state array for a dynamic buffer, relative to the
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
int16_t dynamic_offset_index;
|
int16_t dynamic_offset_index;
|
||||||
|
|
||||||
/* Index into the descriptor set buffer views */
|
/* Index into the descriptor set buffer views */
|
||||||
|
|
@ -1737,11 +1739,13 @@ struct anv_descriptor_set_layout {
|
||||||
void anv_descriptor_set_layout_destroy(struct anv_device *device,
|
void anv_descriptor_set_layout_destroy(struct anv_device *device,
|
||||||
struct anv_descriptor_set_layout *layout);
|
struct anv_descriptor_set_layout *layout);
|
||||||
|
|
||||||
static inline void
|
static inline struct anv_descriptor_set_layout *
|
||||||
anv_descriptor_set_layout_ref(struct anv_descriptor_set_layout *layout)
|
anv_descriptor_set_layout_ref(struct anv_descriptor_set_layout *layout)
|
||||||
{
|
{
|
||||||
assert(layout && layout->ref_cnt >= 1);
|
assert(layout && layout->ref_cnt >= 1);
|
||||||
p_atomic_inc(&layout->ref_cnt);
|
p_atomic_inc(&layout->ref_cnt);
|
||||||
|
|
||||||
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
@ -1982,7 +1986,13 @@ struct anv_pipeline_binding {
|
||||||
/** Plane in the binding index for images */
|
/** Plane in the binding index for images */
|
||||||
uint8_t plane;
|
uint8_t plane;
|
||||||
|
|
||||||
/** Dynamic offset index (for dynamic UBOs and SSBOs) */
|
/** Input attachment index (relative to the subpass) */
|
||||||
|
uint8_t input_attachment_index;
|
||||||
|
|
||||||
|
/** Dynamic offset index
|
||||||
|
*
|
||||||
|
* For dynamic UBOs and SSBOs, relative to set.
|
||||||
|
*/
|
||||||
uint8_t dynamic_offset_index;
|
uint8_t dynamic_offset_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1997,7 +2007,7 @@ struct anv_push_range {
|
||||||
/** Descriptor set index */
|
/** Descriptor set index */
|
||||||
uint8_t set;
|
uint8_t set;
|
||||||
|
|
||||||
/** Dynamic offset index (for dynamic UBOs) */
|
/** Dynamic offset index (for dynamic UBOs), relative to set. */
|
||||||
uint8_t dynamic_offset_index;
|
uint8_t dynamic_offset_index;
|
||||||
|
|
||||||
/** Start offset in units of 32B */
|
/** Start offset in units of 32B */
|
||||||
|
|
@ -2007,8 +2017,8 @@ struct anv_push_range {
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct anv_pipeline_layout {
|
struct anv_pipeline_sets_layout {
|
||||||
struct vk_object_base base;
|
struct anv_device *device;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct anv_descriptor_set_layout *layout;
|
struct anv_descriptor_set_layout *layout;
|
||||||
|
|
@ -2016,12 +2026,35 @@ struct anv_pipeline_layout {
|
||||||
} set[MAX_SETS];
|
} set[MAX_SETS];
|
||||||
|
|
||||||
uint32_t num_sets;
|
uint32_t num_sets;
|
||||||
|
uint32_t num_dynamic_buffers;
|
||||||
|
|
||||||
|
bool independent_sets;
|
||||||
|
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void anv_pipeline_sets_layout_init(struct anv_pipeline_sets_layout *layout,
|
||||||
|
struct anv_device *device,
|
||||||
|
bool independent_sets);
|
||||||
|
|
||||||
|
void anv_pipeline_sets_layout_fini(struct anv_pipeline_sets_layout *layout);
|
||||||
|
|
||||||
|
void anv_pipeline_sets_layout_add(struct anv_pipeline_sets_layout *layout,
|
||||||
|
uint32_t set_idx,
|
||||||
|
struct anv_descriptor_set_layout *set_layout);
|
||||||
|
|
||||||
|
void anv_pipeline_sets_layout_hash(struct anv_pipeline_sets_layout *layout);
|
||||||
|
|
||||||
|
void anv_pipeline_sets_layout_print(const struct anv_pipeline_sets_layout *layout);
|
||||||
|
|
||||||
|
struct anv_pipeline_layout {
|
||||||
|
struct vk_object_base base;
|
||||||
|
|
||||||
|
struct anv_pipeline_sets_layout sets_layout;
|
||||||
|
};
|
||||||
|
|
||||||
const struct anv_descriptor_set_layout *
|
const struct anv_descriptor_set_layout *
|
||||||
anv_pipeline_layout_get_push_set(const struct anv_pipeline_layout *layout,
|
anv_pipeline_layout_get_push_set(const struct anv_pipeline_sets_layout *layout,
|
||||||
uint8_t *desc_idx);
|
uint8_t *desc_idx);
|
||||||
|
|
||||||
struct anv_buffer {
|
struct anv_buffer {
|
||||||
|
|
@ -2394,7 +2427,14 @@ struct anv_push_constants {
|
||||||
/** Ray query globals (RT_DISPATCH_GLOBALS) */
|
/** Ray query globals (RT_DISPATCH_GLOBALS) */
|
||||||
uint64_t ray_query_globals;
|
uint64_t ray_query_globals;
|
||||||
|
|
||||||
/* Base addresses for descriptor sets */
|
#define ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK ((uint64_t)ANV_UBO_ALIGNMENT - 1)
|
||||||
|
#define ANV_DESCRIPTOR_SET_ADDRESS_MASK (~(uint64_t)(ANV_UBO_ALIGNMENT - 1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In bits [0:5] : dynamic offset index in dynamic_offsets[] for the set
|
||||||
|
*
|
||||||
|
* In bits [6:63] : descriptor set address
|
||||||
|
*/
|
||||||
uint64_t desc_sets[MAX_SETS];
|
uint64_t desc_sets[MAX_SETS];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -2524,6 +2564,21 @@ struct anv_cmd_pipeline_state {
|
||||||
|
|
||||||
/* Push constant state allocated when flushing push constants. */
|
/* Push constant state allocated when flushing push constants. */
|
||||||
struct anv_state push_constants_state;
|
struct anv_state push_constants_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic buffer offsets.
|
||||||
|
*
|
||||||
|
* We have a maximum of MAX_DYNAMIC_BUFFERS per pipeline, but with
|
||||||
|
* independent sets we cannot know which how much in total is going to be
|
||||||
|
* used. As a result we need to store the maximum possible number per set.
|
||||||
|
*
|
||||||
|
* Those values are written into anv_push_constants::dynamic_offsets at
|
||||||
|
* flush time when have the pipeline with the final
|
||||||
|
* anv_pipeline_sets_layout.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
uint32_t offsets[MAX_DYNAMIC_BUFFERS];
|
||||||
|
} dynamic_offsets[MAX_SETS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/** State tracking for graphics pipeline
|
/** State tracking for graphics pipeline
|
||||||
|
|
@ -3118,6 +3173,9 @@ struct anv_pipeline {
|
||||||
*/
|
*/
|
||||||
VkShaderStageFlags use_push_descriptor_buffer;
|
VkShaderStageFlags use_push_descriptor_buffer;
|
||||||
|
|
||||||
|
/* Layout of the sets used by the pipeline. */
|
||||||
|
struct anv_pipeline_sets_layout layout;
|
||||||
|
|
||||||
struct util_dynarray executables;
|
struct util_dynarray executables;
|
||||||
|
|
||||||
const struct intel_l3_config * l3_config;
|
const struct intel_l3_config * l3_config;
|
||||||
|
|
|
||||||
|
|
@ -2041,10 +2041,6 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
||||||
if (bt_state->map == NULL)
|
if (bt_state->map == NULL)
|
||||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||||
|
|
||||||
/* Note that we always keep all user-allocated memory objects resident. */
|
|
||||||
|
|
||||||
struct anv_push_constants *push = &pipe_state->push_constants;
|
|
||||||
|
|
||||||
for (uint32_t s = 0; s < map->surface_count; s++) {
|
for (uint32_t s = 0; s < map->surface_count; s++) {
|
||||||
struct anv_pipeline_binding *binding = &map->surface_to_descriptor[s];
|
struct anv_pipeline_binding *binding = &map->surface_to_descriptor[s];
|
||||||
|
|
||||||
|
|
@ -2239,7 +2235,8 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
||||||
if (desc->buffer) {
|
if (desc->buffer) {
|
||||||
/* Compute the offset within the buffer */
|
/* Compute the offset within the buffer */
|
||||||
uint32_t dynamic_offset =
|
uint32_t dynamic_offset =
|
||||||
push->dynamic_offsets[binding->dynamic_offset_index];
|
pipe_state->dynamic_offsets[
|
||||||
|
binding->set].offsets[binding->dynamic_offset_index];
|
||||||
uint64_t offset = desc->offset + dynamic_offset;
|
uint64_t offset = desc->offset + dynamic_offset;
|
||||||
/* Clamp to the buffer size */
|
/* Clamp to the buffer size */
|
||||||
offset = MIN2(offset, desc->buffer->vk.size);
|
offset = MIN2(offset, desc->buffer->vk.size);
|
||||||
|
|
@ -2547,10 +2544,10 @@ get_push_range_address(struct anv_cmd_buffer *cmd_buffer,
|
||||||
} else {
|
} else {
|
||||||
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||||
if (desc->buffer) {
|
if (desc->buffer) {
|
||||||
const struct anv_push_constants *push =
|
const struct anv_cmd_pipeline_state *pipe_state = &gfx_state->base;
|
||||||
&gfx_state->base.push_constants;
|
|
||||||
uint32_t dynamic_offset =
|
uint32_t dynamic_offset =
|
||||||
push->dynamic_offsets[range->dynamic_offset_index];
|
pipe_state->dynamic_offsets[
|
||||||
|
range->set].offsets[range->dynamic_offset_index];
|
||||||
return anv_address_add(desc->buffer->address,
|
return anv_address_add(desc->buffer->address,
|
||||||
desc->offset + dynamic_offset);
|
desc->offset + dynamic_offset);
|
||||||
}
|
}
|
||||||
|
|
@ -2620,10 +2617,10 @@ get_push_range_bound_size(struct anv_cmd_buffer *cmd_buffer,
|
||||||
|
|
||||||
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||||
/* Compute the offset within the buffer */
|
/* Compute the offset within the buffer */
|
||||||
const struct anv_push_constants *push =
|
const struct anv_cmd_pipeline_state *pipe_state = &gfx_state->base;
|
||||||
&gfx_state->base.push_constants;
|
|
||||||
uint32_t dynamic_offset =
|
uint32_t dynamic_offset =
|
||||||
push->dynamic_offsets[range->dynamic_offset_index];
|
pipe_state->dynamic_offsets[
|
||||||
|
range->set].offsets[range->dynamic_offset_index];
|
||||||
uint64_t offset = desc->offset + dynamic_offset;
|
uint64_t offset = desc->offset + dynamic_offset;
|
||||||
/* Clamp to the buffer size */
|
/* Clamp to the buffer size */
|
||||||
offset = MIN2(offset, desc->buffer->vk.size);
|
offset = MIN2(offset, desc->buffer->vk.size);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue