anv: Add support for immutable descriptors
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 17 Oct 2015 15:17:00 +0000 (08:17 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sat, 17 Oct 2015 15:17:00 +0000 (08:17 -0700)
src/vulkan/anv_device.c
src/vulkan/anv_private.h

index 2ae39741fe67f3eb7fe2c87e1a749e11cc5e87ea..75fbe691c5fa6f177600f681204948c3b56dbe98 100644 (file)
@@ -1445,14 +1445,25 @@ VkResult anv_CreateDescriptorSetLayout(
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
 
+   uint32_t immutable_sampler_count = 0;
+   for (uint32_t b = 0; b < pCreateInfo->count; b++) {
+      if (pCreateInfo->pBinding[b].pImmutableSamplers)
+         immutable_sampler_count += pCreateInfo->pBinding[b].arraySize;
+   }
+
    size_t size = sizeof(struct anv_descriptor_set_layout) +
-                 pCreateInfo->count * sizeof(set_layout->binding[0]);
+                 pCreateInfo->count * sizeof(set_layout->binding[0]) +
+                 immutable_sampler_count * sizeof(struct anv_sampler *);
 
    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);
 
+   /* We just allocate all the samplers at the end of the struct */
+   struct anv_sampler **samplers =
+      (struct anv_sampler **)&set_layout->binding[pCreateInfo->count];
+
    set_layout->binding_count = pCreateInfo->count;
    set_layout->shader_stages = 0;
    set_layout->size = 0;
@@ -1461,6 +1472,9 @@ VkResult anv_CreateDescriptorSetLayout(
    memset(set_layout->binding, -1,
           pCreateInfo->count * sizeof(set_layout->binding[0]));
 
+   /* Initialize all samplers to 0 */
+   memset(samplers, 0, immutable_sampler_count * sizeof(*samplers));
+
    uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
    uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
    uint32_t dynamic_offset_count = 0;
@@ -1512,6 +1526,17 @@ VkResult anv_CreateDescriptorSetLayout(
          break;
       }
 
+      if (pCreateInfo->pBinding[b].pImmutableSamplers) {
+         set_layout->binding[b].immutable_samplers = samplers;
+         samplers += array_size;
+
+         for (uint32_t i = 0; i < array_size; i++)
+            set_layout->binding[b].immutable_samplers[i] =
+               anv_sampler_from_handle(pCreateInfo->pBinding[b].pImmutableSamplers[i]);
+      } else {
+         set_layout->binding[b].immutable_samplers = NULL;
+      }
+
       set_layout->shader_stages |= pCreateInfo->pBinding[b].stageFlags;
    }
 
@@ -1574,6 +1599,16 @@ anv_descriptor_set_create(struct anv_device *device,
     */
    memset(set, 0, size);
 
+   /* Go through and fill out immutable samplers if we have any */
+   struct anv_descriptor *desc = set->descriptors;
+   for (uint32_t b = 0; b < layout->binding_count; b++) {
+      if (layout->binding[b].immutable_samplers) {
+         for (uint32_t i = 0; i < layout->binding[b].array_size; i++)
+            desc[i].sampler = layout->binding[b].immutable_samplers[i];
+      }
+      desc += layout->binding[b].array_size;
+   }
+
    *out_set = set;
 
    return VK_SUCCESS;
@@ -1659,16 +1694,21 @@ void anv_UpdateDescriptorSets(
 
       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
          for (uint32_t j = 0; j < write->count; j++) {
+            struct anv_descriptor *desc =
+               &set->descriptors[write->destBinding + j];
             ANV_FROM_HANDLE(anv_image_view, iview,
                             write->pDescriptors[j].imageView);
             ANV_FROM_HANDLE(anv_sampler, sampler,
                             write->pDescriptors[j].sampler);
 
-            set->descriptors[write->destBinding + j] = (struct anv_descriptor) {
-               .type = ANV_DESCRIPTOR_TYPE_IMAGE_VIEW_AND_SAMPLER,
-               .image_view = iview,
-               .sampler = sampler,
-            };
+            desc->type = ANV_DESCRIPTOR_TYPE_IMAGE_VIEW_AND_SAMPLER;
+            desc->image_view = iview;
+
+            /* If this descriptor has an immutable sampler, we don't want
+             * to stomp on it.
+             */
+            if (sampler)
+               desc->sampler = sampler;
          }
          break;
 
index 34bd53cf20b19c122579bac7f00523b217340d18..5f9a3ce5c12ebcf947e8b96fcb75c4215d0bac57 100644 (file)
@@ -674,6 +674,9 @@ struct anv_descriptor_set_binding_layout {
       /* Index into the sampler table for the associated sampler */
       int16_t sampler_index;
    } stage[VK_SHADER_STAGE_NUM];
+
+   /* Immutable samplers (or NULL if no immutable samplers) */
+   struct anv_sampler **immutable_samplers;
 };
 
 struct anv_descriptor_set_layout {
@@ -689,7 +692,7 @@ struct anv_descriptor_set_layout {
    /* Number of dynamic offsets used by this descriptor set */
    uint16_t dynamic_offset_count;
 
-   /* Don't use this directly */
+   /* Bindings in this descriptor set */
    struct anv_descriptor_set_binding_layout binding[0];
 };