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;
}
}
}