tests: Add VK_SHARING_MODE_CONCURRENT support
authorJohn Zulauf <jzulauf@lunarg.com>
Tue, 16 Jan 2018 18:15:15 +0000 (11:15 -0700)
committerjzulauf-lunarg <32470354+jzulauf-lunarg@users.noreply.github.com>
Tue, 23 Jan 2018 18:07:07 +0000 (11:07 -0700)
Added support for the creation of buffer and image resources with
VK_SHARING_MODE_CONCURRENT in framework.

Change-Id: Ie3c042d20a01b6988a15e225427a547689de96d1

tests/vkrenderframework.cpp
tests/vkrenderframework.h
tests/vktestbinding.h

index 5741b61..817d649 100644 (file)
@@ -859,7 +859,8 @@ bool VkImageObj::IsCompatible(const VkImageUsageFlags usages, const VkFormatFeat
 }
 
 void VkImageObj::InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
-                              VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs) {
+                              VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs,
+                              const std::vector<uint32_t> *queue_families) {
     VkFormatProperties image_fmt;
     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
 
@@ -892,6 +893,13 @@ void VkImageObj::InitNoLayout(uint32_t const width, uint32_t const height, uint3
     imageCreateInfo.tiling = tiling;
     imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 
+    // Automatically set sharing mode etc. based on queue family information
+    if (queue_families && (queue_families->size() > 1)) {
+        imageCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
+        imageCreateInfo.queueFamilyIndexCount = static_cast<uint32_t>(queue_families->size());
+        imageCreateInfo.pQueueFamilyIndices = queue_families->data();
+    }
+
     Layout(imageCreateInfo.initialLayout);
     imageCreateInfo.usage = usage;
 
@@ -899,8 +907,9 @@ void VkImageObj::InitNoLayout(uint32_t const width, uint32_t const height, uint3
 }
 
 void VkImageObj::Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
-                      VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs) {
-    InitNoLayout(width, height, mipLevels, format, usage, requested_tiling, reqs);
+                      VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs,
+                      const std::vector<uint32_t> *queue_families) {
+    InitNoLayout(width, height, mipLevels, format, usage, requested_tiling, reqs, queue_families);
 
     VkImageLayout newLayout;
     if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
index 3435a94..54d7243 100644 (file)
@@ -240,12 +240,14 @@ class VkImageObj : public vk_testing::Image {
 
    public:
     void Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format, VkFlags const usage,
-              VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0);
+              VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0,
+              const std::vector<uint32_t> *queue_families = nullptr);
 
     void init(const VkImageCreateInfo *create_info);
 
     void InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
-                      VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0);
+                      VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0,
+                      const std::vector<uint32_t> *queue_families = nullptr);
 
     //    void clear( CommandBuffer*, uint32_t[4] );
 
index f3e2fc9..fbbed3e 100644 (file)
@@ -381,14 +381,17 @@ class Buffer : public internal::NonDispHandle<VkBuffer> {
     void init(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info, 0); }
     void init(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags mem_props) { init(dev, create_info(size, 0), mem_props); }
     void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); }
-    void init_as_src(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
-        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), reqs);
+    void init_as_src(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+                     const std::vector<uint32_t> *queue_families = nullptr) {
+        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, queue_families), reqs);
     }
-    void init_as_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
-        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs);
+    void init_as_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+                     const std::vector<uint32_t> *queue_families = nullptr) {
+        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, queue_families), reqs);
     }
-    void init_as_src_and_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
-        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs);
+    void init_as_src_and_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+                             const std::vector<uint32_t> *queue_families = nullptr) {
+        init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, queue_families), reqs);
     }
     void init_no_mem(const Device &dev, const VkBufferCreateInfo &info);
 
@@ -402,7 +405,7 @@ class Buffer : public internal::NonDispHandle<VkBuffer> {
     // vkBindObjectMemory()
     void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset);
 
-    static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage);
+    static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage, const std::vector<uint32_t> *queue_families = nullptr);
 
     VkBufferMemoryBarrier buffer_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkDeviceSize offset,
                                                 VkDeviceSize size) const {
@@ -413,6 +416,10 @@ class Buffer : public internal::NonDispHandle<VkBuffer> {
         barrier.dstAccessMask = input_mask;
         barrier.offset = offset;
         barrier.size = size;
+        if (create_info_.sharingMode == VK_SHARING_MODE_CONCURRENT) {
+            barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+            barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        }
         return barrier;
     }
 
@@ -466,6 +473,7 @@ class Image : public internal::NonDispHandle<VkImage> {
     VkExtent3D extent(uint32_t mip_level) const { return extent(create_info_.extent, mip_level); }
     VkFormat format() const { return create_info_.format; }
     VkImageUsageFlags usage() const { return create_info_.usage; }
+    VkSharingMode sharing_mode() const { return create_info_.sharingMode; }
     VkImageMemoryBarrier image_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkImageLayout old_layout,
                                               VkImageLayout new_layout, const VkImageSubresourceRange &range) const {
         VkImageMemoryBarrier barrier = {};
@@ -476,6 +484,11 @@ class Image : public internal::NonDispHandle<VkImage> {
         barrier.newLayout = new_layout;
         barrier.image = handle();
         barrier.subresourceRange = range;
+
+        if (sharing_mode() == VK_SHARING_MODE_CONCURRENT) {
+            barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+            barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        }
         return barrier;
     }
 
@@ -690,11 +703,18 @@ inline VkMemoryAllocateInfo DeviceMemory::alloc_info(VkDeviceSize size, uint32_t
     return info;
 }
 
-inline VkBufferCreateInfo Buffer::create_info(VkDeviceSize size, VkFlags usage) {
+inline VkBufferCreateInfo Buffer::create_info(VkDeviceSize size, VkFlags usage, const std::vector<uint32_t> *queue_families) {
     VkBufferCreateInfo info = {};
     info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
     info.size = size;
     info.usage = usage;
+
+    if (queue_families && queue_families->size() > 1) {
+        info.sharingMode = VK_SHARING_MODE_CONCURRENT;
+        info.queueFamilyIndexCount = static_cast<uint32_t>(queue_families->size());
+        info.pQueueFamilyIndices = queue_families->data();
+    }
+
     return info;
 }