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