zink: pool descriptors per batch
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 24 Jun 2019 16:56:23 +0000 (18:56 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:45 +0000 (08:51 +0000)
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/zink_batch.c
src/gallium/drivers/zink/zink_batch.h
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_context.h
src/gallium/drivers/zink/zink_program.c
src/gallium/drivers/zink/zink_program.h

index 45466af5699f2617d5200faf04c1c8c405f0f294..474421081bfa87956146c4aa788d1e5b6ec2960a 100644 (file)
@@ -13,6 +13,8 @@
 static void
 reset_batch(struct zink_screen *screen, struct zink_batch *batch)
 {
+   batch->descs_left = ZINK_BATCH_DESC_SIZE;
+
    // cmdbuf hasn't been submitted before
    if (!batch->fence)
       return;
@@ -41,6 +43,9 @@ reset_batch(struct zink_screen *screen, struct zink_batch *batch)
       vkDestroySampler(screen->dev, *samp, NULL);
    }
    util_dynarray_clear(&batch->zombie_samplers);
+
+   if (vkResetDescriptorPool(screen->dev, batch->descpool, 0) != VK_SUCCESS)
+      fprintf(stderr, "vkResetDescriptorPool failed\n");
 }
 
 void
index 826f651df8eb6c62af16c6a387a515f5167d473c..602040ad446be597853174d67126e4959d594697 100644 (file)
@@ -35,8 +35,12 @@ struct zink_render_pass;
 struct zink_resource;
 struct zink_sampler_view;
 
+#define ZINK_BATCH_DESC_SIZE 1000
+
 struct zink_batch {
    VkCommandBuffer cmdbuf;
+   VkDescriptorPool descpool;
+   int descs_left;
    struct zink_fence *fence;
 
    struct zink_render_pass *rp;
index 8ea635363ec409b683140d5be1122bb64b3c88a0..ca111b70659edf753418deb65023541bf23425f6 100644 (file)
@@ -801,38 +801,26 @@ zink_shader_stage(enum pipe_shader_type type)
 }
 
 static VkDescriptorSet
-allocate_descriptor_set(struct zink_context *ctx, VkDescriptorSetLayout dsl)
+allocate_descriptor_set(struct zink_screen *screen,
+                        struct zink_batch *batch,
+                        struct zink_gfx_program *prog)
 {
-   struct zink_screen *screen = zink_screen(ctx->base.screen);
+   assert(batch->descs_left >= prog->num_descriptors);
    VkDescriptorSetAllocateInfo dsai;
    memset((void *)&dsai, 0, sizeof(dsai));
    dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    dsai.pNext = NULL;
-   dsai.descriptorPool = ctx->descpool;
+   dsai.descriptorPool = batch->descpool;
    dsai.descriptorSetCount = 1;
-   dsai.pSetLayouts = &dsl;
+   dsai.pSetLayouts = &prog->dsl;
 
    VkDescriptorSet desc_set;
    if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) {
-
-      /* if we run out of descriptor sets we either need to create a bunch
-       * more... or flush and wait. For simplicity, let's flush for now.
-       */
-      struct pipe_fence_handle *fence = NULL;
-      ctx->base.flush(&ctx->base, &fence, 0);
-      ctx->base.screen->fence_finish(ctx->base.screen, &ctx->base, fence,
-                                     PIPE_TIMEOUT_INFINITE);
-
-      if (vkResetDescriptorPool(screen->dev, ctx->descpool, 0) != VK_SUCCESS) {
-         fprintf(stderr, "vkResetDescriptorPool failed\n");
-         return VK_NULL_HANDLE;
-      }
-      if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) {
-         fprintf(stderr, "vkAllocateDescriptorSets failed\n");
-         return VK_NULL_HANDLE;
-      }
+      debug_printf("ZINK: failed to allocate descriptor set :/");
+      return VK_NULL_HANDLE;
    }
 
+   batch->descs_left -= prog->num_descriptors;
    return desc_set;
 }
 
@@ -1037,10 +1025,18 @@ zink_draw_vbo(struct pipe_context *pctx,
                                VK_IMAGE_LAYOUT_GENERAL);
    }
 
-   VkDescriptorSet desc_set = allocate_descriptor_set(ctx, gfx_program->dsl);
-
    batch = zink_batch_rp(ctx);
 
+   if (batch->descs_left < gfx_program->num_descriptors) {
+      flush_batch(ctx);
+      batch = zink_batch_rp(ctx);
+      assert(batch->descs_left >= gfx_program->num_descriptors);
+   }
+
+   VkDescriptorSet desc_set = allocate_descriptor_set(screen, batch,
+                                                      gfx_program);
+   assert(desc_set != VK_NULL_HANDLE);
+
    for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
       struct zink_shader *shader = ctx->gfx_stages[i];
       if (!shader)
@@ -1392,6 +1388,17 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    cbai.commandPool = ctx->cmdpool;
    cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    cbai.commandBufferCount = 1;
+
+   VkDescriptorPoolSize sizes[] = {
+      {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ZINK_BATCH_DESC_SIZE}
+   };
+   VkDescriptorPoolCreateInfo dpci = {};
+   dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+   dpci.pPoolSizes = sizes;
+   dpci.poolSizeCount = ARRAY_SIZE(sizes);
+   dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+   dpci.maxSets = ZINK_BATCH_DESC_SIZE;
+
    for (int i = 0; i < ARRAY_SIZE(ctx->batches); ++i) {
       if (vkAllocateCommandBuffers(screen->dev, &cbai, &ctx->batches[i].cmdbuf) != VK_SUCCESS)
          goto fail;
@@ -1406,20 +1413,11 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
          goto fail;
 
       util_dynarray_init(&ctx->batches[i].zombie_samplers, NULL);
-   }
 
-   VkDescriptorPoolSize sizes[] = {
-      {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000}
-   };
-   VkDescriptorPoolCreateInfo dpci = {};
-   dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
-   dpci.pPoolSizes = sizes;
-   dpci.poolSizeCount = ARRAY_SIZE(sizes);
-   dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
-   dpci.maxSets = 1000;
-
-   if(vkCreateDescriptorPool(screen->dev, &dpci, 0, &ctx->descpool) != VK_SUCCESS)
-      goto fail;
+      if (vkCreateDescriptorPool(screen->dev, &dpci, 0,
+                                 &ctx->batches[i].descpool) != VK_SUCCESS)
+         goto fail;
+   }
 
    vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->queue);
 
index 9188c01eaaa062ae99a79c69f0242aa40b96925f..8c17b1c51d7d4ccf1491df41713537cbbcae023e 100644 (file)
@@ -68,8 +68,6 @@ struct zink_context {
 
    VkQueue queue;
 
-   VkDescriptorPool descpool;
-
    struct pipe_constant_buffer ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
    struct pipe_framebuffer_state fb_state;
 
index 24a784173ef5acdd4152ae6f4bdd9b6d5171592c..39a7cde21d4e1e52302e4060aa263ad0aa78e0dd 100644 (file)
@@ -35,7 +35,8 @@
 
 static VkDescriptorSetLayout
 create_desc_set_layout(VkDevice dev,
-                       struct zink_shader *stages[PIPE_SHADER_TYPES - 1])
+                       struct zink_shader *stages[PIPE_SHADER_TYPES - 1],
+                       unsigned *num_descriptors)
 {
    VkDescriptorSetLayoutBinding bindings[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS];
    int num_bindings = 0;
@@ -70,6 +71,7 @@ create_desc_set_layout(VkDevice dev,
       return VK_NULL_HANDLE;
    }
 
+   *num_descriptors = num_bindings;
    return dsl;
 }
 
@@ -124,7 +126,8 @@ zink_create_gfx_program(struct zink_screen *screen,
    for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i)
       prog->stages[i] = stages[i];
 
-   prog->dsl = create_desc_set_layout(screen->dev, stages);
+   prog->dsl = create_desc_set_layout(screen->dev, stages,
+                                      &prog->num_descriptors);
    if (!prog->dsl)
       goto fail;
 
index 3d9cafd3dbd0b3ce424f3e211a75156bdac4f505..8807f044ae3210a2ab6977ebcabbd792223d960f 100644 (file)
@@ -39,6 +39,7 @@ struct zink_gfx_program {
    struct zink_shader *stages[PIPE_SHADER_TYPES - 1]; // compute stage doesn't belong here
    VkDescriptorSetLayout dsl;
    VkPipelineLayout layout;
+   unsigned num_descriptors;
    struct hash_table *pipelines[PIPE_PRIM_TRIANGLE_FAN + 1];
    struct set *render_passes;
 };