Fix memory management, image layout issues in uploadImageSparse()
authorDominik Witczak <Dominik.Witczak@amd.com>
Thu, 17 Nov 2016 12:10:19 +0000 (13:10 +0100)
committerPyry Haulos <phaulos@google.com>
Mon, 28 Nov 2016 19:23:37 +0000 (14:23 -0500)
Fixes an issue where ShaderRenderCaseInstance::uploadSparseImage()
would first configure sparse image bindings and then deallocate
the memory objects, prior to actually sampling the image.

Fixes an issue where the sparse image, after having been filled with
contents, would first be transitioned to SHADER_READ_ONLY_OPTIMAL
layout, and then used in a DS which was expecting it to be in
GENERLA layout.

Finally, the patch addresses a problem, where the function would not
correctly recognize the VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT,
as reported by the running driver.

The change affects dEQP-VK.glsl.*sparse* tests

Khronos issue: #543

Change-Id: Ie5717841fe0ef9c0672b5075380ff96bba9855b9

external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp
external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp

index ffbbdc1..009b9f5 100644 (file)
@@ -1563,7 +1563,6 @@ void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat&               tex
 
                std::vector<VkSparseImageMemoryBind>            imageResidencyMemoryBinds;
                std::vector<VkSparseMemoryBind>                         imageMipTailMemoryBinds;
-               std::vector< de::SharedPtr<Allocation> >        allocations;
 
                for (deUint32 layerNdx = 0; layerNdx < arrayLayers; ++ layerNdx)
                {
@@ -1596,7 +1595,7 @@ void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat&               tex
 
                                        de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release());
 
-                                       allocations.push_back(allocation);
+                                       m_allocations.push_back(allocation);
 
                                        VkOffset3D offset;
                                        offset.x = x*imageGranularity.width;
@@ -1626,28 +1625,35 @@ void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat&             tex
                                }
                        }
 
-                       // Handle MIP tail for each layer
+                       // Handle MIP tail. There are two cases to consider here:
+                       //
+                       // 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
+                       // 2) otherwise:                                                            only one tail is needed.
                        {
-                               const VkMemoryRequirements allocRequirements =
+                               if ( imageMipTailMemoryBinds.size() == 0                                                                                                   ||
+                                       (imageMipTailMemoryBinds.size() != 0 && (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0))
                                {
-                                       aspectRequirements.imageMipTailSize,    // VkDeviceSize size;
-                                       memoryRequirements.alignment,                   // VkDeviceSize alignment;
-                                       memoryRequirements.memoryTypeBits,              // uint32_t             memoryTypeBits;
-                               };
+                                       const VkMemoryRequirements allocRequirements =
+                                       {
+                                               aspectRequirements.imageMipTailSize,    // VkDeviceSize size;
+                                               memoryRequirements.alignment,                   // VkDeviceSize alignment;
+                                               memoryRequirements.memoryTypeBits,              // uint32_t             memoryTypeBits;
+                                       };
 
-                               const de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release());
+                                       const de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release());
 
-                               const VkSparseMemoryBind imageMipTailMemoryBind =
-                               {
-                                       aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride,       // VkDeviceSize                                 resourceOffset;
-                                       aspectRequirements.imageMipTailSize,                                                                                                            // VkDeviceSize                                 size;
-                                       allocation->getMemory(),                                                                                                                                        // VkDeviceMemory                               memory;
-                                       allocation->getOffset(),                                                                                                                                        // VkDeviceSize                                 memoryOffset;
-                                       0u,                                                                                                                                                                                     // VkSparseMemoryBindFlags              flags;
-                               };
+                                       const VkSparseMemoryBind imageMipTailMemoryBind =
+                                       {
+                                               aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride,       // VkDeviceSize                                 resourceOffset;
+                                               aspectRequirements.imageMipTailSize,                                                                                                            // VkDeviceSize                                 size;
+                                               allocation->getMemory(),                                                                                                                                        // VkDeviceMemory                               memory;
+                                               allocation->getOffset(),                                                                                                                                        // VkDeviceSize                                 memoryOffset;
+                                               0u,                                                                                                                                                                                     // VkSparseMemoryBindFlags              flags;
+                                       };
 
-                               allocations.push_back(allocation);
-                               imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+                                       m_allocations.push_back(allocation);
+                                       imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
+                               }
                        }
                }
 
@@ -2213,7 +2219,7 @@ void ShaderRenderCaseInstance::createSamplerUniform (deUint32                                             bindingLocati
        {
                sampler.get(),                                                          // VkSampler                            sampler;
                imageView.get(),                                                        // VkImageView                          imageView;
-               VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        imageLayout;
+               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        imageLayout;
        };
 
        de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
index 71cbfbf..6d8ac05 100644 (file)
@@ -32,6 +32,7 @@
 #include "deUniquePtr.hpp"
 
 #include "vkDefs.hpp"
+#include "vkRefUtil.hpp"
 #include "vkPrograms.hpp"
 #include "vkRef.hpp"
 #include "vkMemUtil.hpp"
@@ -643,6 +644,8 @@ private:
        typedef de::SharedPtr<de::UniquePtr<UniformInfo> >      UniformInfoSp;
        std::vector<UniformInfoSp>                                                      m_uniformInfos;
 
+       std::vector< de::SharedPtr<vk::Allocation> >            m_allocations;
+
        std::vector<vk::VkVertexInputBindingDescription>        m_vertexBindingDescription;
        std::vector<vk::VkVertexInputAttributeDescription>      m_vertexAttributeDescription;