From bf096c9ec3c3f6ce53967386d0c0eb29cb192505 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 15 May 2015 15:03:21 -0700 Subject: [PATCH] vk: Build binding tables at bind descriptor time This changes the way descriptor sets and layouts work so that we fill out binding table contents at the time we bind descriptor sets. We manipulate the binding table contents and sampler state in a shadow-copy in anv_cmd_buffer. At draw time, we allocate the actual binding table and sampler state and flush the anv_cmd_buffer copies. --- src/vulkan/compiler.cpp | 21 ++- src/vulkan/device.c | 302 +++++++++++++++++++++++----------------- src/vulkan/meta.c | 6 +- src/vulkan/pipeline.c | 89 +++--------- src/vulkan/private.h | 55 +++++--- 5 files changed, 241 insertions(+), 232 deletions(-) diff --git a/src/vulkan/compiler.cpp b/src/vulkan/compiler.cpp index d843d035508..6f15b77426c 100644 --- a/src/vulkan/compiler.cpp +++ b/src/vulkan/compiler.cpp @@ -57,9 +57,8 @@ static VkResult set_binding_table_layout(struct brw_stage_prog_data *prog_data, struct anv_pipeline *pipeline, uint32_t stage) { - uint32_t count, bias, set, *map; - - struct anv_pipeline_layout_entry *entries; + uint32_t bias, count, k, *map; + struct anv_pipeline_layout *layout = pipeline->layout; /* No layout is valid for shaders that don't bind any resources. */ if (pipeline->layout == NULL) @@ -72,22 +71,18 @@ set_binding_table_layout(struct brw_stage_prog_data *prog_data, prog_data->binding_table.texture_start = bias; - count = pipeline->layout->stage[stage].surface_count; - entries = pipeline->layout->stage[stage].surface_entries; - + count = layout->stage[stage].surface_count; prog_data->map_entries = (uint32_t *) malloc(count * sizeof(prog_data->map_entries[0])); if (prog_data->map_entries == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - set = 0; + k = bias; map = prog_data->map_entries; - for (uint32_t i = 0; i < count; i++) { - if (entries[i].set == set) { - prog_data->bind_map[set] = map; - set++; - } - *map++ = bias + i; + for (uint32_t i = 0; i < layout->num_sets; i++) { + prog_data->bind_map[i] = map; + for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++) + *map++ = k++; } return VK_SUCCESS; diff --git a/src/vulkan/device.c b/src/vulkan/device.c index 82ac248cb87..8b0c2279f92 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -1417,43 +1417,101 @@ VkResult VKAPI vkCreateDescriptorSetLayout( { struct anv_device *device = (struct anv_device *) _device; struct anv_descriptor_set_layout *set_layout; - uint32_t count, k, num_entries; - size_t size, sampler_total, surface_total; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); - count = 0; - for (uint32_t i = 0; i < pCreateInfo->count; i++) + uint32_t sampler_count[VK_NUM_SHADER_STAGE] = { 0, }; + uint32_t surface_count[VK_NUM_SHADER_STAGE] = { 0, }; + uint32_t num_dynamic_buffers = 0; + uint32_t count = 0; + uint32_t s; + + for (uint32_t i = 0; i < pCreateInfo->count; i++) { + switch (pCreateInfo->pBinding[i].descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + sampler_count[s] += pCreateInfo->pBinding[i].count; + break; + + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + sampler_count[s] += pCreateInfo->pBinding[i].count; + + /* fall through */ + + 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: + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + surface_count[s] += pCreateInfo->pBinding[i].count; + break; + default: + break; + } + count += pCreateInfo->pBinding[i].count; + } - size = sizeof(*set_layout) + - count * sizeof(set_layout->bindings[0]); + for (uint32_t i = 0; i < pCreateInfo->count; i++) { + switch (pCreateInfo->pBinding[i].descriptorType) { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + num_dynamic_buffers++; + break; + default: + break; + } + } + + uint32_t sampler_total = 0; + uint32_t surface_total = 0; + for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { + sampler_total += sampler_count[s]; + surface_total += surface_count[s]; + } + + size_t size = sizeof(*set_layout) + + (sampler_total + surface_total) * sizeof(uint32_t); 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); - k = 0; - sampler_total = 0; - surface_total = 0; - for (uint32_t i = 0; i < pCreateInfo->count; i++) { - for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) { - set_layout->bindings[k].mask = pCreateInfo->pBinding[i].stageFlags; - set_layout->bindings[k].type = pCreateInfo->pBinding[i].descriptorType; - k++; - } + set_layout->num_dynamic_buffers = num_dynamic_buffers; + set_layout->count = count; - num_entries = pCreateInfo->pBinding[i].count * - __builtin_popcount(pCreateInfo->pBinding[i].stageFlags); + uint32_t *p = set_layout->entries; + uint32_t *sampler[VK_NUM_SHADER_STAGE]; + uint32_t *surface[VK_NUM_SHADER_STAGE]; + for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; 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; + for (uint32_t i = 0; i < pCreateInfo->count; i++) { switch (pCreateInfo->pBinding[i].descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: - sampler_total += num_entries; + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) + *(sampler[s])++ = descriptor + j; break; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - sampler_total += num_entries; - surface_total += num_entries; - break; + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) + *(sampler[s])++ = descriptor + j; + + /* fallthrough */ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: @@ -1463,18 +1521,17 @@ VkResult VKAPI vkCreateDescriptorSetLayout( case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - surface_total += num_entries; + for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) + for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) { + *(surface[s])++ = descriptor + j; + } break; - default: - unreachable("invalid descriptor type"); + unreachable(""); } + descriptor += pCreateInfo->pBinding[i].count; } - set_layout->sampler_total = sampler_total; - set_layout->surface_total = surface_total; - set_layout->count = count; - *pSetLayout = (VkDescriptorSetLayout) set_layout; return VK_SUCCESS; @@ -1803,6 +1860,7 @@ VkResult VKAPI vkCreateCommandBuffer( cmd_buffer->device = device; cmd_buffer->rs_state = NULL; cmd_buffer->vp_state = NULL; + memset(&cmd_buffer->bindings, 0, sizeof(cmd_buffer->bindings)); result = anv_batch_init(&cmd_buffer->batch, device); if (result != VK_SUCCESS) @@ -2106,17 +2164,43 @@ void VKAPI vkCmdBindDescriptorSets( const uint32_t* pDynamicOffsets) { struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer; + struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout; - /* What are the semantics for setting descriptor sets? Assuming that - * setting preserves lower sets and invalidate higher sets. This means that - * we can set the number of active sets to firstSet + setCount. - */ - - for (uint32_t i = 0; i < setCount; i++) - cmd_buffer->descriptor_sets[firstSet + i] = + uint32_t offset = 0; + for (uint32_t i = 0; i < setCount; i++) { + struct anv_descriptor_set *set = (struct anv_descriptor_set *) pDescriptorSets[i]; + struct anv_descriptor_set_layout *set_layout = layout->set[firstSet + i].layout; + + for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { + uint32_t *surface_to_desc = set_layout->stage[s].surface_start; + uint32_t *sampler_to_desc = set_layout->stage[s].sampler_start; + uint32_t bias = s == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0; + uint32_t start; + + start = bias + layout->set[firstSet + i].surface_start[s]; + for (uint32_t b = 0; b < set_layout->stage[s].surface_count; b++) { + struct anv_surface_view *view = set->descriptors[surface_to_desc[b]].view; + struct anv_bindings *bindings = &cmd_buffer->bindings; + + bindings->descriptors[s].surfaces[start + b] = + view->surface_state.offset; + bindings->descriptors[s].relocs[start + b].bo = view->bo; + bindings->descriptors[s].relocs[start + b].offset = view->offset; + } + + start = layout->set[firstSet + i].sampler_start[s]; + for (uint32_t b = 0; b < set_layout->stage[s].sampler_count; b++) { + struct anv_sampler *sampler = set->descriptors[sampler_to_desc[b]].sampler; + + memcpy(&cmd_buffer->bindings.descriptors[s].samplers[start + b], + sampler->state, sizeof(sampler->state)); + } + } + + offset += layout->set[firstSet + i].layout->num_dynamic_buffers; + } - cmd_buffer->num_descriptor_sets = firstSet + setCount; cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY; } @@ -2165,112 +2249,61 @@ static void flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer) { struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout; - struct anv_framebuffer *framebuffer = cmd_buffer->framebuffer; for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { - uint32_t bias = s == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0; - uint32_t binding_table_length, *table; - struct anv_state table_state; + uint32_t binding_table_length; + /* This is a little awkward: layout can be NULL but we still have to + * allocate and set a binding table for the PS stage for render + * targets. */ if (layout) binding_table_length = layout->stage[s].surface_count + bias; - else if (s == VK_SHADER_STAGE_FRAGMENT) - binding_table_length = framebuffer->color_attachment_count; else - binding_table_length = 0; - - if (binding_table_length > 0) - table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, - binding_table_length * 4, 32); - table = table_state.map; - - if (s == VK_SHADER_STAGE_FRAGMENT) { - for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) { - struct anv_surface_view *view = framebuffer->color_attachments[i]; - table[i] = view->surface_state.offset; - - /* Don't write the reloc back to the surface state. We do that at - * submit time. Surface address is dwords 8-9. */ - anv_reloc_list_add(&cmd_buffer->batch.surf_relocs, - view->surface_state.offset + 8 * sizeof(int32_t), - view->bo, view->offset); - } - } + binding_table_length = bias; - if (layout) { - for (uint32_t i = 0; i < layout->stage[s].surface_count; i++) { - struct anv_pipeline_layout_entry *e = &layout->stage[s].surface_entries[i]; - struct anv_surface_view *view; - - switch (e->type) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - unreachable("sampler-only descriptor in the surface entries"); - break; - 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: - view = cmd_buffer->descriptor_sets[e->set]->descriptors[e->index].view; - table[bias + i] = view->surface_state.offset; - anv_reloc_list_add(&cmd_buffer->batch.surf_relocs, - view->surface_state.offset + 8 * sizeof(int32_t), - view->bo, view->offset); - break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - break; - default: - break; - } + if (binding_table_length > 0) { + struct anv_state state; + uint32_t size; + + size = binding_table_length * sizeof(uint32_t); + state = + anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 32); + memcpy(state.map, cmd_buffer->bindings.descriptors[s].surfaces, size); + + for (uint32_t i = 0; i < binding_table_length; i++) { + uint32_t offset = cmd_buffer->bindings.descriptors[s].surfaces[i]; + if (offset == 0) + continue; + + anv_reloc_list_add(&cmd_buffer->batch.surf_relocs, + offset + 8 * sizeof(int32_t), + cmd_buffer->bindings.descriptors[s].relocs[i].bo, + cmd_buffer->bindings.descriptors[s].relocs[i].offset); } - } - /* The binding table pointer commands all have the same structure, only - * the opcode differs. - */ - static const uint32_t binding_table_opcodes[] = { - [VK_SHADER_STAGE_VERTEX] = 38, - [VK_SHADER_STAGE_TESS_CONTROL] = 39, - [VK_SHADER_STAGE_TESS_EVALUATION] = 40, - [VK_SHADER_STAGE_GEOMETRY] = 41, - [VK_SHADER_STAGE_FRAGMENT] = 42, - [VK_SHADER_STAGE_COMPUTE] = 0, - }; + static const uint32_t binding_table_opcodes[] = { + [VK_SHADER_STAGE_VERTEX] = 38, + [VK_SHADER_STAGE_TESS_CONTROL] = 39, + [VK_SHADER_STAGE_TESS_EVALUATION] = 40, + [VK_SHADER_STAGE_GEOMETRY] = 41, + [VK_SHADER_STAGE_FRAGMENT] = 42, + [VK_SHADER_STAGE_COMPUTE] = 0, + }; - if (binding_table_length > 0) anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS, ._3DCommandSubOpcode = binding_table_opcodes[s], - .PointertoVSBindingTable = table_state.offset); - + .PointertoVSBindingTable = state.offset); + } if (layout && layout->stage[s].sampler_count > 0) { - struct anv_state sampler_state; - - sampler_state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, - layout->stage[s].sampler_count * 16, 32); - for (uint32_t i = 0; i < layout->stage[s].sampler_count; i++) { - struct anv_pipeline_layout_entry *e = &layout->stage[s].sampler_entries[i]; - struct anv_sampler *sampler; - - switch (e->type) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - sampler = - cmd_buffer->descriptor_sets[e->set]->descriptors[e->index].sampler; - break; - default: - unreachable("non-sampler descriptor in sampler entries"); - break; - } + struct anv_state state; + size_t size; - memcpy(sampler_state.map + i * 16, sampler->state, sizeof(sampler->state)); - } + size = layout->stage[s].sampler_count * 16; + state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32); + memcpy(state.map, cmd_buffer->bindings.descriptors[s].samplers, size); static const uint32_t sampler_state_opcodes[] = { [VK_SHADER_STAGE_VERTEX] = 43, @@ -2284,7 +2317,7 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer) anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS, ._3DCommandSubOpcode = sampler_state_opcodes[s], - .PointertoVSSamplerState = sampler_state.offset); + .PointertoVSSamplerState = state.offset); } } } @@ -2741,9 +2774,10 @@ void VKAPI vkCmdBeginRenderPass( { struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer; struct anv_render_pass *pass = (struct anv_render_pass *) pRenderPassBegin->renderPass; + struct anv_framebuffer *framebuffer = + (struct anv_framebuffer *) pRenderPassBegin->framebuffer; - cmd_buffer->framebuffer = (struct anv_framebuffer *) pRenderPassBegin->framebuffer; - cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY; + cmd_buffer->framebuffer = framebuffer; anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE, .ClippedDrawingRectangleYMin = pass->render_area.offset.y, @@ -2755,6 +2789,18 @@ void VKAPI vkCmdBeginRenderPass( .DrawingRectangleOriginY = 0, .DrawingRectangleOriginX = 0); + for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) { + struct anv_surface_view *view = framebuffer->color_attachments[i]; + + cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i] = + view->surface_state.offset; + cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo = + view->bo; + cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset = + view->offset; + } + cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY; + anv_cmd_buffer_clear(cmd_buffer, pass); } diff --git a/src/vulkan/meta.c b/src/vulkan/meta.c index 4f210e3f235..8fbec09e626 100644 --- a/src/vulkan/meta.c +++ b/src/vulkan/meta.c @@ -151,7 +151,7 @@ struct anv_saved_state { struct anv_buffer *buffer; VkDeviceSize offset; } vb[2]; - struct anv_descriptor_set *dsets[1]; + struct anv_bindings bindings; struct anv_pipeline *pipeline; }; @@ -160,7 +160,7 @@ anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer, struct anv_saved_state *state) { memcpy(state->vb, cmd_buffer->vb, sizeof(state->vb)); - memcpy(state->dsets, cmd_buffer->descriptor_sets, sizeof(state->dsets)); + memcpy(&state->bindings, &cmd_buffer->bindings, sizeof(state->bindings)); state->pipeline = cmd_buffer->pipeline; } @@ -169,7 +169,7 @@ anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer, const struct anv_saved_state *state) { memcpy(cmd_buffer->vb, state->vb, sizeof(state->vb)); - memcpy(cmd_buffer->descriptor_sets, state->dsets, sizeof(state->dsets)); + memcpy(&cmd_buffer->bindings, &state->bindings, sizeof(state->bindings)); cmd_buffer->pipeline = state->pipeline; cmd_buffer->vb_dirty |= (1 << ARRAY_SIZE(state->vb)) - 1; diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index 30185dd0b79..60389e4bbba 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -560,81 +560,38 @@ VkResult VKAPI vkCreatePipelineLayout( { struct anv_device *device = (struct anv_device *) _device; struct anv_pipeline_layout *layout; - struct anv_pipeline_layout_entry *sampler_entry, *surface_entry; - uint32_t sampler_total, surface_total; - size_t size; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); - - sampler_total = 0; - surface_total = 0; - for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { - struct anv_descriptor_set_layout *set_layout = - (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i]; - for (uint32_t j = 0; j < set_layout->count; j++) { - sampler_total += set_layout->sampler_total; - surface_total += set_layout->surface_total; - } - } - size = sizeof(*layout) + - (sampler_total + surface_total) * sizeof(layout->entries[0]); - layout = anv_device_alloc(device, size, 8, + 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); - sampler_entry = layout->entries; - surface_entry = layout->entries + sampler_total; + layout->num_sets = pCreateInfo->descriptorSetCount; + + uint32_t surface_start[VK_NUM_SHADER_STAGE] = { 0, }; + uint32_t sampler_start[VK_NUM_SHADER_STAGE] = { 0, }; + for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { - layout->stage[s].sampler_entries = sampler_entry; - layout->stage[s].surface_entries = surface_entry; - - for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { - struct anv_descriptor_set_layout *set_layout = - (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i]; - for (uint32_t j = 0; j < set_layout->count; j++) { - if (set_layout->bindings[j].mask & (1 << s)) { - switch (set_layout->bindings[j].type) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - sampler_entry->type = set_layout->bindings[j].type; - sampler_entry->set = i; - sampler_entry->index = j; - sampler_entry++; - break; - - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - sampler_entry->type = set_layout->bindings[j].type; - sampler_entry->set = i; - sampler_entry->index = j; - sampler_entry++; - /* fall through */ - - 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: - surface_entry->type = set_layout->bindings[j].type; - surface_entry->set = i; - surface_entry->index = j; - surface_entry++; - break; - - default: - break; - } - } - } - } + layout->stage[s].surface_count = 0; + layout->stage[s].sampler_count = 0; + } + + for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { + struct anv_descriptor_set_layout *set_layout = + (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i]; - layout->stage[s].sampler_count = - sampler_entry - layout->stage[s].sampler_entries; - layout->stage[s].surface_count = - surface_entry - layout->stage[s].surface_entries; + layout->set[i].layout = set_layout; + for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { + layout->set[i].surface_start[s] = surface_start[s]; + surface_start[s] += set_layout->stage[s].surface_count; + layout->set[i].sampler_start[s] = 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; + } } *pPipelineLayout = (VkPipelineLayout) layout; diff --git a/src/vulkan/private.h b/src/vulkan/private.h index 3120b8486e1..2e8ae9fb6bd 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -453,13 +453,16 @@ struct anv_dynamic_cb_state { }; struct anv_descriptor_set_layout { - uint32_t sampler_total; /* total number of samplers in all stages */ - uint32_t surface_total; /* total number of surfaces in all stages */ - uint32_t count; struct { - VkDescriptorType type; - uint32_t mask; - } bindings[0]; + uint32_t surface_count; + uint32_t *surface_start; + uint32_t sampler_count; + uint32_t *sampler_start; + } stage[VK_NUM_SHADER_STAGE]; + + uint32_t count; + uint32_t num_dynamic_buffers; + uint32_t entries[0]; }; struct anv_descriptor { @@ -471,21 +474,23 @@ struct anv_descriptor_set { struct anv_descriptor descriptors[0]; }; -struct anv_pipeline_layout_entry { - VkDescriptorType type; - uint32_t set; - uint32_t index; -}; +#define MAX_VBS 32 +#define MAX_SETS 8 +#define MAX_RTS 8 struct anv_pipeline_layout { struct { - uint32_t sampler_count; - struct anv_pipeline_layout_entry *sampler_entries; + struct anv_descriptor_set_layout *layout; + uint32_t surface_start[VK_NUM_SHADER_STAGE]; + uint32_t sampler_start[VK_NUM_SHADER_STAGE]; + } set[MAX_SETS]; + + uint32_t num_sets; + + struct { uint32_t surface_count; - struct anv_pipeline_layout_entry *surface_entries; + uint32_t sampler_count; } stage[VK_NUM_SHADER_STAGE]; - - struct anv_pipeline_layout_entry entries[0]; }; struct anv_buffer { @@ -497,14 +502,21 @@ struct anv_buffer { VkDeviceSize offset; }; -#define MAX_VBS 32 -#define MAX_SETS 8 -#define MAX_RTS 8 - #define ANV_CMD_BUFFER_PIPELINE_DIRTY (1 << 0) #define ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY (1 << 1) #define ANV_CMD_BUFFER_RS_DIRTY (1 << 2) +struct anv_bindings { + struct { + uint32_t surfaces[256]; + struct { + struct anv_bo *bo; + uint32_t offset; + } relocs[256]; + struct { uint32_t dwords[4]; } samplers[16]; + } descriptors[VK_NUM_SHADER_STAGE]; +}; + struct anv_cmd_buffer { struct anv_device * device; @@ -525,13 +537,12 @@ struct anv_cmd_buffer { VkDeviceSize offset; } vb[MAX_VBS]; uint32_t vb_dirty; - uint32_t num_descriptor_sets; - struct anv_descriptor_set * descriptor_sets[MAX_SETS]; uint32_t dirty; struct anv_pipeline * pipeline; struct anv_framebuffer * framebuffer; struct anv_dynamic_rs_state * rs_state; struct anv_dynamic_vp_state * vp_state; + struct anv_bindings bindings; }; void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer); -- 2.30.2