xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiBufferViewAccessTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan Buffer View Memory Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiBufferViewAccessTests.hpp"
26 #include "vktApiBufferAndImageAllocationUtil.hpp"
27 
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuTexture.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "deSharedPtr.hpp"
45 #include "deArrayUtil.hpp"
46 #include "tcuVectorUtil.hpp"
47 #include "../image/vktImageTestsUtil.hpp"
48 
49 namespace vkt
50 {
51 
52 namespace api
53 {
54 
55 using namespace vk;
56 
57 namespace
58 {
59 
60 enum AllocationKind
61 {
62     ALLOCATION_KIND_SUBALLOCATION = 0,
63     ALLOCATION_KIND_DEDICATED     = 1,
64     ALLOCATION_KIND_LAST
65 };
66 
67 struct BufferViewCaseParams
68 {
69     uint32_t bufferSize;
70     uint32_t bufferViewSize;
71     uint32_t elementOffset;
72     AllocationKind bufferAllocationKind;
73     AllocationKind imageAllocationKind;
74 
75     VkFormat format;
76     VkBufferUsageFlags createUsage;
77     VkBufferUsageFlags bindUsage;
78     VkFormatFeatureFlags feature;
79     VkDescriptorType descType;
80 
BufferViewCaseParamsvkt::api::__anon187255a70111::BufferViewCaseParams81     BufferViewCaseParams(uint32_t bufferSize_, uint32_t bufferViewSize_, uint32_t elementOffset_,
82                          AllocationKind bufferAllocKind_, AllocationKind imageAllocKind_,
83                          VkFormat format_                   = VK_FORMAT_R32_UINT,
84                          VkBufferUsageFlags createUsage_    = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
85                          VkBufferUsageFlags bindUsage_      = VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM,
86                          VkFormatFeatureFlags featureFlags_ = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
87                          VkDescriptorType descType_         = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
88         : bufferSize(bufferSize_)
89         , bufferViewSize(bufferViewSize_)
90         , elementOffset(elementOffset_)
91         , bufferAllocationKind(bufferAllocKind_)
92         , imageAllocationKind(imageAllocKind_)
93         , format(format_)
94         , createUsage(createUsage_)
95         , bindUsage(bindUsage_)
96         , feature(featureFlags_)
97         , descType(descType_)
98     {
99     }
100 };
101 
102 class BufferViewTestInstance : public vkt::TestInstance
103 {
104 public:
105     BufferViewTestInstance(Context &context, BufferViewCaseParams testCase);
106     virtual ~BufferViewTestInstance(void);
107     virtual tcu::TestStatus iterate(void);
108 
109 private:
110     void createQuad(void);
111     tcu::TestStatus checkResult(int8_t factor);
112 
113 private:
114     BufferViewCaseParams m_testCase;
115 
116     const tcu::IVec2 m_renderSize;
117     const VkFormat m_colorFormat;
118 
119     const VkDeviceSize m_pixelDataSize;
120 
121     Move<VkImage> m_colorImage;
122     de::MovePtr<Allocation> m_colorImageAlloc;
123     Move<VkImageView> m_colorAttachmentView;
124     Move<VkRenderPass> m_renderPass;
125     Move<VkFramebuffer> m_framebuffer;
126 
127     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
128     Move<VkDescriptorPool> m_descriptorPool;
129     Move<VkDescriptorSet> m_descriptorSet;
130 
131     Move<VkBuffer> m_uniformBuffer;
132     de::MovePtr<vk::Allocation> m_uniformBufferAlloc;
133     Move<VkBufferView> m_uniformBufferView;
134 
135     Move<VkShaderModule> m_vertexShaderModule;
136     Move<VkShaderModule> m_fragmentShaderModule;
137 
138     Move<VkBuffer> m_vertexBuffer;
139     std::vector<tcu::Vec4> m_vertices;
140     de::MovePtr<Allocation> m_vertexBufferAlloc;
141 
142     Move<VkPipelineLayout> m_pipelineLayout;
143     Move<VkPipeline> m_graphicsPipelines;
144 
145     Move<VkCommandPool> m_cmdPool;
146     Move<VkCommandBuffer> m_cmdBuffer;
147 
148     Move<VkBuffer> m_resultBuffer;
149     de::MovePtr<Allocation> m_resultBufferAlloc;
150 };
151 
generateBuffer(std::vector<uint32_t> & uniformData,uint32_t bufferSize,int8_t factor)152 static void generateBuffer(std::vector<uint32_t> &uniformData, uint32_t bufferSize, int8_t factor)
153 {
154     for (uint32_t i = 0; i < bufferSize; ++i)
155         uniformData.push_back(factor * i);
156 }
157 
createQuad(void)158 void BufferViewTestInstance::createQuad(void)
159 {
160     tcu::Vec4 a(-1.0, -1.0, 0.0, 1.0);
161     tcu::Vec4 b(1.0, -1.0, 0.0, 1.0);
162     tcu::Vec4 c(1.0, 1.0, 0.0, 1.0);
163     tcu::Vec4 d(-1.0, 1.0, 0.0, 1.0);
164 
165     // Triangle 1
166     m_vertices.push_back(a);
167     m_vertices.push_back(c);
168     m_vertices.push_back(b);
169 
170     // Triangle 2
171     m_vertices.push_back(c);
172     m_vertices.push_back(a);
173     m_vertices.push_back(d);
174 }
175 
~BufferViewTestInstance(void)176 BufferViewTestInstance::~BufferViewTestInstance(void)
177 {
178 }
179 
BufferViewTestInstance(Context & context,BufferViewCaseParams testCase)180 BufferViewTestInstance::BufferViewTestInstance(Context &context, BufferViewCaseParams testCase)
181     : vkt::TestInstance(context)
182     , m_testCase(testCase)
183     , m_renderSize(testCase.bufferViewSize, testCase.bufferViewSize)
184     , m_colorFormat(VK_FORMAT_R32_UINT)
185     , m_pixelDataSize(m_renderSize.x() * m_renderSize.y() * mapVkFormat(m_colorFormat).getPixelSize())
186 {
187     const DeviceInterface &vk       = context.getDeviceInterface();
188     const VkDevice vkDevice         = context.getDevice();
189     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
190     SimpleAllocator memAlloc(
191         vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
192     const VkComponentMapping channelMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
193                                                    VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
194 
195     // Create color image
196     if (m_testCase.imageAllocationKind == ALLOCATION_KIND_DEDICATED)
197     {
198         ImageDedicatedAllocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage,
199                                                    MemoryRequirement::Any, m_colorImageAlloc);
200     }
201     else
202     {
203         ImageSuballocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage,
204                                              MemoryRequirement::Any, m_colorImageAlloc);
205     }
206 
207     // Create destination buffer
208     if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
209     {
210         BufferDedicatedAllocation().createTestBuffer(
211             vk, vkDevice, queueFamilyIndex, m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc,
212             m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
213     }
214     else
215     {
216         BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, m_pixelDataSize,
217                                                VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer,
218                                                MemoryRequirement::HostVisible, m_resultBufferAlloc);
219     }
220 
221     // Create color attachment view
222     {
223         const VkImageViewCreateInfo colorAttachmentViewParams = {
224             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,    // VkStructureType sType;
225             DE_NULL,                                     // const void* pNext;
226             0u,                                          // VkImageViewCreateFlags flags;
227             *m_colorImage,                               // VkImage image;
228             VK_IMAGE_VIEW_TYPE_2D,                       // VkImageViewType viewType;
229             m_colorFormat,                               // VkFormat format;
230             channelMappingRGBA,                          // VkChannelMapping channels;
231             {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}, // VkImageSubresourceRange subresourceRange;
232         };
233 
234         m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
235     }
236 
237     // Create render pass
238     m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);
239 
240     // Create framebuffer
241     {
242         const VkImageView attachmentBindInfos[1] = {
243             *m_colorAttachmentView,
244         };
245 
246         const VkFramebufferCreateInfo framebufferParams = {
247             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
248             DE_NULL,                                   // const void* pNext;
249             (VkFramebufferCreateFlags)0,
250             *m_renderPass,              // VkRenderPass renderPass;
251             1u,                         // uint32_t attachmentCount;
252             attachmentBindInfos,        // const VkImageView* pAttachments;
253             (uint32_t)m_renderSize.x(), // uint32_t width;
254             (uint32_t)m_renderSize.y(), // uint32_t height;
255             1u                          // uint32_t layers;
256         };
257 
258         m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
259     }
260 
261     // Create descriptors
262     {
263         const VkDescriptorSetLayoutBinding layoutBindings[1] = {
264             {
265                 0u,                                      // uint32_t binding;
266                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType;
267                 1u,                                      // uint32_t arraySize;
268                 VK_SHADER_STAGE_ALL,                     // VkShaderStageFlags stageFlags;
269                 DE_NULL                                  // const VkSampler* pImmutableSamplers;
270             },
271         };
272 
273         const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams = {
274             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
275             DE_NULL,                                             // const void* pNext;
276             (VkDescriptorSetLayoutCreateFlags)0,
277             DE_LENGTH_OF_ARRAY(layoutBindings), // uint32_t count;
278             layoutBindings                      // const VkDescriptorSetLayoutBinding pBinding;
279         };
280 
281         m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
282 
283         // Generate buffer
284         std::vector<uint32_t> uniformData;
285         generateBuffer(uniformData, testCase.bufferSize, 1);
286 
287         const VkDeviceSize uniformSize = testCase.bufferSize * sizeof(uint32_t);
288 
289         BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, uniformSize, testCase.createUsage,
290                                                m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible,
291                                                m_uniformBufferAlloc);
292         deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
293         flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
294 
295         const VkBufferViewCreateInfo viewInfo = {
296             VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
297             DE_NULL,                                   // void* pNext;
298             (VkBufferViewCreateFlags)0,
299             *m_uniformBuffer,                            // VkBuffer buffer;
300             m_colorFormat,                               // VkFormat format;
301             m_testCase.elementOffset * sizeof(uint32_t), // VkDeviceSize offset;
302             m_testCase.bufferViewSize * sizeof(uint32_t) // VkDeviceSize range;
303         };
304 
305         m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
306 
307         const VkDescriptorPoolSize descriptorTypes[1] = {{
308             VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType type;
309             1                                        // uint32_t count;
310         }};
311 
312         const VkDescriptorPoolCreateInfo descriptorPoolParams = {
313             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,     // VkStructureType sType;
314             DE_NULL,                                           // void* pNext;
315             VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
316             1u,                                                // uint32_t maxSets;
317             DE_LENGTH_OF_ARRAY(descriptorTypes),               // uint32_t count;
318             descriptorTypes                                    // const VkDescriptorTypeCount* pTypeCount
319         };
320 
321         m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
322 
323         const VkDescriptorSetAllocateInfo descriptorSetParams = {
324             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
325             DE_NULL,
326             *m_descriptorPool,
327             1u,
328             &m_descriptorSetLayout.get(),
329         };
330         m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
331 
332         const VkWriteDescriptorSet writeDescritporSets[] = {{
333             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,  // VkStructureType sType;
334             DE_NULL,                                 // const void* pNext;
335             *m_descriptorSet,                        // VkDescriptorSet destSet;
336             0,                                       // uint32_t destBinding;
337             0,                                       // uint32_t destArrayElement;
338             1u,                                      // uint32_t count;
339             VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType;
340             (const VkDescriptorImageInfo *)DE_NULL,
341             (const VkDescriptorBufferInfo *)DE_NULL,
342             &m_uniformBufferView.get(),
343         }};
344 
345         vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
346     }
347 
348     // Create pipeline layout
349     {
350         const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
351             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
352             DE_NULL,                                       // const void* pNext;
353             (VkPipelineLayoutCreateFlags)0,
354             1u,                      // uint32_t descriptorSetCount;
355             &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
356             0u,                      // uint32_t pushConstantRangeCount;
357             DE_NULL                  // const VkPushConstantRange* pPushConstantRanges;
358         };
359 
360         m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
361     }
362 
363     // Create shaders
364     {
365         m_vertexShaderModule   = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
366         m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
367     }
368 
369     // Create pipeline
370     {
371         const std::vector<VkViewport> viewports(1, makeViewport(m_renderSize));
372         const std::vector<VkRect2D> scissors(1, makeRect2D(m_renderSize));
373 
374         m_graphicsPipelines =
375             makeGraphicsPipeline(vk,                      // const DeviceInterface&            vk
376                                  vkDevice,                // const VkDevice                    device
377                                  *m_pipelineLayout,       // const VkPipelineLayout            pipelineLayout
378                                  *m_vertexShaderModule,   // const VkShaderModule              vertexShaderModule
379                                  DE_NULL,                 // const VkShaderModule              tessellationControlModule
380                                  DE_NULL,                 // const VkShaderModule              tessellationEvalModule
381                                  DE_NULL,                 // const VkShaderModule              geometryShaderModule
382                                  *m_fragmentShaderModule, // const VkShaderModule              fragmentShaderModule
383                                  *m_renderPass,           // const VkRenderPass                renderPass
384                                  viewports,               // const std::vector<VkViewport>&    viewports
385                                  scissors);               // const std::vector<VkRect2D>&      scissors
386     }
387 
388     // Create vertex buffer
389     {
390         createQuad();
391         const VkDeviceSize vertexDataSize = m_vertices.size() * sizeof(tcu::Vec4);
392 
393         BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, vertexDataSize,
394                                                VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, m_context, memAlloc, m_vertexBuffer,
395                                                MemoryRequirement::HostVisible, m_vertexBufferAlloc);
396 
397         // Load vertices into vertex buffer
398         deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), (size_t)vertexDataSize);
399         flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
400     }
401 
402     // Create command pool
403     m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
404 
405     // Create command buffer
406     {
407         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
408 
409         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
410 
411         const VkImageMemoryBarrier initialImageBarrier = {
412             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // VkStructureType sType;
413             DE_NULL,                                  // const void* pNext;
414             0,                                        // VkAccessFlags srcAccessMask;
415             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     // VkAccessFlags dstAccessMask;
416             VK_IMAGE_LAYOUT_UNDEFINED,                // VkImageLayout oldLayout;
417             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
418             VK_QUEUE_FAMILY_IGNORED,                  // uint32_t srcQueueFamilyIndex;
419             VK_QUEUE_FAMILY_IGNORED,                  // uint32_t destQueueFamilyIndex;
420             *m_colorImage,                            // VkImage image;
421             {
422                 // VkImageSubresourceRange subresourceRange;
423                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
424                 0u,                        // uint32_t baseMipLevel;
425                 1u,                        // uint32_t mipLevels;
426                 0u,                        // uint32_t baseArraySlice;
427                 1u                         // uint32_t arraySize;
428             }};
429 
430         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
431                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0,
432                               (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
433                               &initialImageBarrier);
434 
435         beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer,
436                         makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
437 
438         const VkDeviceSize vertexBufferOffset[1] = {0};
439 
440         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
441         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1,
442                                  &*m_descriptorSet, 0u, DE_NULL);
443         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), vertexBufferOffset);
444         vk.cmdDraw(*m_cmdBuffer, (uint32_t)m_vertices.size(), 1, 0, 0);
445         endRenderPass(vk, *m_cmdBuffer);
446         copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, m_renderSize);
447         endCommandBuffer(vk, *m_cmdBuffer);
448     }
449 }
450 
checkResult(int8_t factor)451 tcu::TestStatus BufferViewTestInstance::checkResult(int8_t factor)
452 {
453     const DeviceInterface &vk          = m_context.getDeviceInterface();
454     const VkDevice vkDevice            = m_context.getDevice();
455     const tcu::TextureFormat tcuFormat = mapVkFormat(m_colorFormat);
456     de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(tcuFormat, m_renderSize.x(), m_renderSize.y()));
457 
458     invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
459     tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(),
460                                                         m_resultBufferAlloc->getHostPtr()));
461 
462     tcu::ConstPixelBufferAccess pixelBuffer = resultLevel->getAccess();
463     for (int32_t i = 0; i < (int32_t)m_renderSize.x(); ++i)
464     {
465         tcu::IVec4 pixel = pixelBuffer.getPixelInt(i, i);
466         int32_t expected = factor * (m_testCase.elementOffset + i);
467         int32_t actual   = pixel[0];
468         if (expected != actual)
469         {
470             std::ostringstream errorMessage;
471             errorMessage << "BufferView test failed. expected: " << expected << " actual: " << actual;
472             return tcu::TestStatus::fail(errorMessage.str());
473         }
474     }
475 
476     return tcu::TestStatus::pass("BufferView test");
477 }
478 
iterate(void)479 tcu::TestStatus BufferViewTestInstance::iterate(void)
480 {
481     const DeviceInterface &vk = m_context.getDeviceInterface();
482     const VkDevice vkDevice   = m_context.getDevice();
483     const VkQueue queue       = m_context.getUniversalQueue();
484 
485     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
486 
487     tcu::TestStatus testStatus = checkResult(1);
488     if (testStatus.getCode() != QP_TEST_RESULT_PASS)
489         return testStatus;
490 
491     // Generate and bind another buffer
492     std::vector<uint32_t> uniformData;
493     const VkDeviceSize uniformSize = m_testCase.bufferSize * sizeof(uint32_t);
494     const int8_t factor            = 2;
495 
496     generateBuffer(uniformData, m_testCase.bufferSize, factor);
497     deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
498     flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
499 
500     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
501 
502     return checkResult(factor);
503 }
504 
505 class BufferViewTestCase : public vkt::TestCase
506 {
507 public:
BufferViewTestCase(tcu::TestContext & testCtx,const std::string & name,BufferViewCaseParams bufferViewTestInfo)508     BufferViewTestCase(tcu::TestContext &testCtx, const std::string &name, BufferViewCaseParams bufferViewTestInfo)
509         : vkt::TestCase(testCtx, name)
510         , m_bufferViewTestInfo(bufferViewTestInfo)
511     {
512     }
513 
~BufferViewTestCase(void)514     virtual ~BufferViewTestCase(void)
515     {
516     }
517     virtual void initPrograms(SourceCollections &programCollection) const;
518 
createInstance(Context & context) const519     virtual TestInstance *createInstance(Context &context) const
520     {
521         return new BufferViewTestInstance(context, m_bufferViewTestInfo);
522     }
523 
524 private:
525     BufferViewCaseParams m_bufferViewTestInfo;
526 };
527 
initPrograms(SourceCollections & programCollection) const528 void BufferViewTestCase::initPrograms(SourceCollections &programCollection) const
529 {
530     programCollection.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
531                                                                    "layout (location = 0) in highp vec4 a_position;\n"
532                                                                    "void main()\n"
533                                                                    "{\n"
534                                                                    "    gl_Position = a_position;\n"
535                                                                    "}\n");
536 
537     programCollection.glslSources.add("frag")
538         << glu::FragmentSource("#version 310 es\n"
539                                "#extension GL_EXT_texture_buffer : enable\n"
540                                "layout (set=0, binding=0) uniform highp utextureBuffer u_buffer;\n"
541                                "layout (location = 0) out highp uint o_color;\n"
542                                "void main()\n"
543                                "{\n"
544                                "    o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
545                                "}\n");
546 }
547 
548 class BufferViewAllFormatsTestInstance : public vkt::TestInstance
549 {
550 public:
551     BufferViewAllFormatsTestInstance(Context &context, BufferViewCaseParams testCase);
552     virtual ~BufferViewAllFormatsTestInstance(void);
553     virtual tcu::TestStatus iterate(void);
554 
555 private:
556     void checkTexelBufferSupport(Context &context, VkFormat format, BufferViewCaseParams testCase);
557     int getFetchPos(int fetchPosNdx);
558     tcu::TestStatus checkResult();
559     tcu::TestStatus checkResultFloat();
560     void populateSourceBuffer(const tcu::PixelBufferAccess &access, uint32_t bufferNdx);
561 
562 private:
563     enum
564     {
565         // some arbitrary points
566         SAMPLE_POINT_0 = 6,
567         SAMPLE_POINT_1 = 51,
568         SAMPLE_POINT_2 = 42,
569         SAMPLE_POINT_3 = 25,
570     };
571 
572     BufferViewCaseParams m_testCase;
573     const VkFormat m_bufferFormat;
574 
575     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
576     Move<VkDescriptorPool> m_descriptorPool;
577     Move<VkDescriptorSet> m_descriptorSet;
578 
579     Move<VkBuffer> m_uniformBuffer;
580     de::MovePtr<vk::Allocation> m_uniformBufferAlloc;
581     Move<VkBufferView> m_uniformBufferView;
582     Move<VkShaderModule> m_computeShaderModule;
583     Move<VkPipelineLayout> m_pipelineLayout;
584     Move<VkPipeline> m_computePipeline;
585 
586     Move<VkCommandPool> m_cmdPool;
587     Move<VkCommandBuffer> m_cmdBuffer;
588 
589     Move<VkBuffer> m_resultBuffer;
590     de::MovePtr<Allocation> m_resultBufferAlloc;
591 
592     de::ArrayBuffer<uint8_t> m_sourceBuffer;
593     tcu::ConstPixelBufferAccess m_sourceView;
594 };
595 
checkTexelBufferSupport(Context & context,VkFormat format,BufferViewCaseParams testCase)596 void BufferViewAllFormatsTestInstance::checkTexelBufferSupport(Context &context, VkFormat format,
597                                                                BufferViewCaseParams testCase)
598 {
599     const InstanceInterface &vki          = context.getInstanceInterface();
600     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
601 
602     VkFormatProperties properties;
603     properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
604 
605     if (!(properties.bufferFeatures & testCase.feature))
606         TCU_THROW(NotSupportedError, "Format not supported");
607 
608 #ifndef CTS_USES_VULKANSC
609     if (testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
610     {
611         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
612             TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance5 not supported");
613     }
614 #endif
615 }
616 
~BufferViewAllFormatsTestInstance(void)617 BufferViewAllFormatsTestInstance::~BufferViewAllFormatsTestInstance(void)
618 {
619 }
620 
621 /* Taken from BindingShaderAccessTests.cpp */
populateSourceBuffer(const tcu::PixelBufferAccess & access,uint32_t bufferNdx)622 void BufferViewAllFormatsTestInstance::populateSourceBuffer(const tcu::PixelBufferAccess &access, uint32_t bufferNdx)
623 {
624     DE_ASSERT(access.getHeight() == 1);
625     DE_ASSERT(access.getDepth() == 1);
626 
627     const int32_t width = access.getWidth();
628 
629     for (int x = 0; x < width; ++x)
630     {
631         int red   = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
632         int green = ((x % 2 == 0) ? (127) : (0)) +
633                     ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
634         int blue = 16 * (x % 16);                //!< 16-long triangle wave
635 
636         DE_ASSERT(de::inRange(red, 0, 255));
637         DE_ASSERT(de::inRange(green, 0, 255));
638         DE_ASSERT(de::inRange(blue, 0, 255));
639 
640         if (bufferNdx % 2 == 0)
641             red = 255 - red;
642         if (bufferNdx % 3 == 0)
643             green = 255 - green;
644         if (bufferNdx % 4 == 0)
645             blue = 255 - blue;
646 
647         access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
648     }
649 }
650 
BufferViewAllFormatsTestInstance(Context & context,BufferViewCaseParams testCase)651 BufferViewAllFormatsTestInstance::BufferViewAllFormatsTestInstance(Context &context, BufferViewCaseParams testCase)
652     : vkt::TestInstance(context)
653     , m_testCase(testCase)
654     , m_bufferFormat(testCase.format)
655 {
656     const DeviceInterface &vk       = context.getDeviceInterface();
657     const VkDevice vkDevice         = context.getDevice();
658     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
659     SimpleAllocator memAlloc(
660         vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
661 
662     checkTexelBufferSupport(context, m_bufferFormat, testCase);
663 
664     // Create a result buffer
665     BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sizeof(tcu::Vec4[4]),
666                                            VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, m_context, memAlloc, m_resultBuffer,
667                                            MemoryRequirement::HostVisible, m_resultBufferAlloc);
668 
669     // Create descriptors
670     {
671         const VkDescriptorSetLayoutBinding layoutBindings[2] = {
672             {
673                 0u,                                // uint32_t binding;
674                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
675                 1u,                                // uint32_t arraySize;
676                 VK_SHADER_STAGE_COMPUTE_BIT,       // VkShaderStageFlags stageFlags;
677                 DE_NULL                            // const VkSampler* pImmutableSamplers;
678             },
679             {
680                 1u,                          // uint32_t binding;
681                 testCase.descType,           // VkDescriptorType descriptorType;
682                 1u,                          // uint32_t arraySize;
683                 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
684                 DE_NULL                      // const VkSampler* pImmutableSamplers;
685             },
686         };
687 
688         const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams = {
689             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
690             DE_NULL,                                             // const void* pNext;
691             (VkDescriptorSetLayoutCreateFlags)0,
692             DE_LENGTH_OF_ARRAY(layoutBindings), // uint32_t count;
693             layoutBindings                      // const VkDescriptorSetLayoutBinding pBinding;
694         };
695 
696         m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
697 
698         // Generate buffer
699         const tcu::TextureFormat tcuFormat = mapVkFormat(m_bufferFormat);
700 
701         de::ArrayBuffer<uint8_t> sourceBuffer(testCase.bufferSize);
702         populateSourceBuffer(tcu::PixelBufferAccess(tcuFormat,
703                                                     tcu::IVec3(testCase.bufferSize / tcuFormat.getPixelSize(), 1, 1),
704                                                     sourceBuffer.getPtr()),
705                              0);
706 
707         m_sourceBuffer = sourceBuffer;
708         m_sourceView   = tcu::ConstPixelBufferAccess(tcuFormat, tcu::IVec3(64, 1, 1), m_sourceBuffer.getPtr());
709 
710         BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sourceBuffer.size(),
711                                                testCase.createUsage, m_context, memAlloc, m_uniformBuffer,
712                                                MemoryRequirement::HostVisible, m_uniformBufferAlloc);
713         deMemcpy(m_uniformBufferAlloc->getHostPtr(), sourceBuffer.getPtr(), sourceBuffer.size());
714         flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
715 
716         VkBufferViewCreateInfo viewInfo = {
717             VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
718             DE_NULL,                                   // void* pNext;
719             (VkBufferViewCreateFlags)0,
720             *m_uniformBuffer,         // VkBuffer buffer;
721             m_bufferFormat,           // VkFormat format;
722             m_testCase.elementOffset, // VkDeviceSize offset;
723             VK_WHOLE_SIZE             // VkDeviceSize range;
724         };
725 
726 #ifndef CTS_USES_VULKANSC
727         VkBufferUsageFlags2CreateInfoKHR bindUsageInfo;
728         if (testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
729         {
730             bindUsageInfo.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR; // VkStructureType sType;
731             bindUsageInfo.pNext = DE_NULL;                                                // const void* pNext;
732             bindUsageInfo.usage = testCase.bindUsage; // VkBufferUsageFlags2KHR usage;
733 
734             viewInfo.pNext = &bindUsageInfo;
735         }
736 #endif
737 
738         m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
739 
740         const VkDescriptorPoolSize descriptorTypes[2] = {
741             {
742                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType type;
743                 1                                  // uint32_t count;
744             },
745             {
746                 testCase.descType, // VkDescriptorType type;
747                 1                  // uint32_t count;
748             }};
749 
750         const VkDescriptorPoolCreateInfo descriptorPoolParams = {
751             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,     // VkStructureType sType;
752             DE_NULL,                                           // void* pNext;
753             VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
754             1u,                                                // uint32_t maxSets;
755             DE_LENGTH_OF_ARRAY(descriptorTypes),               // uint32_t count;
756             descriptorTypes                                    // const VkDescriptorTypeCount* pTypeCount
757         };
758 
759         m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
760 
761         const VkDescriptorSetAllocateInfo descriptorSetParams = {
762             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
763             DE_NULL,
764             *m_descriptorPool,
765             1u,
766             &m_descriptorSetLayout.get(),
767         };
768         m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
769 
770         const VkDescriptorBufferInfo outBufferInfo = {m_resultBuffer.get(), 0, sizeof(tcu::Vec4[4])};
771 
772         const VkWriteDescriptorSet writeDescritporSets[] = {
773             {
774                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
775                 DE_NULL,                                // const void* pNext;
776                 *m_descriptorSet,                       // VkDescriptorSet destSet;
777                 0,                                      // uint32_t destBinding;
778                 0,                                      // uint32_t destArrayElement;
779                 1u,                                     // uint32_t count;
780                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType descriptorType;
781                 (const VkDescriptorImageInfo *)DE_NULL,
782                 &outBufferInfo,
783                 (const VkBufferView *)DE_NULL,
784             },
785             {
786                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
787                 DE_NULL,                                // const void* pNext;
788                 *m_descriptorSet,                       // VkDescriptorSet destSet;
789                 1,                                      // uint32_t destBinding;
790                 0,                                      // uint32_t destArrayElement;
791                 1u,                                     // uint32_t count;
792                 testCase.descType,                      // VkDescriptorType descriptorType;
793                 (const VkDescriptorImageInfo *)DE_NULL,
794                 (const VkDescriptorBufferInfo *)DE_NULL,
795                 &m_uniformBufferView.get(),
796             }};
797 
798         vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
799     }
800 
801     // Create pipeline layout
802     {
803         const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
804             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
805             DE_NULL,                                       // const void* pNext;
806             (VkPipelineLayoutCreateFlags)0,
807             1u,                      // uint32_t descriptorSetCount;
808             &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
809             0u,                      // uint32_t pushConstantRangeCount;
810             DE_NULL                  // const VkPushConstantRange* pPushConstantRanges;
811         };
812 
813         m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
814     }
815 
816     // Create shaders
817     {
818         m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("comp"), 0);
819     }
820 
821     // Create pipeline
822     {
823         m_computePipeline = makeComputePipeline(vk, vkDevice, m_pipelineLayout.get(), m_computeShaderModule.get());
824     }
825 
826     // Create command pool
827     m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
828 
829     // Create and record a command buffer
830     {
831         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
832 
833         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
834 
835         vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
836         vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u,
837                                  &*m_descriptorSet, 0u, nullptr);
838 
839         const vk::VkBufferMemoryBarrier barrier = {
840             vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
841             DE_NULL,
842             vk::VK_ACCESS_HOST_WRITE_BIT,   // srcAccessMask
843             vk::VK_ACCESS_UNIFORM_READ_BIT, // dstAccessMask
844             VK_QUEUE_FAMILY_IGNORED,        // srcQueueFamilyIndex
845             VK_QUEUE_FAMILY_IGNORED,        // destQueueFamilyIndex
846             *m_resultBuffer,                // buffer
847             0u,                             // offset
848             sizeof(tcu::Vec4[4]),           // size
849         };
850         const vk::VkBufferMemoryBarrier bufferBarrier = {
851             vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
852             DE_NULL,
853             vk::VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
854             vk::VK_ACCESS_HOST_READ_BIT,    // dstAccessMask
855             VK_QUEUE_FAMILY_IGNORED,        // srcQueueFamilyIndex
856             VK_QUEUE_FAMILY_IGNORED,        // destQueueFamilyIndex
857             *m_resultBuffer,                // buffer
858             (vk::VkDeviceSize)0u,           // offset
859             sizeof(tcu::Vec4[4]),           // size
860         };
861 
862         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u,
863                               nullptr, 0u, &barrier, 0u, nullptr);
864         //vk.cmdDispatch(*m_cmdBuffer, 1u, 1u, 1u);
865         vk.cmdDispatch(*m_cmdBuffer, 4u, 1u, 1u);
866         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
867                               nullptr, 1u, &bufferBarrier, 0u, nullptr);
868         endCommandBuffer(vk, *m_cmdBuffer);
869     }
870 }
871 
getFetchPos(int fetchPosNdx)872 int BufferViewAllFormatsTestInstance::getFetchPos(int fetchPosNdx)
873 {
874     static const int fetchPositions[4] = {
875         SAMPLE_POINT_0,
876         SAMPLE_POINT_1,
877         SAMPLE_POINT_2,
878         SAMPLE_POINT_3,
879     };
880 
881     return fetchPositions[fetchPosNdx];
882 }
883 
checkResult()884 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResult()
885 {
886     const DeviceInterface &vk = m_context.getDeviceInterface();
887     const VkDevice vkDevice   = m_context.getDevice();
888     bool allResultsOk         = true;
889 
890     tcu::UVec4 results[4];
891     invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
892     deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::UVec4[4]));
893 
894     // verify
895     for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
896     {
897         const tcu::UVec4 result              = results[resultNdx];
898         const tcu::UVec4 conversionThreshold = tcu::UVec4(0);
899         tcu::UVec4 reference                 = tcu::UVec4(0);
900 
901         reference += m_sourceView.getPixelUint(getFetchPos(resultNdx), 0, 0);
902 
903         if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
904         {
905             allResultsOk = false;
906 
907             m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test sample " << resultNdx << ": Expected "
908                                                 << reference << ", got " << result << tcu::TestLog::EndMessage;
909         }
910     }
911 
912     if (allResultsOk)
913         return tcu::TestStatus::pass("Pass");
914     else
915         return tcu::TestStatus::fail("Invalid result values");
916 }
917 
checkResultFloat()918 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResultFloat()
919 {
920     const DeviceInterface &vk = m_context.getDeviceInterface();
921     const VkDevice vkDevice   = m_context.getDevice();
922     bool allResultsOk         = true;
923 
924     tcu::Vec4 results[4];
925     invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
926     deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::Vec4[4]));
927 
928     // verify
929     for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
930     {
931         const tcu::Vec4 result              = results[resultNdx];
932         const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
933         tcu::Vec4 reference                 = tcu::Vec4(0.0f);
934 
935         reference += m_sourceView.getPixel(getFetchPos(resultNdx), 0, 0);
936 
937         if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
938         {
939             allResultsOk = false;
940 
941             m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test sample " << resultNdx << ": Expected "
942                                                 << reference << ", got " << result << tcu::TestLog::EndMessage;
943         }
944     }
945 
946     if (allResultsOk)
947         return tcu::TestStatus::pass("Pass");
948     else
949         return tcu::TestStatus::fail("Invalid result values");
950 }
951 
iterate(void)952 tcu::TestStatus BufferViewAllFormatsTestInstance::iterate(void)
953 {
954     const DeviceInterface &vk = m_context.getDeviceInterface();
955     const VkDevice vkDevice   = m_context.getDevice();
956     const VkQueue queue       = m_context.getUniversalQueue();
957 
958     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
959 
960     if (isIntFormat(m_bufferFormat) || isUintFormat(m_bufferFormat))
961         return checkResult();
962     else
963         return checkResultFloat();
964 }
965 
966 class BufferViewAllFormatsTestCase : public vkt::TestCase
967 {
968 public:
BufferViewAllFormatsTestCase(tcu::TestContext & testCtx,const std::string & name,BufferViewCaseParams bufferViewTestInfo)969     BufferViewAllFormatsTestCase(tcu::TestContext &testCtx, const std::string &name,
970                                  BufferViewCaseParams bufferViewTestInfo)
971         : vkt::TestCase(testCtx, name)
972         , m_bufferViewTestInfo(bufferViewTestInfo)
973     {
974     }
975 
~BufferViewAllFormatsTestCase(void)976     virtual ~BufferViewAllFormatsTestCase(void)
977     {
978     }
979     virtual void initPrograms(SourceCollections &programCollection) const;
checkSupport(Context & context) const980     virtual void checkSupport(Context &context) const
981     {
982         const InstanceInterface &vki          = context.getInstanceInterface();
983         const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
984 
985 #ifndef CTS_USES_VULKANSC
986         if ((m_bufferViewTestInfo.format == VK_FORMAT_A8_UNORM_KHR) ||
987             (m_bufferViewTestInfo.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR))
988             context.requireDeviceFunctionality("VK_KHR_maintenance5");
989 #endif // CTS_USES_VULKANSC
990 
991         if ((m_bufferViewTestInfo.createUsage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) != 0)
992         {
993             VkFormatProperties properties;
994             properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, m_bufferViewTestInfo.format);
995             if ((properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) == 0)
996             {
997                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT not supported for format");
998             }
999         }
1000     }
1001 
createInstance(Context & context) const1002     virtual TestInstance *createInstance(Context &context) const
1003     {
1004         return new BufferViewAllFormatsTestInstance(context, m_bufferViewTestInfo);
1005     }
1006 
1007 private:
1008     BufferViewCaseParams m_bufferViewTestInfo;
1009 };
1010 
strLayoutFormat(VkFormat format)1011 const std::string strLayoutFormat(VkFormat format)
1012 {
1013     std::ostringstream buf;
1014 
1015     buf << ", " << image::getShaderImageFormatQualifier(mapVkFormat(format)).c_str();
1016 
1017     return buf.str();
1018 }
1019 
initPrograms(SourceCollections & programCollection) const1020 void BufferViewAllFormatsTestCase::initPrograms(SourceCollections &programCollection) const
1021 {
1022     std::ostringstream buf;
1023 
1024     const bool isIntFmt  = isIntFormat(m_bufferViewTestInfo.format);
1025     const bool isUintFmt = isUintFormat(m_bufferViewTestInfo.format);
1026 
1027     bool isUniform;
1028     if (m_bufferViewTestInfo.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
1029     {
1030         isUniform = m_bufferViewTestInfo.bindUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false;
1031     }
1032     else
1033     {
1034         isUniform = m_bufferViewTestInfo.createUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false;
1035     }
1036     const char *const storageType     = isUniform ? "textureBuffer " : "imageBuffer ";
1037     const char *const extraOption     = isUniform ? "" : "readonly ";
1038     const std::string stringFmtLayout = isUniform ? "" : strLayoutFormat(m_bufferViewTestInfo.format);
1039     const char *const fmtLayout       = isUniform ? "" : stringFmtLayout.c_str();
1040     const char *const opName          = isUniform ? "texelFetch" : "imageLoad";
1041     const char *const outFormat       = isIntFmt ? "i" : isUintFmt ? "u" : "";
1042     const char *const inFormat        = vk::isScaledFormat(m_bufferViewTestInfo.format) ? "" : outFormat;
1043 
1044     buf << "#version 440\n"
1045         << "#extension GL_EXT_texture_buffer : require\n"
1046         << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1047         << "layout(set = 0, binding = 1" << fmtLayout << ") uniform highp " << extraOption << inFormat << storageType
1048         << " texelBuffer;\n"
1049         << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
1050         << "{\n"
1051         << "    highp " << outFormat << "vec4 read_colors[4];\n"
1052         << "} b_out;\n"
1053         << "void main (void)\n"
1054         << "{\n"
1055         << "    highp int quadrant_id = int(gl_WorkGroupID.x);\n"
1056         << "    highp " << outFormat << "vec4 result_color;\n"
1057         << "    result_color = " << outFormat << "vec4(0);\n"
1058         << "    if (quadrant_id == 0)\n"
1059         << "        result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 6));\n"
1060         << "    else if (quadrant_id == 1)\n"
1061         << "        result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 51));\n"
1062         << "    else if (quadrant_id == 2)\n"
1063         << "        result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 42));\n"
1064         << "    else\n"
1065         << "        result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 25));\n"
1066         << "    b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
1067         << "}\n";
1068 
1069     programCollection.glslSources.add("comp") << glu::ComputeSource(buf.str());
1070 }
1071 
1072 } // namespace
1073 
isSupportedImageLoadStore(const tcu::TextureFormat & format)1074 bool isSupportedImageLoadStore(const tcu::TextureFormat &format)
1075 {
1076     if (!image::isPackedType(mapTextureFormat(format)))
1077     {
1078         switch (format.order)
1079         {
1080         case tcu::TextureFormat::RGBA:
1081             break;
1082         default:
1083             return false;
1084         }
1085 
1086         switch (format.type)
1087         {
1088         case tcu::TextureFormat::FLOAT:
1089         case tcu::TextureFormat::HALF_FLOAT:
1090 
1091         case tcu::TextureFormat::UNSIGNED_INT32:
1092         case tcu::TextureFormat::UNSIGNED_INT16:
1093         case tcu::TextureFormat::UNSIGNED_INT8:
1094 
1095         case tcu::TextureFormat::SIGNED_INT32:
1096         case tcu::TextureFormat::SIGNED_INT16:
1097         case tcu::TextureFormat::SIGNED_INT8:
1098 
1099         case tcu::TextureFormat::UNORM_INT16:
1100         case tcu::TextureFormat::UNORM_INT8:
1101 
1102         case tcu::TextureFormat::SNORM_INT16:
1103         case tcu::TextureFormat::SNORM_INT8:
1104             break;
1105 
1106         default:
1107             return false;
1108         }
1109     }
1110     else
1111     {
1112         switch (mapTextureFormat(format))
1113         {
1114         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1115         case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1116             break;
1117 
1118         default:
1119             return false;
1120         }
1121     }
1122 
1123     return true;
1124 }
1125 
createBufferViewAccessTests(tcu::TestContext & testCtx)1126 tcu::TestCaseGroup *createBufferViewAccessTests(tcu::TestContext &testCtx)
1127 {
1128     const char *const bufferTexts[ALLOCATION_KIND_LAST] = {"buffer_suballocated", "buffer_dedicated_alloc"};
1129 
1130     const char *const imageTexts[ALLOCATION_KIND_LAST] = {"image_suballocated", "image_dedicated_alloc"};
1131 
1132     de::MovePtr<tcu::TestCaseGroup> bufferViewTests(new tcu::TestCaseGroup(testCtx, "access"));
1133     de::MovePtr<tcu::TestCaseGroup> bufferViewAllocationGroupTests[] = {
1134         // BufferView Access Tests for Suballocated Objects
1135         de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation")),
1136         // BufferView Access Tests for Dedicatedly Allocated Objects
1137         de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc"))};
1138 
1139     for (uint32_t buffersAllocationNdx = 0u; buffersAllocationNdx < ALLOCATION_KIND_LAST; ++buffersAllocationNdx)
1140         for (uint32_t imageAllocationNdx = 0u; imageAllocationNdx < ALLOCATION_KIND_LAST; ++imageAllocationNdx)
1141         {
1142             const uint32_t testCaseGroupNdx = (buffersAllocationNdx == 0u && imageAllocationNdx == 0u) ? 0u : 1u;
1143             de::MovePtr<tcu::TestCaseGroup> &currentTestsGroup = bufferViewAllocationGroupTests[testCaseGroupNdx];
1144             {
1145                 const BufferViewCaseParams info = {512, // uint32_t                    bufferSize
1146                                                    512, // uint32_t                    bufferViewSize
1147                                                    0,   // uint32_t                    elementOffset
1148                                                    static_cast<AllocationKind>(buffersAllocationNdx),
1149                                                    static_cast<AllocationKind>(imageAllocationNdx)};
1150                 std::ostringstream name;
1151                 name << "buffer_view_memory_test_complete";
1152                 if (testCaseGroupNdx != 0)
1153                     name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1154                 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1155             }
1156 
1157             {
1158                 const BufferViewCaseParams info = {4096, // uint32_t                    bufferSize
1159                                                    512,  // uint32_t                    bufferViewSize
1160                                                    0,    // uint32_t                    elementOffset
1161                                                    static_cast<AllocationKind>(buffersAllocationNdx),
1162                                                    static_cast<AllocationKind>(imageAllocationNdx)};
1163                 std::ostringstream name;
1164                 name << "buffer_view_memory_test_partial_offset0";
1165                 if (testCaseGroupNdx != 0)
1166                     name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1167                 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1168             }
1169 
1170             {
1171                 const BufferViewCaseParams info = {4096, // uint32_t                    bufferSize
1172                                                    512,  // uint32_t                    bufferViewSize
1173                                                    128,  // uint32_t                    elementOffset
1174                                                    static_cast<AllocationKind>(buffersAllocationNdx),
1175                                                    static_cast<AllocationKind>(imageAllocationNdx)};
1176                 std::ostringstream name;
1177                 name << "buffer_view_memory_test_partial_offset1";
1178                 if (testCaseGroupNdx != 0)
1179                     name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1180                 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1181             }
1182         }
1183 
1184     for (uint32_t subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
1185     {
1186         bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
1187     }
1188 
1189     VkFormat testFormats[] = {
1190         VK_FORMAT_R4G4_UNORM_PACK8,
1191         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1192         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1193         VK_FORMAT_R5G6B5_UNORM_PACK16,
1194         VK_FORMAT_B5G6R5_UNORM_PACK16,
1195         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1196         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1197         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1198 #ifndef CTS_USES_VULKANSC
1199         VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
1200 #endif // CTS_USES_VULKANSC
1201         VK_FORMAT_R8_UNORM,
1202         VK_FORMAT_R8_SNORM,
1203         VK_FORMAT_R8_USCALED,
1204         VK_FORMAT_R8_SSCALED,
1205         VK_FORMAT_R8_UINT,
1206         VK_FORMAT_R8_SINT,
1207 #ifndef CTS_USES_VULKANSC
1208         VK_FORMAT_A8_UNORM_KHR,
1209 #endif // CTS_USES_VULKANSC
1210         VK_FORMAT_R8G8_UNORM,
1211         VK_FORMAT_R8G8_SNORM,
1212         VK_FORMAT_R8G8_USCALED,
1213         VK_FORMAT_R8G8_SSCALED,
1214         VK_FORMAT_R8G8_UINT,
1215         VK_FORMAT_R8G8_SINT,
1216         VK_FORMAT_R8G8B8_UNORM,
1217         VK_FORMAT_R8G8B8_SNORM,
1218         VK_FORMAT_R8G8B8_USCALED,
1219         VK_FORMAT_R8G8B8_SSCALED,
1220         VK_FORMAT_R8G8B8_UINT,
1221         VK_FORMAT_R8G8B8_SINT,
1222         VK_FORMAT_B8G8R8_UNORM,
1223         VK_FORMAT_B8G8R8_SNORM,
1224         VK_FORMAT_B8G8R8_USCALED,
1225         VK_FORMAT_B8G8R8_SSCALED,
1226         VK_FORMAT_B8G8R8_UINT,
1227         VK_FORMAT_B8G8R8_SINT,
1228         VK_FORMAT_R8G8B8A8_UNORM,
1229         VK_FORMAT_R8G8B8A8_SNORM,
1230         VK_FORMAT_R8G8B8A8_USCALED,
1231         VK_FORMAT_R8G8B8A8_SSCALED,
1232         VK_FORMAT_R8G8B8A8_UINT,
1233         VK_FORMAT_R8G8B8A8_SINT,
1234         VK_FORMAT_B8G8R8A8_UNORM,
1235         VK_FORMAT_B8G8R8A8_SNORM,
1236         VK_FORMAT_B8G8R8A8_USCALED,
1237         VK_FORMAT_B8G8R8A8_SSCALED,
1238         VK_FORMAT_B8G8R8A8_UINT,
1239         VK_FORMAT_B8G8R8A8_SINT,
1240         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1241         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1242         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1243         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1244         VK_FORMAT_A8B8G8R8_UINT_PACK32,
1245         VK_FORMAT_A8B8G8R8_SINT_PACK32,
1246         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1247         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1248         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1249         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1250         VK_FORMAT_A2R10G10B10_UINT_PACK32,
1251         VK_FORMAT_A2R10G10B10_SINT_PACK32,
1252         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1253         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1254         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1255         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1256         VK_FORMAT_A2B10G10R10_UINT_PACK32,
1257         VK_FORMAT_A2B10G10R10_SINT_PACK32,
1258         VK_FORMAT_R16_UNORM,
1259         VK_FORMAT_R16_SNORM,
1260         VK_FORMAT_R16_USCALED,
1261         VK_FORMAT_R16_SSCALED,
1262         VK_FORMAT_R16_UINT,
1263         VK_FORMAT_R16_SINT,
1264         VK_FORMAT_R16_SFLOAT,
1265         VK_FORMAT_R16G16_UNORM,
1266         VK_FORMAT_R16G16_SNORM,
1267         VK_FORMAT_R16G16_USCALED,
1268         VK_FORMAT_R16G16_SSCALED,
1269         VK_FORMAT_R16G16_UINT,
1270         VK_FORMAT_R16G16_SINT,
1271         VK_FORMAT_R16G16_SFLOAT,
1272         VK_FORMAT_R16G16B16_UNORM,
1273         VK_FORMAT_R16G16B16_SNORM,
1274         VK_FORMAT_R16G16B16_USCALED,
1275         VK_FORMAT_R16G16B16_SSCALED,
1276         VK_FORMAT_R16G16B16_UINT,
1277         VK_FORMAT_R16G16B16_SINT,
1278         VK_FORMAT_R16G16B16_SFLOAT,
1279         VK_FORMAT_R16G16B16A16_UNORM,
1280         VK_FORMAT_R16G16B16A16_SNORM,
1281         VK_FORMAT_R16G16B16A16_USCALED,
1282         VK_FORMAT_R16G16B16A16_SSCALED,
1283         VK_FORMAT_R16G16B16A16_UINT,
1284         VK_FORMAT_R16G16B16A16_SINT,
1285         VK_FORMAT_R16G16B16A16_SFLOAT,
1286         VK_FORMAT_R32_UINT,
1287         VK_FORMAT_R32_SINT,
1288         VK_FORMAT_R32_SFLOAT,
1289         VK_FORMAT_R32G32_UINT,
1290         VK_FORMAT_R32G32_SINT,
1291         VK_FORMAT_R32G32_SFLOAT,
1292     };
1293 
1294     {
1295         const char *const usageName[]              = {"uniform_texel_buffer", "storage_texel_buffer"};
1296         const vk::VkBufferUsageFlags createUsage[] = {vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
1297                                                       vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT};
1298         const vk::VkBufferUsageFlags bindUsage[]   = {vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM,
1299                                                       vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM};
1300         const vk::VkFormatFeatureFlags feature[]   = {vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
1301                                                       vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT};
1302         const vk::VkDescriptorType descType[]      = {vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
1303                                                       vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER};
1304 
1305         for (uint32_t usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(createUsage); ++usageNdx)
1306         {
1307             de::MovePtr<tcu::TestCaseGroup> usageGroup(new tcu::TestCaseGroup(testCtx, usageName[usageNdx]));
1308 
1309             for (uint32_t formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++)
1310             {
1311                 const auto skip = strlen("VK_FORMAT_");
1312                 const std::string fmtName =
1313                     de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip));
1314 
1315                 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, fmtName.c_str()));
1316 
1317                 if (createUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT &&
1318                     !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx])))
1319                     continue;
1320 
1321                 const BufferViewCaseParams info = {
1322                     512,                           // uint32_t                    bufferSize
1323                     128,                           // uint32_t                    bufferViewSize
1324                     0,                             // uint32_t                    elementOffset
1325                     ALLOCATION_KIND_SUBALLOCATION, // AllocationKind            bufferAllocationKind
1326                     ALLOCATION_KIND_SUBALLOCATION, // AllocationKind            imageAllocationKind
1327 
1328                     testFormats[formatIdx], // VkFormat                    format
1329                     createUsage[usageNdx],  // VkBufferUsageFlags        createUsage
1330                     bindUsage[usageNdx],    // VkBufferUsageFlags        bindUsage
1331                     feature[usageNdx],      // VkFormatFeatureFlags2KHR    feature
1332                     descType[usageNdx],     // VkDescriptorType            descType
1333                 };
1334 
1335                 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info));
1336             }
1337 
1338             bufferViewTests->addChild(usageGroup.release());
1339         }
1340     }
1341 
1342 #ifndef CTS_USES_VULKANSC
1343     de::MovePtr<tcu::TestCaseGroup> uniformStorageGroup(
1344         new tcu::TestCaseGroup(testCtx, "uniform_storage_texel_buffer"));
1345     {
1346 
1347         const char *const usageName[] = {"bind_as_uniform", "bind_as_storage"};
1348         const vk::VkBufferUsageFlags createUsage =
1349             vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
1350         const vk::VkBufferUsageFlags bindUsage[] = {vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
1351                                                     vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT};
1352         const vk::VkFormatFeatureFlags feature[] = {vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
1353                                                     vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT};
1354         const vk::VkDescriptorType descType[]    = {vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
1355                                                     vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER};
1356 
1357         for (uint32_t usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageName); ++usageNdx)
1358         {
1359             de::MovePtr<tcu::TestCaseGroup> usageGroup(new tcu::TestCaseGroup(testCtx, usageName[usageNdx]));
1360 
1361             for (uint32_t formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++)
1362             {
1363                 const auto skip = strlen("VK_FORMAT_");
1364                 const std::string fmtName =
1365                     de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip));
1366 
1367                 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, fmtName.c_str()));
1368 
1369                 if (bindUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT &&
1370                     !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx])))
1371                     continue;
1372 
1373                 const BufferViewCaseParams info = {
1374                     512,                           // uint32_t                    bufferSize
1375                     128,                           // uint32_t                    bufferViewSize
1376                     0,                             // uint32_t                    elementOffset
1377                     ALLOCATION_KIND_SUBALLOCATION, // AllocationKind            bufferAllocationKind
1378                     ALLOCATION_KIND_SUBALLOCATION, // AllocationKind            imageAllocationKind
1379 
1380                     testFormats[formatIdx], // VkFormat                    format
1381                     createUsage,            // VkBufferUsageFlags        createUsage
1382                     bindUsage[usageNdx],    // VkBufferUsageFlags        bindUsage
1383                     feature[usageNdx],      // VkFormatFeatureFlags2KHR    feature
1384                     descType[usageNdx],     // VkDescriptorType            descType
1385                 };
1386 
1387                 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info));
1388             }
1389 
1390             uniformStorageGroup->addChild(usageGroup.release());
1391         }
1392     }
1393 
1394     bufferViewTests->addChild(uniformStorageGroup.release());
1395 #endif
1396 
1397     return bufferViewTests.release();
1398 }
1399 
1400 } // namespace api
1401 } // namespace vkt
1402