Bug 14583: Remove VkBufferView for UBO/SSBO descriptor types

For descriptor types:
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
No longer need to create a VkBufferView, instead can
put the buffer, offset and range directly into a descriptor.
Many places in the driver assumed it could point to a persistent
buffer view and that is no longer the case. Now cache the
view info rather than a pointer to deal with that.
diff --git a/demos/cube.c b/demos/cube.c
index 8f8390c..13565d3 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -363,7 +363,6 @@
     struct {
         VkBuffer buf;
         VkDeviceMemory mem;
-        VkBufferView view;
         VkDescriptorInfo desc;
     } uniform_data;
 
@@ -1259,7 +1258,6 @@
 void demo_prepare_cube_data_buffer(struct demo *demo)
 {
     VkBufferCreateInfo buf_info;
-    VkBufferViewCreateInfo view_info;
     VkMemoryAllocInfo alloc_info = {
         .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
         .pNext = NULL,
@@ -1321,17 +1319,9 @@
             demo->uniform_data.mem, 0);
     assert(!err);
 
-    memset(&view_info, 0, sizeof(view_info));
-    view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
-    view_info.buffer = demo->uniform_data.buf;
-    view_info.viewType = VK_BUFFER_VIEW_TYPE_RAW;
-    view_info.offset = 0;
-    view_info.range = sizeof(data);
-
-    err = vkCreateBufferView(demo->device, &view_info, &demo->uniform_data.view);
-    assert(!err);
-
-    demo->uniform_data.desc.bufferView = demo->uniform_data.view;
+    demo->uniform_data.desc.shaderBuffer.buffer = demo->uniform_data.buf;
+    demo->uniform_data.desc.shaderBuffer.offset = 0;
+    demo->uniform_data.desc.shaderBuffer.range = sizeof(data);
 }
 
 static void demo_prepare_descriptor_layout(struct demo *demo)
@@ -1952,7 +1942,6 @@
     vkDestroyImage(demo->device, demo->depth.image);
     vkFreeMemory(demo->device, demo->depth.mem);
 
-    vkDestroyBufferView(demo->device, demo->uniform_data.view);
     vkDestroyBuffer(demo->device, demo->uniform_data.buf);
     vkFreeMemory(demo->device, demo->uniform_data.mem);
 
diff --git a/icd/intel/desc.c b/icd/intel/desc.c
index 10d9025..81abcef 100644
--- a/icd/intel/desc.c
+++ b/icd/intel/desc.c
@@ -47,7 +47,7 @@
     enum intel_desc_surface_type type;
     union {
         const void *unused;
-        const struct intel_buf_view *buf;
+        const struct intel_buf_view buf;
         const struct intel_img_view *img;
     } u;
 };
@@ -332,8 +332,8 @@
     switch (desc->type) {
     case INTEL_DESC_SURFACE_BUF:
         *cmd = (stage == VK_SHADER_STAGE_FRAGMENT) ?
-            desc->u.buf->fs_cmd : desc->u.buf->cmd;
-        *cmd_len = desc->u.buf->cmd_len;
+            desc->u.buf.fs_cmd : desc->u.buf.cmd;
+        *cmd_len = desc->u.buf.cmd_len;
         break;
     case INTEL_DESC_SURFACE_IMG:
         *cmd = desc->u.img->cmd;
@@ -546,7 +546,7 @@
     desc.mem = buf_view->buf->obj.mem;
     desc.read_only = false;
     desc.type = INTEL_DESC_SURFACE_BUF;
-    desc.u.buf = buf_view;
+    memcpy(&desc.u.buf, buf_view, sizeof(*buf_view));
     intel_desc_region_update(set->region, &iter->begin, &iter->end,
             &desc, NULL);
 }
@@ -963,10 +963,6 @@
             break;
         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:
             for (j = 0; j < write->count; j++) {
                 const VkDescriptorInfo *info = &write->pDescriptors[j];
                 const struct intel_buf_view *buf_view =
@@ -981,6 +977,37 @@
                 }
             }
             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:
+            {
+                const struct intel_dev *dev = intel_dev(device);
+                VkBufferViewCreateInfo view_info;
+                memset(&view_info, 0, sizeof(view_info));
+                view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+                view_info.viewType = VK_BUFFER_VIEW_TYPE_RAW;
+
+                for (j = 0; j < write->count; j++) {
+                    const VkDescriptorInfo *info = &write->pDescriptors[j];
+                    struct intel_buf_view buf_view;
+
+                    view_info.buffer = info->shaderBuffer.buffer;
+                    view_info.offset = info->shaderBuffer.offset;
+                    view_info.range = info->shaderBuffer.range;
+
+                    intel_buf_view_init(dev, &view_info, &buf_view);
+
+                    desc_set_write_buffer(set, &iter, &buf_view);
+
+                    if (!intel_desc_iter_advance(&iter)) {
+                        /* TODOVV: Move test to validation */
+    //                    return VK_ERROR_INVALID_VALUE;
+    //                    return VK_ERROR_UNKNOWN;
+                    }
+                }
+            }
+            break;
         default:
             /* TODOVV: Make sure validation layer covers this case */
 //            return VK_ERROR_UNKNOWN;
diff --git a/icd/intel/view.c b/icd/intel/view.c
index f45d616..b8ce87b 100644
--- a/icd/intel/view.c
+++ b/icd/intel/view.c
@@ -105,6 +105,15 @@
    surface_format = (typed) ?
       intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;
 
+   /*
+    * It's possible that the buffer view being used is smaller than
+    * the format element size (required to be 16 for non-fragment shaders)
+    * Make certain that size is at least struct_size to keep HW happy.
+    */
+   if (size < struct_size) {
+       size = struct_size;
+   }
+
    num_entries = size / struct_size;
    /* see if there is enough space to fit another element */
    if (size % struct_size >= elem_size && !structured)
@@ -1135,9 +1144,9 @@
     intel_buf_view_destroy(view);
 }
 
-VkResult intel_buf_view_create(struct intel_dev *dev,
-                                 const VkBufferViewCreateInfo *info,
-                                 struct intel_buf_view **view_ret)
+void intel_buf_view_init(struct intel_dev *dev,
+                         const VkBufferViewCreateInfo *info,
+                         struct intel_buf_view *view)
 {
     struct intel_buf *buf = intel_buf(info->buffer);
     /* TODO: Is transfer destination the only shader write operation? */
@@ -1145,16 +1154,10 @@
                              VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
     VkFormat format;
     VkDeviceSize stride;
+    VkDeviceSize range = info->range;
     uint32_t *cmd;
-    struct intel_buf_view *view;
     int i;
 
-    view = (struct intel_buf_view *) intel_base_create(&dev->base.handle,
-            sizeof(*view), dev->base.dbg, VK_OBJECT_TYPE_BUFFER_VIEW,
-            info, 0);
-    if (!view)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
-
     view->obj.destroy = buf_view_destroy;
 
     view->buf = buf;
@@ -1195,6 +1198,21 @@
             break;
         }
     }
+}
+
+VkResult intel_buf_view_create(struct intel_dev *dev,
+                               const VkBufferViewCreateInfo *info,
+                               struct intel_buf_view **view_ret)
+{
+    struct intel_buf_view *view;
+
+    view = (struct intel_buf_view *) intel_base_create(&dev->base.handle,
+            sizeof(*view), dev->base.dbg, VK_OBJECT_TYPE_BUFFER_VIEW,
+            info, 0);
+    if (!view)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+    intel_buf_view_init(dev, info, view);
 
     *view_ret = view;
 
diff --git a/icd/intel/view.h b/icd/intel/view.h
index dabe78b..6c95b99 100644
--- a/icd/intel/view.h
+++ b/icd/intel/view.h
@@ -114,9 +114,13 @@
 void intel_null_view_init(struct intel_null_view *view,
                           struct intel_dev *dev);
 
+void intel_buf_view_init(struct intel_dev *dev,
+                         const VkBufferViewCreateInfo *info,
+                         struct intel_buf_view *view);
+
 VkResult intel_buf_view_create(struct intel_dev *dev,
-                                 const VkBufferViewCreateInfo *info,
-                                 struct intel_buf_view **view_ret);
+                               const VkBufferViewCreateInfo *info,
+                               struct intel_buf_view **view_ret);
 
 void intel_buf_view_destroy(struct intel_buf_view *view);
 
diff --git a/include/vulkan.h b/include/vulkan.h
index 15e96c1..c031488 100644
--- a/include/vulkan.h
+++ b/include/vulkan.h
@@ -1779,10 +1779,17 @@
 } VkDescriptorPoolCreateInfo;
 
 typedef struct {
+    VkBuffer                                    buffer;
+    VkDeviceSize                                offset;
+    VkDeviceSize                                range;
+} VkShaderBufferInfo;
+
+typedef struct {
     VkBufferView                                bufferView;
     VkSampler                                   sampler;
     VkImageView                                 imageView;
     VkImageLayout                               imageLayout;
+    VkShaderBufferInfo                          shaderBuffer;
 } VkDescriptorInfo;
 
 typedef struct {
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index ebb2117..810fc3b 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -495,6 +495,10 @@
 
 int VkDescriptorSetObj::AppendBuffer(VkDescriptorType type, VkConstantBufferObj &constantBuffer)
 {
+    assert(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
+           type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
+           type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
+           type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
     VkDescriptorTypeCount tc = {};
     tc.type = type;
     tc.count = 1;
@@ -948,16 +952,14 @@
     memcpy(pData, data, allocationSize);
     memory().unmap();
 
-    // set up the buffer view for the constant buffer
-    VkBufferViewCreateInfo view_info = {};
-    view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
-    view_info.buffer = handle();
-    view_info.viewType = VK_BUFFER_VIEW_TYPE_RAW;
-    view_info.offset = 0;
-    view_info.range  = allocationSize;
-    m_bufferView.init(*m_device, view_info);
-
-    this->m_descriptorInfo.bufferView = m_bufferView.handle();
+    /*
+     * Constant buffers are going to be used as vertex input buffers
+     * or as shader uniform buffers. So, we'll create the shaderbuffer
+     * descriptor here so it's ready if needed.
+     */
+    this->m_descriptorInfo.shaderBuffer.buffer = handle();
+    this->m_descriptorInfo.shaderBuffer.offset = 0;
+    this->m_descriptorInfo.shaderBuffer.range = allocationSize;
 }
 
 void VkConstantBufferObj::Bind(VkCmdBuffer cmdBuffer, VkDeviceSize offset, uint32_t binding)
diff --git a/vktrace/src/vktrace_extensions/vktracevulkan/vkreplay/vkreplay_vkreplay.cpp b/vktrace/src/vktrace_extensions/vktracevulkan/vkreplay/vkreplay_vkreplay.cpp
index a7e16e7..e8b449e 100644
--- a/vktrace/src/vktrace_extensions/vktracevulkan/vkreplay/vkreplay_vkreplay.cpp
+++ b/vktrace/src/vktrace_extensions/vktracevulkan/vkreplay/vkreplay_vkreplay.cpp
@@ -817,40 +817,91 @@
 
         for (uint32_t j = 0; j < pPacket->pDescriptorWrites[i].count; j++)
         {
-            if (pPacket->pDescriptorWrites[i].pDescriptors[j].bufferView.handle != 0)
-            {
-                const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].bufferView.handle = m_objMapper.remap_bufferviews(pPacket->pDescriptorWrites[i].pDescriptors[j].bufferView.handle);
-                if (pRemappedWrites[i].pDescriptors[j].bufferView.handle == 0)
+            switch (pPacket->pDescriptorWrites[i].descriptorType) {
+            case VK_DESCRIPTOR_TYPE_SAMPLER:
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle != 0)
                 {
-                    vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkBufferView.");
-                    VKTRACE_DELETE(pRemappedWrites);
-                    VKTRACE_DELETE(pRemappedCopies);
-                    return;
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].sampler.handle = m_objMapper.remap_samplers(pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].sampler.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkSampler.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
                 }
-            }
-
-            if (pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle != 0)
-            {
-                const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].sampler.handle = m_objMapper.remap_samplers(pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle);
-                if (pRemappedWrites[i].pDescriptors[j].sampler.handle == 0)
+                break;
+            case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+            case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+            case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle != 0)
                 {
-                    vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkSampler.");
-                    VKTRACE_DELETE(pRemappedWrites);
-                    VKTRACE_DELETE(pRemappedCopies);
-                    return;
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].imageView.handle = m_objMapper.remap_imageviews(pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].imageView.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkImageView.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
                 }
-            }
-
-            if (pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle != 0)
-            {
-                const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].imageView.handle = m_objMapper.remap_imageviews(pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle);
-                if (pRemappedWrites[i].pDescriptors[j].imageView.handle == 0)
+                break;
+            case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle != 0)
                 {
-                    vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkImageView.");
-                    VKTRACE_DELETE(pRemappedWrites);
-                    VKTRACE_DELETE(pRemappedCopies);
-                    return;
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].sampler.handle = m_objMapper.remap_samplers(pPacket->pDescriptorWrites[i].pDescriptors[j].sampler.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].sampler.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkSampler.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
                 }
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle != 0)
+                {
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].imageView.handle = m_objMapper.remap_imageviews(pPacket->pDescriptorWrites[i].pDescriptors[j].imageView.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].imageView.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkImageView.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
+                }
+                break;
+            case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+            case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].bufferView.handle != 0)
+                {
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].bufferView.handle = m_objMapper.remap_bufferviews(pPacket->pDescriptorWrites[i].pDescriptors[j].bufferView.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].bufferView.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkBufferView.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
+                }
+                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:
+                if (pPacket->pDescriptorWrites[i].pDescriptors[j].shaderBuffer.buffer.handle != 0)
+                {
+                    const_cast<VkDescriptorInfo*>(pRemappedWrites[i].pDescriptors)[j].shaderBuffer.buffer.handle = m_objMapper.remap_buffers(pPacket->pDescriptorWrites[i].pDescriptors[j].shaderBuffer.buffer.handle);
+                    if (pRemappedWrites[i].pDescriptors[j].shaderBuffer.buffer.handle == 0)
+                    {
+                        vktrace_LogError("Skipping vkUpdateDescriptorSets() due to invalid remapped VkBufferView.");
+                        VKTRACE_DELETE(pRemappedWrites);
+                        VKTRACE_DELETE(pRemappedCopies);
+                        return;
+                    }
+                }
+                /* Nothing to do, already copied the constant values into the new descriptor info */
+            default:
+                break;
             }
         }
     }