1 #ifndef _VKTSPARSERESOURCESSHADERINTRINSICSBASE_HPP
2 #define _VKTSPARSERESOURCESSHADERINTRINSICSBASE_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2016 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file  vktSparseResourcesShaderIntrinsicsBase.hpp
23  * \brief Sparse Resources Shader Intrinsics Base Classes
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "vktTestCase.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktSparseResourcesBase.hpp"
30 #include "vktSparseResourcesTestsUtil.hpp"
31 
32 #include "vkDefs.hpp"
33 #include "vkRef.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkPlatform.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkBuilderUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkDebugReportUtil.hpp"
43 #include "tcuTextureUtil.hpp"
44 
45 #include "deStringUtil.hpp"
46 #include "deUniquePtr.hpp"
47 #include "deSharedPtr.hpp"
48 
49 #include <string>
50 #include <vector>
51 
52 #include <deMath.h>
53 
54 namespace vkt
55 {
56 namespace sparse
57 {
58 
59 enum
60 {
61     MEMORY_BLOCK_BOUND      = 0u,
62     MEMORY_BLOCK_NOT_BOUND  = 1u,
63     MEMORY_BLOCK_TYPE_COUNT = 2u
64 };
65 
66 enum
67 {
68     MEMORY_BLOCK_BOUND_VALUE     = 1u,
69     MEMORY_BLOCK_NOT_BOUND_VALUE = 2u
70 };
71 
72 enum
73 {
74     BINDING_IMAGE_SPARSE    = 0u,
75     BINDING_IMAGE_TEXELS    = 1u,
76     BINDING_IMAGE_RESIDENCY = 2u
77 };
78 
79 enum SpirVFunction
80 {
81     SPARSE_FETCH = 0u,
82     SPARSE_READ,
83     SPARSE_SAMPLE_EXPLICIT_LOD,
84     SPARSE_SAMPLE_IMPLICIT_LOD,
85     SPARSE_GATHER,
86     SPARSE_SPIRV_FUNCTION_TYPE_LAST
87 };
88 
89 std::string getOpTypeImageComponent(const tcu::TextureFormat &format);
90 std::string getOpTypeImageComponent(const vk::PlanarFormatDescription &description);
91 std::string getImageComponentTypeName(const tcu::TextureFormat &format);
92 std::string getImageComponentTypeName(const vk::PlanarFormatDescription &description);
93 std::string getImageComponentVec4TypeName(const tcu::TextureFormat &format);
94 std::string getImageComponentVec4TypeName(const vk::PlanarFormatDescription &description);
95 std::string getOpTypeImageSparse(const ImageType imageType, const tcu::TextureFormat &format,
96                                  const std::string &componentType, const bool requiresSampler);
97 std::string getOpTypeImageSparse(const ImageType imageType, const vk::VkFormat format, const std::string &componentType,
98                                  const bool requiresSampler);
99 std::string getOpTypeImageResidency(const ImageType imageType);
100 
101 class SparseShaderIntrinsicsCaseBase : public TestCase
102 {
103 public:
SparseShaderIntrinsicsCaseBase(tcu::TestContext & testCtx,const std::string & name,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const vk::VkFormat format,const std::string & operand)104     SparseShaderIntrinsicsCaseBase(tcu::TestContext &testCtx, const std::string &name, const SpirVFunction function,
105                                    const ImageType imageType, const tcu::UVec3 &imageSize, const vk::VkFormat format,
106                                    const std::string &operand)
107         : TestCase(testCtx, name)
108         , m_function(function)
109         , m_imageType(imageType)
110         , m_imageSize(imageSize)
111         , m_format(format)
112         , m_operand(operand)
113     {
114     }
115 
checkSupport(Context & context) const116     virtual void checkSupport(Context &context) const
117     {
118         const vk::InstanceInterface &instance     = context.getInstanceInterface();
119         const vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
120 
121         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY);
122 
123         // Check if image size does not exceed device limits
124         if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
125             TCU_THROW(NotSupportedError, "Image size not supported for device");
126 
127         // Check if device supports sparse operations for image type
128         if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
129             TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
130 
131         if ((m_operand.find("Nontemporal") != std::string::npos) && (context.getUsedApiVersion() < VK_API_VERSION_1_3))
132             TCU_THROW(NotSupportedError, "Vulkan 1.3 or higher is required for this test to run");
133     }
134 
135 protected:
136     const SpirVFunction m_function;
137     const ImageType m_imageType;
138     const tcu::UVec3 m_imageSize;
139     const vk::VkFormat m_format;
140     const std::string m_operand;
141 };
142 
143 class SparseShaderIntrinsicsInstanceBase : public SparseResourcesBaseInstance
144 {
145 public:
SparseShaderIntrinsicsInstanceBase(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const vk::VkFormat format)146     SparseShaderIntrinsicsInstanceBase(Context &context, const SpirVFunction function, const ImageType imageType,
147                                        const tcu::UVec3 &imageSize, const vk::VkFormat format)
148         : SparseResourcesBaseInstance(context)
149         , m_function(function)
150         , m_imageType(imageType)
151         , m_imageSize(imageSize)
152         , m_format(format)
153         , m_residencyFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32)
154     {
155     }
156 
157     tcu::TestStatus iterate(void);
158 
159     virtual vk::VkImageUsageFlags imageSparseUsageFlags(void) const = 0;
160     virtual vk::VkImageUsageFlags imageOutputUsageFlags(void) const = 0;
161 
162     virtual vk::VkQueueFlags getQueueFlags(void) const = 0;
163 
164     virtual void recordCommands(const vk::VkCommandBuffer commandBuffer, const vk::VkImageCreateInfo &imageSparseInfo,
165                                 const vk::VkImage imageSparse, const vk::VkImage imageTexels,
166                                 const vk::VkImage imageResidency) = 0;
167     virtual void checkSupport(vk::VkImageCreateInfo imageSparseInfo) const;
168 
169 protected:
170     const SpirVFunction m_function;
171     const ImageType m_imageType;
172     const tcu::UVec3 m_imageSize;
173     const vk::VkFormat m_format;
174     const tcu::TextureFormat m_residencyFormat;
175 
176     typedef de::SharedPtr<vk::Unique<vk::VkPipeline>> SharedVkPipeline;
177     std::vector<SharedVkPipeline> pipelines;
178     vk::Move<vk::VkPipelineLayout> pipelineLayout;
179 
180     typedef de::SharedPtr<vk::Unique<vk::VkImageView>> SharedVkImageView;
181     std::vector<SharedVkImageView> imageSparseViews;
182     std::vector<SharedVkImageView> imageTexelsViews;
183     std::vector<SharedVkImageView> imageResidencyViews;
184 
185     vk::Move<vk::VkDescriptorPool> descriptorPool;
186 
187     typedef de::SharedPtr<vk::Unique<vk::VkDescriptorSet>> SharedVkDescriptorSet;
188     std::vector<SharedVkDescriptorSet> descriptorSets;
189 };
190 
191 } // namespace sparse
192 } // namespace vkt
193 
194 #endif // _VKTSPARSERESOURCESSHADERINTRINSICSBASE_HPP
195