bug-14827: Remove DescriptorInfo union

The DescriptorInfo union is invalid in C++
diff --git a/include/vulkan.h b/include/vulkan.h
index e4e5655..312ed70 100644
--- a/include/vulkan.h
+++ b/include/vulkan.h
@@ -1823,16 +1823,6 @@
     VkDeviceSize                                range;
 } VkDescriptorBufferInfo;
 
-/* TODO: this should be union, except that causes a compiler error:
- * error: member 'VkDescriptorImageInfo <anonymous union>::imageInfo' with constructor not allowed in union
- * This issue should go away when the change to remove the constructor lands.
- */
-typedef struct {
-    VkDescriptorImageInfo                       imageInfo;
-    VkDescriptorBufferInfo                      bufferInfo;
-    VkBufferView                                texelBufferView;
-} VkDescriptorInfo;
-
 typedef struct {
     VkStructureType                             sType;
     const void*                                 pNext;
@@ -1841,7 +1831,9 @@
     uint32_t                                    destArrayElement;
     uint32_t                                    count;
     VkDescriptorType                            descriptorType;
-    const VkDescriptorInfo*                     pDescriptors;
+    const VkDescriptorImageInfo*                pImageInfo;
+    const VkDescriptorBufferInfo*               pBufferInfo;
+    const VkBufferView*                         pTexelBufferView;
 } VkWriteDescriptorSet;
 
 typedef struct {
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index f0d0d93..310821c 100755
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -830,11 +830,40 @@
             pWDS = new VkWriteDescriptorSet;
             *pNewNode = (GENERIC_HEADER*)pWDS;
             memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet));
-            /* TODO: restore new once constructors have been removed from vulkan.h */
-//            pWDS->pDescriptors = new VkDescriptorInfo[pWDS->count];
-            pWDS->pDescriptors = (VkDescriptorInfo *) malloc(sizeof(VkDescriptorInfo) * pWDS->count);
-            array_size = sizeof(VkDescriptorInfo) * pWDS->count;
-            memcpy((void*)pWDS->pDescriptors, ((VkWriteDescriptorSet*)pUpdate)->pDescriptors, array_size);
+
+            switch (pWDS->descriptorType) {
+            case VK_DESCRIPTOR_TYPE_SAMPLER:
+            case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+            case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+            case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                {
+                    VkDescriptorImageInfo *info = new VkDescriptorImageInfo[pWDS->count];
+                    memcpy(info, pWDS->pImageInfo, pWDS->count * sizeof(VkDescriptorImageInfo));
+                    pWDS->pImageInfo = info;
+            }
+                break;
+            case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+            case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+                {
+                    VkBufferView *info = new VkBufferView[pWDS->count];
+                    memcpy(info, pWDS->pTexelBufferView, pWDS->count * sizeof(VkBufferView));
+                    pWDS->pTexelBufferView = info;
+                }
+                break;
+            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:
+                {
+                    VkDescriptorBufferInfo *info = new VkDescriptorBufferInfo[pWDS->count];
+                    memcpy(info, pWDS->pBufferInfo, pWDS->count * sizeof(VkDescriptorBufferInfo));
+                    pWDS->pBufferInfo = info;
+                }
+                break;
+            default:
+                return VK_ERROR_VALIDATION_FAILED;
+                break;
+            }
             break;
         case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
             pCDS = new VkCopyDescriptorSet;
@@ -859,13 +888,13 @@
     // Check ImageAspects of each descriptorSet in each writeDescriptorSet array
     for (uint32_t i = 0; i < writeDsCount; i++) {
         for (uint32_t j = 0; j < pWDS[i].count; j++) {
-            const VkDescriptorInfo *dInfo = &pWDS[i].pDescriptors[j];
-            auto imageViewItem = dev_data->imageViewMap.find(dInfo->imageInfo.imageView.handle);
+            const VkDescriptorImageInfo *dInfo = &pWDS[i].pImageInfo[j];
+            auto imageViewItem = dev_data->imageViewMap.find(dInfo->imageView.handle);
             if (imageViewItem != dev_data->imageViewMap.end()) {
                 VkImageAspectFlags flags = ((*imageViewItem).second)->subresourceRange.aspectMask;
                 if ((flags & VK_IMAGE_ASPECT_DEPTH_BIT) &&
                     (flags & VK_IMAGE_ASPECT_STENCIL_BIT)) {
-                    skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE_VIEW, dInfo->imageInfo.imageView.handle, 0,
+                    skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE_VIEW, dInfo->imageView.handle, 0,
                         DRAWSTATE_INVALID_IMAGE_ASPECT, "DS", "vkUpdateDescriptorSets: DesriptorSet[%d] in WriteDesriptorSet[%d] "
                         "has ImageView with both STENCIL and DEPTH aspects set", j, i);
                 }
@@ -877,7 +906,8 @@
 
 // update DS mappings based on ppUpdateArray
 // TODO : copy updates are completely broken
-// TODO : Validate that actual VkDescriptorInfo in pDescriptors matches type:
+// TODO : Validate that actual VkDescriptorImageInfo, VkDescriptorBufferInfo
+//        and VkBufferView in VkWriteDescriptorSet matches type:
 //   pImageInfo array should be used for each descriptor if type is:
 //    VK_DESCRIPTOR_TYPE_SAMPLER:
 //      - uses sampler field of VkDescriptorImageInfo,
@@ -1017,9 +1047,14 @@
         {
             case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
                 pWDS = (VkWriteDescriptorSet*)pFreeUpdate;
-                if (pWDS->pDescriptors) {
-//                    delete[] pWDS->pDescriptors;
-                    free((void *) pWDS->pDescriptors);
+                if (pWDS->pImageInfo) {
+                    delete[] pWDS->pImageInfo;
+                }
+                if (pWDS->pBufferInfo) {
+                    delete[] pWDS->pBufferInfo;
+                }
+                if (pWDS->pTexelBufferView) {
+                    delete[] pWDS->pTexelBufferView;
                 }
                 break;
             case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index dc9f8da..793a423 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -4783,10 +4783,12 @@
         "vkUpdateDescriptorSets parameter, VkDescriptorType pDescriptorWrites->descriptorType, is an unrecognized enumerator");
         return false;
     }
-    if(pDescriptorWrites->pDescriptors != nullptr)
+    /* TODO: Validate other parts of pImageInfo, pBufferInfo, pTexelBufferView? */
+    /* TODO: This test should probably only be done if descriptorType is correct type of descriptor */
+    if(pDescriptorWrites->pImageInfo != nullptr)
     {
-    if(pDescriptorWrites->pDescriptors->imageInfo.imageLayout < VK_IMAGE_LAYOUT_BEGIN_RANGE ||
-        pDescriptorWrites->pDescriptors->imageInfo.imageLayout > VK_IMAGE_LAYOUT_END_RANGE)
+    if(pDescriptorWrites->pImageInfo->imageLayout < VK_IMAGE_LAYOUT_BEGIN_RANGE ||
+        pDescriptorWrites->pImageInfo->imageLayout > VK_IMAGE_LAYOUT_END_RANGE)
     {
         log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, 1, "PARAMCHECK",
         "vkUpdateDescriptorSets parameter, VkImageLayout pDescriptorWrites->pDescriptors->imageLayout, is an unrecognized enumerator");
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index c28af1e..e065518 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -2843,9 +2843,8 @@
     err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
     ASSERT_VK_SUCCESS(err);
 
-    VkDescriptorInfo descriptor_info;
-    memset(&descriptor_info, 0, sizeof(descriptor_info));
-    descriptor_info.imageInfo.sampler = sampler;
+    VkDescriptorImageInfo info = {};
+    info.sampler = sampler;
 
     VkWriteDescriptorSet descriptor_write;
     memset(&descriptor_write, 0, sizeof(descriptor_write));
@@ -2854,7 +2853,7 @@
     descriptor_write.count = 1;
     // This is a mismatched type for the layout which expects BUFFER
     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
-    descriptor_write.pDescriptors = &descriptor_info;
+    descriptor_write.pImageInfo = &info;
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
@@ -2941,9 +2940,8 @@
     err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
     ASSERT_VK_SUCCESS(err);
 
-    VkDescriptorInfo descriptor_info;
-    memset(&descriptor_info, 0, sizeof(descriptor_info));
-    descriptor_info.imageInfo.sampler = sampler;
+    VkDescriptorImageInfo info = {};
+    info.sampler = sampler;
 
     VkWriteDescriptorSet descriptor_write;
     memset(&descriptor_write, 0, sizeof(descriptor_write));
@@ -2953,7 +2951,7 @@
     descriptor_write.count = 1;
     // This is the wrong type, but out of bounds will be flagged first
     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
-    descriptor_write.pDescriptors = &descriptor_info;
+    descriptor_write.pImageInfo = &info;
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
@@ -3039,9 +3037,8 @@
     err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
     ASSERT_VK_SUCCESS(err);
 
-    VkDescriptorInfo descriptor_info;
-    memset(&descriptor_info, 0, sizeof(descriptor_info));
-    descriptor_info.imageInfo.sampler = sampler;
+    VkDescriptorImageInfo info = {};
+    info.sampler = sampler;
 
     VkWriteDescriptorSet descriptor_write;
     memset(&descriptor_write, 0, sizeof(descriptor_write));
@@ -3051,7 +3048,7 @@
     descriptor_write.count = 1;
     // This is the wrong type, but out of bounds will be flagged first
     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
-    descriptor_write.pDescriptors = &descriptor_info;
+    descriptor_write.pImageInfo = &info;
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
@@ -3138,9 +3135,8 @@
     ASSERT_VK_SUCCESS(err);
 
 
-    VkDescriptorInfo descriptor_info;
-    memset(&descriptor_info, 0, sizeof(descriptor_info));
-    descriptor_info.imageInfo.sampler = sampler;
+    VkDescriptorImageInfo info = {};
+    info.sampler = sampler;
 
     VkWriteDescriptorSet descriptor_write;
     memset(&descriptor_write, 0, sizeof(descriptor_write));
@@ -3149,7 +3145,7 @@
     descriptor_write.count = 1;
     // This is the wrong type, but out of bounds will be flagged first
     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
-    descriptor_write.pDescriptors = &descriptor_info;
+    descriptor_write.pImageInfo = &info;
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 0effd81..4ea2eaa 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -462,7 +462,7 @@
     m_type_counts.push_back(tc);
 
     m_writes.push_back(vk_testing::Device::write_descriptor_set(vk_testing::DescriptorSet(),
-                m_nextSlot, 0, type, 1, &constantBuffer.m_descriptorInfo));
+                m_nextSlot, 0, type, 1, &constantBuffer.m_descriptorBufferInfo));
 
     return m_nextSlot++;
 }
@@ -474,12 +474,12 @@
     tc.count = 1;
     m_type_counts.push_back(tc);
 
-    VkDescriptorInfo tmp = texture->m_descriptorInfo;
-    tmp.imageInfo.sampler = sampler->handle();
+    VkDescriptorImageInfo tmp = texture->m_imageInfo;
+    tmp.sampler = sampler->handle();
     m_imageSamplerDescriptors.push_back(tmp);
 
     m_writes.push_back(vk_testing::Device::write_descriptor_set(vk_testing::DescriptorSet(),
-                m_nextSlot, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, NULL));
+                m_nextSlot, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &tmp));
 
     return m_nextSlot++;
 }
@@ -541,7 +541,7 @@
          it != m_writes.end(); it++) {
         it->destSet = m_set->handle();
         if (it->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
-            it->pDescriptors = &m_imageSamplerDescriptors[imageSamplerCount++];
+            it->pImageInfo = &m_imageSamplerDescriptors[imageSamplerCount++];
     }
 
     // do the updates
@@ -551,8 +551,8 @@
 VkImageObj::VkImageObj(VkDeviceObj *dev)
 {
     m_device = dev;
-    m_descriptorInfo.imageInfo.imageView = VK_NULL_HANDLE;
-    m_descriptorInfo.imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+    m_descriptorImageInfo.imageView = VK_NULL_HANDLE;
+    m_descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
 }
 
 void VkImageObj::ImageMemoryBarrier(
@@ -612,7 +612,7 @@
             VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
             VK_MEMORY_INPUT_TRANSFER_BIT;
 
-    if (image_layout == m_descriptorInfo.imageInfo.imageLayout) {
+    if (image_layout == m_descriptorImageInfo.imageLayout) {
         return;
     }
 
@@ -639,7 +639,7 @@
     }
 
     ImageMemoryBarrier(cmd_buf, aspect, output_mask, input_mask, image_layout);
-    m_descriptorInfo.imageInfo.imageLayout = image_layout;
+    m_descriptorImageInfo.imageLayout = image_layout;
 }
 
 void VkImageObj::SetLayout(VkImageAspectFlagBits aspect,
@@ -647,7 +647,7 @@
 {
     VkResult U_ASSERT_ONLY err;
 
-    if (image_layout == m_descriptorInfo.imageInfo.imageLayout) {
+    if (image_layout == m_descriptorImageInfo.imageLayout) {
         return;
     }
 
@@ -810,7 +810,7 @@
     if (colors == NULL)
         colors = tex_colors;
 
-    memset(&m_descriptorInfo,0,sizeof(m_descriptorInfo));
+    memset(&m_imageInfo,0,sizeof(m_imageInfo));
 
     VkImageViewCreateInfo view = {};
     view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@@ -834,7 +834,7 @@
     /* create image view */
     view.image = handle();
     m_textureView.init(*m_device, view);
-    m_descriptorInfo.imageInfo.imageView = m_textureView.handle();
+    m_imageInfo.imageView = m_textureView.handle();
 
     data = stagingImage.MapMemory();
 
@@ -879,7 +879,7 @@
     m_device = device;
     m_commandBuffer = 0;
 
-    memset(&m_descriptorInfo,0,sizeof(m_descriptorInfo));
+    memset(&m_descriptorBufferInfo,0,sizeof(m_descriptorBufferInfo));
 }
 
 VkConstantBufferObj::~VkConstantBufferObj()
@@ -896,7 +896,7 @@
     m_device = device;
     m_commandBuffer = 0;
 
-    memset(&m_descriptorInfo,0,sizeof(m_descriptorInfo));
+    memset(&m_descriptorBufferInfo,0,sizeof(m_descriptorBufferInfo));
     m_numVertices = constantCount;
     m_stride = constantSize;
 
@@ -913,9 +913,9 @@
      * or as shader uniform buffers. So, we'll create the shaderbuffer
      * descriptor here so it's ready if needed.
      */
-    this->m_descriptorInfo.bufferInfo.buffer = handle();
-    this->m_descriptorInfo.bufferInfo.offset = 0;
-    this->m_descriptorInfo.bufferInfo.range = allocationSize;
+    this->m_descriptorBufferInfo.buffer = handle();
+    this->m_descriptorBufferInfo.offset = 0;
+    this->m_descriptorBufferInfo.range = allocationSize;
 }
 
 void VkConstantBufferObj::Bind(VkCmdBuffer cmdBuffer, VkDeviceSize offset, uint32_t binding)
@@ -1034,9 +1034,9 @@
     memory().unmap();
 
     // set up the descriptor for the constant buffer
-    this->m_descriptorInfo.bufferInfo.buffer = handle();
-    this->m_descriptorInfo.bufferInfo.offset = 0;
-    this->m_descriptorInfo.bufferInfo.range = allocationSize;
+    this->m_descriptorBufferInfo.buffer = handle();
+    this->m_descriptorBufferInfo.offset = 0;
+    this->m_descriptorBufferInfo.range = allocationSize;
 }
 
 void VkIndexBufferObj::Bind(VkCmdBuffer cmdBuffer, VkDeviceSize offset)
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 24f4071..26aff66 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -233,7 +233,7 @@
 
     void Bind(VkCmdBuffer cmdBuffer, VkDeviceSize offset, uint32_t binding);
 
-    VkDescriptorInfo                    m_descriptorInfo;
+    VkDescriptorBufferInfo              m_descriptorBufferInfo;
 
 protected:
     VkDeviceObj                        *m_device;
@@ -273,7 +273,7 @@
 
     void layout( VkImageLayout layout )
     {
-        m_descriptorInfo.imageInfo.imageLayout = layout;
+        m_descriptorImageInfo.imageLayout = layout;
     }
 
     VkDeviceMemory memory() const
@@ -329,7 +329,7 @@
 
     VkImageLayout layout() const
     {
-        return m_descriptorInfo.imageInfo.imageLayout;
+        return m_descriptorImageInfo.imageLayout;
     }
     uint32_t width() const
     {
@@ -348,7 +348,7 @@
     VkDeviceObj                        *m_device;
 
     vk_testing::ImageView               m_targetView;
-    VkDescriptorInfo                    m_descriptorInfo;
+    VkDescriptorImageInfo               m_descriptorImageInfo;
 };
 
 class VkTextureObj : public VkImageObj
@@ -356,7 +356,7 @@
 public:
     VkTextureObj(VkDeviceObj *device, uint32_t *colors = NULL);
 
-    VkDescriptorInfo                    m_descriptorInfo;
+    VkDescriptorImageInfo               m_imageInfo;
 
 protected:
     VkDeviceObj                        *m_device;
@@ -393,7 +393,7 @@
     vector<VkDescriptorTypeCount>       m_type_counts;
     int                                 m_nextSlot;
 
-    vector<VkDescriptorInfo>            m_imageSamplerDescriptors;
+    vector<VkDescriptorImageInfo>       m_imageSamplerDescriptors;
     vector<VkWriteDescriptorSet>        m_writes;
 
     vk_testing::DescriptorSetLayout     m_layout;
diff --git a/tests/vktestbinding.h b/tests/vktestbinding.h
index 5fdc1aa..9f0baa7 100644
--- a/tests/vktestbinding.h
+++ b/tests/vktestbinding.h
@@ -186,9 +186,17 @@
     void update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes) { return update_descriptor_sets(writes, std::vector<VkCopyDescriptorSet>()); }
 
     static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
-                                                     VkDescriptorType type, uint32_t count, const VkDescriptorInfo *descriptors);
+                                                     VkDescriptorType type, uint32_t count, const VkDescriptorImageInfo *image_info);
     static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
-                                                     VkDescriptorType type, const std::vector<VkDescriptorInfo> &descriptors);
+                                                     VkDescriptorType type, uint32_t count, const VkDescriptorBufferInfo *buffer_info);
+    static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                     VkDescriptorType type, uint32_t count, const VkBufferView *buffer_views);
+    static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                     VkDescriptorType type, const std::vector<VkDescriptorImageInfo> &image_info);
+    static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                     VkDescriptorType type, const std::vector<VkDescriptorBufferInfo> &buffer_info);
+    static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                     VkDescriptorType type, const std::vector<VkBufferView> &buffer_views);
 
     static VkCopyDescriptorSet copy_descriptor_set(const DescriptorSet &src_set, uint32_t src_binding, uint32_t src_array_element,
                                                    const DescriptorSet &dst_set, uint32_t dst_binding, uint32_t dst_array_element,
@@ -806,7 +814,7 @@
 }
 
 inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
-                                                         VkDescriptorType type, uint32_t count, const VkDescriptorInfo *descriptors)
+                                                         VkDescriptorType type, uint32_t count, const VkDescriptorImageInfo *image_info)
 {
     VkWriteDescriptorSet write = {};
     write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@@ -815,14 +823,54 @@
     write.destArrayElement = array_element;
     write.count = count;
     write.descriptorType = type;
-    write.pDescriptors = descriptors;
+    write.pImageInfo = image_info;
     return write;
 }
 
 inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
-                                                         VkDescriptorType type, const std::vector<VkDescriptorInfo> &descriptors)
+                                                         VkDescriptorType type, uint32_t count, const VkDescriptorBufferInfo *buffer_info)
 {
-    return write_descriptor_set(set, binding, array_element, type, descriptors.size(), &descriptors[0]);
+    VkWriteDescriptorSet write = {};
+    write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    write.destSet = set.handle();
+    write.destBinding = binding;
+    write.destArrayElement = array_element;
+    write.count = count;
+    write.descriptorType = type;
+    write.pBufferInfo = buffer_info;
+    return write;
+}
+
+inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                         VkDescriptorType type, uint32_t count, const VkBufferView *buffer_views)
+{
+    VkWriteDescriptorSet write = {};
+    write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    write.destSet = set.handle();
+    write.destBinding = binding;
+    write.destArrayElement = array_element;
+    write.count = count;
+    write.descriptorType = type;
+    write.pTexelBufferView = buffer_views;
+    return write;
+}
+
+inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                         VkDescriptorType type, const std::vector<VkDescriptorImageInfo> &image_info)
+{
+    return write_descriptor_set(set, binding, array_element, type, image_info.size(), &image_info[0]);
+}
+
+inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                         VkDescriptorType type, const std::vector<VkDescriptorBufferInfo> &buffer_info)
+{
+    return write_descriptor_set(set, binding, array_element, type, buffer_info.size(), &buffer_info[0]);
+}
+
+inline VkWriteDescriptorSet Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element,
+                                                         VkDescriptorType type, const std::vector<VkBufferView> &buffer_views)
+{
+    return write_descriptor_set(set, binding, array_element, type, buffer_views.size(), &buffer_views[0]);
 }
 
 inline VkCopyDescriptorSet Device::copy_descriptor_set(const DescriptorSet &src_set, uint32_t src_binding, uint32_t src_array_element,