1 #ifndef _VKTDESCRIPTORSETSINDEXINGTESTS_HPP
2 #define _VKTDESCRIPTORSETSINDEXINGTESTS_HPP
3 /*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
6 *
7 * Copyright (c) 2019 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
23 * \brief Vulkan Descriptor Indexing Tests
24 *//*--------------------------------------------------------------------*/
25
26 #include <vector>
27 #include <fstream>
28 #include <iterator>
29 #include "deSharedPtr.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuRGBA.hpp"
32 #include "tcuSurface.hpp"
33 #include "vkDefs.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vktTestCase.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38
39 namespace vkt
40 {
41 namespace DescriptorIndexing
42 {
43 using namespace vk;
44
45 namespace ut
46 {
47
48 struct FrameBuffer;
49 struct ImageHandleAlloc;
50 struct BufferHandleAlloc;
51
52 typedef de::SharedPtr<FrameBuffer> FrameBufferSp;
53 typedef de::SharedPtr<BufferHandleAlloc> BufferHandleAllocSp;
54 typedef de::SharedPtr<ImageHandleAlloc> ImageHandleAllocSp;
55
56 typedef de::MovePtr<Allocation> AllocMv;
57 typedef de::SharedPtr<Move<VkBufferView>> BufferViewSp;
58 typedef de::SharedPtr<Move<VkImageView>> ImageViewSp;
59 typedef de::SharedPtr<Move<VkSampler>> SamplerSp;
60
61 static const uint32_t maxDeUint32 = static_cast<uint32_t>(-1);
62
63 struct ImageHandleAlloc
64 {
65 Move<VkImage> image;
66 AllocMv alloc;
67 VkExtent3D extent;
68 VkFormat format;
69 uint32_t levels;
70
usesMipMapsvkt::DescriptorIndexing::ut::ImageHandleAlloc71 bool usesMipMaps(void) const
72 {
73 return levels > 0;
74 }
75
ImageHandleAllocvkt::DescriptorIndexing::ut::ImageHandleAlloc76 ImageHandleAlloc(void) : image(), alloc()
77 {
78 }
79
80 ImageHandleAlloc(Move<VkImage> &image_, AllocMv &alloc_, const VkExtent3D &extent_, VkFormat format_,
81 bool usesMipMaps_ = false);
82
83 private:
ImageHandleAllocvkt::DescriptorIndexing::ut::ImageHandleAlloc84 ImageHandleAlloc(const ImageHandleAlloc &)
85 {
86 }
87 };
88
89 struct FrameBuffer
90 {
91 ImageHandleAllocSp image;
92 Move<VkImageView> attachment0;
93 std::vector<VkImageView> attachments;
94 Move<VkFramebuffer> buffer;
95
FrameBuffervkt::DescriptorIndexing::ut::FrameBuffer96 FrameBuffer(void) : image(), attachment0(), attachments(), buffer()
97 {
98 }
99
100 private:
FrameBuffervkt::DescriptorIndexing::ut::FrameBuffer101 FrameBuffer(const FrameBuffer &)
102 {
103 }
104 };
105
106 struct BufferHandleAlloc
107 {
108 Move<VkBuffer> buffer;
109 AllocMv alloc;
110
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc111 BufferHandleAlloc(void) : buffer(), alloc()
112 {
113 }
114
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc115 BufferHandleAlloc(Move<VkBuffer> &buffer_, AllocMv &alloc_) : buffer(buffer_), alloc(alloc_)
116 {
117 }
118
119 private:
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc120 BufferHandleAlloc(const BufferHandleAlloc &)
121 {
122 }
123 };
124
125 std::string buildShaderName(VkShaderStageFlagBits stage, VkDescriptorType descriptorType, bool updateAfterBind,
126 bool calculateInLoop, bool minNonUniform, bool performWritesInVertex);
127
128 std::vector<uint32_t> generatePrimes(uint32_t limit);
129
130 uint32_t computePrimeCount(uint32_t limit);
131
132 uint32_t computeImageSize(const ImageHandleAllocSp &image);
133
134 uint32_t computeMipMapCount(const VkExtent3D &extent);
135
136 uint32_t computeImageSize(const VkExtent3D &extent, VkFormat format, bool withMipMaps = false,
137 uint32_t level = maxDeUint32);
138
139 std::vector<tcu::Vec4> createVertices(uint32_t width, uint32_t height, float &xSize, float &ySize);
140
141 VkDeviceSize createBufferAndBind(ut::BufferHandleAllocSp &output, const vkt::Context &ctx, VkBufferUsageFlags usage,
142 VkDeviceSize desiredSize);
143
144 void createImageAndBind(ut::ImageHandleAllocSp &output, const vkt::Context &ctx, VkFormat colorFormat,
145 const VkExtent3D &extent, VkImageLayout initialLayout, bool withMipMaps = false,
146 VkImageType imageType = VK_IMAGE_TYPE_2D);
147
148 void createFrameBuffer(ut::FrameBufferSp &outputFB, const vkt::Context &context, const VkExtent3D &extent,
149 VkFormat colorFormat, VkRenderPass renderpass, uint32_t additionalAttachmentCount = 0u,
150 const VkImageView additionalAttachments[] = DE_NULL);
151
152 void recordCopyBufferToImage(VkCommandBuffer cmd, const DeviceInterface &interface,
153 VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask,
154 const VkDescriptorBufferInfo &bufferInfo, VkImage image, const VkExtent3D &imageExtent,
155 VkFormat imageFormat, VkImageLayout oldImageLayout, VkImageLayout newImageLayout,
156 uint32_t mipLevelCount);
157
158 void recordCopyImageToBuffer(VkCommandBuffer cmd, const DeviceInterface &interface,
159 VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask, VkImage image,
160 const VkExtent3D &imageExtent, VkFormat imageFormat, VkImageLayout oldimageLayout,
161 VkImageLayout newImageLayout, const VkDescriptorBufferInfo &bufferInfo);
162
163 VkAccessFlags pipelineAccessFromStage(VkPipelineStageFlagBits stage, bool readORwrite);
164
165 bool isDynamicDescriptor(VkDescriptorType descriptorType);
166
167 class DeviceProperties
168 {
169 VkPhysicalDeviceDescriptorIndexingFeatures m_descriptorIndexingFeatures;
170 VkPhysicalDeviceFeatures2 m_features2;
171
172 VkPhysicalDeviceDescriptorIndexingProperties m_descriptorIndexingProperties;
173 VkPhysicalDeviceProperties2 m_properties2;
174
175 public:
176 DeviceProperties(const DeviceProperties &src);
177 DeviceProperties(const vkt::Context &testContext);
178
179 inline const VkPhysicalDeviceDescriptorIndexingFeatures &descriptorIndexingFeatures(void) const;
180 inline const VkPhysicalDeviceProperties &physicalDeviceProperties(void) const;
181 inline const VkPhysicalDeviceDescriptorIndexingProperties &descriptorIndexingProperties(void) const;
182 inline const VkPhysicalDeviceFeatures &physicalDeviceFeatures(void) const;
183
184 uint32_t computeMaxPerStageDescriptorCount(VkDescriptorType descriptorType, bool enableUpdateAfterBind,
185 bool reserveUniformTexelBuffer) const;
186 };
187
descriptorIndexingFeatures(void) const188 inline const VkPhysicalDeviceDescriptorIndexingFeatures &DeviceProperties::descriptorIndexingFeatures(void) const
189 {
190 return m_descriptorIndexingFeatures;
191 }
192
physicalDeviceProperties(void) const193 inline const VkPhysicalDeviceProperties &DeviceProperties::physicalDeviceProperties(void) const
194 {
195 return m_properties2.properties;
196 }
197
descriptorIndexingProperties(void) const198 inline const VkPhysicalDeviceDescriptorIndexingProperties &DeviceProperties::descriptorIndexingProperties(void) const
199 {
200 return m_descriptorIndexingProperties;
201 }
202
physicalDeviceFeatures(void) const203 inline const VkPhysicalDeviceFeatures &DeviceProperties::physicalDeviceFeatures(void) const
204 {
205 return m_features2.features;
206 }
207
208 template <VkFormat _Format>
209 struct VkFormatName
210 {
211 static const VkFormat value = _Format;
212 };
213 template <class T>
214 struct mapType2vkFormat;
215 template <>
216 struct mapType2vkFormat<uint32_t> : public VkFormatName<VK_FORMAT_R32_UINT>
217 {
218 };
219 template <>
220 struct mapType2vkFormat<tcu::UVec2> : public VkFormatName<VK_FORMAT_R32G32_UINT>
221 {
222 };
223 template <>
224 struct mapType2vkFormat<tcu::UVec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_UINT>
225 {
226 };
227 template <>
228 struct mapType2vkFormat<tcu::IVec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_SINT>
229 {
230 };
231 template <>
232 struct mapType2vkFormat<tcu::Vec2> : public VkFormatName<VK_FORMAT_R32G32_SFLOAT>
233 {
234 };
235 template <>
236 struct mapType2vkFormat<tcu::Vec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_SFLOAT>
237 {
238 };
239
240 template <VkFormat _Format>
241 struct mapVkFormat2Type;
242 template <>
243 struct mapVkFormat2Type<VK_FORMAT_R32_UINT> : public VkFormatName<VK_FORMAT_R32_UINT>
244 {
245 typedef uint32_t type;
246 };
247 template <>
248 struct mapVkFormat2Type<VK_FORMAT_R32G32B32A32_SINT> : public VkFormatName<VK_FORMAT_R32G32B32A32_SINT>
249 {
250 typedef tcu::IVec4 type;
251 };
252
253 struct UpdatablePixelBufferAccess : public tcu::PixelBufferAccess
254 {
UpdatablePixelBufferAccessvkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess255 UpdatablePixelBufferAccess(const tcu::TextureFormat &format, const vk::VkExtent3D &extent, void *data)
256 : PixelBufferAccess(format, extent.width, extent.height, extent.depth, data)
257 {
258 }
~UpdatablePixelBufferAccessvkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess259 virtual ~UpdatablePixelBufferAccess(void)
260 {
261 }
262 virtual void invalidate(void) const = 0;
263 virtual void fillColor(const tcu::Vec4 &color) const = 0;
calcTexSizevkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess264 static uint32_t calcTexSize(const tcu::TextureFormat &format, const vk::VkExtent3D &extent)
265 {
266 return extent.width * extent.height * extent.depth * format.getPixelSize();
267 }
calcTexSizevkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess268 static uint32_t calcTexSize(const tcu::TextureFormat &format, uint32_t width, uint32_t height, uint32_t depth)
269 {
270 return width * height * depth * format.getPixelSize();
271 }
272 };
273
274 typedef de::SharedPtr<UpdatablePixelBufferAccess> UpdatablePixelBufferAccessPtr;
275
276 struct PixelBufferAccessBuffer : public UpdatablePixelBufferAccess
277 {
278 const VkDevice m_device;
279 const DeviceInterface &m_interface;
280 de::SharedPtr<Move<VkBuffer>> m_buffer;
281 de::SharedPtr<de::MovePtr<Allocation>> m_allocation;
282
PixelBufferAccessBuffervkt::DescriptorIndexing::ut::PixelBufferAccessBuffer283 PixelBufferAccessBuffer(const VkDevice &device, const DeviceInterface &interface, const tcu::TextureFormat &format,
284 const vk::VkExtent3D &extent, de::SharedPtr<Move<VkBuffer>> buffer,
285 de::SharedPtr<de::MovePtr<Allocation>> allocation)
286 : UpdatablePixelBufferAccess(format, extent, (*allocation)->getHostPtr())
287 , m_device(device)
288 , m_interface(interface)
289 , m_buffer(buffer)
290 , m_allocation(allocation)
291 {
292 }
fillColorvkt::DescriptorIndexing::ut::PixelBufferAccessBuffer293 void fillColor(const tcu::Vec4 &) const
294 {
295 }
invalidatevkt::DescriptorIndexing::ut::PixelBufferAccessBuffer296 void invalidate(void) const
297 {
298 invalidateAlloc(m_interface, m_device, **m_allocation);
299 }
300 };
301
302 struct PixelBufferAccessAllocation : public UpdatablePixelBufferAccess
303 {
304 std::vector<unsigned char> m_data;
PixelBufferAccessAllocationvkt::DescriptorIndexing::ut::PixelBufferAccessAllocation305 PixelBufferAccessAllocation(const tcu::TextureFormat &format, const VkExtent3D &extent)
306 : UpdatablePixelBufferAccess(format, extent, (new unsigned char[calcTexSize(format, extent)]))
307 , m_data(static_cast<unsigned char *>(getDataPtr()),
308 (static_cast<unsigned char *>(getDataPtr()) + calcTexSize(format, extent)))
309 {
310 }
invalidatevkt::DescriptorIndexing::ut::PixelBufferAccessAllocation311 void invalidate(void) const
312 { /* intentionally empty, only for compability */
313 }
fillColorvkt::DescriptorIndexing::ut::PixelBufferAccessAllocation314 void fillColor(const tcu::Vec4 &color) const
315 {
316 tcu::clear(*this, color);
317 }
318 };
319
320 template <class K, class V>
operator <<(std::ostream & s,const std::pair<K,V> & p)321 static std::ostream &operator<<(std::ostream &s, const std::pair<K, V> &p)
322 {
323 s << "{ " << p.first << ", " << p.second << " } ";
324 return s;
325 }
326
327 template <template <class, class> class TCont, class TItem, class TAlloc>
printContainer(std::ostream & s,const std::string & header,const TCont<TItem,TAlloc> & cont)328 inline void printContainer(std::ostream &s, const std::string &header, const TCont<TItem, TAlloc> &cont)
329 {
330 typename TCont<TItem, TAlloc>::const_iterator i, end = cont.end();
331 s << header << '\n';
332 for (i = cont.begin(); i != end; ++i)
333 {
334 s << *i;
335 }
336 s << '\n';
337 }
338
printImage(std::ostream & s,const std::string & header,const tcu::PixelBufferAccess * pa,const uint32_t & rgn=4)339 inline void printImage(std::ostream &s, const std::string &header, const tcu::PixelBufferAccess *pa,
340 const uint32_t &rgn = 4)
341 {
342 if (header.length())
343 {
344 s << header << std::endl;
345 }
346 for (uint32_t r = 0; r < rgn; ++r)
347 {
348 for (uint32_t c = 0; c < rgn; ++c)
349 {
350 s << pa->getPixel(c, r) << " (" << r << "," << c << ")\n";
351 }
352 }
353 }
354
readFile(const std::string & fileName,std::string & content)355 inline bool readFile(const std::string &fileName, std::string &content)
356 {
357 bool result = false;
358 std::ifstream file(fileName.c_str());
359
360 if (file.is_open())
361 {
362 file >> std::noskipws;
363 content.resize(static_cast<size_t>(file.tellg()));
364 content.assign(std::istream_iterator<std::ifstream::char_type>(file),
365 std::istream_iterator<std::ifstream::char_type>());
366 result = true;
367 }
368
369 return result;
370 }
371
372 } // namespace ut
373 } // namespace DescriptorIndexing
374 } // namespace vkt
375
376 #endif // _VKTDESCRIPTORSETSINDEXINGTESTS_HPP
377