vk: Add support for sampler descriptors
authorKristian Høgsberg <kristian.h.kristensen@intel.com>
Wed, 13 May 2015 21:43:08 +0000 (14:43 -0700)
committerKristian Høgsberg <kristian.h.kristensen@intel.com>
Wed, 13 May 2015 21:47:11 +0000 (14:47 -0700)
src/vulkan/compiler.cpp
src/vulkan/device.c
src/vulkan/pipeline.c
src/vulkan/private.h

index f8be0f070a8470ba71bd5f20f79f3396b9ade81a..f81008b8f72f33d84477e791726e43ca3b19a18c 100644 (file)
@@ -70,8 +70,8 @@ set_binding_table_layout(struct brw_stage_prog_data *prog_data,
    else
       bias = 0;
 
-   count = pipeline->layout->stage[stage].count;
-   entries = pipeline->layout->stage[stage].entries;
+   count = pipeline->layout->stage[stage].surface_count;
+   entries = pipeline->layout->stage[stage].surface_entries;
 
    prog_data->map_entries =
       (uint32_t *) malloc(count * sizeof(prog_data->map_entries[0]));
index 7da2322137fdd88a97ad96e10925ac9b79aa02c8..d5eab4866d4172dee680915d09f4f23e2e3ebcb7 100644 (file)
@@ -1415,8 +1415,8 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
 {
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_descriptor_set_layout *set_layout;
-   uint32_t count, k;
-   size_t size, total;
+   uint32_t count, k, num_entries;
+   size_t size, sampler_total, surface_total;
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
 
@@ -1432,7 +1432,8 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
    k = 0;
-   total = 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;
@@ -1440,11 +1441,36 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
          k++;
       }
 
-      total += pCreateInfo->pBinding[i].count *
+      num_entries = pCreateInfo->pBinding[i].count *
          __builtin_popcount(pCreateInfo->pBinding[i].stageFlags);
+
+      switch (pCreateInfo->pBinding[i].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+         sampler_total += num_entries;
+         break;
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         sampler_total += num_entries;
+         surface_total += num_entries;
+         break;
+
+      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_total += num_entries;
+         break;
+
+      default:
+         unreachable("invalid descriptor type");
+      }
    }
 
-   set_layout->total = total;
+   set_layout->sampler_total = sampler_total;
+   set_layout->surface_total = surface_total;
    set_layout->count = count;
 
    *pSetLayout = (VkDescriptorSetLayout) set_layout;
@@ -2136,36 +2162,25 @@ void VKAPI vkCmdBindVertexBuffers(
 static void
 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
 {
-   static const uint32_t 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,
-   };
-
    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 count, *table;
+      uint32_t binding_table_length, *table;
       struct anv_state table_state;
 
       if (layout)
-         count = layout->stage[s].count + bias;
+         binding_table_length = layout->stage[s].surface_count + bias;
       else if (s == VK_SHADER_STAGE_FRAGMENT)
-         count = framebuffer->color_attachment_count;
+         binding_table_length = framebuffer->color_attachment_count;
       else
-         count = 0;
+         binding_table_length = 0;
       
-      if (count == 0)
-         continue;
-
-      table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
-                                           count * 4, 32);
+      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) {
@@ -2182,8 +2197,8 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
       }
 
       if (layout) {
-         for (uint32_t i = 0; i < layout->stage[s].count; i++) {
-            struct anv_pipeline_layout_entry *e = &layout->stage[s].entries[i];
+         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_descriptor *d =
                &cmd_buffer->descriptor_sets[e->set]->descriptors[e->index];
             struct anv_image_view *image_view;
@@ -2227,15 +2242,62 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
          }
       }
 
-      /* FIXME: Samplers */
-
       /* The binding table pointer commands all have the same structure, only
        * the opcode differs.
        */
-      anv_batch_emit(&cmd_buffer->batch,
-                     GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
-                     ._3DCommandSubOpcode  = opcodes[s],
-                     .PointertoVSBindingTable = table_state.offset);
+      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);
+
+
+      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;
+            }
+
+            memcpy(sampler_state.map + i * 16, sampler->state, sizeof(sampler->state));
+         }
+
+         static const uint32_t sampler_state_opcodes[] = {
+            [VK_SHADER_STAGE_VERTEX] = 43,
+            [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
+            [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
+            [VK_SHADER_STAGE_GEOMETRY] = 46,
+            [VK_SHADER_STAGE_FRAGMENT] = 47,
+            [VK_SHADER_STAGE_COMPUTE] = 0,
+         };
+
+         anv_batch_emit(&cmd_buffer->batch,
+                        GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
+                        ._3DCommandSubOpcode  = sampler_state_opcodes[s],
+                        .PointertoVSSamplerState = sampler_state.offset);
+      }
    }
 }
 
index ce1fa303d7c927005fe27e937084c532afec5e9e..a260c3cd24a0803075de7ee6ada22dcbf1007cf5 100644 (file)
@@ -560,43 +560,81 @@ VkResult VKAPI vkCreatePipelineLayout(
 {
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_pipeline_layout *layout;
-   struct anv_pipeline_layout_entry *entry;
-   uint32_t total;
+   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);
    
-   total = 0;
+   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++)
-         total += set_layout->total;
+      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) + total * sizeof(layout->entries[0]);
+   size = sizeof(*layout) +
+      (sampler_total + surface_total) * 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);
 
-   entry = layout->entries;
+   sampler_entry = layout->entries;
+   surface_entry = layout->entries + sampler_total;
    for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
-      layout->stage[s].entries = entry;
+      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++)
+         for (uint32_t j = 0; j < set_layout->count; j++) {
             if (set_layout->bindings[j].mask & (1 << s)) {
-               entry->type = set_layout->bindings[j].type;
-               entry->set = i;
-               entry->index = j;
-               entry++;
+               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].count = entry - layout->stage[s].entries;
+      layout->stage[s].sampler_count =
+         sampler_entry - layout->stage[s].sampler_entries;
+      layout->stage[s].surface_count =
+         surface_entry - layout->stage[s].surface_entries;
    }
 
    *pPipelineLayout = (VkPipelineLayout) layout;
index dbb29acbf20767558fce14bfabe28cc08c39390a..09535a73b6457591ff53d469f20147785fadbea5 100644 (file)
@@ -446,7 +446,8 @@ struct anv_dynamic_cb_state {
 };
 
 struct anv_descriptor_set_layout {
-   uint32_t total; /* total number of entries in all stages */
+   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;
@@ -476,8 +477,10 @@ struct anv_pipeline_layout_entry {
 
 struct anv_pipeline_layout {
    struct {
-      uint32_t count;
-      struct anv_pipeline_layout_entry *entries;
+      uint32_t sampler_count;
+      struct anv_pipeline_layout_entry *sampler_entries;
+      uint32_t surface_count;
+      struct anv_pipeline_layout_entry *surface_entries;
    } stage[VK_NUM_SHADER_STAGE];
    
    struct anv_pipeline_layout_entry entries[0];