cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
}
- if (set_layout->num_dynamic_buffers > 0) {
+ if (set_layout->dynamic_offset_count > 0) {
VkShaderStage s;
for_each_bit(s, set_layout->shader_stages) {
anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s,
cmd_buffer->state.push_constants[s]->dynamic_offsets +
layout->set[firstSet + i].dynamic_offset_start;
- memcpy(offsets, pDynamicOffsets + dynamic_slot,
- set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
+ typed_memcpy(offsets, pDynamicOffsets + dynamic_slot,
+ set_layout->dynamic_offset_count);
}
cmd_buffer->state.push_constants_dirty |= set_layout->shader_stages;
- dynamic_slot += set_layout->num_dynamic_buffers;
+ dynamic_slot += set_layout->dynamic_offset_count;
}
}
}
if (layout == NULL)
return VK_SUCCESS;
- for (uint32_t set = 0; set < layout->num_sets; set++) {
- struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set];
- struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
- struct anv_descriptor_slot *surface_slots =
- set_layout->stage[stage].surface_start;
-
- uint32_t start = bias + layout->set[set].stage[stage].surface_start;
-
- for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
- struct anv_descriptor *desc =
- &d->set->descriptors[surface_slots[b].index];
-
- const struct anv_state *surface_state;
- struct anv_bo *bo;
- uint32_t bo_offset;
-
- switch (desc->type) {
- case ANV_DESCRIPTOR_TYPE_EMPTY:
- case ANV_DESCRIPTOR_TYPE_SAMPLER:
- continue;
- case ANV_DESCRIPTOR_TYPE_BUFFER_VIEW:
- surface_state = &desc->buffer_view->surface_state;
- bo = desc->buffer_view->bo;
- bo_offset = desc->buffer_view->offset;
- break;
- case ANV_DESCRIPTOR_TYPE_IMAGE_VIEW:
- surface_state = &desc->image_view->nonrt_surface_state;
- bo = desc->image_view->bo;
- bo_offset = desc->image_view->offset;
- break;
- }
-
- bt_map[start + b] = surface_state->offset + state_offset;
- add_surface_state_reloc(cmd_buffer, *surface_state, bo, bo_offset);
+ for (uint32_t s = 0; s < layout->stage[stage].surface_count; s++) {
+ struct anv_pipeline_binding *binding =
+ &layout->stage[stage].surface_to_descriptor[s];
+ struct anv_descriptor_set *set =
+ cmd_buffer->state.descriptors[binding->set].set;
+ struct anv_descriptor *desc = &set->descriptors[binding->offset];
+
+ const struct anv_state *surface_state;
+ struct anv_bo *bo;
+ uint32_t bo_offset;
+
+ switch (desc->type) {
+ case ANV_DESCRIPTOR_TYPE_EMPTY:
+ case ANV_DESCRIPTOR_TYPE_SAMPLER:
+ continue;
+ case ANV_DESCRIPTOR_TYPE_BUFFER_VIEW:
+ surface_state = &desc->buffer_view->surface_state;
+ bo = desc->buffer_view->bo;
+ bo_offset = desc->buffer_view->offset;
+ break;
+ case ANV_DESCRIPTOR_TYPE_IMAGE_VIEW:
+ surface_state = &desc->image_view->nonrt_surface_state;
+ bo = desc->image_view->bo;
+ bo_offset = desc->image_view->offset;
+ break;
}
+
+ bt_map[bias + s] = surface_state->offset + state_offset;
+ add_surface_state_reloc(cmd_buffer, *surface_state, bo, bo_offset);
}
return VK_SUCCESS;
if (state->map == NULL)
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
- for (uint32_t set = 0; set < layout->num_sets; set++) {
- struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set];
- struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
- struct anv_descriptor_slot *sampler_slots =
- set_layout->stage[stage].sampler_start;
-
- uint32_t start = layout->set[set].stage[stage].sampler_start;
+ for (uint32_t s = 0; s < layout->stage[stage].sampler_count; s++) {
+ struct anv_pipeline_binding *binding =
+ &layout->stage[stage].sampler_to_descriptor[s];
+ struct anv_descriptor_set *set =
+ cmd_buffer->state.descriptors[binding->set].set;
+ struct anv_descriptor *desc = &set->descriptors[binding->offset];
- for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
- struct anv_descriptor *desc =
- &d->set->descriptors[sampler_slots[b].index];
+ if (desc->type != ANV_DESCRIPTOR_TYPE_SAMPLER)
+ continue;
- if (desc->type != ANV_DESCRIPTOR_TYPE_SAMPLER)
- continue;
+ struct anv_sampler *sampler = desc->sampler;
- struct anv_sampler *sampler = desc->sampler;
-
- memcpy(state->map + (start + b) * 16,
- sampler->state, sizeof(sampler->state));
- }
+ memcpy(state->map + (s * 16),
+ sampler->state, sizeof(sampler->state));
}
return VK_SUCCESS;
k = bias;
map = prog_data->map_entries;
- for (uint32_t i = 0; i < layout->num_sets; i++) {
- prog_data->bind_map[i].index = map;
- for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++)
- *map++ = k++;
+ for (uint32_t set = 0; set < layout->num_sets; set++) {
+ prog_data->bind_map[set].index = map;
+ unsigned index_count = 0;
+ for (uint32_t b = 0; b < layout->set[set].layout->binding_count; b++) {
+ if (layout->set[set].layout->binding[b].stage[stage].surface_index < 0)
+ continue;
+
+ unsigned array_size = layout->set[set].layout->binding[b].array_size;
+ for (uint32_t i = 0; i < array_size; i++)
+ *map++ = k++;
+ index_count += array_size;
+ }
- prog_data->bind_map[i].index_count =
- layout->set[i].layout->stage[stage].surface_count;
+ prog_data->bind_map[set].index_count = index_count;
}
return VK_SUCCESS;
{
ANV_FROM_HANDLE(anv_device, device, _device);
struct anv_descriptor_set_layout *set_layout;
+ uint32_t s;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
+ size_t size = sizeof(struct anv_descriptor_set_layout) +
+ pCreateInfo->count * sizeof(set_layout->binding[0]);
+
+ set_layout = anv_device_alloc(device, size, 8,
+ VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ if (!set_layout)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ set_layout->binding_count = pCreateInfo->count;
+ set_layout->shader_stages = 0;
+ set_layout->size = 0;
+
+ /* Initialize all binding_layout entries to -1 */
+ memset(set_layout->binding, -1,
+ pCreateInfo->count * sizeof(set_layout->binding[0]));
+
uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
- uint32_t num_dynamic_buffers = 0;
- uint32_t count = 0;
- VkShaderStageFlags stages = 0;
- uint32_t s;
+ uint32_t dynamic_offset_count = 0;
+
+ for (uint32_t b = 0; b < pCreateInfo->count; b++) {
+ uint32_t array_size = MAX2(1, pCreateInfo->pBinding[b].arraySize);
+ set_layout->binding[b].array_size = array_size;
+ set_layout->size += array_size;
- for (uint32_t i = 0; i < pCreateInfo->count; i++) {
- switch (pCreateInfo->pBinding[i].descriptorType) {
+ switch (pCreateInfo->pBinding[b].descriptorType) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
- sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
+ for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) {
+ set_layout->binding[b].stage[s].sampler_index = sampler_count[s];
+ sampler_count[s] += array_size;
+ }
break;
default:
break;
}
- switch (pCreateInfo->pBinding[i].descriptorType) {
+ switch (pCreateInfo->pBinding[b].descriptorType) {
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
- surface_count[s] += pCreateInfo->pBinding[i].arraySize;
+ for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) {
+ set_layout->binding[b].stage[s].surface_index = surface_count[s];
+ surface_count[s] += array_size;
+ }
break;
default:
break;
}
- switch (pCreateInfo->pBinding[i].descriptorType) {
+ switch (pCreateInfo->pBinding[b].descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
+ set_layout->binding[b].dynamic_offset_index = dynamic_offset_count;
+ dynamic_offset_count += array_size;
break;
default:
break;
}
- stages |= pCreateInfo->pBinding[i].stageFlags;
- count += pCreateInfo->pBinding[i].arraySize;
+ set_layout->shader_stages |= pCreateInfo->pBinding[b].stageFlags;
}
- uint32_t sampler_total = 0;
- uint32_t surface_total = 0;
- for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
- sampler_total += sampler_count[s];
- surface_total += surface_count[s];
- }
-
- size_t size = sizeof(*set_layout) +
- (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
- set_layout = anv_device_alloc(device, size, 8,
- VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
- if (!set_layout)
- return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
- set_layout->num_dynamic_buffers = num_dynamic_buffers;
- set_layout->count = count;
- set_layout->shader_stages = stages;
-
- struct anv_descriptor_slot *p = set_layout->entries;
- struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
- struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
- for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
- set_layout->stage[s].surface_count = surface_count[s];
- set_layout->stage[s].surface_start = surface[s] = p;
- p += surface_count[s];
- set_layout->stage[s].sampler_count = sampler_count[s];
- set_layout->stage[s].sampler_start = sampler[s] = p;
- p += sampler_count[s];
- }
-
- uint32_t descriptor = 0;
- int8_t dynamic_slot = 0;
- bool is_dynamic;
- for (uint32_t i = 0; i < pCreateInfo->count; i++) {
- switch (pCreateInfo->pBinding[i].descriptorType) {
- case VK_DESCRIPTOR_TYPE_SAMPLER:
- case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
- for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
- sampler[s]->index = descriptor + j;
- sampler[s]->dynamic_slot = -1;
- sampler[s]++;
- }
- break;
- default:
- break;
- }
-
- switch (pCreateInfo->pBinding[i].descriptorType) {
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- is_dynamic = true;
- break;
- default:
- is_dynamic = false;
- break;
- }
-
- switch (pCreateInfo->pBinding[i].descriptorType) {
- case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
- case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
- for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
- surface[s]->index = descriptor + j;
- if (is_dynamic)
- surface[s]->dynamic_slot = dynamic_slot + j;
- else
- surface[s]->dynamic_slot = -1;
- surface[s]++;
- }
- break;
- default:
- break;
- }
-
- if (is_dynamic)
- dynamic_slot += pCreateInfo->pBinding[i].arraySize;
-
- descriptor += pCreateInfo->pBinding[i].arraySize;
- }
+ set_layout->dynamic_offset_count = dynamic_offset_count;
*pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
struct anv_descriptor_set **out_set)
{
struct anv_descriptor_set *set;
- size_t size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
+ size_t size = sizeof(*set) + layout->size * sizeof(set->descriptors[0]);
set = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
if (!set)
{
struct apply_dynamic_offsets_state *state = void_state;
struct anv_descriptor_set_layout *set_layout;
- const struct anv_descriptor_slot *slot;
nir_foreach_instr_safe(block, instr) {
if (instr->type != nir_instr_type_intrinsic)
}
set_layout = state->layout->set[set].layout;
- slot = &set_layout->stage[state->stage].surface_start[binding];
- if (slot->dynamic_slot < 0)
+ if (set_layout->binding[binding].dynamic_offset_index < 0)
continue;
- uint32_t dynamic_index = state->layout->set[set].dynamic_offset_start +
- slot->dynamic_slot;
+ uint32_t index = state->layout->set[set].dynamic_offset_start +
+ set_layout->binding[binding].dynamic_offset_index;
state->builder.cursor = nir_before_instr(&intrin->instr);
nir_intrinsic_instr *offset_load =
nir_intrinsic_instr_create(state->shader, nir_intrinsic_load_uniform);
offset_load->num_components = 1;
- offset_load->const_index[0] = state->indices_start + dynamic_index;
+ offset_load->const_index[0] = state->indices_start + index;
offset_load->const_index[1] = 0;
nir_ssa_dest_init(&offset_load->instr, &offset_load->dest, 1, NULL);
nir_builder_instr_insert(&state->builder, &offset_load->instr);
VkPipelineLayout* pPipelineLayout)
{
ANV_FROM_HANDLE(anv_device, device, _device);
- struct anv_pipeline_layout *layout;
+ struct anv_pipeline_layout l, *layout;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
- layout = anv_device_alloc(device, sizeof(*layout), 8,
- VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
- if (layout == NULL)
- return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ l.num_sets = pCreateInfo->descriptorSetCount;
+
+ unsigned dynamic_offset_count = 0;
+
+ memset(l.stage, 0, sizeof(l.stage));
+ for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) {
+ ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
+ pCreateInfo->pSetLayouts[set]);
+ l.set[set].layout = set_layout;
+
+ l.set[set].dynamic_offset_start = dynamic_offset_count;
+ for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+ if (set_layout->binding[b].dynamic_offset_index >= 0)
+ dynamic_offset_count += set_layout->binding[b].array_size;
+ }
+
+ for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+ l.set[set].stage[s].surface_start = l.stage[s].surface_count;
+ l.set[set].stage[s].sampler_start = l.stage[s].sampler_count;
+
+ for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+ unsigned array_size = set_layout->binding[b].array_size;
- layout->num_sets = pCreateInfo->descriptorSetCount;
+ if (set_layout->binding[b].stage[s].surface_index >= 0) {
+ l.stage[s].surface_count += array_size;
- uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, };
- uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, };
+ if (set_layout->binding[b].dynamic_offset_index >= 0)
+ l.stage[s].has_dynamic_offsets = true;
+ }
- for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
- layout->stage[s].has_dynamic_offsets = false;
- layout->stage[s].surface_count = 0;
- layout->stage[s].sampler_count = 0;
+ if (set_layout->binding[b].stage[s].sampler_index >= 0)
+ l.stage[s].sampler_count += array_size;
+ }
+ }
}
- uint32_t num_dynamic_offsets = 0;
- for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
- ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
- pCreateInfo->pSetLayouts[i]);
-
- layout->set[i].layout = set_layout;
- layout->set[i].dynamic_offset_start = num_dynamic_offsets;
- num_dynamic_offsets += set_layout->num_dynamic_buffers;
- for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
- if (set_layout->num_dynamic_buffers > 0)
- layout->stage[s].has_dynamic_offsets = true;
-
- layout->set[i].stage[s].surface_start = surface_start[s];
- surface_start[s] += set_layout->stage[s].surface_count;
- layout->set[i].stage[s].sampler_start = sampler_start[s];
- sampler_start[s] += set_layout->stage[s].sampler_count;
-
- layout->stage[s].surface_count += set_layout->stage[s].surface_count;
- layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
+ unsigned num_bindings = 0;
+ for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++)
+ num_bindings += l.stage[s].surface_count + l.stage[s].sampler_count;
+
+ size_t size = sizeof(*layout) + num_bindings * sizeof(layout->entries[0]);
+
+ layout = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ if (layout == NULL)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ /* Now we can actually build our surface and sampler maps */
+ struct anv_pipeline_binding *entry = layout->entries;
+ for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+ l.stage[s].surface_to_descriptor = entry;
+ entry += l.stage[s].surface_count;
+ l.stage[s].sampler_to_descriptor = entry;
+ entry += l.stage[s].sampler_count;
+
+ int surface = 0;
+ int sampler = 0;
+ for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) {
+ struct anv_descriptor_set_layout *set_layout = l.set[set].layout;
+
+ unsigned set_offset = 0;
+ for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+ unsigned array_size = set_layout->binding[b].array_size;
+
+ if (set_layout->binding[b].stage[s].surface_index >= 0) {
+ assert(surface == l.set[set].stage[s].surface_start +
+ set_layout->binding[b].stage[s].surface_index);
+ for (unsigned i = 0; i < array_size; i++) {
+ l.stage[s].surface_to_descriptor[surface + i].set = set;
+ l.stage[s].surface_to_descriptor[surface + i].offset = set_offset + i;
+ }
+ surface += array_size;
+ }
+
+ if (set_layout->binding[b].stage[s].sampler_index >= 0) {
+ assert(sampler == l.set[set].stage[s].sampler_start +
+ set_layout->binding[b].stage[s].sampler_index);
+ for (unsigned i = 0; i < array_size; i++) {
+ l.stage[s].sampler_to_descriptor[sampler + i].set = set;
+ l.stage[s].sampler_to_descriptor[sampler + i].offset = set_offset + i;
+ }
+ sampler += array_size;
+ }
+
+ set_offset += array_size;
+ }
}
}
+ /* Finally, we're done setting it up, copy into the allocated version */
+ *layout = l;
+
*pPipelineLayout = anv_pipeline_layout_to_handle(layout);
return VK_SUCCESS;
void * map;
};
-struct anv_descriptor_slot {
- int8_t dynamic_slot;
- uint8_t index;
-};
+struct anv_descriptor_set_binding_layout {
+ /* Number of array elements in this binding */
+ uint16_t array_size;
+
+ /* Index into the dynamic state array for a dynamic buffer */
+ int16_t dynamic_offset_index;
-struct anv_descriptor_set_layout {
struct {
- uint32_t surface_count;
- struct anv_descriptor_slot *surface_start;
- uint32_t sampler_count;
- struct anv_descriptor_slot *sampler_start;
+ /* Index into the binding table for the associated surface */
+ int16_t surface_index;
+
+ /* Index into the sampler table for the associated sampler */
+ int16_t sampler_index;
} stage[VK_SHADER_STAGE_NUM];
+};
+
+struct anv_descriptor_set_layout {
+ /* Number of bindings in this descriptor set */
+ uint16_t binding_count;
+
+ /* Total size of the descriptor set with room for all array entries */
+ uint16_t size;
+
+ /* Shader stages affected by this descriptor set */
+ uint16_t shader_stages;
+
+ /* Number of dynamic offsets used by this descriptor set */
+ uint16_t dynamic_offset_count;
- uint32_t count;
- uint32_t num_dynamic_buffers;
- VkShaderStageFlags shader_stages;
- struct anv_descriptor_slot entries[0];
+ /* Don't use this directly */
+ struct anv_descriptor_set_binding_layout binding[0];
};
enum anv_descriptor_type {
#define MAX_DYNAMIC_BUFFERS 16
#define MAX_IMAGES 8
+struct anv_pipeline_binding {
+ /* The descriptor set this surface corresponds to */
+ uint16_t set;
+
+ /* Offset into the descriptor set */
+ uint16_t offset;
+};
+
struct anv_pipeline_layout {
struct {
struct anv_descriptor_set_layout *layout;
struct {
bool has_dynamic_offsets;
uint32_t surface_count;
+ struct anv_pipeline_binding *surface_to_descriptor;
uint32_t sampler_count;
+ struct anv_pipeline_binding *sampler_to_descriptor;
} stage[VK_SHADER_STAGE_NUM];
+
+ struct anv_pipeline_binding entries[0];
};
struct anv_buffer {