vk: Build binding tables at bind descriptor time
authorKristian Høgsberg <kristian.h.kristensen@intel.com>
Fri, 15 May 2015 22:03:21 +0000 (15:03 -0700)
committerKristian Høgsberg <kristian.h.kristensen@intel.com>
Fri, 15 May 2015 23:05:31 +0000 (16:05 -0700)
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
src/vulkan/device.c
src/vulkan/meta.c
src/vulkan/pipeline.c
src/vulkan/private.h

index d843d035508fd95df16127d0060bfb1ea17f7460..6f15b77426cc4f02cdcd97f5d0907cfcfb32f68c 100644 (file)
@@ -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;
index 82ac248cb87480145665324c3edd586dc310f86b..8b0c2279f92e33d39ccc2ea86b5de5973399f33d 100644 (file)
@@ -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);
 }
 
index 4f210e3f2355b851da8f5af8b2dbb9cea26dea2b..8fbec09e626720a953c789dd4aaa01171b819773 100644 (file)
@@ -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;
index 30185dd0b79b71171941f56cd05fd9b5badb66e8..60389e4bbba6aa106a1f3a94cdc5d6ce38eaf8cb 100644 (file)
@@ -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;
index 3120b8486e1c323fe31cd4df16c85d7b867493a1..2e8ae9fb6bdb54a7030f87c9d7e1fb3a0caac05f 100644 (file)
@@ -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);