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 ®ion);
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 ®ion);
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