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 deUint32 maxDeUint32 = static_cast<deUint32>(-1);
62
63 struct ImageHandleAlloc
64 {
65 Move<VkImage> image;
66 AllocMv alloc;
67 VkExtent3D extent;
68 VkFormat format;
69 deUint32 levels;
70
usesMipMapsvkt::DescriptorIndexing::ut::ImageHandleAlloc71 bool usesMipMaps (void) const { return levels > 0; }
72
ImageHandleAllocvkt::DescriptorIndexing::ut::ImageHandleAlloc73 ImageHandleAlloc (void)
74 : image()
75 , alloc() {}
76
77 ImageHandleAlloc (Move<VkImage>& image_,
78 AllocMv& alloc_,
79 const VkExtent3D& extent_,
80 VkFormat format_,
81 bool usesMipMaps_ = false);
82 private:
ImageHandleAllocvkt::DescriptorIndexing::ut::ImageHandleAlloc83 ImageHandleAlloc (const ImageHandleAlloc&) {}
84 };
85
86 struct FrameBuffer
87 {
88 ImageHandleAllocSp image;
89 Move<VkImageView> attachment0;
90 std::vector<VkImageView> attachments;
91 Move<VkFramebuffer> buffer;
92
FrameBuffervkt::DescriptorIndexing::ut::FrameBuffer93 FrameBuffer (void)
94 : image ()
95 , attachment0 ()
96 , attachments ()
97 , buffer () {}
98 private:
FrameBuffervkt::DescriptorIndexing::ut::FrameBuffer99 FrameBuffer (const FrameBuffer&) {}
100 };
101
102 struct BufferHandleAlloc
103 {
104 Move<VkBuffer> buffer;
105 AllocMv alloc;
106
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc107 BufferHandleAlloc (void)
108 : buffer ()
109 , alloc () {}
110
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc111 BufferHandleAlloc (Move<VkBuffer>& buffer_,
112 AllocMv& alloc_)
113 : buffer (buffer_)
114 , alloc (alloc_) {}
115 private:
BufferHandleAllocvkt::DescriptorIndexing::ut::BufferHandleAlloc116 BufferHandleAlloc(const BufferHandleAlloc&) {}
117 };
118
119 std::string buildShaderName (VkShaderStageFlagBits stage,
120 VkDescriptorType descriptorType,
121 deBool updateAfterBind,
122 bool calculateInLoop,
123 bool minNonUniform,
124 bool performWritesInVertex);
125
126 std::vector<deUint32> generatePrimes (deUint32 limit);
127
128 deUint32 computePrimeCount (deUint32 limit);
129
130 deUint32 computeImageSize (const ImageHandleAllocSp& image);
131
132 deUint32 computeMipMapCount (const VkExtent3D& extent);
133
134 deUint32 computeImageSize (const VkExtent3D& extent,
135 VkFormat format,
136 bool withMipMaps = false,
137 deUint32 level = maxDeUint32);
138
139 std::vector<tcu::Vec4> createVertices (deUint32 width,
140 deUint32 height,
141 float& xSize,
142 float& ySize);
143
144 VkDeviceSize createBufferAndBind (ut::BufferHandleAllocSp& output,
145 const vkt::Context& ctx,
146 VkBufferUsageFlags usage,
147 VkDeviceSize desiredSize);
148
149 void createImageAndBind (ut::ImageHandleAllocSp& output,
150 const vkt::Context& ctx,
151 VkFormat colorFormat,
152 const VkExtent3D& extent,
153 VkImageLayout initialLayout,
154 bool withMipMaps = false,
155 VkImageType imageType = VK_IMAGE_TYPE_2D);
156
157 void createFrameBuffer (ut::FrameBufferSp& outputFB,
158 const vkt::Context& context,
159 const VkExtent3D& extent,
160 VkFormat colorFormat,
161 VkRenderPass renderpass,
162 deUint32 additionalAttachmentCount = 0u,
163 const VkImageView additionalAttachments[] = DE_NULL);
164
165 void recordCopyBufferToImage (VkCommandBuffer cmd,
166 const DeviceInterface& interface,
167 VkPipelineStageFlagBits srcStageMask,
168 VkPipelineStageFlagBits dstStageMask,
169 const VkDescriptorBufferInfo& bufferInfo,
170 VkImage image,
171 const VkExtent3D& imageExtent,
172 VkFormat imageFormat,
173 VkImageLayout oldImageLayout,
174 VkImageLayout newImageLayout,
175 deUint32 mipLevelCount);
176
177 void recordCopyImageToBuffer (VkCommandBuffer cmd,
178 const DeviceInterface& interface,
179 VkPipelineStageFlagBits srcStageMask,
180 VkPipelineStageFlagBits dstStageMask,
181 VkImage image,
182 const VkExtent3D& imageExtent,
183 VkFormat imageFormat,
184 VkImageLayout oldimageLayout,
185 VkImageLayout newImageLayout,
186 const VkDescriptorBufferInfo& bufferInfo);
187
188 VkAccessFlags pipelineAccessFromStage (VkPipelineStageFlagBits stage,
189 bool readORwrite);
190
191 bool isDynamicDescriptor (VkDescriptorType descriptorType);
192
193 class DeviceProperties
194 {
195 VkPhysicalDeviceDescriptorIndexingFeatures m_descriptorIndexingFeatures;
196 VkPhysicalDeviceFeatures2 m_features2;
197
198 VkPhysicalDeviceDescriptorIndexingProperties m_descriptorIndexingProperties;
199 VkPhysicalDeviceProperties2 m_properties2;
200
201 public:
202 DeviceProperties (const DeviceProperties& src);
203 DeviceProperties (const vkt::Context& testContext);
204
205 inline const VkPhysicalDeviceDescriptorIndexingFeatures& descriptorIndexingFeatures (void) const;
206 inline const VkPhysicalDeviceProperties& physicalDeviceProperties (void) const;
207 inline const VkPhysicalDeviceDescriptorIndexingProperties& descriptorIndexingProperties(void) const;
208 inline const VkPhysicalDeviceFeatures& physicalDeviceFeatures (void) const;
209
210 deUint32 computeMaxPerStageDescriptorCount (VkDescriptorType descriptorType,
211 bool enableUpdateAfterBind,
212 bool reserveUniformTexelBuffer) const;
213 };
214
descriptorIndexingFeatures(void) const215 inline const VkPhysicalDeviceDescriptorIndexingFeatures& DeviceProperties::descriptorIndexingFeatures (void) const
216 {
217 return m_descriptorIndexingFeatures;
218 }
219
physicalDeviceProperties(void) const220 inline const VkPhysicalDeviceProperties& DeviceProperties::physicalDeviceProperties (void) const
221 {
222 return m_properties2.properties;
223 }
224
descriptorIndexingProperties(void) const225 inline const VkPhysicalDeviceDescriptorIndexingProperties& DeviceProperties::descriptorIndexingProperties (void) const
226 {
227 return m_descriptorIndexingProperties;
228 }
229
physicalDeviceFeatures(void) const230 inline const VkPhysicalDeviceFeatures& DeviceProperties::physicalDeviceFeatures (void) const
231 {
232 return m_features2.features;
233 }
234
235 template<VkFormat _Format> struct VkFormatName
236 {
237 static const VkFormat value = _Format;
238 };
239 template<class T> struct mapType2vkFormat;
240 template<> struct mapType2vkFormat<deUint32> : public VkFormatName<VK_FORMAT_R32_UINT>{};
241 template<> struct mapType2vkFormat<tcu::UVec2> : public VkFormatName<VK_FORMAT_R32G32_UINT>{};
242 template<> struct mapType2vkFormat<tcu::UVec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_UINT>{};
243 template<> struct mapType2vkFormat<tcu::IVec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_SINT>{};
244 template<> struct mapType2vkFormat<tcu::Vec2> : public VkFormatName<VK_FORMAT_R32G32_SFLOAT>{};
245 template<> struct mapType2vkFormat<tcu::Vec4> : public VkFormatName<VK_FORMAT_R32G32B32A32_SFLOAT>{};
246
247 template<VkFormat _Format> struct mapVkFormat2Type;
248 template<> struct mapVkFormat2Type<VK_FORMAT_R32_UINT> : public VkFormatName<VK_FORMAT_R32_UINT>
249 {
250 typedef deUint32 type;
251 };
252 template<> struct mapVkFormat2Type<VK_FORMAT_R32G32B32A32_SINT> : public VkFormatName<VK_FORMAT_R32G32B32A32_SINT>
253 {
254 typedef tcu::IVec4 type;
255 };
256
257 struct UpdatablePixelBufferAccess : public tcu::PixelBufferAccess
258 {
UpdatablePixelBufferAccessvkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess259 UpdatablePixelBufferAccess (const tcu::TextureFormat& format, const vk::VkExtent3D& extent, void* data)
260 : PixelBufferAccess(format, extent.width, extent.height, extent.depth, data)
261 {
262 }
~UpdatablePixelBufferAccessvkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess263 virtual ~UpdatablePixelBufferAccess (void) { }
264 virtual void invalidate (void) const = 0;
265 virtual void fillColor (const tcu::Vec4& color) const = 0;
calcTexSizevkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess266 static deUint32 calcTexSize (const tcu::TextureFormat& format, const vk::VkExtent3D& extent)
267 {
268 return extent.width * extent.height * extent.depth * format.getPixelSize();
269 }
calcTexSizevkt::DescriptorIndexing::ut::UpdatablePixelBufferAccess270 static deUint32 calcTexSize (const tcu::TextureFormat& format, deUint32 width, deUint32 height, deUint32 depth)
271 {
272 return width * height * depth * format.getPixelSize();
273 }
274 };
275
276 typedef de::SharedPtr<UpdatablePixelBufferAccess> UpdatablePixelBufferAccessPtr;
277
278 struct PixelBufferAccessBuffer : public UpdatablePixelBufferAccess
279 {
280 const VkDevice m_device;
281 const DeviceInterface& m_interface;
282 de::SharedPtr< Move<VkBuffer> > m_buffer;
283 de::SharedPtr< de::MovePtr<Allocation> > m_allocation;
284
PixelBufferAccessBuffervkt::DescriptorIndexing::ut::PixelBufferAccessBuffer285 PixelBufferAccessBuffer (const VkDevice& device, const DeviceInterface& interface,
286 const tcu::TextureFormat& format, const vk::VkExtent3D& extent,
287 de::SharedPtr< Move<VkBuffer> > buffer, de::SharedPtr< de::MovePtr<Allocation> > allocation)
288 : UpdatablePixelBufferAccess(format, extent, (*allocation)->getHostPtr())
289 , m_device(device), m_interface(interface), m_buffer(buffer), m_allocation(allocation)
290 {
291 }
fillColorvkt::DescriptorIndexing::ut::PixelBufferAccessBuffer292 void fillColor (const tcu::Vec4&) const { }
invalidatevkt::DescriptorIndexing::ut::PixelBufferAccessBuffer293 void invalidate (void) const
294 {
295 invalidateAlloc(m_interface, m_device, **m_allocation);
296 }
297 };
298
299 struct PixelBufferAccessAllocation : public UpdatablePixelBufferAccess
300 {
301 std::vector<unsigned char> m_data;
PixelBufferAccessAllocationvkt::DescriptorIndexing::ut::PixelBufferAccessAllocation302 PixelBufferAccessAllocation (const tcu::TextureFormat& format, const VkExtent3D& extent)
303 : UpdatablePixelBufferAccess(format, extent, (new unsigned char[calcTexSize(format, extent)]))
304 , m_data(static_cast<unsigned char*>(getDataPtr()), (static_cast<unsigned char*>(getDataPtr()) + calcTexSize(format, extent)))
305 {
306 }
invalidatevkt::DescriptorIndexing::ut::PixelBufferAccessAllocation307 void invalidate (void) const { /* intentionally empty, only for compability */ }
fillColorvkt::DescriptorIndexing::ut::PixelBufferAccessAllocation308 void fillColor (const tcu::Vec4& color) const
309 {
310 tcu::clear(*this, color);
311 }
312 };
313
314 template<class K, class V>
operator <<(std::ostream & s,const std::pair<K,V> & p)315 static std::ostream& operator<< (std::ostream& s, const std::pair<K, V>& p)
316 {
317 s << "{ " << p.first << ", " << p.second << " } ";
318 return s;
319 }
320
321 template<template<class, class> class TCont, class TItem, class TAlloc>
printContainer(std::ostream & s,const std::string & header,const TCont<TItem,TAlloc> & cont)322 inline void printContainer (std::ostream& s, const std::string& header, const TCont<TItem, TAlloc>& cont)
323 {
324 typename TCont<TItem, TAlloc>::const_iterator i, end = cont.end();
325 s << header << '\n';
326 for (i = cont.begin(); i != end; ++i)
327 {
328 s << *i;
329 }
330 s << '\n';
331 }
332
printImage(std::ostream & s,const std::string & header,const tcu::PixelBufferAccess * pa,const deUint32 & rgn=4)333 inline void printImage (std::ostream& s, const std::string& header, const tcu::PixelBufferAccess* pa, const deUint32& rgn = 4)
334 {
335 if (header.length())
336 {
337 s << header << std::endl;
338 }
339 for (deUint32 r = 0; r < rgn; ++r)
340 {
341 for (deUint32 c = 0; c < rgn; ++c)
342 {
343 s << pa->getPixel(c, r) << " (" << r << "," << c << ")\n";
344 }
345 }
346 }
347
readFile(const std::string & fileName,std::string & content)348 inline bool readFile (const std::string& fileName, std::string& content)
349 {
350 bool result = false;
351 std::ifstream file(fileName.c_str());
352
353 if (file.is_open())
354 {
355 file >> std::noskipws;
356 content.resize(static_cast<size_t>(file.tellg()));
357 content.assign(std::istream_iterator<std::ifstream::char_type>(file),
358 std::istream_iterator<std::ifstream::char_type>());
359 result = true;
360 }
361
362 return result;
363 }
364
365 } // namespace ut
366 } // namespace DescriptorIndexing
367 } // namespace vkt
368
369 #endif // _VKTDESCRIPTORSETSINDEXINGTESTS_HPP
370