nvk: Implement vkUpdateDescriptorSets
authorFaith Ekstrand <faith.ekstrand@collabora.com>
Tue, 31 Jan 2023 02:11:47 +0000 (20:11 -0600)
committerMarge Bot <emma+marge@anholt.net>
Fri, 4 Aug 2023 21:31:53 +0000 (21:31 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>

src/nouveau/vulkan/meson.build
src/nouveau/vulkan/nvk_buffer.h
src/nouveau/vulkan/nvk_descriptor_set.c [new file with mode: 0644]
src/nouveau/vulkan/nvk_descriptor_set.h
src/nouveau/vulkan/nvk_image_view.h
src/nouveau/vulkan/nvk_sampler.h

index 4ee9051..683a747 100644 (file)
@@ -6,6 +6,7 @@ nvk_files = files(
   'nvk_cmd_buffer.c',
   'nvk_cmd_buffer.h',
   'nvk_descriptor_set.h',
+  'nvk_descriptor_set.c',
   'nvk_descriptor_set_layout.c',
   'nvk_descriptor_set_layout.h',
   'nvk_device.c',
index ba12e38..9b48d90 100644 (file)
@@ -15,4 +15,10 @@ struct nvk_buffer {
 
 VK_DEFINE_HANDLE_CASTS(nvk_buffer, vk.base, VkBuffer, VK_OBJECT_TYPE_BUFFER)
 
+static inline uint64_t
+nvk_buffer_address(struct nvk_buffer *buffer)
+{
+   return 0; /* TODO */
+}
+
 #endif
diff --git a/src/nouveau/vulkan/nvk_descriptor_set.c b/src/nouveau/vulkan/nvk_descriptor_set.c
new file mode 100644 (file)
index 0000000..d11444e
--- /dev/null
@@ -0,0 +1,165 @@
+#include "nvk_descriptor_set.h"
+
+#include "nvk_buffer.h"
+#include "nvk_descriptor_set_layout.h"
+#include "nvk_image_view.h"
+#include "nvk_sampler.h"
+
+static void *desc_ubo_data(struct nvk_descriptor_set *set, uint32_t binding,
+                           uint32_t elem) {
+  const struct nvk_descriptor_set_binding_layout *binding_layout =
+      &set->layout->binding[binding];
+
+  return (char *)set->map + binding_layout->offset +
+         elem * binding_layout->stride;
+}
+
+static void write_sampler_desc(struct nvk_descriptor_set *set,
+                               const VkDescriptorImageInfo *const info,
+                               uint32_t binding, uint32_t elem) {
+  const struct nvk_descriptor_set_binding_layout *binding_layout =
+      &set->layout->binding[binding];
+
+  if (binding_layout->immutable_samplers)
+    return;
+
+  VK_FROM_HANDLE(nvk_sampler, sampler, info->sampler);
+
+  struct nvk_image_descriptor *desc = desc_ubo_data(set, binding, elem);
+  assert(sampler->desc_index < (1 << 12));
+  desc->sampler_index = sampler->desc_index;
+}
+
+static void write_image_view_desc(struct nvk_descriptor_set *set,
+                                  const VkDescriptorImageInfo *const info,
+                                  uint32_t binding, uint32_t elem) {
+  VK_FROM_HANDLE(nvk_image_view, view, info->imageView);
+
+  struct nvk_image_descriptor *desc = desc_ubo_data(set, binding, elem);
+  assert(view->desc_index < (1 << 20));
+  desc->image_index = view->desc_index;
+}
+
+static void write_buffer_desc(struct nvk_descriptor_set *set,
+                              const VkDescriptorBufferInfo *const info,
+                              uint32_t binding, uint32_t elem) {
+  VK_FROM_HANDLE(nvk_buffer, buffer, info->buffer);
+
+  struct nvk_buffer_address *desc = desc_ubo_data(set, binding, elem);
+  *desc = (struct nvk_buffer_address){
+      .base_addr = nvk_buffer_address(buffer) + info->offset,
+      .size = vk_buffer_range(&buffer->vk, info->offset, info->range),
+  };
+}
+
+static void write_buffer_view_desc(struct nvk_descriptor_set *set,
+                                   const VkBufferView bufferView,
+                                   uint32_t binding, uint32_t elem) {
+  /* TODO */
+}
+
+static void
+write_inline_uniform_data(struct nvk_descriptor_set *set,
+                          const VkWriteDescriptorSetInlineUniformBlock *info,
+                          uint32_t binding, uint32_t offset) {
+  memcpy((char *)desc_ubo_data(set, binding, 0) + offset, info->pData,
+         info->dataSize);
+}
+
+VKAPI_ATTR void VKAPI_CALL nvk_UpdateDescriptorSets(
+    VkDevice device, uint32_t descriptorWriteCount,
+    const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
+    const VkCopyDescriptorSet *pDescriptorCopies) {
+  for (uint32_t w = 0; w < descriptorWriteCount; w++) {
+    const VkWriteDescriptorSet *write = &pDescriptorWrites[w];
+    VK_FROM_HANDLE(nvk_descriptor_set, set, write->dstSet);
+
+    switch (write->descriptorType) {
+    case VK_DESCRIPTOR_TYPE_SAMPLER:
+      for (uint32_t j = 0; j < write->descriptorCount; j++) {
+        write_sampler_desc(set, write->pImageInfo + j, write->dstBinding,
+                           write->dstArrayElement + j);
+      }
+      break;
+
+    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+      for (uint32_t j = 0; j < write->descriptorCount; j++) {
+        write_sampler_desc(set, write->pImageInfo + j, write->dstBinding,
+                           write->dstArrayElement + j);
+        write_image_view_desc(set, write->pImageInfo + j, write->dstBinding,
+                              write->dstArrayElement + j);
+      }
+      break;
+
+    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+      for (uint32_t j = 0; j < write->descriptorCount; j++) {
+        write_image_view_desc(set, write->pImageInfo + j, write->dstBinding,
+                              write->dstArrayElement + j);
+      }
+      break;
+
+    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+      for (uint32_t j = 0; j < write->descriptorCount; j++) {
+        write_buffer_view_desc(set, write->pTexelBufferView[j],
+                               write->dstBinding, write->dstArrayElement + j);
+      }
+      break;
+
+    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+      for (uint32_t j = 0; j < write->descriptorCount; j++) {
+        write_buffer_desc(set, write->pBufferInfo + j, write->dstBinding,
+                          write->dstArrayElement + j);
+      }
+      break;
+
+    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+      unreachable("Dynamic buffers not yet supported");
+
+    case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: {
+      const VkWriteDescriptorSetInlineUniformBlock *write_inline =
+          vk_find_struct_const(write->pNext,
+                               WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK);
+      assert(write_inline->dataSize == write->descriptorCount);
+      write_inline_uniform_data(set, write_inline, write->dstBinding,
+                                write->dstArrayElement);
+      break;
+    }
+
+    default:
+      break;
+    }
+  }
+
+  for (uint32_t i = 0; i < descriptorCopyCount; i++) {
+    const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
+    VK_FROM_HANDLE(nvk_descriptor_set, src, copy->srcSet);
+    VK_FROM_HANDLE(nvk_descriptor_set, dst, copy->dstSet);
+
+    const struct nvk_descriptor_set_binding_layout *src_binding_layout =
+        &src->layout->binding[copy->srcBinding];
+    const struct nvk_descriptor_set_binding_layout *dst_binding_layout =
+        &dst->layout->binding[copy->dstBinding];
+
+    assert(dst_binding_layout->type == src_binding_layout->type);
+
+    if (dst_binding_layout->stride > 0 && src_binding_layout->stride > 0) {
+      for (uint32_t j = 0; j < copy->descriptorCount; j++) {
+        memcpy(desc_ubo_data(dst, copy->dstBinding, copy->dstArrayElement + j),
+               desc_ubo_data(src, copy->srcBinding, copy->srcArrayElement + j),
+               MIN2(dst_binding_layout->stride, src_binding_layout->stride));
+      }
+    }
+
+    switch (src_binding_layout->type) {
+      /* Insert any special copy stuff here */
+
+    default:
+      break;
+    }
+  }
+}
index f9a269e..ad76ae1 100644 (file)
@@ -3,6 +3,10 @@
 
 #include "nvk_private.h"
 
+#include "vulkan/runtime/vk_object.h"
+
+struct nvk_descriptor_set_layout;
+
 struct nvk_image_descriptor {
   unsigned image_index:20;
   unsigned sampler_index:12;
@@ -15,4 +19,15 @@ struct nvk_buffer_address {
   uint32_t zero; /* Must be zero! */
 };
 
+struct nvk_descriptor_set {
+  struct vk_object_base base;
+
+  struct nvk_descriptor_set_layout *layout;
+
+  void *map;
+};
+
+VK_DEFINE_HANDLE_CASTS(nvk_descriptor_set, base, VkDescriptorSet,
+                       VK_OBJECT_TYPE_DESCRIPTOR_SET)
+
 #endif
index 796adae..2a0bda3 100644 (file)
@@ -9,7 +9,7 @@ struct nvk_image_view {
    struct vk_image_view vk;
 
    /** Index in the image descriptor table */
-   uint32_t desc_idx;
+   uint32_t desc_index;
 };
 
 VK_DEFINE_HANDLE_CASTS(nvk_image_view, vk.base, VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW)
index 5b14f4d..fdb213c 100644 (file)
@@ -7,6 +7,8 @@
 
 struct nvk_sampler {
    struct vk_object_base base;
+
+   uint32_t desc_index;
 };
 
 VK_DEFINE_HANDLE_CASTS(nvk_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER)