xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/binding_model/vktBindingStagesTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 Nintendo
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Binding shader access tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktBindingStagesTests.hpp"
25 
26 #include "vktTestCase.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vkCmdUtil.hpp"
29 #include "vkObjUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include <cstdlib>
34 #include <cmath>
35 
36 namespace vkt
37 {
38 namespace BindingModel
39 {
40 
41 namespace
42 {
43 
makeImageCreateInfo(const vk::VkFormat format,const tcu::IVec2 & size,vk::VkImageUsageFlags usage)44 vk::VkImageCreateInfo makeImageCreateInfo(const vk::VkFormat format, const tcu::IVec2 &size,
45                                           vk::VkImageUsageFlags usage)
46 {
47     const vk::VkImageCreateInfo imageParams = {
48         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
49         DE_NULL,                                 // const void* pNext;
50         (vk::VkImageCreateFlags)0,               // VkImageCreateFlags flags;
51         vk::VK_IMAGE_TYPE_2D,                    // VkImageType imageType;
52         format,                                  // VkFormat format;
53         vk::makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
54         1u,                                      // uint32_t mipLevels;
55         1u,                                      // uint32_t arrayLayers;
56         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
57         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
58         usage,                                   // VkImageUsageFlags usage;
59         vk::VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
60         0u,                                      // uint32_t queueFamilyIndexCount;
61         DE_NULL,                                 // const uint32_t* pQueueFamilyIndices;
62         vk::VK_IMAGE_LAYOUT_UNDEFINED,           // VkImageLayout initialLayout;
63     };
64     return imageParams;
65 }
66 
67 class StagesTestInstance : public TestInstance
68 {
69 public:
StagesTestInstance(Context & context,vk::VkDescriptorType descriptorType)70     StagesTestInstance(Context &context, vk::VkDescriptorType descriptorType)
71         : vkt::TestInstance(context)
72         , m_descriptorType(descriptorType)
73     {
74     }
~StagesTestInstance(void)75     ~StagesTestInstance(void)
76     {
77     }
78     tcu::TestStatus iterate(void);
79 
80 private:
81     const vk::VkDescriptorType m_descriptorType;
82 };
83 
iterate(void)84 tcu::TestStatus StagesTestInstance::iterate(void)
85 {
86     const auto &vk           = m_context.getDeviceInterface();
87     const auto device        = m_context.getDevice();
88     vk::Allocator &allocator = m_context.getDefaultAllocator();
89     const auto queueIndex    = m_context.getUniversalQueueFamilyIndex();
90     const auto queue         = m_context.getUniversalQueue();
91 
92     const auto cmdPool   = vk::makeCommandPool(vk, device, queueIndex);
93     const auto cmdBuffer = allocateCommandBuffer(vk, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
94 
95     const auto readDescriptorPool(vk::DescriptorPoolBuilder()
96                                       .addType(m_descriptorType)
97                                       .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
98     const auto writeDescriptorPool(vk::DescriptorPoolBuilder()
99                                        .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
100                                        .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
101 
102     const auto readDescriptorSetLayout(
103         vk::DescriptorSetLayoutBuilder()
104             .addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_FRAGMENT_BIT | vk::VK_SHADER_STAGE_COMPUTE_BIT)
105             .build(vk, device));
106     const auto writeDescriptorSetLayout(
107         vk::DescriptorSetLayoutBuilder()
108             .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
109                               vk::VK_SHADER_STAGE_FRAGMENT_BIT | vk::VK_SHADER_STAGE_COMPUTE_BIT)
110             .build(vk, device));
111     const auto pipelineLayout =
112         vk::makePipelineLayout(vk, device, {*readDescriptorSetLayout, *writeDescriptorSetLayout});
113     const auto readDescriptorSet(makeDescriptorSet(vk, device, *readDescriptorPool, *readDescriptorSetLayout));
114     const auto writeDescriptorSet(makeDescriptorSet(vk, device, *writeDescriptorPool, *writeDescriptorSetLayout));
115 
116     const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
117 
118     de::MovePtr<vk::BufferWithMemory> readBuffer;
119     de::MovePtr<vk::ImageWithMemory> readImage;
120     vk::Move<vk::VkImageView> readImageView;
121 
122     const vk::VkSamplerCreateInfo samplerCreateInfo = {
123         vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,   // VkStructureType sType;
124         DE_NULL,                                     // const void* pNext;
125         0u,                                          // VkSamplerCreateFlags flags;
126         vk::VK_FILTER_LINEAR,                        // VkFilter magFilter;
127         vk::VK_FILTER_LINEAR,                        // VkFilter minFilter;
128         vk::VK_SAMPLER_MIPMAP_MODE_NEAREST,          // VkSamplerMipmapMode mipmapMode;
129         vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode addressModeU;
130         vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode addressModeV;
131         vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode addressModeW;
132         0.0f,                                        // float mipLodBias;
133         VK_FALSE,                                    // VkBool32 anisotropyEnable;
134         1.0f,                                        // float maxAnisotropy;
135         VK_FALSE,                                    // VkBool32 compareEnable;
136         vk::VK_COMPARE_OP_NEVER,                     // VkCompareOp compareOp;
137         0.0f,                                        // float minLod;
138         1.0f,                                        // float maxLod;
139         vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
140         VK_FALSE                                     // VkBool32 unnormalizedCoordinates;
141     };
142 
143     const auto sampler = vk::createSampler(vk, device, &samplerCreateInfo);
144 
145     if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
146         m_descriptorType == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
147     {
148         vk::VkBufferUsageFlags usage = m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ?
149                                            vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT :
150                                            vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
151 
152         vk::VkBufferCreateInfo readBufferCreateInfo = {
153             vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
154             DE_NULL,                                  // const void* pNext;
155             (vk::VkBufferCreateFlags)0u,              // VkBufferCreateFlags flags;
156             sizeof(float) * 4u,                       // VkDeviceSize size;
157             usage,                                    // VkBufferUsageFlags usage;
158             vk::VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
159             0u,                                       // uint32_t queueFamilyIndexCount;
160             DE_NULL,                                  // const uint32_t* pQueueFamilyIndices;
161         };
162         readBuffer = de::MovePtr<vk::BufferWithMemory>(
163             new vk::BufferWithMemory(vk, device, allocator, readBufferCreateInfo, vk::MemoryRequirement::HostVisible));
164 
165         vk::VkDescriptorBufferInfo readBufferInfo = {
166             **readBuffer,  // VkBuffer buffer;
167             0u,            // VkDeviceSize offset;
168             VK_WHOLE_SIZE, // VkDeviceSize range;
169         };
170 
171         vk::VkWriteDescriptorSet readDescriptorWrite = {
172             vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
173             DE_NULL,                                    // const void* pNext;
174             *readDescriptorSet,                         // VkDescriptorSet dstSet;
175             0u,                                         // uint32_t dstBinding;
176             0u,                                         // uint32_t dstArrayElement;
177             1u,                                         // uint32_t descriptorCount;
178             m_descriptorType,                           // VkDescriptorType descriptorType;
179             DE_NULL,                                    // const VkDescriptorImageInfo* pImageInfo;
180             &readBufferInfo,                            // const VkDescriptorBufferInfo* pBufferInfo;
181             DE_NULL,                                    // const VkBufferView* pTexelBufferView;
182         };
183         vk.updateDescriptorSets(device, 1u, &readDescriptorWrite, 0u, DE_NULL);
184 
185         const auto &readAlloc  = readBuffer->getAllocation();
186         const auto readDataPtr = reinterpret_cast<float *>(readAlloc.getHostPtr()) + readAlloc.getOffset();
187         for (uint32_t i = 0; i < 4; ++i)
188             readDataPtr[i] = float(i) + 1.0f;
189         vk::flushAlloc(vk, device, readAlloc);
190     }
191     else
192     {
193         vk::VkImageCreateInfo imageCreateInfo = {
194             vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                              // VkStructureType sType;
195             DE_NULL,                                                              // const void* pNext;
196             (vk::VkImageCreateFlags)0u,                                           // VkImageCreateFlags flags;
197             vk::VK_IMAGE_TYPE_2D,                                                 // VkImageType imageType;
198             vk::VK_FORMAT_R8G8B8A8_UNORM,                                         // VkFormat format;
199             {4u, 4u, 1u},                                                         // VkExtent3D extent;
200             1u,                                                                   // uint32_t mipLevels;
201             1u,                                                                   // uint32_t arrayLayers;
202             vk::VK_SAMPLE_COUNT_1_BIT,                                            // VkSampleCountFlagBits samples;
203             vk::VK_IMAGE_TILING_OPTIMAL,                                          // VkImageTiling tiling;
204             vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
205             vk::VK_SHARING_MODE_EXCLUSIVE,                                        // VkSharingMode sharingMode;
206             0u,                                                                   // uint32_t queueFamilyIndexCount;
207             DE_NULL,                       // const uint32_t* pQueueFamilyIndices;
208             vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
209         };
210         readImage = de::MovePtr<vk::ImageWithMemory>(
211             new vk::ImageWithMemory(vk, device, allocator, imageCreateInfo, vk::MemoryRequirement::Any));
212 
213         vk::VkImageViewCreateInfo imageViewCreateInfo = {
214             vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
215             DE_NULL,                                      // const void* pNext;
216             (vk::VkImageViewCreateFlags)0u,               // VkImageViewCreateFlags flags;
217             **readImage,                                  // VkImage image;
218             vk::VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType viewType;
219             vk::VK_FORMAT_R8G8B8A8_UNORM,                 // VkFormat format;
220             {
221                 vk::VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
222                 vk::VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
223                 vk::VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
224                 vk::VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle a;
225             },                              // VkComponentMapping  components;
226             {
227                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
228                 0u,                            // uint32_t baseMipLevel;
229                 1u,                            // uint32_t levelCount;
230                 0u,                            // uint32_t baseArrayLayer;
231                 1u                             // uint32_t layerCount;
232             }                                  // VkImageSubresourceRange subresourceRange;
233         };
234         readImageView = vk::createImageView(vk, device, &imageViewCreateInfo);
235 
236         vk::VkDescriptorImageInfo readImageInfo = {
237             *sampler,                                     // VkSampler sampler;
238             *readImageView,                               // VkImageView imageView;
239             vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout imageLayout;
240         };
241 
242         vk::VkWriteDescriptorSet readDescriptorWrite = {
243             vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
244             DE_NULL,                                    // const void* pNext;
245             *readDescriptorSet,                         // VkDescriptorSet dstSet;
246             0u,                                         // uint32_t dstBinding;
247             0u,                                         // uint32_t dstArrayElement;
248             1u,                                         // uint32_t descriptorCount;
249             m_descriptorType,                           // VkDescriptorType descriptorType;
250             &readImageInfo,                             // const VkDescriptorImageInfo* pImageInfo;
251             DE_NULL,                                    // const VkDescriptorBufferInfo* pBufferInfo;
252             DE_NULL,                                    // const VkBufferView* pTexelBufferView;
253         };
254         vk.updateDescriptorSets(device, 1u, &readDescriptorWrite, 0u, DE_NULL);
255 
256         vk::VkDeviceSize bufferSize = 4u * 4u * 4u;
257 
258         vk::VkBufferCreateInfo readBufferCreateInfo = {
259             vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
260             DE_NULL,                                  // const void* pNext;
261             (vk::VkBufferCreateFlags)0u,              // VkBufferCreateFlags flags;
262             bufferSize,                               // VkDeviceSize size;
263             vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
264             vk::VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
265             0u,                                       // uint32_t queueFamilyIndexCount;
266             DE_NULL,                                  // const uint32_t* pQueueFamilyIndices;
267         };
268         readBuffer = de::MovePtr<vk::BufferWithMemory>(
269             new vk::BufferWithMemory(vk, device, allocator, readBufferCreateInfo, vk::MemoryRequirement::HostVisible));
270 
271         const auto &readAlloc  = readBuffer->getAllocation();
272         const auto readDataPtr = reinterpret_cast<uint8_t *>(readAlloc.getHostPtr()) + readAlloc.getOffset();
273         for (uint32_t i = 0; i < 4 * 4 * 4; ++i)
274             readDataPtr[i] = (uint8_t)(((i + 1) % 4) * 64 - 1);
275         vk::flushAlloc(vk, device, readAlloc);
276 
277         const auto copyCmdBuffer =
278             allocateCommandBuffer(vk, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
279         vk::beginCommandBuffer(vk, *copyCmdBuffer);
280         vk::VkBufferImageCopy region = {
281             0u,                                          // VkDeviceSize bufferOffset;
282             0u,                                          // uint32_t bufferRowLength;
283             0u,                                          // uint32_t bufferImageHeight;
284             {vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u}, // VkImageSubresourceLayers imageSubresource;
285             {0, 0, 0},                                   // VkOffset3D imageOffset;
286             {4u, 4u, 1u},                                // VkExtent3D imageExtent;
287         };
288         vk::VkImageMemoryBarrier preImageMemoryBarrier = vk::makeImageMemoryBarrier(
289             vk::VK_ACCESS_NONE, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
290             vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **readImage, subresourceRange);
291         vk::VkImageMemoryBarrier postImageMemoryBarrier = vk::makeImageMemoryBarrier(
292             vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
293             vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, **readImage, subresourceRange);
294         vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
295                               0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preImageMemoryBarrier);
296         vk.cmdCopyBufferToImage(*copyCmdBuffer, **readBuffer, **readImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u,
297                                 &region);
298         vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
299                               vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
300                               0u, DE_NULL, 0u, DE_NULL, 1u, &postImageMemoryBarrier);
301         vk::endCommandBuffer(vk, *copyCmdBuffer);
302         vk::submitCommandsAndWait(vk, device, queue, *copyCmdBuffer);
303     }
304 
305     vk::VkBufferCreateInfo writeBufferCreateInfo = {
306         vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
307         DE_NULL,                                  // const void* pNext;
308         (vk::VkBufferCreateFlags)0u,              // VkBufferCreateFlags flags;
309         sizeof(float) * 4u,                       // VkDeviceSize size;
310         vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,   // VkBufferUsageFlags usage;
311         vk::VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
312         0u,                                       // uint32_t queueFamilyIndexCount;
313         DE_NULL,                                  // const uint32_t* pQueueFamilyIndices;
314     };
315     const auto writeBuffer = de::MovePtr<vk::BufferWithMemory>(
316         new vk::BufferWithMemory(vk, device, allocator, writeBufferCreateInfo, vk::MemoryRequirement::HostVisible));
317 
318     vk::VkDescriptorBufferInfo writeBufferInfo = {
319         **writeBuffer, // VkBuffer buffer;
320         0u,            // VkDeviceSize offset;
321         VK_WHOLE_SIZE, // VkDeviceSize range;
322     };
323     ;
324 
325     vk::VkWriteDescriptorSet writeDescriptorWrite = {
326         vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
327         DE_NULL,                                    // const void* pNext;
328         *writeDescriptorSet,                        // VkDescriptorSet dstSet;
329         0u,                                         // uint32_t dstBinding;
330         0u,                                         // uint32_t dstArrayElement;
331         1u,                                         // uint32_t descriptorCount;
332         vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType descriptorType;
333         DE_NULL,                                    // const VkDescriptorImageInfo* pImageInfo;
334         &writeBufferInfo,                           // const VkDescriptorBufferInfo* pBufferInfo;
335         DE_NULL,                                    // const VkBufferView* pTexelBufferView;
336     };
337     vk.updateDescriptorSets(device, 1u, &writeDescriptorWrite, 0u, DE_NULL);
338 
339     const auto renderSize            = tcu::IVec2(32, 32);
340     const auto colorFormat           = vk::VK_FORMAT_R8G8B8A8_UNORM;
341     const auto colorSubresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
342     const auto colorImage(
343         makeImage(vk, device,
344                   makeImageCreateInfo(colorFormat, renderSize,
345                                       vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
346     const auto colorImageAlloc(bindImage(vk, device, allocator, *colorImage, vk::MemoryRequirement::Any));
347     const auto colorImageView(
348         makeImageView(vk, device, *colorImage, vk::VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
349 
350     const auto renderPass(makeRenderPass(vk, device, colorFormat));
351     const auto framebuffer(
352         vk::makeFramebuffer(vk, device, *renderPass, *colorImageView, renderSize.x(), renderSize.y()));
353 
354     const auto vertexModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
355     const auto fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
356     const auto compModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0u));
357     std::vector<vk::VkViewport> viewports = {
358         vk::VkViewport{0.0f, 0.0f, (float)renderSize.x(), (float)renderSize.y(), 0.0f, 1.0f}};
359     std::vector<vk::VkRect2D> scissors = {vk::VkRect2D{{0, 0}, {(uint32_t)renderSize.x(), (uint32_t)renderSize.y()}}};
360     vk::VkPipelineVertexInputStateCreateInfo vertexInputState = {
361         vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
362         DE_NULL,                                                       // const void* pNext;
363         (vk::VkPipelineVertexInputStateCreateFlags)0u,                 // VkPipelineVertexInputStateCreateFlags flags;
364         0u,                                                            // uint32_t vertexBindingDescriptionCount;
365         DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
366         0u,      // uint32_t vertexAttributeDescriptionCount;
367         DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
368     };
369     const auto pipeline        = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, *vertexModule, DE_NULL, DE_NULL,
370                                                           DE_NULL, *fragmentModule, *renderPass, 0u, &vertexInputState);
371     const auto computePipeline = vk::makeComputePipeline(vk, device, *pipelineLayout, *compModule);
372 
373     vk::VkDescriptorSet descriptorSets[] = {*readDescriptorSet, *writeDescriptorSet};
374 
375     vk::VkBindDescriptorSetsInfoKHR bindDescriptorSetsInfo = {
376         vk::VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO_KHR,                // VkStructureType sType;
377         DE_NULL,                                                            // const void* pNext;
378         vk::VK_SHADER_STAGE_FRAGMENT_BIT | vk::VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
379         *pipelineLayout,                                                    // VkPipelineLayout layout;
380         0u,                                                                 // uint32_t firstSet;
381         2u,                                                                 // uint32_t descriptorSetCount;
382         descriptorSets,                                                     // const VkDescriptorSet* pDescriptorSets;
383         0u,                                                                 // uint32_t dynamicOffsetCount;
384         DE_NULL,                                                            // const uint32_t* pDynamicOffsets;
385     };
386 
387     const vk::VkDeviceSize colorOutputBufferSize =
388         renderSize.x() * renderSize.y() * tcu::getPixelSize(vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM));
389     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
390         vk, device, allocator, vk::makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
391         vk::MemoryRequirement::HostVisible));
392 
393     vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
394 
395     vk::VkRenderPassBeginInfo renderPassBegin = {
396         vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                   // VkStructureType sType;
397         DE_NULL,                                                        // const void* pNext;
398         *renderPass,                                                    // VkRenderPass renderPass;
399         *framebuffer,                                                   // VkFramebuffer framebuffer;
400         {{0, 0}, {(uint32_t)renderSize.x(), (uint32_t)renderSize.y()}}, // VkRect2D renderArea;
401         1u,                                                             // uint32_t clearValueCount;
402         &clearValue,                                                    // const VkClearValue* pClearValues;
403     };
404 
405     vk::beginCommandBuffer(vk, *cmdBuffer);
406     vk.cmdBindDescriptorSets2KHR(*cmdBuffer, &bindDescriptorSetsInfo);
407 
408     vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
409     vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
410     vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
411     vk.cmdEndRenderPass(*cmdBuffer);
412     vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
413     vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
414 
415     vk::VkImageMemoryBarrier imageMemoryBarrier =
416         vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
417                                    vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
418                                    vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorImage, subresourceRange);
419     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
420                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier);
421 
422     vk::VkBufferImageCopy region = {
423         0u,                                                       // VkDeviceSize bufferOffset;
424         0u,                                                       // uint32_t bufferRowLength;
425         0u,                                                       // uint32_t bufferImageHeight;
426         {vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u},              // VkImageSubresourceLayers imageSubresource;
427         {0u, 0u, 0u},                                             // VkOffset3D imageOffset;
428         {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1u}, // VkExtent3D imageExtent;
429     };
430     vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **colorOutputBuffer, 1u,
431                             &region);
432 
433     vk::endCommandBuffer(vk, *cmdBuffer);
434 
435     vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
436 
437     invalidateAlloc(vk, device, writeBuffer->getAllocation());
438     const auto &writeAlloc  = writeBuffer->getAllocation();
439     const auto writeDataPtr = reinterpret_cast<float *>(writeAlloc.getHostPtr()) + writeAlloc.getOffset();
440 
441     for (uint32_t i = 0; i < 4; ++i)
442     {
443         if (std::abs((float)(writeDataPtr[i] - (float(i) + 1.0f))) >= 0.02f)
444         {
445             return tcu::TestStatus::fail("Fail");
446         }
447     }
448 
449     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
450         tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), renderSize.x(), renderSize.y(), 1,
451         (const void *)colorOutputBuffer.get()->getAllocation().getHostPtr());
452 
453     for (int y = 0; y < resultBuffer.getHeight(); y++)
454     {
455         for (int x = 0; x < resultBuffer.getWidth(); x++)
456         {
457             const auto pixel = resultBuffer.getPixel(x, y);
458             for (int i = 0; i < 4; ++i)
459             {
460                 if (std::abs((float)(pixel[i] - float(i + 1) / 4.0f)) >= 0.02f)
461                 {
462                     return tcu::TestStatus::fail("Fail");
463                 }
464             }
465         }
466     }
467 
468     return tcu::TestStatus::pass("Pass");
469 }
470 
471 class StagesTestCase : public TestCase
472 {
473 public:
StagesTestCase(tcu::TestContext & context,const char * name,vk::VkDescriptorType descriptorType)474     StagesTestCase(tcu::TestContext &context, const char *name, vk::VkDescriptorType descriptorType)
475         : vkt::TestCase(context, name)
476         , m_descriptorType(descriptorType)
477     {
478     }
~StagesTestCase(void)479     virtual ~StagesTestCase(void)
480     {
481     }
createInstance(Context & context) const482     virtual TestInstance *createInstance(Context &context) const
483     {
484         return new StagesTestInstance(context, m_descriptorType);
485     }
486     virtual void initPrograms(vk::SourceCollections &programCollection) const;
487     void checkSupport(Context &context) const;
488 
489 private:
490     const vk::VkDescriptorType m_descriptorType;
491 };
492 
initPrograms(vk::SourceCollections & programCollection) const493 void StagesTestCase::initPrograms(vk::SourceCollections &programCollection) const
494 {
495     std::ostringstream comp;
496     comp << "#version 450\n"
497          << "\n";
498     if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
499     {
500         comp << "layout(set = 0, binding = 0) buffer readBuffer{\n"
501              << "    float readValues[];\n"
502              << "};\n";
503     }
504     else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
505     {
506         comp << "layout(set = 0, binding = 0) uniform readBuffer{\n"
507              << "    vec4 readValues;\n"
508              << "};\n";
509     }
510     else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
511     {
512         comp << "layout(set = 0, binding = 0) uniform sampler2D readImage;\n";
513     }
514     comp << "layout(set = 1, binding = 0) buffer writeBuffer{\n"
515          << "    float writeValues[];\n"
516          << "};\n"
517          << "\n"
518          << "void main (void) {\n";
519     if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
520         m_descriptorType == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
521     {
522         comp << "    writeValues[gl_GlobalInvocationID.x] = readValues[gl_GlobalInvocationID.x];\n";
523     }
524     else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
525     {
526         comp << "    writeValues[gl_GlobalInvocationID.x] = texture(readImage, vec2(0.0f))[gl_GlobalInvocationID.x] * "
527                 "4.0f;\n";
528     }
529     comp << "}\n";
530 
531     programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
532 
533     std::ostringstream vert;
534     vert << "#version 450\n"
535          << "\n"
536          << "void main (void) {\n"
537          << "    gl_Position = vec4(float(gl_VertexIndex & 1) * 2.0f - 1.0f, float((gl_VertexIndex >> 1) & 1) * 2.0f - "
538             "1.0f, 0.0f, 1.0f);\n"
539          << "}\n";
540 
541     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
542 
543     std::ostringstream frag;
544     frag << "#version 450\n"
545          << "\n";
546     if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
547     {
548         frag << "layout(set = 0, binding = 0) buffer readBuffer{\n"
549              << "    float readValues[];\n"
550              << "};\n";
551     }
552     else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
553     {
554         frag << "layout(set = 0, binding = 0) uniform readBuffer{\n"
555              << "    vec4 readValues;\n"
556              << "};\n";
557     }
558     else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
559     {
560         frag << "layout(set = 0, binding = 0) uniform sampler2D readImage;\n";
561     }
562     frag << "layout(location = 0) out vec4 color;\n"
563          << "void main (void) {\n";
564     if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
565         m_descriptorType == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
566     {
567         frag << "    color = vec4(readValues[0] / 4.0f, readValues[1] / 4.0f, readValues[2] / 4.0f, readValues[3] / "
568                 "4.0f);\n";
569     }
570     else
571     {
572         frag << "    color = texture(readImage, vec2(0.5f));\n";
573     }
574     frag << "}\n";
575 
576     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
577 }
578 
checkSupport(Context & context) const579 void StagesTestCase::checkSupport(Context &context) const
580 {
581     context.requireDeviceFunctionality("VK_KHR_maintenance6");
582 }
583 
584 } // namespace
585 
createStagesTests(tcu::TestContext & testCtx)586 tcu::TestCaseGroup *createStagesTests(tcu::TestContext &testCtx)
587 {
588 
589     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
590         testCtx, "stages", "Update stages from different pipeline bind points with the same call"));
591 
592     constexpr struct DescriptorTypeTest
593     {
594         vk::VkDescriptorType descriptorType;
595         const char *name;
596     } descriptorTypeTests[] = {
597         {vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer"},
598         {
599             vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
600             "uniform_buffer",
601         },
602         {
603             vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
604             "combined_image_sampler",
605         },
606     };
607 
608     for (const auto &descriptorTypeTest : descriptorTypeTests)
609     {
610         group->addChild(new StagesTestCase(testCtx, descriptorTypeTest.name, descriptorTypeTest.descriptorType));
611     }
612 
613     return group.release();
614 }
615 
616 } // namespace BindingModel
617 } // namespace vkt
618