1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 Google Inc.
6 * Copyright (c) 2018 The Khronos Group Inc.
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 Tests for subpass dependency
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRenderPassSubpassDependencyTests.hpp"
26 #include "vktRenderPassTestsUtil.hpp"
27
28 #include "vktTestCaseUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37
38 #include "tcuImageCompare.hpp"
39 #include "tcuResultCollector.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42
43 #include "rrRenderer.hpp"
44 #include "deRandom.hpp"
45 #include "deMath.h"
46
47 using namespace vk;
48
49 using tcu::UVec2;
50 using tcu::UVec4;
51 using tcu::Vec2;
52 using tcu::Vec4;
53
54 using tcu::ConstPixelBufferAccess;
55 using tcu::PixelBufferAccess;
56
57 using tcu::TestLog;
58
59 using de::SharedPtr;
60 using std::string;
61 using std::vector;
62
63 typedef de::SharedPtr<Unique<VkImage>> SharedPtrVkImage;
64 typedef de::SharedPtr<Unique<VkImageView>> SharedPtrVkImageView;
65 typedef de::SharedPtr<Unique<VkPipeline>> SharedPtrVkPipeline;
66 typedef de::SharedPtr<Unique<VkSampler>> SharedPtrVkSampler;
67 typedef de::SharedPtr<Unique<VkRenderPass>> SharedPtrVkRenderPass;
68 typedef de::SharedPtr<Unique<VkFramebuffer>> SharedPtrVkFramebuffer;
69 typedef de::SharedPtr<Unique<VkDescriptorPool>> SharedPtrVkDescriptorPool;
70 typedef de::SharedPtr<Unique<VkDescriptorSetLayout>> SharedPtrVkDescriptorLayout;
71 typedef de::SharedPtr<Unique<VkDescriptorSet>> SharedPtrVkDescriptorSet;
72 typedef de::SharedPtr<Unique<VkPipelineLayout>> SharedPtrVkPipelineLayout;
73 typedef de::SharedPtr<Unique<VkPipeline>> SharedPtrVkPipeline;
74
75 namespace vkt
76 {
77 namespace
78 {
79 using namespace renderpass;
80
81 template <typename T>
makeSharedPtr(Move<T> move)82 inline SharedPtr<Unique<T>> makeSharedPtr(Move<T> move)
83 {
84 return SharedPtr<Unique<T>>(new Unique<T>(move));
85 }
86
getRepresentableDepthChannel(const ConstPixelBufferAccess & access)87 tcu::TextureLevel getRepresentableDepthChannel(const ConstPixelBufferAccess &access)
88 {
89 tcu::TextureLevel depthChannel(mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());
90
91 for (int y = 0; y < access.getHeight(); y++)
92 for (int x = 0; x < access.getWidth(); x++)
93 depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);
94
95 return depthChannel;
96 }
97
verifyDepth(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const float threshold)98 bool verifyDepth(Context &context, const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
99 const float threshold)
100 {
101 tcu::TestLog &log(context.getTestContext().getLog());
102
103 return tcu::floatThresholdCompare(log, // log
104 "Depth channel", // imageSetName
105 "Depth compare", // imageSetDesc
106 getRepresentableDepthChannel(reference), // reference
107 getRepresentableDepthChannel(result), // result
108 Vec4(threshold), // threshold
109 tcu::COMPARE_LOG_RESULT); // logMode
110 }
111
verifyStencil(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result)112 bool verifyStencil(Context &context, const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result)
113 {
114 tcu::TextureLevel stencilErrorImage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
115 result.getWidth(), result.getHeight());
116 tcu::TestLog &log(context.getTestContext().getLog());
117 bool stencilOk(true);
118
119 for (int y = 0; y < result.getHeight(); y++)
120 for (int x = 0; x < result.getWidth(); x++)
121 {
122 if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
123 {
124 stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
125 stencilOk = false;
126 }
127 else
128 stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
129 }
130
131 log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
132 << tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
133 << tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);
134
135 if (!stencilOk)
136 log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);
137
138 log << tcu::TestLog::EndImageSet;
139
140 return stencilOk;
141 }
142
143 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(const DeviceInterface & vkd,VkCommandBuffer secCmdBuffer,VkFormat colorAttachmentFormat,VkFormat dsAttachmentFormat,bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)144 void beginSecondaryCmdBuffer(const DeviceInterface &vkd, VkCommandBuffer secCmdBuffer, VkFormat colorAttachmentFormat,
145 VkFormat dsAttachmentFormat, bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
146 {
147 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
148 if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
149 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
150
151 const VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
152 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
153 DE_NULL, // const void* pNext;
154 0u, // VkRenderingFlagsKHR flags;
155 0u, // uint32_t viewMask;
156 1u, // uint32_t colorAttachmentCount;
157 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats;
158 dsAttachmentFormat, // VkFormat depthAttachmentFormat;
159 dsAttachmentFormat, // VkFormat stencilAttachmentFormat;
160 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
161 };
162 const VkCommandBufferInheritanceInfo bufferInheritanceInfo{
163 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
164 &inheritanceRenderingInfo, // const void* pNext;
165 DE_NULL, // VkRenderPass renderPass;
166 0u, // uint32_t subpass;
167 DE_NULL, // VkFramebuffer framebuffer;
168 VK_FALSE, // VkBool32 occlusionQueryEnable;
169 (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags;
170 (VkQueryPipelineStatisticFlags)0u // VkQueryPipelineStatisticFlags pipelineStatistics;
171 };
172 const VkCommandBufferBeginInfo commandBufBeginParams{
173 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
174 DE_NULL, // const void* pNext;
175 usageFlags, // VkCommandBufferUsageFlags flags;
176 &bufferInheritanceInfo // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
177 };
178 VK_CHECK(vkd.beginCommandBuffer(secCmdBuffer, &commandBufBeginParams));
179 }
180 #endif // CTS_USES_VULKANSC
181
182 // Reference renderer shaders
183 class DepthVertShader : public rr::VertexShader
184 {
185 public:
DepthVertShader(void)186 DepthVertShader(void) : rr::VertexShader(1, 1)
187 {
188 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
189 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
190 }
191
~DepthVertShader()192 virtual ~DepthVertShader()
193 {
194 }
195
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const196 void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
197 {
198 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
199 {
200 packets[packetNdx]->position =
201 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
202
203 packets[packetNdx]->outputs[0] =
204 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
205 }
206 }
207 };
208
209 class DepthFragShader : public rr::FragmentShader
210 {
211 public:
DepthFragShader(void)212 DepthFragShader(void) : rr::FragmentShader(1, 1)
213 {
214 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
215 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
216 }
217
~DepthFragShader()218 virtual ~DepthFragShader()
219 {
220 }
221
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const222 void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
223 const rr::FragmentShadingContext &context) const
224 {
225 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
226 {
227 rr::FragmentPacket &packet = packets[packetNdx];
228 for (uint32_t fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
229 {
230 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
231
232 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
233 }
234 }
235 }
236 };
237
238 class SelfDependencyBackwardsVertShader : public rr::VertexShader
239 {
240 public:
SelfDependencyBackwardsVertShader(void)241 SelfDependencyBackwardsVertShader(void) : rr::VertexShader(1, 0)
242 {
243 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
244 }
245
~SelfDependencyBackwardsVertShader()246 virtual ~SelfDependencyBackwardsVertShader()
247 {
248 }
249
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const250 void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
251 {
252 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
253 {
254 packets[packetNdx]->position =
255 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
256 }
257 }
258 };
259
260 class SelfDependencyBackwardsFragShader : public rr::FragmentShader
261 {
262 public:
SelfDependencyBackwardsFragShader(void)263 SelfDependencyBackwardsFragShader(void) : rr::FragmentShader(0, 1)
264 {
265 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
266 }
267
~SelfDependencyBackwardsFragShader()268 virtual ~SelfDependencyBackwardsFragShader()
269 {
270 }
271
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const272 void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
273 const rr::FragmentShadingContext &context) const
274 {
275 DE_UNREF(packets);
276
277 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
278 for (uint32_t fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
279 rr::writeFragmentOutput<tcu::Vec4>(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
280 }
281 };
282
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)283 de::MovePtr<Allocation> createBufferMemory(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
284 VkBuffer buffer)
285 {
286 de::MovePtr<Allocation> allocation(
287 allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
288
289 VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
290
291 return allocation;
292 }
293
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)294 Move<VkImageView> createImageView(const DeviceInterface &vk, VkDevice device, VkImageViewCreateFlags flags,
295 VkImage image, VkImageViewType viewType, VkFormat format,
296 VkComponentMapping components, VkImageSubresourceRange subresourceRange)
297 {
298 const VkImageViewCreateInfo pCreateInfo = {
299 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
300 DE_NULL, // const void* pNext
301 flags, // VkImageViewCreateFlags flags
302 image, // VkImage image
303 viewType, // VkImageViewType viewType
304 format, // VkFormat format
305 components, // VkComponentMapping components
306 subresourceRange, // VkImageSubresourceRange subresourceRange
307 };
308
309 return createImageView(vk, device, &pCreateInfo);
310 }
311
createImageViews(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkImage> images,VkFormat format,VkImageAspectFlags aspect)312 vector<SharedPtrVkImageView> createImageViews(const DeviceInterface &vkd, VkDevice device,
313 vector<SharedPtrVkImage> images, VkFormat format,
314 VkImageAspectFlags aspect)
315 {
316 vector<SharedPtrVkImageView> imageViews;
317
318 for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
319 {
320 const VkImageSubresourceRange range = {
321 aspect, // VkImageAspectFlags aspectMask
322 0u, // uint32_t baseMipLevel
323 1u, // uint32_t levelCount
324 0u, // uint32_t baseArrayLayer
325 1u // uint32_t layerCount
326 };
327
328 imageViews.push_back(
329 makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format,
330 makeComponentMappingRGBA(), range)));
331 }
332
333 return imageViews;
334 }
335
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,uint32_t width,uint32_t height)336 Move<VkBuffer> createBuffer(const DeviceInterface &vkd, VkDevice device, VkFormat format, uint32_t width,
337 uint32_t height)
338 {
339 const VkBufferUsageFlags bufferUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
340 const VkDeviceSize pixelSize = mapVkFormat(format).getPixelSize();
341 const VkBufferCreateInfo createInfo = {
342 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
343 DE_NULL, // const void* pNext
344 0u, // VkBufferCreateFlags flags
345 width * height * pixelSize, // VkDeviceSize size
346 bufferUsage, // VkBufferUsageFlags usage
347 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
348 0u, // uint32_t queueFamilyIndexCount
349 DE_NULL // const uint32_t* pQueueFamilyIndices
350 };
351
352 return createBuffer(vkd, device, &createInfo);
353 }
354
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkSampler> & samplers)355 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts(const DeviceInterface &vkd, VkDevice device,
356 vector<SharedPtrVkSampler> &samplers)
357 {
358 vector<SharedPtrVkDescriptorLayout> layouts;
359
360 for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
361 {
362 const VkDescriptorSetLayoutBinding bindings = {
363 0u, // uint32_t binding
364 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType
365 1u, // uint32_t descriptorCount
366 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
367 &**samplers[layoutNdx] // const VkSampler* pImmutableSamplers
368 };
369
370 const VkDescriptorSetLayoutCreateInfo createInfo = {
371 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
372 DE_NULL, // const void* pNext
373 0u, // VkDescriptorSetLayoutCreateFlags flags
374 1u, // uint32_t bindingCount
375 &bindings // const VkDescriptorSetLayoutBinding* pBindings
376 };
377
378 layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
379 }
380
381 return layouts;
382 }
383
createDescriptorPools(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorLayout> & layouts,VkDescriptorType type)384 vector<SharedPtrVkDescriptorPool> createDescriptorPools(const DeviceInterface &vkd, VkDevice device,
385 vector<SharedPtrVkDescriptorLayout> &layouts,
386 VkDescriptorType type)
387 {
388 vector<SharedPtrVkDescriptorPool> descriptorPools;
389
390 for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
391 {
392 const VkDescriptorPoolSize size = {
393 type, // VkDescriptorType type
394 1u // uint32_t descriptorCount
395 };
396
397 const VkDescriptorPoolCreateInfo createInfo = {
398 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
399 DE_NULL, // const void* pNext
400 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
401 1u, // uint32_t maxSets
402 1u, // uint32_t poolSizeCount
403 &size // const VkDescriptorPoolSize* pPoolSizes
404 };
405
406 descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
407 }
408
409 return descriptorPools;
410 }
411
412 struct ExternalTestConfig
413 {
ExternalTestConfigvkt::__anonc414995a0111::ExternalTestConfig414 ExternalTestConfig(VkFormat format_, UVec2 imageSize_, vector<RenderPass> renderPasses_,
415 const SharedGroupParams groupParams_, SynchronizationType synchronizationType_,
416 uint32_t blurKernel_ = 4)
417 : format(format_)
418 , imageSize(imageSize_)
419 , renderPasses(renderPasses_)
420 , groupParams(groupParams_)
421 , synchronizationType(synchronizationType_)
422 , blurKernel(blurKernel_)
423 {
424 }
425
426 VkFormat format;
427 UVec2 imageSize;
428 vector<RenderPass> renderPasses;
429 const SharedGroupParams groupParams;
430 SynchronizationType synchronizationType;
431 uint32_t blurKernel;
432 };
433
434 class ExternalDependencyTestInstance : public TestInstance
435 {
436 public:
437 ExternalDependencyTestInstance(Context &context, ExternalTestConfig testConfig);
438 ~ExternalDependencyTestInstance(void);
439
440 vector<SharedPtrVkImage> createAndAllocateImages(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
441 vector<de::SharedPtr<Allocation>> &imageMemories,
442 uint32_t universalQueueFamilyIndex, VkFormat format,
443 uint32_t width, uint32_t height, vector<RenderPass> renderPasses);
444
445 vector<SharedPtrVkSampler> createSamplers(const DeviceInterface &vkd, const VkDevice device,
446 vector<RenderPass> &renderPasses);
447
448 vector<SharedPtrVkRenderPass> createRenderPasses(const DeviceInterface &vkd, VkDevice device,
449 vector<RenderPass> renderPassInfos,
450 const RenderingType renderingType,
451 const SynchronizationType synchronizationType);
452
453 vector<SharedPtrVkFramebuffer> createFramebuffers(const DeviceInterface &vkd, VkDevice device,
454 vector<SharedPtrVkRenderPass> &renderPasses,
455 vector<SharedPtrVkImageView> &dstImageViews, uint32_t width,
456 uint32_t height);
457
458 vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts(
459 const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
460 vector<SharedPtrVkDescriptorLayout> &descriptorSetLayouts);
461
462 vector<SharedPtrVkPipeline> createRenderPipelines(const DeviceInterface &vkd, VkDevice device,
463 vector<SharedPtrVkRenderPass> &renderPasses,
464 vector<SharedPtrVkPipelineLayout> &pipelineLayouts,
465 const BinaryCollection &binaryCollection, uint32_t width,
466 uint32_t height);
467
468 vector<SharedPtrVkDescriptorSet> createDescriptorSets(const DeviceInterface &vkd, VkDevice device,
469 vector<SharedPtrVkDescriptorPool> &pools,
470 vector<SharedPtrVkDescriptorLayout> &layouts,
471 vector<SharedPtrVkImageView> &imageViews,
472 vector<SharedPtrVkSampler> &samplers);
473
474 tcu::TestStatus iterate(void);
475
476 template <typename RenderpassSubpass>
477 tcu::TestStatus iterateInternal(void);
478
479 private:
480 const bool m_renderPass2Supported;
481 const bool m_synchronization2Supported;
482 const SharedGroupParams m_groupParams;
483
484 const uint32_t m_width;
485 const uint32_t m_height;
486 const uint32_t m_blurKernel;
487 const VkFormat m_format;
488
489 vector<de::SharedPtr<Allocation>> m_imageMemories;
490 vector<SharedPtrVkImage> m_images;
491 vector<SharedPtrVkImageView> m_imageViews;
492 vector<SharedPtrVkSampler> m_samplers;
493
494 const Unique<VkBuffer> m_dstBuffer;
495 const de::UniquePtr<Allocation> m_dstBufferMemory;
496
497 vector<SharedPtrVkRenderPass> m_renderPasses;
498 vector<SharedPtrVkFramebuffer> m_framebuffers;
499
500 vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
501 vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
502 vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
503
504 vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
505 vector<SharedPtrVkPipeline> m_renderPipelines;
506
507 const Unique<VkCommandPool> m_commandPool;
508 tcu::ResultCollector m_resultCollector;
509 };
510
ExternalDependencyTestInstance(Context & context,ExternalTestConfig testConfig)511 ExternalDependencyTestInstance::ExternalDependencyTestInstance(Context &context, ExternalTestConfig testConfig)
512 : TestInstance(context)
513 , m_renderPass2Supported((testConfig.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) &&
514 context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
515 , m_synchronization2Supported((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) &&
516 context.requireDeviceFunctionality("VK_KHR_synchronization2"))
517 , m_groupParams(testConfig.groupParams)
518 , m_width(testConfig.imageSize.x())
519 , m_height(testConfig.imageSize.y())
520 , m_blurKernel(testConfig.blurKernel)
521 , m_format(testConfig.format)
522 , m_images(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(),
523 m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width,
524 m_height, testConfig.renderPasses))
525 , m_imageViews(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format,
526 VK_IMAGE_ASPECT_COLOR_BIT))
527 , m_samplers(createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
528 , m_dstBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
529 , m_dstBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
530 context.getDefaultAllocator(), *m_dstBuffer))
531 , m_renderPasses(createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses,
532 testConfig.groupParams->renderingType, testConfig.synchronizationType))
533 , m_framebuffers(createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews,
534 m_width, m_height))
535 , m_subpassDescriptorSetLayouts(
536 createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
537 , m_subpassDescriptorPools(createDescriptorPools(context.getDeviceInterface(), context.getDevice(),
538 m_subpassDescriptorSetLayouts,
539 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
540 , m_subpassDescriptorSets(createDescriptorSets(context.getDeviceInterface(), context.getDevice(),
541 m_subpassDescriptorPools, m_subpassDescriptorSetLayouts,
542 m_imageViews, m_samplers))
543 , m_renderPipelineLayouts(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(),
544 m_renderPasses, m_subpassDescriptorSetLayouts))
545 , m_renderPipelines(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses,
546 m_renderPipelineLayouts, context.getBinaryCollection(), m_width,
547 m_height))
548 , m_commandPool(createCommandPool(context.getDeviceInterface(), context.getDevice(),
549 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
550 {
551 }
552
~ExternalDependencyTestInstance(void)553 ExternalDependencyTestInstance::~ExternalDependencyTestInstance(void)
554 {
555 }
556
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,uint32_t universalQueueFamilyIndex,VkFormat format,uint32_t width,uint32_t height,vector<RenderPass> renderPasses)557 vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages(
558 const DeviceInterface &vk, VkDevice device, Allocator &allocator, vector<de::SharedPtr<Allocation>> &imageMemories,
559 uint32_t universalQueueFamilyIndex, VkFormat format, uint32_t width, uint32_t height,
560 vector<RenderPass> renderPasses)
561 {
562 vector<SharedPtrVkImage> images;
563
564 for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
565 {
566 const VkExtent3D imageExtent = {
567 width, // uint32_t width
568 height, // uint32_t height
569 1u // uint32_t depth
570 };
571
572 const VkImageCreateInfo imageCreateInfo = {
573 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
574 DE_NULL, // const void* pNext
575 0u, // VkImageCreateFlags flags
576 VK_IMAGE_TYPE_2D, // VkImageType imageType
577 format, // VkFormat format
578 imageExtent, // VkExtent3D extent
579 1u, // uint32_t mipLevels
580 1u, // uint32_t arrayLayers
581 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
582 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
583 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
584 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
585 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
586 1u, // uint32_t queueFamilyIndexCount
587 &universalQueueFamilyIndex, // const uint32_t* pQueueFamilyIndices
588 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
589 };
590
591 images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
592 imageMemories.push_back(
593 (de::SharedPtr<Allocation>)allocator
594 .allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any)
595 .release());
596 VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(),
597 imageMemories[imageNdx]->getOffset()));
598 }
599
600 return images;
601 }
602
createSamplers(const DeviceInterface & vkd,const VkDevice device,vector<RenderPass> & renderPasses)603 vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers(const DeviceInterface &vkd,
604 const VkDevice device,
605 vector<RenderPass> &renderPasses)
606 {
607 vector<SharedPtrVkSampler> samplers;
608
609 for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
610 {
611 const VkSamplerCreateInfo samplerInfo = {
612 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
613 DE_NULL, // const void* pNext
614 0u, // VkSamplerCreateFlags flags
615 VK_FILTER_NEAREST, // VkFilter magFilter
616 VK_FILTER_NEAREST, // VkFilter minFilter
617 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
618 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
619 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
620 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
621 0.0f, // float mipLodBias
622 VK_FALSE, // VkBool32 anisotropyEnable
623 1.0f, // float maxAnisotropy
624 VK_FALSE, // VkBool32 compareEnable
625 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
626 0.0f, // float minLod
627 0.0f, // float maxLod
628 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
629 VK_FALSE, // VkBool32 unnormalizedCoordinates
630 };
631
632 samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
633 }
634
635 return samplers;
636 }
637
createRenderPasses(const DeviceInterface & vkd,VkDevice device,vector<RenderPass> renderPassInfos,const RenderingType renderingType,const SynchronizationType synchronizationType)638 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses(
639 const DeviceInterface &vkd, VkDevice device, vector<RenderPass> renderPassInfos, const RenderingType renderingType,
640 const SynchronizationType synchronizationType)
641 {
642 vector<SharedPtrVkRenderPass> renderPasses;
643 renderPasses.reserve(renderPassInfos.size());
644
645 for (const auto &renderPassInfo : renderPassInfos)
646 renderPasses.push_back(
647 makeSharedPtr(createRenderPass(vkd, device, renderPassInfo, renderingType, synchronizationType)));
648
649 return renderPasses;
650 }
651
createFramebuffers(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkImageView> & dstImageViews,uint32_t width,uint32_t height)652 vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers(
653 const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
654 vector<SharedPtrVkImageView> &dstImageViews, uint32_t width, uint32_t height)
655 {
656 vector<SharedPtrVkFramebuffer> framebuffers;
657
658 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
659 {
660 VkRenderPass renderPass(**renderPasses[renderPassNdx]);
661
662 const VkFramebufferCreateInfo createInfo = {
663 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
664 DE_NULL, // const void* pNext
665 0u, // VkFramebufferCreateFlags flags
666 renderPass, // VkRenderPass renderPass
667 1u, // uint32_t attachmentCount
668 &**dstImageViews[renderPassNdx], // const VkImageView* pAttachments
669 width, // uint32_t width
670 height, // uint32_t height
671 1u // uint32_t layers
672 };
673
674 framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
675 }
676
677 return framebuffers;
678 }
679
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews,vector<SharedPtrVkSampler> & samplers)680 vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets(
681 const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkDescriptorPool> &pools,
682 vector<SharedPtrVkDescriptorLayout> &layouts, vector<SharedPtrVkImageView> &imageViews,
683 vector<SharedPtrVkSampler> &samplers)
684 {
685 vector<SharedPtrVkDescriptorSet> descriptorSets;
686
687 for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
688 {
689 const VkDescriptorSetAllocateInfo allocateInfo = {
690 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
691 DE_NULL, // const void* pNext
692 **pools[setNdx], // VkDescriptorPool descriptorPool
693 1u, // uint32_t descriptorSetCount
694 &**layouts[setNdx] // const VkDescriptorSetLayout* pSetLayouts
695 };
696
697 descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
698
699 {
700 const VkDescriptorImageInfo imageInfo = {
701 **samplers[setNdx], // VkSampler sampler
702 **imageViews[setNdx], // VkImageView imageView
703 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout
704 };
705
706 const VkWriteDescriptorSet write = {
707 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
708 DE_NULL, // const void* pNext
709 **descriptorSets[setNdx], // VkDescriptorSet dstSet
710 0u, // uint32_t dstBinding
711 0u, // uint32_t dstArrayElement
712 1u, // uint32_t descriptorCount
713 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType
714 &imageInfo, // const VkDescriptorImageInfo* pImageInfo
715 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
716 DE_NULL // const VkBufferView* pTexelBufferView
717 };
718
719 vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
720 }
721 }
722
723 return descriptorSets;
724 }
725
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkDescriptorLayout> & descriptorSetLayouts)726 vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts(
727 const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
728 vector<SharedPtrVkDescriptorLayout> &descriptorSetLayouts)
729 {
730 vector<SharedPtrVkPipelineLayout> pipelineLayouts;
731
732 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
733 {
734 const VkPipelineLayoutCreateInfo createInfo = {
735 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
736 DE_NULL, // const void* pNext
737 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
738 renderPassNdx > 0 ? 1u : 0u, // uint32_t setLayoutCount
739 renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] :
740 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts
741 0u, // uint32_t pushConstantRangeCount
742 DE_NULL // const VkPushConstantRange* pPushConstantRanges
743 };
744
745 pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
746 }
747
748 return pipelineLayouts;
749 }
750
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,uint32_t width,uint32_t height)751 vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines(
752 const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
753 vector<SharedPtrVkPipelineLayout> &pipelineLayouts, const BinaryCollection &binaryCollection, uint32_t width,
754 uint32_t height)
755 {
756 vector<SharedPtrVkPipeline> pipelines;
757
758 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
759 {
760 const Unique<VkShaderModule> vertexShaderModule(
761 createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
762 const Unique<VkShaderModule> fragmentShaderModule(
763 createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));
764
765 const VkPipelineVertexInputStateCreateInfo vertexInputState = {
766 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
767 DE_NULL, // const void* pNext
768 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
769 0u, // uint32_t vertexBindingDescriptionCount
770 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
771 0u, // uint32_t vertexAttributeDescriptionCount
772 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
773 };
774
775 const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(width, height)));
776 const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(width, height)));
777 const VkRenderPass renderPass(**renderPasses[renderPassNdx]);
778 const VkPipelineLayout layout(**pipelineLayouts[renderPassNdx]);
779
780 pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
781 vkd, // const DeviceInterface& vk
782 device, // const VkDevice device
783 layout, // const VkPipelineLayout pipelineLayout
784 *vertexShaderModule, // const VkShaderModule vertexShaderModule
785 DE_NULL, // const VkShaderModule tessellationControlShaderModule
786 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
787 DE_NULL, // const VkShaderModule geometryShaderModule
788 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
789 renderPass, // const VkRenderPass renderPass
790 viewports, // const std::vector<VkViewport>& viewports
791 scissors, // const std::vector<VkRect2D>& scissors
792 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
793 0u, // const uint32_t subpass
794 0u, // const uint32_t patchControlPoints
795 &vertexInputState))); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
796 }
797
798 return pipelines;
799 }
800
iterate(void)801 tcu::TestStatus ExternalDependencyTestInstance::iterate(void)
802 {
803 switch (m_groupParams->renderingType)
804 {
805 case RENDERING_TYPE_RENDERPASS_LEGACY:
806 return iterateInternal<RenderpassSubpass1>();
807 case RENDERING_TYPE_RENDERPASS2:
808 return iterateInternal<RenderpassSubpass2>();
809 default:
810 TCU_THROW(InternalError, "Impossible");
811 }
812 }
813
814 template <typename RenderpassSubpass>
iterateInternal(void)815 tcu::TestStatus ExternalDependencyTestInstance::iterateInternal(void)
816 {
817 const DeviceInterface &vkd(m_context.getDeviceInterface());
818 const Unique<VkCommandBuffer> commandBuffer(
819 allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
820 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
821 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
822
823 beginCommandBuffer(vkd, *commandBuffer);
824
825 for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
826 {
827 // Begin render pass
828 {
829 VkRect2D renderArea = {
830 {0u, 0u}, // VkOffset2D offset
831 {m_width, m_height} // VkExtent2D extent
832 };
833
834 const VkRenderPassBeginInfo beginInfo = {
835 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
836 DE_NULL, // const void* pNext
837 **m_renderPasses[renderPassNdx], // VkRenderPass renderPass
838 **m_framebuffers[renderPassNdx], // VkFramebuffer framebuffer
839 renderArea, // VkRect2D renderArea
840 0u, // uint32_t clearValueCount
841 DE_NULL // const VkClearValue* pClearValues
842 };
843
844 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
845 }
846
847 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);
848
849 // Use results from the previous pass as input texture
850 if (renderPassNdx > 0)
851 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
852 **m_renderPipelineLayouts[renderPassNdx], 0, 1,
853 &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);
854
855 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
856
857 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
858 }
859
860 // Memory barrier between rendering and copy
861 {
862 VkImageSubresourceRange imageSubresourceRange = {
863 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
864 0u, // uint32_t baseMipLevel
865 1u, // uint32_t levelCount
866 0u, // uint32_t baseArrayLayer
867 1u // uint32_t layerCount
868 };
869
870 const VkImageMemoryBarrier barrier = {
871 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
872 DE_NULL, // const void* pNext
873 0, // VkAccessFlags srcAccessMask
874 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
875 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout oldLayout
876 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
877 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
878 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
879 **m_images[m_renderPasses.size() - 1], // VkImage image
880 imageSubresourceRange // VkImageSubresourceRange subresourceRange
881 };
882 // Since the implicit 'end' subpass dependency has VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT in its dstStageMask,
883 // we can't form an execution dependency chain with a specific pipeline stage. The cases that provide an explict
884 // 'end' subpass dependency could use a specific pipline stage, but there isn't a way to distinguish between the
885 // implicit and explicit cases here.
886 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
887 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
888 }
889
890 // Copy image memory to buffer
891 {
892 const VkImageSubresourceLayers imageSubresourceLayers = {
893 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
894 0u, // uint32_t mipLevel
895 0u, // uint32_t baseArrayLayer
896 1u // uint32_t layerCount
897 };
898
899 const VkBufferImageCopy region = {
900 0u, // VkDeviceSize bufferOffset
901 0u, // uint32_t bufferRowLength
902 0u, // uint32_t bufferImageHeight
903 imageSubresourceLayers, // VkImageSubresourceLayers imageSubresource
904 {0u, 0u, 0u}, // VkOffset3D imageOffset
905 {m_width, m_height, 1u} // VkExtent3D imageExtent
906 };
907
908 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1],
909 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, ®ion);
910 }
911
912 // Memory barrier between copy and host access
913 {
914 const VkBufferMemoryBarrier barrier = {
915 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
916 DE_NULL, // const void* pNext
917 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
918 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
919 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
920 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
921 *m_dstBuffer, // VkBuffer buffer
922 0u, // VkDeviceSize offset
923 VK_WHOLE_SIZE // VkDeviceSize size
924 };
925
926 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
927 DE_NULL, 1u, &barrier, 0u, DE_NULL);
928 }
929
930 endCommandBuffer(vkd, *commandBuffer);
931 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
932 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(),
933 m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);
934
935 {
936 const tcu::TextureFormat format(mapVkFormat(m_format));
937 const void *const ptr(m_dstBufferMemory->getHostPtr());
938 const tcu::ConstPixelBufferAccess access(format, m_width, m_height, 1, ptr);
939 tcu::TextureLevel reference(format, m_width, m_height);
940 tcu::TextureLevel textureA(format, m_width, m_height);
941 tcu::TextureLevel textureB(format, m_width, m_height);
942
943 for (uint32_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
944 {
945 // First pass renders four quads of different color, which will be blurred in the following passes
946 if (renderPassNdx == 0)
947 {
948 for (uint32_t y = 0; y < m_height; y++)
949 for (uint32_t x = 0; x < m_width; x++)
950 {
951 if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
952 textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
953 else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
954 textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
955 else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
956 textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
957 else
958 textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
959 }
960 }
961 // Blur previous pass
962 else
963 {
964 for (uint32_t y = 0; y < m_height; y++)
965 for (uint32_t x = 0; x < m_width; x++)
966 {
967 Vec4 blurColor(Vec4(0.0));
968
969 for (uint32_t sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
970 {
971 if (renderPassNdx % 2 == 0)
972 {
973 // Do a horizontal blur
974 blurColor +=
975 0.12f *
976 textureB.getAccess().getPixel(
977 deClamp32((int32_t)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
978 }
979 else
980 {
981 // Do a vertical blur
982 blurColor += 0.12f * textureA.getAccess().getPixel(
983 x, deClamp32((int32_t)y - (m_blurKernel / 2) + sampleNdx, 0u,
984 m_height - 1u));
985 }
986 }
987
988 renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) :
989 textureB.getAccess().setPixel(blurColor, x, y);
990 }
991 }
992 }
993
994 reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;
995
996 {
997 // Allow error of 4 times the minimum presentable difference
998 const Vec4 threshold(
999 4.0f * 1.0f /
1000 ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<uint32_t>()) - 1u).cast<float>());
1001
1002 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access,
1003 threshold, tcu::COMPARE_LOG_ON_ERROR))
1004 m_resultCollector.fail("Compare failed.");
1005 }
1006 }
1007
1008 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1009 }
1010
1011 struct SubpassTestConfig
1012 {
SubpassTestConfigvkt::__anonc414995a0111::SubpassTestConfig1013 SubpassTestConfig(VkFormat format_, UVec2 imageSize_, RenderPass renderPass_, SharedGroupParams groupParams_)
1014 : format(format_)
1015 , imageSize(imageSize_)
1016 , renderPass(renderPass_)
1017 , groupParams(groupParams_)
1018 {
1019 }
1020
1021 VkFormat format;
1022 UVec2 imageSize;
1023 RenderPass renderPass;
1024 SharedGroupParams groupParams;
1025 };
1026
1027 class SubpassDependencyTestInstance : public TestInstance
1028 {
1029 public:
1030 SubpassDependencyTestInstance(Context &context, SubpassTestConfig testConfig);
1031
1032 ~SubpassDependencyTestInstance(void) = default;
1033
1034 vector<SharedPtrVkImage> createAndAllocateImages(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
1035 vector<de::SharedPtr<Allocation>> &imageMemories,
1036 uint32_t universalQueueFamilyIndex, RenderPass renderPassInfo,
1037 VkFormat format, uint32_t width, uint32_t height);
1038
1039 vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts(
1040 const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1041 vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts);
1042
1043 vector<SharedPtrVkPipeline> createRenderPipelines(const DeviceInterface &vkd, VkDevice device,
1044 RenderPass renderPassInfo, VkRenderPass renderPass,
1045 vector<SharedPtrVkPipelineLayout> &pipelineLayouts,
1046 const BinaryCollection &binaryCollection, VkFormat format,
1047 uint32_t width, uint32_t height);
1048
1049 Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1050 VkRenderPass renderPass, vector<SharedPtrVkImageView> &dstImageViews,
1051 uint32_t width, uint32_t height);
1052
1053 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts(const DeviceInterface &vkd, VkDevice device,
1054 RenderPass renderPassInfo);
1055
1056 vector<SharedPtrVkDescriptorSet> createDescriptorSets(const DeviceInterface &vkd, VkDevice device, VkFormat format,
1057 vector<SharedPtrVkDescriptorPool> &pools,
1058 vector<SharedPtrVkDescriptorLayout> &layouts,
1059 vector<SharedPtrVkImageView> &imageViews);
1060
1061 tcu::TestStatus iterate(void);
1062
1063 template <typename RenderpassSubpass>
1064 tcu::TestStatus iterateInternal(void);
1065
1066 private:
1067 const RenderPass m_renderPassInfo;
1068 const SharedGroupParams m_groupParams;
1069
1070 const uint32_t m_width;
1071 const uint32_t m_height;
1072 const VkFormat m_format;
1073
1074 vector<de::SharedPtr<Allocation>> m_imageMemories;
1075 vector<SharedPtrVkImage> m_images;
1076 vector<SharedPtrVkImageView> m_imageViews;
1077
1078 const Unique<VkBuffer> m_primaryBuffer;
1079 const Unique<VkBuffer> m_secondaryBuffer;
1080 const de::UniquePtr<Allocation> m_primaryBufferMemory;
1081 const de::UniquePtr<Allocation> m_secondaryBufferMemory;
1082
1083 const Unique<VkRenderPass> m_renderPass;
1084 const Unique<VkFramebuffer> m_framebuffer;
1085
1086 vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
1087 vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
1088 vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
1089
1090 vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
1091 vector<SharedPtrVkPipeline> m_renderPipelines;
1092
1093 const Unique<VkCommandPool> m_commandPool;
1094 tcu::ResultCollector m_resultCollector;
1095 };
1096
SubpassDependencyTestInstance(Context & context,SubpassTestConfig testConfig)1097 SubpassDependencyTestInstance::SubpassDependencyTestInstance(Context &context, SubpassTestConfig testConfig)
1098 : TestInstance(context)
1099 , m_renderPassInfo(testConfig.renderPass)
1100 , m_groupParams(testConfig.groupParams)
1101 , m_width(testConfig.imageSize.x())
1102 , m_height(testConfig.imageSize.y())
1103 , m_format(testConfig.format)
1104 , m_images(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(),
1105 m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo,
1106 m_format, m_width, m_height))
1107 , m_imageViews(
1108 createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format,
1109 isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
1110 , m_primaryBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1111 , m_secondaryBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1112 , m_primaryBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
1113 context.getDefaultAllocator(), *m_primaryBuffer))
1114 , m_secondaryBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
1115 context.getDefaultAllocator(), *m_secondaryBuffer))
1116 , m_renderPass(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1117 m_groupParams->renderingType))
1118 , m_framebuffer(createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1119 *m_renderPass, m_imageViews, m_width, m_height))
1120 , m_subpassDescriptorSetLayouts(
1121 createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
1122 , m_subpassDescriptorPools(createDescriptorPools(context.getDeviceInterface(), context.getDevice(),
1123 m_subpassDescriptorSetLayouts,
1124 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
1125 , m_subpassDescriptorSets(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format,
1126 m_subpassDescriptorPools, m_subpassDescriptorSetLayouts,
1127 m_imageViews))
1128 , m_renderPipelineLayouts(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(),
1129 m_renderPassInfo, m_subpassDescriptorSetLayouts))
1130 , m_renderPipelines(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1131 *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(),
1132 m_format, m_width, m_height))
1133 , m_commandPool(createCommandPool(context.getDeviceInterface(), context.getDevice(),
1134 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1135 {
1136 }
1137
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,uint32_t universalQueueFamilyIndex,RenderPass renderPassInfo,VkFormat format,uint32_t width,uint32_t height)1138 vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages(
1139 const DeviceInterface &vk, VkDevice device, Allocator &allocator, vector<de::SharedPtr<Allocation>> &imageMemories,
1140 uint32_t universalQueueFamilyIndex, RenderPass renderPassInfo, VkFormat format, uint32_t width, uint32_t height)
1141 {
1142 // Verify format support
1143 {
1144 const VkFormatFeatureFlags flags =
1145 (isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT :
1146 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) |
1147 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
1148 const VkFormatProperties properties = vk::getPhysicalDeviceFormatProperties(
1149 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);
1150
1151 if ((properties.optimalTilingFeatures & flags) != flags)
1152 TCU_THROW(NotSupportedError, "Format not supported");
1153 }
1154
1155 vector<SharedPtrVkImage> images;
1156
1157 for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
1158 {
1159 const VkExtent3D imageExtent = {
1160 width, // uint32_t width
1161 height, // uint32_t height
1162 1u // uint32_t depth
1163 };
1164
1165 VkImageUsageFlags usage = ((isDepthStencilFormat(format) ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT :
1166 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) |
1167 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1168
1169 const VkImageCreateInfo imageCreateInfo = {
1170 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1171 DE_NULL, // const void* pNext
1172 0u, // VkImageCreateFlags flags
1173 VK_IMAGE_TYPE_2D, // VkImageType imageType
1174 format, // VkFormat format
1175 imageExtent, // VkExtent3D extent
1176 1u, // uint32_t mipLevels
1177 1u, // uint32_t arrayLayers
1178 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1179 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1180 usage, // VkImageUsageFlags usage
1181 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1182 1u, // uint32_t queueFamilyIndexCount
1183 &universalQueueFamilyIndex, // const uint32_t* pQueueFamilyIndices
1184 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1185 };
1186
1187 images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
1188 imageMemories.push_back(
1189 (de::SharedPtr<Allocation>)allocator
1190 .allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any)
1191 .release());
1192 VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(),
1193 imageMemories[imageNdx]->getOffset()));
1194 }
1195
1196 return images;
1197 }
1198
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)1199 vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts(
1200 const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1201 vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)
1202 {
1203 vector<SharedPtrVkPipelineLayout> pipelineLayouts;
1204 vector<VkDescriptorSetLayout> descriptorSetLayoutHandles;
1205 const size_t descriptorSetLayoutCount = descriptorSetLayouts.size();
1206
1207 for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
1208 descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));
1209
1210 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1211 {
1212 const VkPipelineLayoutCreateInfo createInfo = {
1213 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
1214 DE_NULL, // const void* pNext
1215 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
1216 (uint32_t)descriptorSetLayoutCount, // uint32_t setLayoutCount
1217 descriptorSetLayoutHandles.data(), // const VkDescriptorSetLayout* pSetLayouts
1218 0u, // uint32_t pushConstantRangeCount
1219 DE_NULL // const VkPushConstantRange* pPushConstantRanges
1220 };
1221
1222 pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
1223 }
1224
1225 return pipelineLayouts;
1226 }
1227
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,VkFormat format,uint32_t width,uint32_t height)1228 vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines(
1229 const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo, VkRenderPass renderPass,
1230 vector<SharedPtrVkPipelineLayout> &pipelineLayouts, const BinaryCollection &binaryCollection, VkFormat format,
1231 uint32_t width, uint32_t height)
1232 {
1233 vector<SharedPtrVkPipeline> pipelines;
1234
1235 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1236 {
1237 const Unique<VkShaderModule> vertexShaderModule(
1238 createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
1239 const Unique<VkShaderModule> fragmentShaderModule(
1240 createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));
1241
1242 const VkVertexInputBindingDescription vertexBinding0 = {
1243 0u, // uint32_t binding;
1244 sizeof(Vec4), // uint32_t strideInBytes;
1245 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1246 };
1247
1248 VkVertexInputAttributeDescription attr0 = {
1249 0u, // uint32_t location;
1250 0u, // uint32_t binding;
1251 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1252 0u // uint32_t offsetInBytes;
1253 };
1254
1255 const VkPipelineVertexInputStateCreateInfo vertexInputState = {
1256 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1257 DE_NULL, // const void* pNext
1258 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
1259 1u, // uint32_t vertexBindingDescriptionCount
1260 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1261 1u, // uint32_t vertexAttributeDescriptionCount
1262 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1263 };
1264
1265 const VkStencilOpState stencilOpState = {
1266 VK_STENCIL_OP_KEEP, // stencilFailOp
1267 VK_STENCIL_OP_KEEP, // stencilPassOp
1268 VK_STENCIL_OP_KEEP, // stencilDepthFailOp
1269 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1270 0x0u, // stencilCompareMask
1271 0x0u, // stencilWriteMask
1272 0u // stencilReference
1273 };
1274
1275 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
1276 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1277 DE_NULL, // const void* pNext
1278 0u, // VkPipelineDepthStencilStateCreateFlags flags
1279 VK_TRUE, // VkBool32 depthTestEnable
1280 VK_TRUE, // VkBool32 depthWriteEnable
1281 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp
1282 VK_FALSE, // VkBool32 depthBoundsTestEnable
1283 VK_TRUE, // VkBool32 stencilTestEnable
1284 stencilOpState, // VkStencilOpState front
1285 stencilOpState, // VkStencilOpState back
1286 0.0f, // float minDepthBounds
1287 1.0f, // float maxDepthBounds
1288 };
1289
1290 const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(width, height)));
1291 const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(width, height)));
1292 const VkPipelineLayout layout(**pipelineLayouts[subpassNdx]);
1293 const VkPipelineDepthStencilStateCreateInfo depthStencilCreateInfo(
1294 isDepthStencilFormat(format) ? depthStencilStateCreateInfo : VkPipelineDepthStencilStateCreateInfo());
1295
1296 pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
1297 vkd, // const DeviceInterface& vk
1298 device, // const VkDevice device
1299 layout, // const VkPipelineLayout pipelineLayout
1300 *vertexShaderModule, // const VkShaderModule vertexShaderModule
1301 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1302 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1303 DE_NULL, // const VkShaderModule geometryShaderModule
1304 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1305 renderPass, // const VkRenderPass renderPass
1306 viewports, // const std::vector<VkViewport>& viewports
1307 scissors, // const std::vector<VkRect2D>& scissors
1308 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1309 (uint32_t)subpassNdx, // const uint32_t subpass
1310 0u, // const uint32_t patchControlPoints
1311 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1312 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1313 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1314 &depthStencilCreateInfo, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1315 DE_NULL))); // const VkPipelineDynamicStateCreateInfo* pDynamicState
1316 }
1317
1318 return pipelines;
1319 }
1320
createFramebuffer(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkImageView> & dstImageViews,uint32_t width,uint32_t height)1321 Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer(const DeviceInterface &vkd, VkDevice device,
1322 RenderPass renderPassInfo, VkRenderPass renderPass,
1323 vector<SharedPtrVkImageView> &dstImageViews,
1324 uint32_t width, uint32_t height)
1325 {
1326 const size_t attachmentCount(renderPassInfo.getAttachments().size());
1327 vector<VkImageView> attachmentHandles;
1328
1329 for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1330 attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));
1331
1332 const VkFramebufferCreateInfo createInfo = {
1333 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
1334 DE_NULL, // const void* pNext
1335 0u, // VkFramebufferCreateFlags flags
1336 renderPass, // VkRenderPass renderPass
1337 (uint32_t)attachmentCount, // uint32_t attachmentCount
1338 attachmentHandles.data(), // const VkImageView* pAttachments
1339 width, // uint32_t width
1340 height, // uint32_t height
1341 1u // uint32_t layers
1342 };
1343
1344 return vk::createFramebuffer(vkd, device, &createInfo);
1345 }
1346
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo)1347 vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts(
1348 const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo)
1349 {
1350 vector<SharedPtrVkDescriptorLayout> layouts;
1351
1352 size_t attachmentCount = renderPassInfo.getAttachments().size();
1353
1354 for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
1355 {
1356 const VkDescriptorSetLayoutBinding bindings = {
1357 0u, // uint32_t binding
1358 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1359 1u, // uint32_t descriptorCount
1360 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
1361 DE_NULL // const VkSampler* pImmutableSamplers
1362 };
1363
1364 const VkDescriptorSetLayoutCreateInfo createInfo = {
1365 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
1366 DE_NULL, // const void* pNext
1367 0u, // VkDescriptorSetLayoutCreateFlags flags
1368 1u, // uint32_t bindingCount
1369 &bindings // const VkDescriptorSetLayoutBinding* pBindings
1370 };
1371
1372 layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
1373 }
1374
1375 return layouts;
1376 }
1377
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,VkFormat format,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews)1378 vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets(
1379 const DeviceInterface &vkd, VkDevice device, VkFormat format, vector<SharedPtrVkDescriptorPool> &pools,
1380 vector<SharedPtrVkDescriptorLayout> &layouts, vector<SharedPtrVkImageView> &imageViews)
1381 {
1382 vector<SharedPtrVkDescriptorSet> descriptorSets;
1383
1384 for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
1385 {
1386 const VkDescriptorSetAllocateInfo allocateInfo = {
1387 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
1388 DE_NULL, // const void* pNext
1389 **pools[setNdx], // VkDescriptorPool descriptorPool
1390 1u, // uint32_t descriptorSetCount
1391 &**layouts[setNdx] // const VkDescriptorSetLayout* pSetLayouts
1392 };
1393
1394 descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
1395
1396 {
1397 VkImageLayout imageLayout = isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL :
1398 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1399
1400 const VkDescriptorImageInfo imageInfo = {
1401 DE_NULL, // VkSampler sampler
1402 **imageViews[setNdx], // VkImageView imageView
1403 imageLayout // VkImageLayout imageLayout
1404 };
1405
1406 const VkWriteDescriptorSet write = {
1407 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1408 DE_NULL, // const void* pNext
1409 **descriptorSets[setNdx], // VkDescriptorSet dstSet
1410 0u, // uint32_t dstBinding
1411 0u, // uint32_t dstArrayElement
1412 1u, // uint32_t descriptorCount
1413 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1414 &imageInfo, // const VkDescriptorImageInfo* pImageInfo
1415 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
1416 DE_NULL // const VkBufferView* pTexelBufferView
1417 };
1418
1419 vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
1420 }
1421 }
1422
1423 return descriptorSets;
1424 }
1425
iterate(void)1426 tcu::TestStatus SubpassDependencyTestInstance::iterate(void)
1427 {
1428 switch (m_groupParams->renderingType)
1429 {
1430 case RENDERING_TYPE_RENDERPASS_LEGACY:
1431 return iterateInternal<RenderpassSubpass1>();
1432 case RENDERING_TYPE_RENDERPASS2:
1433 return iterateInternal<RenderpassSubpass2>();
1434 default:
1435 TCU_THROW(InternalError, "Impossible");
1436 }
1437 }
1438
1439 template <typename RenderpassSubpass>
iterateInternal(void)1440 tcu::TestStatus SubpassDependencyTestInstance::iterateInternal(void)
1441 {
1442 de::Random rand(5);
1443 const DeviceInterface &vkd(m_context.getDeviceInterface());
1444 const Unique<VkCommandBuffer> commandBuffer(
1445 allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1446 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1447 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
1448 const size_t attachmentCount(m_renderPassInfo.getAttachments().size());
1449 const size_t subpassCount(m_renderPassInfo.getSubpasses().size());
1450 vector<VkClearValue> clearValues;
1451 vector<Vec4> vertexData;
1452
1453 beginCommandBuffer(vkd, *commandBuffer);
1454
1455 // Transition stencil aspects to the final layout directly.
1456 if (isDepthStencilFormat(m_format))
1457 {
1458 const VkImageSubresourceRange imageSubresourceRange = {
1459 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask
1460 0u, // uint32_t baseMipLevel
1461 1u, // uint32_t levelCount
1462 0u, // uint32_t baseArrayLayer
1463 1u // uint32_t layerCount
1464 };
1465
1466 VkImageMemoryBarrier barrier = {
1467 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1468 DE_NULL, // const void* pNext
1469 0u, // VkAccessFlags srcAccessMask
1470 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1471 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1472 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, // VkImageLayout newLayout
1473 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1474 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1475 DE_NULL, // VkImage image
1476 imageSubresourceRange // VkImageSubresourceRange subresourceRange
1477 };
1478
1479 for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; ++attachmentNdx)
1480 {
1481 barrier.image = **m_images[attachmentNdx];
1482 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1483 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1484 }
1485 }
1486
1487 // Begin render pass
1488 {
1489 VkRect2D renderArea = {
1490 {0u, 0u}, // VkOffset2D offset
1491 {m_width, m_height} // VkExtent2D extent
1492 };
1493
1494 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1495 clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) :
1496 makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
1497
1498 const VkRenderPassBeginInfo beginInfo = {
1499 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
1500 DE_NULL, // const void* pNext
1501 *m_renderPass, // VkRenderPass renderPass
1502 *m_framebuffer, // VkFramebuffer framebuffer
1503 renderArea, // VkRect2D renderArea
1504 (uint32_t)attachmentCount, // uint32_t clearValueCount
1505 clearValues.data() // const VkClearValue* pClearValues
1506 };
1507
1508 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1509 }
1510
1511 // Generate vertices for 128 triangles with pseudorandom positions and depths values
1512 for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
1513 {
1514 float primitiveDepth = rand.getFloat();
1515
1516 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1517 {
1518 float x = 2.0f * rand.getFloat() - 1.0f;
1519 float y = 2.0f * rand.getFloat() - 1.0f;
1520
1521 vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
1522 }
1523 }
1524
1525 const size_t singleVertexDataSize = sizeof(Vec4);
1526 const size_t vertexCount = vertexData.size();
1527 const size_t vertexDataSize = vertexCount * singleVertexDataSize;
1528 const uint32_t queueFamilyIndices = m_context.getUniversalQueueFamilyIndex();
1529
1530 const VkBufferCreateInfo vertexBufferParams = {
1531 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1532 DE_NULL, // const void* pNext;
1533 0u, // VkBufferCreateFlags flags;
1534 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
1535 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1536 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1537 1u, // uint32_t queueFamilyCount;
1538 &queueFamilyIndices, // const uint32_t* pQueueFamilyIndices;
1539 };
1540
1541 const Unique<VkBuffer> vertexBuffer(createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
1542 const de::UniquePtr<Allocation> vertexBufferMemory(m_context.getDefaultAllocator().allocate(
1543 getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));
1544
1545 VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(),
1546 vertexBufferMemory->getOffset()));
1547
1548 const VkDeviceSize bindingOffset = 0;
1549 vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
1550
1551 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1552 {
1553 if (subpassNdx > 0)
1554 {
1555 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1556 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1557 **m_renderPipelineLayouts[subpassNdx], 0, 1,
1558 &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
1559 }
1560
1561 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);
1562
1563 if (subpassNdx == 0)
1564 {
1565 // Upload vertex data
1566 {
1567 void *vertexBufPtr = vertexBufferMemory->getHostPtr();
1568 deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
1569 flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
1570 }
1571
1572 vkd.cmdDraw(*commandBuffer, (uint32_t)vertexData.size(), 1u, 0u, 0u);
1573 }
1574 else
1575 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1576 }
1577
1578 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1579
1580 // Memory barrier between rendering and copy
1581 {
1582 const VkImageAspectFlags imageAspectFlags = isDepthStencilFormat(m_format) ?
1583 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT :
1584 VK_IMAGE_ASPECT_COLOR_BIT;
1585 const VkAccessFlags srcAccessMask = isDepthStencilFormat(m_format) ?
1586 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT :
1587 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1588 const VkImageLayout oldLayout = isDepthStencilFormat(m_format) ?
1589 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL :
1590 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1591 const VkPipelineStageFlags srcStageMask = isDepthStencilFormat(m_format) ?
1592 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT :
1593 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1594
1595 VkImageSubresourceRange imageSubresourceRange = {
1596 imageAspectFlags, // VkImageAspectFlags aspectMask
1597 0u, // uint32_t baseMipLevel
1598 1u, // uint32_t levelCount
1599 0u, // uint32_t baseArrayLayer
1600 1u // uint32_t layerCount
1601 };
1602
1603 const VkImageMemoryBarrier barrier = {
1604 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1605 DE_NULL, // const void* pNext
1606 srcAccessMask, // VkAccessFlags srcAccessMask
1607 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1608 oldLayout, // VkImageLayout oldLayout
1609 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
1610 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1611 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1612 **m_images[attachmentCount - 1], // VkImage image
1613 imageSubresourceRange // VkImageSubresourceRange subresourceRange
1614 };
1615
1616 vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u,
1617 DE_NULL, 1u, &barrier);
1618 }
1619
1620 // Copy image memory to buffer
1621 {
1622 if (isDepthStencilFormat(m_format))
1623 {
1624 // Copy depth
1625 const VkImageSubresourceLayers subresourceLayersDepth = {
1626 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
1627 0u, // uint32_t mipLevel
1628 0u, // uint32_t baseArrayLayer
1629 1u // uint32_t layerCount
1630 };
1631
1632 const VkBufferImageCopy regionDepth = {
1633 0u, // VkDeviceSize bufferOffset
1634 0u, // uint32_t bufferRowLength
1635 0u, // uint32_t bufferImageHeight
1636 subresourceLayersDepth, // VkImageSubresourceLayers imageSubresource
1637 {0u, 0u, 0u}, // VkOffset3D imageOffset
1638 {m_width, m_height, 1u} // VkExtent3D imageExtent
1639 };
1640
1641 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1642 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, ®ionDepth);
1643
1644 // Copy stencil
1645 const VkImageSubresourceLayers subresourceLayersStencil = {
1646 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask
1647 0u, // uint32_t mipLevel
1648 0u, // uint32_t baseArrayLayer
1649 1u // uint32_t layerCount
1650 };
1651
1652 const VkBufferImageCopy regionStencil = {
1653 0u, // VkDeviceSize bufferOffset
1654 0u, // uint32_t bufferRowLength
1655 0u, // uint32_t bufferImageHeight
1656 subresourceLayersStencil, // VkImageSubresourceLayers imageSubresource
1657 {0u, 0u, 0u}, // VkOffset3D imageOffset
1658 {m_width, m_height, 1u} // VkExtent3D imageExtent
1659 };
1660
1661 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1662 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, ®ionStencil);
1663 }
1664 else
1665 {
1666 // Copy color
1667 const VkImageSubresourceLayers imageSubresourceLayers = {
1668 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1669 0u, // uint32_t mipLevel
1670 0u, // uint32_t baseArrayLayer
1671 1u // uint32_t layerCount
1672 };
1673
1674 const VkBufferImageCopy region = {
1675 0u, // VkDeviceSize bufferOffset
1676 0u, // uint32_t bufferRowLength
1677 0u, // uint32_t bufferImageHeight
1678 imageSubresourceLayers, // VkImageSubresourceLayers imageSubresource
1679 {0u, 0u, 0u}, // VkOffset3D imageOffset
1680 {m_width, m_height, 1u} // VkExtent3D imageExtent
1681 };
1682
1683 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1684 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, ®ion);
1685 }
1686 }
1687
1688 // Memory barrier between copy and host access
1689 {
1690 const VkBufferMemoryBarrier barrier = {
1691 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
1692 DE_NULL, // const void* pNext
1693 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1694 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
1695 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1696 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1697 *m_primaryBuffer, // VkBuffer buffer
1698 0u, // VkDeviceSize offset
1699 VK_WHOLE_SIZE // VkDeviceSize size
1700 };
1701
1702 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1703 DE_NULL, 1u, &barrier, 0u, DE_NULL);
1704
1705 if (isDepthStencilFormat(m_format))
1706 {
1707 const VkBufferMemoryBarrier stencilBarrier = {
1708 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
1709 DE_NULL, // const void* pNext
1710 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1711 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
1712 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1713 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1714 *m_secondaryBuffer, // VkBuffer buffer
1715 0u, // VkDeviceSize offset
1716 VK_WHOLE_SIZE // VkDeviceSize size
1717 };
1718
1719 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1720 DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
1721 }
1722 }
1723
1724 endCommandBuffer(vkd, *commandBuffer);
1725 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
1726 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(),
1727 m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1728 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(),
1729 m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1730
1731 // Verify result
1732 {
1733 const tcu::TextureFormat format(mapVkFormat(m_format));
1734
1735 if (isDepthStencilFormat(m_format))
1736 {
1737 const void *const ptrDepth(m_primaryBufferMemory->getHostPtr());
1738 const void *const ptrStencil(m_secondaryBufferMemory->getHostPtr());
1739 tcu::TextureLevel reference(format, m_width, m_height);
1740 tcu::TextureLevel colorBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
1741 const tcu::ConstPixelBufferAccess resultDepthAccess(getDepthCopyFormat(m_format), m_width, m_height, 1,
1742 ptrDepth);
1743 const tcu::ConstPixelBufferAccess resultStencilAccess(getStencilCopyFormat(m_format), m_width, m_height, 1,
1744 ptrStencil);
1745 const PixelBufferAccess referenceDepthAccess(
1746 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
1747 const PixelBufferAccess referenceStencilAccess(
1748 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
1749
1750 tcu::clearDepth(referenceDepthAccess, 1.0f);
1751 tcu::clearStencil(referenceStencilAccess, 255);
1752
1753 // Setup and run reference renderer
1754 {
1755 const DepthVertShader vertShader;
1756 const DepthFragShader fragShader;
1757 const rr::Renderer renderer;
1758 const rr::Program program(&vertShader, &fragShader);
1759 const rr::MultisamplePixelBufferAccess depthBuffer(
1760 rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
1761 const rr::MultisamplePixelBufferAccess colorBufferAccess(
1762 rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
1763 const rr::RenderTarget renderTarget(rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer,
1764 rr::MultisamplePixelBufferAccess());
1765 const rr::PrimitiveType primitiveType(rr::PRIMITIVETYPE_TRIANGLES);
1766 const rr::PrimitiveList primitiveList(rr::PrimitiveList(primitiveType, (uint32_t)vertexData.size(), 0));
1767 rr::RenderState renderState((rr::ViewportState(depthBuffer)),
1768 m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1769
1770 const rr::VertexAttrib vertices =
1771 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);
1772
1773 renderState.fragOps.depthTestEnabled = true;
1774 renderState.fragOps.depthFunc = rr::TESTFUNC_LEQUAL;
1775
1776 renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
1777 }
1778
1779 for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
1780 {
1781 for (int y = 0; y < reference.getHeight(); y++)
1782 for (int x = 0; x < reference.getWidth(); x++)
1783 reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
1784 }
1785
1786 // Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
1787 const float depthThreshold(
1788 (float)subpassCount *
1789 (1.0f /
1790 ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<uint32_t>()) -
1791 1u)
1792 .cast<float>()
1793 .x()));
1794
1795 if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
1796 m_resultCollector.fail("Depth compare failed.");
1797
1798 if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
1799 m_resultCollector.fail("Stencil compare failed.");
1800 }
1801 else
1802 DE_FATAL("Not implemented");
1803 }
1804
1805 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1806 }
1807
1808 struct SubpassSelfDependencyBackwardsTestConfig
1809 {
SubpassSelfDependencyBackwardsTestConfigvkt::__anonc414995a0111::SubpassSelfDependencyBackwardsTestConfig1810 SubpassSelfDependencyBackwardsTestConfig(VkFormat format_, UVec2 imageSize_, RenderingType renderingType_)
1811 : format(format_)
1812 , imageSize(imageSize_)
1813 , renderingType(renderingType_)
1814 {
1815 }
1816
1817 VkFormat format;
1818 UVec2 imageSize;
1819 RenderingType renderingType;
1820 };
1821
1822 class SubpassSelfDependencyBackwardsTestInstance : public TestInstance
1823 {
1824 public:
1825 SubpassSelfDependencyBackwardsTestInstance(Context &context, SubpassSelfDependencyBackwardsTestConfig testConfig);
1826
1827 ~SubpassSelfDependencyBackwardsTestInstance(void);
1828
1829 tcu::TestStatus iterate(void);
1830
1831 template <typename RenderpassSubpass>
1832 tcu::TestStatus iterateInternal(void);
1833
1834 private:
1835 const bool m_extensionSupported;
1836 const bool m_featuresSupported;
1837 const RenderingType m_renderingType;
1838
1839 const uint32_t m_width;
1840 const uint32_t m_height;
1841 const VkFormat m_format;
1842 tcu::ResultCollector m_resultCollector;
1843 };
1844
SubpassSelfDependencyBackwardsTestInstance(Context & context,SubpassSelfDependencyBackwardsTestConfig testConfig)1845 SubpassSelfDependencyBackwardsTestInstance::SubpassSelfDependencyBackwardsTestInstance(
1846 Context &context, SubpassSelfDependencyBackwardsTestConfig testConfig)
1847 : TestInstance(context)
1848 , m_extensionSupported((testConfig.renderingType == RENDERING_TYPE_RENDERPASS2) &&
1849 context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1850 , m_featuresSupported(context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
1851 , m_renderingType(testConfig.renderingType)
1852 , m_width(testConfig.imageSize.x())
1853 , m_height(testConfig.imageSize.y())
1854 , m_format(testConfig.format)
1855 {
1856 }
1857
~SubpassSelfDependencyBackwardsTestInstance(void)1858 SubpassSelfDependencyBackwardsTestInstance::~SubpassSelfDependencyBackwardsTestInstance(void)
1859 {
1860 }
1861
iterate(void)1862 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterate(void)
1863 {
1864 switch (m_renderingType)
1865 {
1866 case RENDERING_TYPE_RENDERPASS_LEGACY:
1867 return iterateInternal<RenderpassSubpass1>();
1868 case RENDERING_TYPE_RENDERPASS2:
1869 return iterateInternal<RenderpassSubpass2>();
1870 default:
1871 TCU_THROW(InternalError, "Impossible");
1872 }
1873 }
1874
1875 template <typename RenderpassSubpass>
iterateInternal(void)1876 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterateInternal(void)
1877 {
1878 de::Random rand(5);
1879 const DeviceInterface &vkd(m_context.getDeviceInterface());
1880 const VkDevice device = m_context.getDevice();
1881 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1882 const Unique<VkCommandPool> commandPool(
1883 createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1884 const Unique<VkCommandBuffer> commandBuffer(
1885 allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1886 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1887 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
1888 vector<Vec4> vertexData;
1889 Move<VkImage> outputImage;
1890 de::MovePtr<Allocation> outputImageAllocation;
1891 Move<VkImageView> outputImageView;
1892 Move<VkPipelineLayout> pipelineLayout;
1893 Move<VkPipeline> renderPipeline;
1894 Move<VkFramebuffer> framebuffer;
1895 Move<VkRenderPass> renderPass;
1896 Move<VkBuffer> indirectBuffer;
1897 de::MovePtr<Allocation> indirectBufferMemory;
1898 Move<VkBuffer> resultBuffer;
1899 de::MovePtr<Allocation> resultBufferMemory;
1900 const VkDeviceSize indirectBufferSize = 4 * sizeof(uint32_t);
1901 Move<VkBuffer> vertexBuffer;
1902 de::MovePtr<Allocation> vertexBufferMemory;
1903
1904 // Create output image.
1905 {
1906 const VkExtent3D imageExtent = {
1907 m_width, // uint32_t width
1908 m_height, // uint32_t height
1909 1u // uint32_t depth
1910 };
1911
1912 VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1913
1914 const VkImageCreateInfo imageCreateInfo = {
1915 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1916 DE_NULL, // const void* pNext
1917 0u, // VkImageCreateFlags flags
1918 VK_IMAGE_TYPE_2D, // VkImageType imageType
1919 m_format, // VkFormat format
1920 imageExtent, // VkExtent3D extent
1921 1u, // uint32_t mipLevels
1922 1u, // uint32_t arrayLayers
1923 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1924 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1925 usage, // VkImageUsageFlags usage
1926 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1927 1u, // uint32_t queueFamilyIndexCount
1928 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
1929 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1930 };
1931
1932 outputImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
1933 outputImageAllocation = m_context.getDefaultAllocator().allocate(
1934 getImageMemoryRequirements(vkd, device, *outputImage), MemoryRequirement::Any);
1935 VK_CHECK(vkd.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(),
1936 outputImageAllocation->getOffset()));
1937 }
1938
1939 // Create indirect buffer and initialize.
1940 {
1941 const VkBufferUsageFlags bufferUsage(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1942 const VkBufferCreateInfo bufferCreateInfo = {
1943 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
1944 DE_NULL, // const void* pNext
1945 0u, // VkBufferCreateFlags flags
1946 indirectBufferSize, // VkDeviceSize size
1947 bufferUsage, // VkBufferUsageFlags usage
1948 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1949 0u, // uint32_t queueFamilyIndexCount
1950 DE_NULL // const uint32_t* pQueueFamilyIndices
1951 };
1952
1953 indirectBuffer = createBuffer(vkd, device, &bufferCreateInfo);
1954 indirectBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *indirectBuffer);
1955
1956 VkDrawIndirectCommand drawIndirectCommand = {
1957 64u, // uint32_t vertexCount
1958 1u, // uint32_t instanceCount
1959 0u, // uint32_t firstVertex
1960 0u, // uint32_t firstInstance
1961 };
1962
1963 deMemcpy(indirectBufferMemory->getHostPtr(), (void *)&drawIndirectCommand, sizeof(VkDrawIndirectCommand));
1964 flushAlloc(vkd, device, *indirectBufferMemory);
1965 }
1966
1967 // Create result buffer.
1968 {
1969 resultBuffer = createBuffer(vkd, device, m_format, m_width, m_height);
1970 resultBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
1971 }
1972
1973 // Create descriptor set layout.
1974 Unique<VkDescriptorSetLayout> descriptorSetLayout(
1975 DescriptorSetLayoutBuilder()
1976 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
1977 .build(vkd, device));
1978 // Create descriptor pool.
1979 Unique<VkDescriptorPool> descriptorPool(
1980 DescriptorPoolBuilder()
1981 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
1982 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1983 // Create descriptor set.
1984 Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
1985
1986 // Update descriptor set information.
1987 {
1988 VkDescriptorBufferInfo descIndirectBuffer = makeDescriptorBufferInfo(*indirectBuffer, 0, indirectBufferSize);
1989
1990 DescriptorSetUpdateBuilder()
1991 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1992 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descIndirectBuffer)
1993 .update(vkd, device);
1994 }
1995
1996 // Create render pipeline layout.
1997 {
1998 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1999 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
2000 DE_NULL, // const void* pNext
2001 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
2002 1u, // uint32_t setLayoutCount
2003 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts
2004 0u, // uint32_t pushConstantRangeCount
2005 DE_NULL // const VkPushConstantRange* pPushConstantRanges
2006 };
2007
2008 pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2009 }
2010
2011 // Create render pass.
2012 {
2013 vector<Attachment> attachments;
2014 vector<AttachmentReference> colorAttachmentReferences;
2015
2016 attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2017 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2018 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
2019 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2020 colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2021
2022 const vector<Subpass> subpasses(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
2023 colorAttachmentReferences, vector<AttachmentReference>(),
2024 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
2025 vector<uint32_t>()));
2026 vector<SubpassDependency> deps;
2027
2028 deps.push_back(SubpassDependency(0u, // uint32_t srcPass
2029 0u, // uint32_t dstPass
2030 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, // VkPipelineStageFlags srcStageMask
2031 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags dstStageMask
2032 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
2033 VK_ACCESS_INDIRECT_COMMAND_READ_BIT, // VkAccessFlags dstAccessMask
2034 0)); // VkDependencyFlags flags
2035
2036 renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, deps), m_renderingType);
2037 }
2038
2039 // Create render pipeline.
2040 {
2041 const Unique<VkShaderModule> vertexShaderModule(
2042 createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2043 const Unique<VkShaderModule> geometryShaderModule(
2044 createShaderModule(vkd, device, m_context.getBinaryCollection().get("geom"), 0u));
2045 const Unique<VkShaderModule> fragmentShaderModule(
2046 createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2047
2048 const VkVertexInputBindingDescription vertexBinding0 = {
2049 0u, // uint32_t binding;
2050 sizeof(Vec4), // uint32_t strideInBytes;
2051 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
2052 };
2053
2054 VkVertexInputAttributeDescription attr0 = {
2055 0u, // uint32_t location;
2056 0u, // uint32_t binding;
2057 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2058 0u // uint32_t offsetInBytes;
2059 };
2060
2061 const VkPipelineVertexInputStateCreateInfo vertexInputState = {
2062 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
2063 DE_NULL, // const void* pNext
2064 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
2065 1u, // uint32_t vertexBindingDescriptionCount
2066 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
2067 1u, // uint32_t vertexAttributeDescriptionCount
2068 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
2069 };
2070
2071 const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(m_width, m_height)));
2072 const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(m_width, m_height)));
2073
2074 renderPipeline = makeGraphicsPipeline(
2075 vkd, // const DeviceInterface& vk
2076 device, // const VkDevice device
2077 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2078 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2079 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2080 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2081 *geometryShaderModule, // const VkShaderModule geometryShaderModule
2082 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2083 *renderPass, // const VkRenderPass renderPass
2084 viewports, // const std::vector<VkViewport>& viewports
2085 scissors, // const std::vector<VkRect2D>& scissors
2086 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology
2087 0u, // const uint32_t subpass
2088 0u, // const uint32_t patchControlPoints
2089 &vertexInputState); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2090 }
2091
2092 // Create framebuffer.
2093 {
2094 const VkImageViewCreateInfo imageViewCreateInfo = {
2095 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2096 DE_NULL, // const void* pNext
2097 0u, // VkImageViewCreateFlags flags
2098 *outputImage, // VkImage image
2099 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2100 m_format, // VkFormat format
2101 makeComponentMappingRGBA(), // VkComponentMapping components
2102 { // VkImageSubresourceRange subresourceRange
2103 VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
2104 outputImageView = createImageView(vkd, device, &imageViewCreateInfo);
2105
2106 const VkFramebufferCreateInfo framebufferCreateInfo = {
2107 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
2108 DE_NULL, // const void* pNext
2109 0u, // VkFramebufferCreateFlags flags
2110 *renderPass, // VkRenderPass renderPass
2111 1u, // uint32_t attachmentCount
2112 &*outputImageView, // const VkImageView* pAttachments
2113 m_width, // uint32_t width
2114 m_height, // uint32_t height
2115 1u // uint32_t layers
2116 };
2117
2118 framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2119 }
2120
2121 // Generate random point locations (pixel centered to make reference comparison easier).
2122 for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
2123 {
2124 vertexData.push_back(Vec4((float)((rand.getUint32() % m_width) * 2) / (float)m_width - 1.0f,
2125 (float)((rand.getUint32() % m_height) * 2) / (float)m_height - 1.0f, 1.0f, 1.0f));
2126 }
2127
2128 // Upload vertex data.
2129 {
2130 const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
2131
2132 const VkBufferCreateInfo vertexBufferParams = {
2133 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2134 DE_NULL, // const void* pNext;
2135 0u, // VkBufferCreateFlags flags;
2136 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
2137 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2138 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2139 1u, // uint32_t queueFamilyCount;
2140 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
2141 };
2142
2143 vertexBuffer = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2144 vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2145
2146 deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2147 flushAlloc(vkd, device, *vertexBufferMemory);
2148 }
2149
2150 beginCommandBuffer(vkd, *commandBuffer);
2151 vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2152 vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
2153 &*descriptorSet, 0u, DE_NULL);
2154
2155 // Begin render pass.
2156 {
2157 VkRect2D renderArea = {
2158 {0u, 0u}, // VkOffset2D offset
2159 {m_width, m_height} // VkExtent2D extent
2160 };
2161
2162 VkClearValue clearValue = makeClearValueColor(Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2163
2164 const VkRenderPassBeginInfo beginInfo = {
2165 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
2166 DE_NULL, // const void* pNext
2167 *renderPass, // VkRenderPass renderPass
2168 *framebuffer, // VkFramebuffer framebuffer
2169 renderArea, // VkRect2D renderArea
2170 1u, // uint32_t clearValueCount
2171 &clearValue // const VkClearValue* pClearValues
2172 };
2173
2174 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2175 }
2176
2177 const VkDeviceSize bindingOffset = 0;
2178 vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2179
2180 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2181
2182 // The first indirect draw: Draw the first 64 items.
2183 vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2184
2185 // Barrier for indirect buffer.
2186 {
2187 const VkMemoryBarrier barrier = {
2188 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType
2189 DE_NULL, // const void* pNext
2190 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
2191 VK_ACCESS_INDIRECT_COMMAND_READ_BIT // VkAccessFlags dstAccessMask
2192 };
2193
2194 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
2195 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
2196 }
2197
2198 // The second indirect draw: Draw the last 64 items.
2199 vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2200
2201 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2202
2203 // Copy results to a buffer.
2204 copyImageToBuffer(vkd, *commandBuffer, *outputImage, *resultBuffer, tcu::IVec2(m_width, m_height));
2205
2206 endCommandBuffer(vkd, *commandBuffer);
2207 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2208 invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(),
2209 resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
2210
2211 // Verify result.
2212 {
2213 const tcu::TextureFormat format(mapVkFormat(m_format));
2214
2215 const void *const ptrResult(resultBufferMemory->getHostPtr());
2216 tcu::TextureLevel reference(format, m_width, m_height);
2217 const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
2218 const PixelBufferAccess referenceAccess(reference.getAccess());
2219
2220 // Setup and run reference renderer.
2221 {
2222 vector<Vec4> triangles;
2223 const float offset = 0.03f;
2224
2225 // Convert points into triangles to have quads similar to what GPU is producing from geometry shader.
2226 for (size_t vtxIdx = 0; vtxIdx < vertexData.size(); vtxIdx++)
2227 {
2228 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, offset, 0.0f, 0.0f));
2229 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2230 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2231
2232 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2233 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2234 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, -offset, 0.0f, 0.0f));
2235 }
2236
2237 const SelfDependencyBackwardsVertShader vertShader;
2238 const SelfDependencyBackwardsFragShader fragShader;
2239 const rr::Renderer renderer;
2240 const rr::Program program(&vertShader, &fragShader);
2241 const rr::MultisamplePixelBufferAccess msAccess(
2242 rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceAccess));
2243 const rr::RenderTarget renderTarget(msAccess);
2244 const rr::PrimitiveType primitiveType(rr::PRIMITIVETYPE_TRIANGLES);
2245 const rr::PrimitiveList primitiveList(rr::PrimitiveList(primitiveType, (uint32_t)triangles.size(), 0));
2246 const rr::ViewportState viewportState(msAccess);
2247 const rr::RenderState renderState(viewportState,
2248 m_context.getDeviceProperties().limits.subPixelPrecisionBits);
2249 const rr::VertexAttrib vertices =
2250 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &triangles[0]);
2251
2252 tcu::clear(referenceAccess, tcu::UVec4(0, 255, 0, 255));
2253 renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
2254 }
2255
2256 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
2257 "Color buffer", // imageSetName
2258 "", // imageSetDesc
2259 referenceAccess, // reference
2260 resultAccess, // result
2261 Vec4(0.01f), // threshold
2262 tcu::COMPARE_LOG_RESULT)) // logMode
2263 {
2264 m_resultCollector.fail("Image compare failed.");
2265 }
2266 }
2267
2268 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2269 }
2270
2271 struct SeparateChannelsTestConfig
2272 {
SeparateChannelsTestConfigvkt::__anonc414995a0111::SeparateChannelsTestConfig2273 SeparateChannelsTestConfig(VkFormat format_, SharedGroupParams groupParams_)
2274 : format(format_)
2275 , groupParams(groupParams_)
2276 {
2277 }
2278
2279 VkFormat format;
2280 SharedGroupParams groupParams;
2281 };
2282
2283 class SeparateChannelsTestInstance : public TestInstance
2284 {
2285 public:
2286 SeparateChannelsTestInstance(Context &context, SeparateChannelsTestConfig testConfig);
2287
2288 ~SeparateChannelsTestInstance(void) = default;
2289
2290 tcu::TestStatus iterate(void);
2291
2292 protected:
2293 void setup(void);
2294 #ifndef CTS_USES_VULKANSC
2295 void startDynamicRendering(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u);
2296 #endif // CTS_USES_VULKANSC
2297 void draw(VkCommandBuffer cmdBuffer);
2298 void postRenderCommands(VkCommandBuffer cmdBuffer);
2299 tcu::TestStatus verifyResults(void);
2300
2301 template <typename RenderpassSubpass>
2302 void iterateInternal(void);
2303 void iterateInternalDynamicRendering(void);
2304
2305 private:
2306 SharedGroupParams m_groupParams;
2307 const uint32_t m_width;
2308 const uint32_t m_height;
2309 const VkFormat m_format;
2310 const uint32_t m_stencilRefValue;
2311 const uint32_t m_tileSize;
2312 const tcu::Vec4 m_colorInitValues[2];
2313 const float m_depthInitValues[2];
2314 const uint32_t m_stencilInitValues[2];
2315
2316 Move<VkImage> m_colorImage;
2317 de::MovePtr<Allocation> m_colorImageAllocation;
2318 Move<VkImage> m_dsImage;
2319 de::MovePtr<Allocation> m_dsImageAllocation;
2320 Move<VkImageView> m_imageView;
2321 Move<VkImageView> m_dsImageView;
2322 PipelineLayoutWrapper m_pipelineLayout;
2323 GraphicsPipelineWrapper m_renderPipeline;
2324 Move<VkFramebuffer> m_framebuffer;
2325 Move<VkRenderPass> m_renderPass;
2326 Move<VkBuffer> m_resultBuffer0;
2327 de::MovePtr<Allocation> m_resultBuffer0Memory;
2328 Move<VkBuffer> m_resultBuffer1;
2329 de::MovePtr<Allocation> m_resultBuffer1Memory;
2330 Move<VkBuffer> m_vertexBuffer;
2331 de::MovePtr<Allocation> m_vertexBufferMemory;
2332 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2333 Move<VkDescriptorPool> m_descriptorPool;
2334 Move<VkDescriptorSet> m_descriptorSet;
2335 };
2336
SeparateChannelsTestInstance(Context & context,SeparateChannelsTestConfig testConfig)2337 SeparateChannelsTestInstance::SeparateChannelsTestInstance(Context &context, SeparateChannelsTestConfig testConfig)
2338 : TestInstance(context)
2339 , m_groupParams(testConfig.groupParams)
2340 , m_width(256u)
2341 , m_height(256u)
2342 , m_format(testConfig.format)
2343 , m_stencilRefValue(200u)
2344 , m_tileSize(32u)
2345 , m_colorInitValues{tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f)}
2346 , m_depthInitValues{0.3f, 0.7f}
2347 , m_stencilInitValues{2u, 100u}
2348 , m_renderPipeline(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
2349 context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
2350 {
2351 }
2352
iterate(void)2353 tcu::TestStatus SeparateChannelsTestInstance::iterate(void)
2354 {
2355 setup();
2356
2357 switch (m_groupParams->renderingType)
2358 {
2359 case RENDERING_TYPE_RENDERPASS_LEGACY:
2360 iterateInternal<RenderpassSubpass1>();
2361 break;
2362 case RENDERING_TYPE_RENDERPASS2:
2363 iterateInternal<RenderpassSubpass2>();
2364 break;
2365 case RENDERING_TYPE_DYNAMIC_RENDERING:
2366 iterateInternalDynamicRendering();
2367 break;
2368 default:
2369 TCU_THROW(InternalError, "Impossible");
2370 }
2371
2372 return verifyResults();
2373 }
2374
setup(void)2375 void SeparateChannelsTestInstance::setup(void)
2376 {
2377 const DeviceInterface &vkd = m_context.getDeviceInterface();
2378 const VkDevice device = m_context.getDevice();
2379 const VkQueue queue = m_context.getUniversalQueue();
2380 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2381 const bool isDSFormat = isDepthStencilFormat(m_format);
2382 const VkFormat colorFormat = isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
2383 const VkExtent3D imageExtent{
2384 m_width, // uint32_t width
2385 m_height, // uint32_t height
2386 1u // uint32_t depth
2387 };
2388
2389 // When testing color formats the same attachment is used as input and output.
2390 // This requires general layout to be used for render pass object or local_read for dynamic rendering.
2391 VkImageLayout colorImageLayout = isDSFormat ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
2392 #ifndef CTS_USES_VULKANSC
2393 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !isDSFormat)
2394 colorImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2395 #endif
2396
2397 // Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
2398 {
2399 VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
2400 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2401
2402 const VkImageCreateInfo imageCreateInfo = {
2403 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2404 DE_NULL, // const void* pNext
2405 0u, // VkImageCreateFlags flags
2406 VK_IMAGE_TYPE_2D, // VkImageType imageType
2407 colorFormat, // VkFormat format
2408 imageExtent, // VkExtent3D extent
2409 1u, // uint32_t mipLevels
2410 1u, // uint32_t arrayLayers
2411 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2412 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2413 usage, // VkImageUsageFlags usage
2414 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2415 1u, // uint32_t queueFamilyIndexCount
2416 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2417 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2418 };
2419
2420 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2421
2422 m_colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2423 m_colorImageAllocation = m_context.getDefaultAllocator().allocate(
2424 getImageMemoryRequirements(vkd, device, *m_colorImage), MemoryRequirement::Any);
2425 VK_CHECK(vkd.bindImageMemory(device, *m_colorImage, m_colorImageAllocation->getMemory(),
2426 m_colorImageAllocation->getOffset()));
2427 }
2428
2429 // Create depth/stencil image
2430 if (isDSFormat)
2431 {
2432 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2433 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2434
2435 const VkImageCreateInfo imageCreateInfo = {
2436 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2437 DE_NULL, // const void* pNext
2438 0u, // VkImageCreateFlags flags
2439 VK_IMAGE_TYPE_2D, // VkImageType imageType
2440 m_format, // VkFormat format
2441 imageExtent, // VkExtent3D extent
2442 1u, // uint32_t mipLevels
2443 1u, // uint32_t arrayLayers
2444 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2445 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2446 usage, // VkImageUsageFlags usage
2447 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2448 1u, // uint32_t queueFamilyIndexCount
2449 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2450 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2451 };
2452
2453 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2454
2455 m_dsImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2456 m_dsImageAllocation = m_context.getDefaultAllocator().allocate(
2457 getImageMemoryRequirements(vkd, device, *m_dsImage), MemoryRequirement::Any);
2458 VK_CHECK(vkd.bindImageMemory(device, *m_dsImage, m_dsImageAllocation->getMemory(),
2459 m_dsImageAllocation->getOffset()));
2460
2461 // Initialize depth / stencil image
2462 initDepthStencilImageChessboardPattern(
2463 vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_dsImage, m_format,
2464 m_depthInitValues[0], m_depthInitValues[1], m_stencilInitValues[0], m_stencilInitValues[1], m_width,
2465 m_height, m_tileSize, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2466 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2467 }
2468
2469 // Initialize color image
2470 initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
2471 *m_colorImage, colorFormat, m_colorInitValues[0], m_colorInitValues[1], m_width,
2472 m_height, m_tileSize, VK_IMAGE_LAYOUT_UNDEFINED, colorImageLayout,
2473 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2474
2475 // Create color image views
2476 {
2477 const VkImageViewCreateInfo imageViewCreateInfo = {
2478 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2479 DE_NULL, // const void* pNext
2480 0u, // VkImageViewCreateFlags flags
2481 *m_colorImage, // VkImage image
2482 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2483 colorFormat, // VkFormat format
2484 makeComponentMappingRGBA(), // VkComponentMapping components
2485 { // VkImageSubresourceRange subresourceRange
2486 VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
2487
2488 m_imageView = createImageView(vkd, device, &imageViewCreateInfo);
2489 }
2490
2491 // Create depth/stencil image view
2492 if (isDSFormat)
2493 {
2494 const VkImageViewCreateInfo imageViewCreateInfo = {
2495 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2496 DE_NULL, // const void* pNext
2497 0u, // VkImageViewCreateFlags flags
2498 *m_dsImage, // VkImage image
2499 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2500 m_format, // VkFormat format
2501 makeComponentMappingRGBA(), // VkComponentMapping components
2502 { // VkImageSubresourceRange subresourceRange
2503 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u}};
2504
2505 m_dsImageView = createImageView(vkd, device, &imageViewCreateInfo);
2506 }
2507
2508 // Create result buffers.
2509 {
2510 m_resultBuffer0 = createBuffer(vkd, device, m_format, m_width, m_height);
2511 m_resultBuffer0Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer0);
2512 m_resultBuffer1 = createBuffer(vkd, device, m_format, m_width, m_height);
2513 m_resultBuffer1Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer1);
2514 }
2515
2516 // Create descriptor set layout.
2517 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2518 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
2519 .build(vkd, device);
2520 // Create descriptor pool.
2521 m_descriptorPool = DescriptorPoolBuilder()
2522 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
2523 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2524 // Create descriptor set.
2525 m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
2526
2527 // Update descriptor set information.
2528 if (!isDSFormat)
2529 {
2530 VkDescriptorImageInfo descInputAttachment =
2531 makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
2532
2533 DescriptorSetUpdateBuilder()
2534 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
2535 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
2536 .update(vkd, device);
2537 }
2538
2539 // Create render pipeline layout.
2540 m_pipelineLayout =
2541 PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayout);
2542
2543 if (m_groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
2544 {
2545 // Create render pass.
2546 vector<Attachment> attachments;
2547 vector<AttachmentReference> colorAttachmentReferences;
2548 vector<AttachmentReference> inputAttachmentReferences;
2549 AttachmentReference dsAttachmentReference(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2550 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
2551
2552 const VkImageAspectFlags inputAttachmentAspectMask(
2553 (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
2554 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
2555 static_cast<VkImageAspectFlags>(0));
2556
2557 attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2558 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2559 VK_ATTACHMENT_STORE_OP_DONT_CARE, colorImageLayout, colorImageLayout));
2560 colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));
2561
2562 if (isDSFormat)
2563 {
2564 attachments.push_back(Attachment(
2565 m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
2566 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
2567 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
2568 }
2569 else
2570 {
2571 inputAttachmentReferences.push_back(
2572 AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
2573 }
2574
2575 const vector<Subpass> subpasses(
2576 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, colorAttachmentReferences,
2577 vector<AttachmentReference>(),
2578 isDSFormat ? dsAttachmentReference :
2579 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
2580 vector<uint32_t>()));
2581 vector<SubpassDependency> subpassDependency;
2582 if (!isDSFormat)
2583 {
2584 /* Self supass-dependency */
2585 subpassDependency.push_back(
2586 SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2587 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2588 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
2589 }
2590 m_renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, subpassDependency),
2591 m_groupParams->renderingType);
2592
2593 // Create framebuffer.
2594 const VkImageView dsAttachments[]{*m_imageView, *m_dsImageView};
2595
2596 const VkFramebufferCreateInfo framebufferCreateInfo{
2597 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
2598 DE_NULL, // const void* pNext
2599 0u, // VkFramebufferCreateFlags flags
2600 *m_renderPass, // VkRenderPass renderPass
2601 isDSFormat ? 2u : 1u, // uint32_t attachmentCount
2602 isDSFormat ? dsAttachments : &*m_imageView, // const VkImageView* pAttachments
2603 m_width, // uint32_t width
2604 m_height, // uint32_t height
2605 1u // uint32_t layers
2606 };
2607
2608 m_framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2609 }
2610
2611 // Create render pipeline.
2612 {
2613 const ShaderWrapper vertexShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
2614 const ShaderWrapper fragmentShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
2615
2616 const VkVertexInputBindingDescription vertexBinding0{
2617 0u, // uint32_t binding
2618 sizeof(Vec4), // uint32_t strideInBytes
2619 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate
2620 };
2621
2622 const VkVertexInputAttributeDescription attr0{
2623 0u, // uint32_t location
2624 0u, // uint32_t binding
2625 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
2626 0u // uint32_t offsetInBytes
2627 };
2628
2629 const VkPipelineVertexInputStateCreateInfo vertexInputState{
2630 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
2631 DE_NULL, // const void* pNext
2632 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
2633 1u, // uint32_t vertexBindingDescriptionCount
2634 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
2635 1u, // uint32_t vertexAttributeDescriptionCount
2636 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
2637 };
2638
2639 // Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
2640 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState{
2641 VK_FALSE, // VkBool32 blendEnable
2642 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
2643 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
2644 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
2645 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
2646 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
2647 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
2648 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT // VkColorComponentFlags colorWriteMask
2649 };
2650
2651 const VkPipelineColorBlendStateCreateInfo colorBlendState{
2652 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
2653 DE_NULL, // const void* pNext
2654 0u, // VkPipelineColorBlendStateCreateFlags flags
2655 VK_FALSE, // VkBool32 logicOpEnable
2656 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
2657 1u, // uint32_t attachmentCount
2658 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
2659 {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4]
2660 };
2661
2662 const VkStencilOpState stencilOpState{
2663 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp
2664 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
2665 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp
2666 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
2667 0xff, // uint32_t compareMask
2668 0xff, // uint32_t writeMask
2669 m_stencilRefValue // uint32_t reference
2670 };
2671
2672 const VkPipelineDepthStencilStateCreateInfo depthStencilState{
2673 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
2674 DE_NULL, // const void* pNext
2675 0u, // VkPipelineDepthStencilStateCreateFlags flags
2676 VK_TRUE, // VkBool32 depthTestEnable
2677 VK_FALSE, // VkBool32 depthWriteEnable
2678 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
2679 VK_FALSE, // VkBool32 depthBoundsTestEnable
2680 VK_TRUE, // VkBool32 stencilTestEnable
2681 stencilOpState, // VkStencilOpState front
2682 stencilOpState, // VkStencilOpState back
2683 0.0f, // float minDepthBounds
2684 1.0f // float maxDepthBounds
2685 };
2686
2687 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
2688 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
2689 const std::vector<VkViewport> viewports{makeViewport(m_width, m_height)};
2690 const std::vector<VkRect2D> scissors{makeRect2D(m_width, m_height)};
2691
2692 #ifndef CTS_USES_VULKANSC
2693 const uint32_t inputAttachmentIndex = 0;
2694 const uint32_t dsInputAttachmentIndex = VK_ATTACHMENT_UNUSED;
2695 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo{
2696 VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR,
2697 DE_NULL,
2698 1u,
2699 &inputAttachmentIndex,
2700 (isDSFormat ? &dsInputAttachmentIndex : DE_NULL),
2701 (isDSFormat ? &dsInputAttachmentIndex : DE_NULL)};
2702 VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2703 DE_NULL,
2704 0u,
2705 1u,
2706 &colorFormat,
2707 (isDSFormat ? m_format : VK_FORMAT_UNDEFINED),
2708 (isDSFormat ? m_format : VK_FORMAT_UNDEFINED)};
2709 if (*m_renderPass == DE_NULL)
2710 {
2711 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
2712 if (!isDSFormat)
2713 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
2714 }
2715 #endif
2716 if (isDSFormat)
2717 m_renderPipeline.setDefaultColorBlendState();
2718 else
2719 m_renderPipeline.setDefaultDepthStencilState();
2720
2721 m_renderPipeline.setDefaultMultisampleState()
2722 .setDefaultRasterizationState()
2723 .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2724 .setupVertexInputState(&vertexInputState)
2725 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayout, *m_renderPass, 0u,
2726 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
2727 DE_NULL, DE_NULL, renderingCreateInfoWrapper, DE_NULL)
2728 .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fragmentShaderModule,
2729 (isDSFormat ? &depthStencilState : DE_NULL), 0, 0, 0, {},
2730 renderingInputAttachmentIndexInfoWrapper)
2731 .setupFragmentOutputState(*m_renderPass, 0u, (isDSFormat ? DE_NULL : &colorBlendState))
2732 .setMonolithicPipelineLayout(m_pipelineLayout)
2733 .buildPipeline();
2734 }
2735
2736 // Generate quad vertices
2737 vector<Vec4> vertexData{tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f),
2738 tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f)};
2739
2740 // Upload vertex data.
2741 {
2742 const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
2743
2744 const VkBufferCreateInfo vertexBufferParams{
2745 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
2746 DE_NULL, // const void* pNext
2747 0u, // VkBufferCreateFlags flags
2748 (VkDeviceSize)vertexDataSize, // VkDeviceSize size
2749 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
2750 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2751 1u, // uint32_t queueFamilyCount
2752 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2753 };
2754
2755 m_vertexBuffer = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2756 m_vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_vertexBuffer);
2757
2758 deMemcpy(m_vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2759 flushAlloc(vkd, device, *m_vertexBufferMemory);
2760 }
2761 }
2762
2763 #ifndef CTS_USES_VULKANSC
startDynamicRendering(VkCommandBuffer cmdBuffer,VkRenderingFlagsKHR renderingFlags)2764 void SeparateChannelsTestInstance::startDynamicRendering(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags)
2765 {
2766 const DeviceInterface &vkd(m_context.getDeviceInterface());
2767 const bool isDSFormat = isDepthStencilFormat(m_format);
2768 const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f));
2769 const VkRect2D renderArea = makeRect2D(m_width, m_height);
2770
2771 if (isDSFormat)
2772 {
2773 beginRendering(vkd, cmdBuffer, *m_imageView, *m_dsImageView, true, renderArea, clearValue, clearValue,
2774 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2775 VK_ATTACHMENT_LOAD_OP_LOAD, renderingFlags);
2776 }
2777 else
2778 {
2779 beginRendering(vkd, cmdBuffer, *m_imageView, renderArea, clearValue, VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR,
2780 VK_ATTACHMENT_LOAD_OP_LOAD, renderingFlags);
2781 }
2782 }
2783 #endif
2784
draw(VkCommandBuffer cmdBuffer)2785 void SeparateChannelsTestInstance::draw(VkCommandBuffer cmdBuffer)
2786 {
2787 const DeviceInterface &vkd(m_context.getDeviceInterface());
2788 const bool isDSFormat = isDepthStencilFormat(m_format);
2789 const VkDeviceSize bindingOffset = 0;
2790
2791 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_renderPipeline.getPipeline());
2792 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
2793 if (!isDSFormat)
2794 {
2795 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u,
2796 &*m_descriptorSet, 0u, DE_NULL);
2797
2798 const VkMemoryBarrier memoryBarrier =
2799 makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
2800 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2801 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1u, &memoryBarrier,
2802 0u, DE_NULL, 0u, DE_NULL);
2803 }
2804 vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
2805 }
2806
postRenderCommands(VkCommandBuffer cmdBuffer)2807 void SeparateChannelsTestInstance::postRenderCommands(VkCommandBuffer cmdBuffer)
2808 {
2809 const DeviceInterface &vkd(m_context.getDeviceInterface());
2810 const bool isDSFormat = isDepthStencilFormat(m_format);
2811
2812 if (isDSFormat)
2813 copyDepthStencilImageToBuffers(vkd, cmdBuffer, *m_dsImage, *m_resultBuffer0, *m_resultBuffer1,
2814 tcu::IVec2(m_width, m_height), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2815 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
2816 else
2817 copyImageToBuffer(vkd, cmdBuffer, *m_colorImage, *m_resultBuffer0, tcu::IVec2(m_width, m_height),
2818 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
2819 }
2820
verifyResults(void)2821 tcu::TestStatus SeparateChannelsTestInstance::verifyResults(void)
2822 {
2823 const tcu::TextureFormat format(mapVkFormat(m_format));
2824 tcu::TextureLevel reference(format, m_width, m_height);
2825 tcu::ResultCollector resultCollector;
2826
2827 if (isDepthStencilFormat(m_format))
2828 {
2829 const void *const ptrDepth(m_resultBuffer0Memory->getHostPtr());
2830 const void *const ptrStencil(m_resultBuffer1Memory->getHostPtr());
2831 const tcu::ConstPixelBufferAccess resultDepthAccess(getDepthCopyFormat(m_format), m_width, m_height, 1,
2832 ptrDepth);
2833 const tcu::ConstPixelBufferAccess resultStencilAccess(getStencilCopyFormat(m_format), m_width, m_height, 1,
2834 ptrStencil);
2835 const PixelBufferAccess referenceDepthAccess(
2836 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
2837 const PixelBufferAccess referenceStencilAccess(
2838 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
2839 const float depthThreshold(
2840 1.0f /
2841 ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<uint32_t>()) - 1u)
2842 .cast<float>()
2843 .x());
2844
2845 for (uint32_t x = 0; x < m_width; x++)
2846 for (uint32_t y = 0; y < m_height; y++)
2847 {
2848 float depthValue =
2849 ((x / m_tileSize) % 2 != (y / m_tileSize) % 2) ? m_depthInitValues[0] : m_depthInitValues[1];
2850 referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
2851 referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? m_stencilRefValue : 0), x, y, 0);
2852 }
2853
2854 if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
2855 resultCollector.fail("Depth compare failed.");
2856
2857 if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
2858 resultCollector.fail("Stencil compare failed.");
2859 }
2860 else
2861 {
2862 const void *const ptrResult(m_resultBuffer0Memory->getHostPtr());
2863 const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
2864 const PixelBufferAccess referenceAccess(reference.getAccess());
2865
2866 for (uint32_t x = 0; x < m_width; x++)
2867 for (uint32_t y = 0; y < m_height; y++)
2868 {
2869 const tcu::Vec4 initValue =
2870 ((x / m_tileSize) % 2 != (y / m_tileSize) % 2) ? m_colorInitValues[0] : m_colorInitValues[1];
2871 const tcu::Vec4 refValue = tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);
2872
2873 referenceAccess.setPixel(refValue, x, y, 0);
2874 }
2875
2876 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
2877 "Rendered result", // imageSetName
2878 "", // imageSetDesc
2879 referenceAccess, // reference
2880 resultAccess, // result
2881 Vec4(0.01f), // threshold
2882 tcu::COMPARE_LOG_RESULT)) // logMode
2883 {
2884 resultCollector.fail("Image compare failed.");
2885 }
2886 }
2887
2888 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
2889 }
2890
2891 template <typename RenderpassSubpass>
iterateInternal(void)2892 void SeparateChannelsTestInstance::iterateInternal(void)
2893 {
2894 const DeviceInterface &vkd(m_context.getDeviceInterface());
2895 const VkDevice device = m_context.getDevice();
2896 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2897 const Unique<VkCommandPool> commandPool(
2898 createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2899 const Unique<VkCommandBuffer> commandBuffer(
2900 allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2901 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2902 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
2903
2904 beginCommandBuffer(vkd, *commandBuffer);
2905
2906 // Begin render pass.
2907 {
2908 VkRect2D renderArea = makeRect2D(m_width, m_height);
2909 const VkRenderPassBeginInfo beginInfo = {
2910 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
2911 DE_NULL, // const void* pNext
2912 *m_renderPass, // VkRenderPass renderPass
2913 *m_framebuffer, // VkFramebuffer framebuffer
2914 renderArea, // VkRect2D renderArea
2915 0u, // uint32_t clearValueCount
2916 DE_NULL // const VkClearValue* pClearValues
2917 };
2918
2919 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2920 }
2921
2922 draw(*commandBuffer);
2923 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2924
2925 // Copy results to a buffer.
2926 postRenderCommands(*commandBuffer);
2927
2928 endCommandBuffer(vkd, *commandBuffer);
2929 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
2930 invalidateMappedMemoryRange(vkd, device, m_resultBuffer0Memory->getMemory(), m_resultBuffer0Memory->getOffset(),
2931 VK_WHOLE_SIZE);
2932 invalidateMappedMemoryRange(vkd, device, m_resultBuffer1Memory->getMemory(), m_resultBuffer1Memory->getOffset(),
2933 VK_WHOLE_SIZE);
2934 }
2935
iterateInternalDynamicRendering(void)2936 void SeparateChannelsTestInstance::iterateInternalDynamicRendering(void)
2937 {
2938 #ifndef CTS_USES_VULKANSC
2939 const DeviceInterface &vkd(m_context.getDeviceInterface());
2940 const VkDevice device = m_context.getDevice();
2941 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2942 const Unique<VkCommandPool> commandPool(
2943 createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2944 const Unique<VkCommandBuffer> cmdBuffer(
2945 allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2946 Move<VkCommandBuffer> secCmdBuffer;
2947 const bool isDSFormat = isDepthStencilFormat(m_format);
2948 const VkFormat colorFormat = isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
2949 const VkFormat dsFormat = isDSFormat ? m_format : VK_FORMAT_UNDEFINED;
2950
2951 if (m_groupParams->useSecondaryCmdBuffer)
2952 {
2953 secCmdBuffer = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2954
2955 // record secondary command buffer
2956 {
2957 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2958 {
2959 beginSecondaryCmdBuffer(vkd, *secCmdBuffer, colorFormat, dsFormat, true);
2960 startDynamicRendering(*secCmdBuffer);
2961 }
2962 else
2963 beginSecondaryCmdBuffer(vkd, *secCmdBuffer, colorFormat, dsFormat, false);
2964
2965 draw(*secCmdBuffer);
2966
2967 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2968 vkd.cmdEndRendering(*secCmdBuffer);
2969
2970 endCommandBuffer(vkd, *secCmdBuffer);
2971 }
2972
2973 // record primary command buffer
2974 beginCommandBuffer(vkd, *cmdBuffer);
2975
2976 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2977 startDynamicRendering(*cmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
2978 vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
2979 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2980 vkd.cmdEndRendering(*cmdBuffer);
2981
2982 postRenderCommands(*cmdBuffer);
2983 endCommandBuffer(vkd, *cmdBuffer);
2984 }
2985 else
2986 {
2987 beginCommandBuffer(vkd, *cmdBuffer);
2988
2989 startDynamicRendering(*cmdBuffer);
2990 draw(*cmdBuffer);
2991 endRendering(vkd, *cmdBuffer);
2992
2993 // Copy results to a buffer.
2994 postRenderCommands(*cmdBuffer);
2995
2996 endCommandBuffer(vkd, *cmdBuffer);
2997 }
2998
2999 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
3000 invalidateMappedMemoryRange(vkd, device, m_resultBuffer0Memory->getMemory(), m_resultBuffer0Memory->getOffset(),
3001 VK_WHOLE_SIZE);
3002 invalidateMappedMemoryRange(vkd, device, m_resultBuffer1Memory->getMemory(), m_resultBuffer1Memory->getOffset(),
3003 VK_WHOLE_SIZE);
3004 #endif
3005 }
3006
3007 struct SingleAttachmentTestConfig
3008 {
SingleAttachmentTestConfigvkt::__anonc414995a0111::SingleAttachmentTestConfig3009 SingleAttachmentTestConfig(VkFormat format_, SharedGroupParams groupParams_)
3010 : format(format_)
3011 , groupParams(groupParams_)
3012 {
3013 }
3014
SingleAttachmentTestConfigvkt::__anonc414995a0111::SingleAttachmentTestConfig3015 SingleAttachmentTestConfig(const SingleAttachmentTestConfig &config)
3016 : format(config.format)
3017 , groupParams(config.groupParams)
3018 {
3019 }
3020
3021 VkFormat format;
3022 SharedGroupParams groupParams;
3023 };
3024
3025 class SingleAttachmentTestInstance : public TestInstance
3026 {
3027 public:
3028 SingleAttachmentTestInstance(Context &context, SingleAttachmentTestConfig testConfig);
3029
3030 ~SingleAttachmentTestInstance(void) = default;
3031
3032 tcu::TestStatus iterate(void);
3033
3034 protected:
3035 void setup(void);
3036 tcu::TestStatus verifyResults(void);
3037
3038 template <typename RenderpassSubpass>
3039 void iterateInternal(void);
3040 void iterateInternalDynamicRendering(void);
3041
3042 #ifndef CTS_USES_VULKANSC
3043 void preRenderCommands(VkCommandBuffer cmdBuffer);
3044 #endif // CTS_USES_VULKANSC
3045
3046 void drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer);
3047 void inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer);
3048 void drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer);
3049 void postRenderCommands(VkCommandBuffer cmdBuffer);
3050
3051 private:
3052 SharedGroupParams m_groupParams;
3053
3054 const uint32_t m_width;
3055 const uint32_t m_height;
3056 const VkFormat m_format;
3057
3058 Move<VkImage> m_colorImage;
3059 Move<VkImage> m_resultImage;
3060 de::MovePtr<Allocation> m_colorImageAllocation;
3061 de::MovePtr<Allocation> m_resultImageAllocation;
3062 Move<VkImageView> m_imageViewInput;
3063 Move<VkImageView> m_imageViewResult;
3064 PipelineLayoutWrapper m_pipelineLayoutInput;
3065 PipelineLayoutWrapper m_pipelineLayoutImageSampler;
3066 GraphicsPipelineWrapper m_pipelineSolidColor;
3067 GraphicsPipelineWrapper m_pipelineInputAtt;
3068 GraphicsPipelineWrapper m_pipelineImageSampler;
3069 Move<VkFramebuffer> m_framebuffer1;
3070 Move<VkFramebuffer> m_framebuffer0;
3071 Move<VkRenderPass> m_renderPass0;
3072 Move<VkRenderPass> m_renderPass1;
3073 Move<VkBuffer> m_resultBuffer;
3074 de::MovePtr<Allocation> m_resultBufferMemory;
3075 Move<VkBuffer> m_vertexBuffer;
3076 de::MovePtr<Allocation> m_vertexBufferMemory;
3077 Move<VkSampler> m_sampler;
3078 Move<VkDescriptorSetLayout> m_descriptorSetLayoutInput;
3079 Move<VkDescriptorSetLayout> m_descriptorSetLayoutImageSampler;
3080 Move<VkDescriptorPool> m_descriptorPool;
3081 Move<VkDescriptorSet> m_descriptorSetInput;
3082 Move<VkDescriptorSet> m_descriptorSetImageSampler;
3083 };
3084
SingleAttachmentTestInstance(Context & context,SingleAttachmentTestConfig testConfig)3085 SingleAttachmentTestInstance::SingleAttachmentTestInstance(Context &context, SingleAttachmentTestConfig testConfig)
3086 : TestInstance(context)
3087 , m_groupParams(testConfig.groupParams)
3088 , m_width(256u)
3089 , m_height(256u)
3090 , m_format(testConfig.format)
3091 , m_pipelineSolidColor(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3092 context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
3093 , m_pipelineInputAtt(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3094 context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
3095 , m_pipelineImageSampler(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3096 context.getDevice(), context.getDeviceExtensions(),
3097 m_groupParams->pipelineConstructionType)
3098 {
3099 }
3100
iterate(void)3101 tcu::TestStatus SingleAttachmentTestInstance::iterate(void)
3102 {
3103 setup();
3104
3105 switch (m_groupParams->renderingType)
3106 {
3107 case RENDERING_TYPE_RENDERPASS_LEGACY:
3108 iterateInternal<RenderpassSubpass1>();
3109 break;
3110 case RENDERING_TYPE_RENDERPASS2:
3111 iterateInternal<RenderpassSubpass2>();
3112 break;
3113 case RENDERING_TYPE_DYNAMIC_RENDERING:
3114 iterateInternalDynamicRendering();
3115 break;
3116 default:
3117 TCU_THROW(InternalError, "Impossible");
3118 }
3119
3120 return verifyResults();
3121 }
3122
setup(void)3123 void SingleAttachmentTestInstance::setup(void)
3124 {
3125 const DeviceInterface &vkd(m_context.getDeviceInterface());
3126 const VkDevice device = m_context.getDevice();
3127 const VkQueue queue = m_context.getUniversalQueue();
3128 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3129 const tcu::Vec4 colorInitValues[2] = {tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f)};
3130 const VkExtent3D imageExtent = {m_width, m_height, 1u};
3131
3132 // Create image used for both input and output.
3133 {
3134 VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
3135 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3136 VK_IMAGE_USAGE_SAMPLED_BIT;
3137
3138 const VkImageCreateInfo imageCreateInfo{
3139 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
3140 DE_NULL, // const void* pNext
3141 0u, // VkImageCreateFlags flags
3142 VK_IMAGE_TYPE_2D, // VkImageType imageType
3143 m_format, // VkFormat format
3144 imageExtent, // VkExtent3D extent
3145 1u, // uint32_t mipLevels
3146 1u, // uint32_t arrayLayers
3147 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
3148 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
3149 usage, // VkImageUsageFlags usage
3150 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
3151 1u, // uint32_t queueFamilyIndexCount
3152 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
3153 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
3154 };
3155
3156 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3157
3158 m_colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3159 m_colorImageAllocation = m_context.getDefaultAllocator().allocate(
3160 getImageMemoryRequirements(vkd, device, *m_colorImage), MemoryRequirement::Any);
3161 VK_CHECK(vkd.bindImageMemory(device, *m_colorImage, m_colorImageAllocation->getMemory(),
3162 m_colorImageAllocation->getOffset()));
3163 }
3164
3165 // Create image used for final result.
3166 {
3167 VkImageUsageFlags usage =
3168 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3169
3170 const VkImageCreateInfo imageCreateInfo{
3171 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
3172 DE_NULL, // const void* pNext
3173 0u, // VkImageCreateFlags flags
3174 VK_IMAGE_TYPE_2D, // VkImageType imageType
3175 m_format, // VkFormat format
3176 imageExtent, // VkExtent3D extent
3177 1u, // uint32_t mipLevels
3178 1u, // uint32_t arrayLayers
3179 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
3180 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
3181 usage, // VkImageUsageFlags usage
3182 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
3183 1u, // uint32_t queueFamilyIndexCount
3184 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
3185 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
3186 };
3187
3188 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3189
3190 m_resultImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3191 m_resultImageAllocation = m_context.getDefaultAllocator().allocate(
3192 getImageMemoryRequirements(vkd, device, *m_resultImage), MemoryRequirement::Any);
3193 VK_CHECK(vkd.bindImageMemory(device, *m_resultImage, m_resultImageAllocation->getMemory(),
3194 m_resultImageAllocation->getOffset()));
3195 }
3196
3197 // Initialize color image. This is expected to be cleared later.
3198 initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
3199 *m_colorImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height,
3200 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
3201 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3202 // Initialize result image. This will be overwritten later.
3203 initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
3204 *m_resultImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height,
3205 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3206 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3207
3208 // Create image views.
3209 {
3210 VkImageViewCreateInfo imageViewCreateInfo{
3211 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
3212 DE_NULL, // const void* pNext
3213 0u, // VkImageViewCreateFlags flags
3214 *m_colorImage, // VkImage image
3215 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
3216 m_format, // VkFormat format
3217 makeComponentMappingRGBA(), // VkComponentMapping components
3218 { // VkImageSubresourceRange subresourceRange
3219 VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
3220
3221 m_imageViewInput = createImageView(vkd, device, &imageViewCreateInfo);
3222 imageViewCreateInfo.image = *m_resultImage;
3223 m_imageViewResult = createImageView(vkd, device, &imageViewCreateInfo);
3224 }
3225
3226 // Create result buffer.
3227 {
3228 m_resultBuffer = createBuffer(vkd, device, m_format, m_width, m_height);
3229 m_resultBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer);
3230 }
3231
3232 // Create sampler.
3233 {
3234 const VkSamplerCreateInfo samplerInfo{
3235 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
3236 DE_NULL, // const void* pNext
3237 0u, // VkSamplerCreateFlags flags
3238 VK_FILTER_NEAREST, // VkFilter magFilter
3239 VK_FILTER_NEAREST, // VkFilter minFilter
3240 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
3241 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
3242 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
3243 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
3244 0.0f, // float mipLodBias
3245 VK_FALSE, // VkBool32 anisotropyEnable
3246 1.0f, // float maxAnisotropy
3247 VK_FALSE, // VkBool32 compareEnable
3248 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
3249 0.0f, // float minLod
3250 0.0f, // float maxLod
3251 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
3252 VK_FALSE, // VkBool32 unnormalizedCoordinates
3253 };
3254
3255 m_sampler = createSampler(vkd, device, &samplerInfo);
3256 }
3257
3258 // Create descriptor set layouts.
3259 m_descriptorSetLayoutInput =
3260 DescriptorSetLayoutBuilder()
3261 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
3262 .build(vkd, device);
3263
3264 m_descriptorSetLayoutImageSampler =
3265 DescriptorSetLayoutBuilder()
3266 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
3267 .build(vkd, device);
3268
3269 // Create descriptor pool.
3270 m_descriptorPool = DescriptorPoolBuilder()
3271 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
3272 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
3273 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
3274
3275 // Create desriptor sets.
3276 m_descriptorSetInput = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutInput);
3277 m_descriptorSetImageSampler = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutImageSampler);
3278
3279 VkImageLayout ioImageLayout = VK_IMAGE_LAYOUT_GENERAL;
3280 #ifndef CTS_USES_VULKANSC
3281 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3282 ioImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3283 #endif // CTS_USES_VULKANSC
3284
3285 // Update descriptor set information.
3286 VkDescriptorImageInfo descIOAttachment = makeDescriptorImageInfo(DE_NULL, *m_imageViewInput, ioImageLayout);
3287 VkDescriptorImageInfo descImageSampler =
3288 makeDescriptorImageInfo(*m_sampler, *m_imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3289
3290 DescriptorSetUpdateBuilder()
3291 .writeSingle(*m_descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u),
3292 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
3293 .update(vkd, device);
3294
3295 DescriptorSetUpdateBuilder()
3296 .writeSingle(*m_descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u),
3297 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
3298 .update(vkd, device);
3299
3300 // Create pipeline layouts.
3301 m_pipelineLayoutInput =
3302 PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayoutInput);
3303 m_pipelineLayoutImageSampler =
3304 PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayoutImageSampler);
3305
3306 if (m_groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3307 {
3308 // Create render passes.
3309
3310 vector<Attachment> attachments{{m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
3311 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3312 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3313 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
3314
3315 vector<AttachmentReference> colorAttachmentReferences{{0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
3316
3317 vector<Subpass> subpasses{{VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
3318 colorAttachmentReferences, vector<AttachmentReference>(),
3319 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
3320 vector<uint32_t>()}};
3321
3322 m_renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()),
3323 m_groupParams->renderingType);
3324
3325 attachments.clear();
3326 attachments.emplace_back(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
3327 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3328 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL);
3329
3330 colorAttachmentReferences[0].setImageLayout(VK_IMAGE_LAYOUT_GENERAL);
3331
3332 const VkImageAspectFlags inputAttachmentAspectMask(
3333 (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
3334 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
3335 static_cast<VkImageAspectFlags>(0));
3336 vector<AttachmentReference> inputAttachmentReferences{{0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask}};
3337
3338 subpasses.clear();
3339 subpasses.emplace_back(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
3340 colorAttachmentReferences, vector<AttachmentReference>(),
3341 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>());
3342
3343 const vector<SubpassDependency> dependencies(
3344 1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3345 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3346 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
3347
3348 m_renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies),
3349 m_groupParams->renderingType);
3350
3351 // Create framebuffers.
3352 VkFramebufferCreateInfo framebufferCreateInfo{
3353 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
3354 DE_NULL, // const void* pNext
3355 0u, // VkFramebufferCreateFlags flags
3356 *m_renderPass0, // VkRenderPass renderPass
3357 1u, // uint32_t attachmentCount
3358 &m_imageViewInput.get(), // const VkImageView* pAttachments
3359 m_width, // uint32_t width
3360 m_height, // uint32_t height
3361 1u // uint32_t layers
3362 };
3363
3364 m_framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3365
3366 framebufferCreateInfo.pAttachments = &m_imageViewResult.get();
3367 framebufferCreateInfo.renderPass = *m_renderPass1;
3368
3369 m_framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3370 }
3371
3372 // Create pipelines.
3373 {
3374 const ShaderWrapper vertexShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
3375 const ShaderWrapper fragmentShaderModuleInputAtt(
3376 vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u);
3377 const ShaderWrapper fragmentShaderModuleSolidColor(vkd, device,
3378 m_context.getBinaryCollection().get("frag_solid_color"), 0u);
3379 const ShaderWrapper fragmentShaderModuleSampler(
3380 vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u);
3381
3382 const VkVertexInputBindingDescription vertexBinding0 = {
3383 0u, // uint32_t binding
3384 sizeof(Vec4), // uint32_t strideInBytes
3385 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate
3386 };
3387
3388 const VkVertexInputAttributeDescription attr0 = {
3389 0u, // uint32_t location
3390 0u, // uint32_t binding
3391 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
3392 0u // uint32_t offsetInBytes
3393 };
3394
3395 const VkPipelineVertexInputStateCreateInfo vertexInputState = {
3396 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
3397 DE_NULL, // const void* pNext
3398 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
3399 1u, // uint32_t vertexBindingDescriptionCount
3400 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
3401 1u, // uint32_t vertexAttributeDescriptionCount
3402 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
3403 };
3404
3405 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
3406 const std::vector<VkViewport> viewports{makeViewport(m_width, m_height)};
3407 const std::vector<VkRect2D> scissors{makeRect2D(m_width, m_height)};
3408
3409 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
3410 VK_TRUE, // VkBool32 blendEnable
3411 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor
3412 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
3413 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
3414 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
3415 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor
3416 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
3417 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
3418 | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};
3419
3420 const VkPipelineColorBlendStateCreateInfo colorBlendState = {
3421 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
3422 DE_NULL, // const void* pNext
3423 0u, // VkPipelineColorBlendStateCreateFlags flags
3424 VK_FALSE, // VkBool32 logicOpEnable
3425 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
3426 1u, // uint32_t attachmentCount
3427 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
3428 {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4]
3429 };
3430
3431 #ifndef CTS_USES_VULKANSC
3432 VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
3433 DE_NULL,
3434 0u,
3435 1u,
3436 &m_format,
3437 VK_FORMAT_UNDEFINED,
3438 VK_FORMAT_UNDEFINED};
3439 if (*m_renderPass0 == DE_NULL)
3440 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
3441 #endif
3442 m_pipelineSolidColor.setDefaultMultisampleState()
3443 .setDefaultDepthStencilState()
3444 .setDefaultRasterizationState()
3445 .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3446 .setupVertexInputState(&vertexInputState)
3447 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutInput, *m_renderPass0, 0u,
3448 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3449 DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3450 .setupFragmentShaderState(m_pipelineLayoutInput, *m_renderPass0, 0u, fragmentShaderModuleSolidColor)
3451 .setupFragmentOutputState(*m_renderPass0, 0u, &colorBlendState)
3452 .setMonolithicPipelineLayout(m_pipelineLayoutInput)
3453 .buildPipeline();
3454
3455 m_pipelineInputAtt.setDefaultMultisampleState()
3456 .setDefaultDepthStencilState()
3457 .setDefaultRasterizationState()
3458 .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3459 .setupVertexInputState(&vertexInputState)
3460 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutInput, *m_renderPass0, 0u,
3461 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3462 DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3463 .setupFragmentShaderState(m_pipelineLayoutInput, *m_renderPass0, 0u, fragmentShaderModuleInputAtt)
3464 .setupFragmentOutputState(*m_renderPass0, 0u, &colorBlendState)
3465 .setMonolithicPipelineLayout(m_pipelineLayoutInput)
3466 .buildPipeline();
3467
3468 m_pipelineImageSampler.setDefaultMultisampleState()
3469 .setDefaultDepthStencilState()
3470 .setDefaultRasterizationState()
3471 .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3472 .setupVertexInputState(&vertexInputState)
3473 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutImageSampler, *m_renderPass1, 0u,
3474 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3475 DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3476 .setupFragmentShaderState(m_pipelineLayoutImageSampler, *m_renderPass1, 0u, fragmentShaderModuleSampler)
3477 .setupFragmentOutputState(*m_renderPass1, 0u, &colorBlendState)
3478 .setMonolithicPipelineLayout(m_pipelineLayoutImageSampler)
3479 .buildPipeline();
3480 }
3481
3482 // Generate quad vertices.
3483 vector<Vec4> vertexData{tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f),
3484 tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f)};
3485
3486 // Upload vertex data.
3487 {
3488 const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
3489
3490 const VkBufferCreateInfo vertexBufferParams = {
3491 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
3492 DE_NULL, // const void* pNext
3493 0u, // VkBufferCreateFlags flags
3494 (VkDeviceSize)vertexDataSize, // VkDeviceSize size
3495 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
3496 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
3497 1u, // uint32_t queueFamilyCount
3498 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
3499 };
3500
3501 m_vertexBuffer = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
3502 m_vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_vertexBuffer);
3503
3504 deMemcpy(m_vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
3505 flushAlloc(vkd, device, *m_vertexBufferMemory);
3506 }
3507 }
3508
verifyResults()3509 tcu::TestStatus SingleAttachmentTestInstance::verifyResults()
3510 {
3511 const tcu::TextureFormat format(mapVkFormat(m_format));
3512 tcu::TextureLevel reference(format, m_width, m_height);
3513 const void *const ptrResult(m_resultBufferMemory->getHostPtr());
3514 const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
3515 const PixelBufferAccess referenceAccess(reference.getAccess());
3516 tcu::ResultCollector resultCollector;
3517
3518 for (uint32_t x = 0; x < m_width; x++)
3519 for (uint32_t y = 0; y < m_height; y++)
3520 {
3521 referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
3522 }
3523
3524 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
3525 "Rendered result", // imageSetName
3526 "", // imageSetDesc
3527 referenceAccess, // reference
3528 resultAccess, // result
3529 Vec4(0.05f), // threshold
3530 tcu::COMPARE_LOG_RESULT)) // logMode
3531 {
3532 resultCollector.fail("Image compare failed.");
3533 }
3534
3535 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
3536 }
3537
3538 template <typename RenderpassSubpass>
iterateInternal(void)3539 void SingleAttachmentTestInstance::iterateInternal(void)
3540 {
3541 const DeviceInterface &vkd(m_context.getDeviceInterface());
3542 const VkDevice device = m_context.getDevice();
3543 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3544 const Unique<VkCommandPool> commandPool(
3545 createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
3546 const Unique<VkCommandBuffer> commandBuffer(
3547 allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3548 const VkRect2D renderArea = makeRect2D(m_width, m_height);
3549 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
3550 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
3551 vector<Vec4> vertexData;
3552
3553 beginCommandBuffer(vkd, *commandBuffer);
3554
3555 // Begin render pass.
3556 {
3557 const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3558 const VkRenderPassBeginInfo beginInfo = {
3559 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
3560 DE_NULL, // const void* pNext
3561 *m_renderPass0, // VkRenderPass renderPass
3562 *m_framebuffer0, // VkFramebuffer framebuffer
3563 renderArea, // VkRect2D renderArea
3564 1u, // uint32_t clearValueCount
3565 &clearValue // const VkClearValue* pClearValues
3566 };
3567
3568 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3569 }
3570
3571 drawThatUsesInputAttachment(*commandBuffer);
3572
3573 // End render pass.
3574 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3575
3576 // Pipeline barrier.
3577 inbetweenDrawsRenderBarriers(*commandBuffer);
3578
3579 // Begin render pass.
3580 {
3581 const VkRenderPassBeginInfo beginInfo{
3582 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
3583 DE_NULL, // const void* pNext
3584 *m_renderPass1, // VkRenderPass renderPass
3585 *m_framebuffer1, // VkFramebuffer framebuffer
3586 renderArea, // VkRect2D renderArea
3587 0u, // uint32_t clearValueCount
3588 DE_NULL // const VkClearValue* pClearValues
3589 };
3590
3591 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3592 }
3593
3594 drawThatSamplesPreviousResult(*commandBuffer);
3595
3596 // End render pass.
3597 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3598
3599 // Copy results to a buffer.
3600 postRenderCommands(*commandBuffer);
3601
3602 endCommandBuffer(vkd, *commandBuffer);
3603 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
3604 invalidateMappedMemoryRange(vkd, device, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(),
3605 VK_WHOLE_SIZE);
3606 }
3607
iterateInternalDynamicRendering(void)3608 void SingleAttachmentTestInstance::iterateInternalDynamicRendering(void)
3609 {
3610 #ifndef CTS_USES_VULKANSC
3611 const DeviceInterface &vkd(m_context.getDeviceInterface());
3612 const VkDevice device = m_context.getDevice();
3613 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3614 const Unique<VkCommandPool> commandPool(
3615 createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
3616 const Unique<VkCommandBuffer> cmdBuffer(
3617 allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3618 Move<VkCommandBuffer> secCmdBuffer[2];
3619 const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f));
3620 const VkRect2D renderArea = makeRect2D(m_width, m_height);
3621
3622 if (m_groupParams->useSecondaryCmdBuffer)
3623 {
3624 secCmdBuffer[0] = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3625 secCmdBuffer[1] = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3626
3627 // record first secondary command buffer
3628 {
3629 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3630 {
3631 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[0], m_format, VK_FORMAT_UNDEFINED, true);
3632 beginRendering(vkd, *secCmdBuffer[0], *m_imageViewInput, renderArea, clearValue,
3633 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR);
3634 }
3635 else
3636 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[0], m_format, VK_FORMAT_UNDEFINED, false);
3637
3638 drawThatUsesInputAttachment(*secCmdBuffer[0]);
3639
3640 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3641 vkd.cmdEndRendering(*secCmdBuffer[0]);
3642
3643 endCommandBuffer(vkd, *secCmdBuffer[0]);
3644 }
3645
3646 // record second secondary command buffer
3647 {
3648 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3649 {
3650 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[1], m_format, VK_FORMAT_UNDEFINED, true);
3651 beginRendering(vkd, *secCmdBuffer[1], *m_imageViewResult, renderArea, clearValue);
3652 }
3653 else
3654 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[1], m_format, VK_FORMAT_UNDEFINED, false);
3655
3656 drawThatSamplesPreviousResult(*secCmdBuffer[1]);
3657
3658 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3659 vkd.cmdEndRendering(*secCmdBuffer[1]);
3660
3661 endCommandBuffer(vkd, *secCmdBuffer[1]);
3662 }
3663
3664 // record primary command buffer
3665 beginCommandBuffer(vkd, *cmdBuffer);
3666 preRenderCommands(*cmdBuffer);
3667
3668 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3669 {
3670 beginRendering(vkd, *cmdBuffer, *m_imageViewInput, renderArea, clearValue,
3671 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR,
3672 VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
3673 }
3674 vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer[0]);
3675 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3676 vkd.cmdEndRendering(*cmdBuffer);
3677
3678 inbetweenDrawsRenderBarriers(*cmdBuffer);
3679
3680 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3681 {
3682 beginRendering(vkd, *cmdBuffer, *m_imageViewResult, renderArea, clearValue, VK_IMAGE_LAYOUT_GENERAL,
3683 VK_ATTACHMENT_LOAD_OP_LOAD, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
3684 }
3685 vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer[1]);
3686 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3687 vkd.cmdEndRendering(*cmdBuffer);
3688
3689 postRenderCommands(*cmdBuffer);
3690 endCommandBuffer(vkd, *cmdBuffer);
3691 }
3692 else
3693 {
3694 beginCommandBuffer(vkd, *cmdBuffer);
3695 preRenderCommands(*cmdBuffer);
3696
3697 beginRendering(vkd, *cmdBuffer, *m_imageViewInput, renderArea, clearValue,
3698 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR);
3699 drawThatUsesInputAttachment(*cmdBuffer);
3700 vkd.cmdEndRendering(*cmdBuffer);
3701
3702 inbetweenDrawsRenderBarriers(*cmdBuffer);
3703
3704 beginRendering(vkd, *cmdBuffer, *m_imageViewResult, renderArea, clearValue);
3705 drawThatSamplesPreviousResult(*cmdBuffer);
3706 vkd.cmdEndRendering(*cmdBuffer);
3707
3708 postRenderCommands(*cmdBuffer);
3709 endCommandBuffer(vkd, *cmdBuffer);
3710 }
3711
3712 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
3713 invalidateMappedMemoryRange(vkd, device, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(),
3714 VK_WHOLE_SIZE);
3715 #endif
3716 }
3717
3718 #ifndef CTS_USES_VULKANSC
preRenderCommands(VkCommandBuffer cmdBuffer)3719 void SingleAttachmentTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer)
3720 {
3721 const DeviceInterface &vkd(m_context.getDeviceInterface());
3722 const VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
3723 VkImageMemoryBarrier imageBarrier =
3724 makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
3725 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, *m_colorImage, subresourceRange);
3726
3727 // Transition color attachment to proper layout.
3728 vkd.cmdPipelineBarrier(cmdBuffer, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
3729 1u, &imageBarrier);
3730 }
3731 #endif // CTS_USES_VULKANSC
3732
drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer)3733 void SingleAttachmentTestInstance::drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer)
3734 {
3735 const DeviceInterface &vkd(m_context.getDeviceInterface());
3736 const VkDeviceSize bindingOffset(0);
3737 const VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
3738 VkImageMemoryBarrier imageBarrier =
3739 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
3740 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, *m_colorImage, subresourceRange);
3741 // Bind pipeline.
3742 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineSolidColor.getPipeline());
3743
3744 // Bind vertex buffer.
3745 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
3746
3747 // Bind descriptor set.
3748 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutInput, 0u, 1u,
3749 &*m_descriptorSetInput, 0u, DE_NULL);
3750
3751 // Draw solid color.
3752 vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3753
3754 // Pipeline barrier to handle self dependency.
3755 #ifndef CTS_USES_VULKANSC
3756 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3757 {
3758 imageBarrier.newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3759 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3760 }
3761 #endif
3762 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3763 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL,
3764 1u, &imageBarrier);
3765
3766 // Bind pipeline.
3767 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineInputAtt.getPipeline());
3768
3769 // Bind descriptor set.
3770 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutInput, 0u, 1u,
3771 &*m_descriptorSetInput, 0u, DE_NULL);
3772
3773 // Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
3774 vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3775 }
3776
inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer)3777 void SingleAttachmentTestInstance::inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer)
3778 {
3779 const DeviceInterface &vkd(m_context.getDeviceInterface());
3780 const VkImageSubresourceRange subresourceRange{1u, 0u, 1u, 0u, 1u};
3781 VkImageMemoryBarrier imageBarriers[]{
3782 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT |
3783 VK_ACCESS_HOST_WRITE_BIT,
3784 VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
3785 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, *m_colorImage, subresourceRange),
3786 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3787 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3788 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3789 *m_resultImage, subresourceRange)};
3790
3791 #ifndef CTS_USES_VULKANSC
3792 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3793 {
3794 imageBarriers[0].oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3795 imageBarriers[1].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3796 }
3797 #endif
3798
3799 vkd.cmdPipelineBarrier(cmdBuffer,
3800 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
3801 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
3802 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
3803 }
3804
drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer)3805 void SingleAttachmentTestInstance::drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer)
3806 {
3807 const DeviceInterface &vkd(m_context.getDeviceInterface());
3808 const VkDeviceSize bindingOffset(0);
3809
3810 // Bind pipeline.
3811 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineImageSampler.getPipeline());
3812
3813 // Bind vertex buffer.
3814 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
3815
3816 // Bind descriptor set.
3817 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutImageSampler, 0u, 1u,
3818 &*m_descriptorSetImageSampler, 0u, DE_NULL);
3819
3820 // Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
3821 vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3822 }
3823
postRenderCommands(VkCommandBuffer cmdBuffer)3824 void SingleAttachmentTestInstance::postRenderCommands(VkCommandBuffer cmdBuffer)
3825 {
3826 const DeviceInterface &vkd(m_context.getDeviceInterface());
3827
3828 // Copy results to a buffer.
3829 copyImageToBuffer(vkd, cmdBuffer, *m_resultImage, *m_resultBuffer, tcu::IVec2(m_width, m_height),
3830 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3831 }
3832
3833 // Shader programs for testing dependencies between render pass instances
3834 struct ExternalPrograms
3835 {
initvkt::__anonc414995a0111::ExternalPrograms3836 void init(vk::SourceCollections &dst, ExternalTestConfig testConfig) const
3837 {
3838 for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
3839 {
3840 dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
3841 "#version 450\n"
3842 "layout(location = 0) out highp vec2 vtxTexCoords;\n"
3843 "highp float;\n"
3844 "void main (void)\n"
3845 "{\n"
3846 " vec4 position;"
3847 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3848 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3849 " gl_Position = position;\n"
3850 " vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
3851 "}\n");
3852
3853 // First pass renders four quads of different color
3854 if (renderPassNdx == 0)
3855 {
3856 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx))
3857 << glu::FragmentSource("#version 450\n"
3858 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3859 "layout(location = 0) out highp vec4 o_color;\n"
3860 "void main (void)\n"
3861 "{\n"
3862 " if (gl_FragCoord.x <= " +
3863 de::toString(testConfig.imageSize.x() / 2) +
3864 " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) +
3865 ")\n"
3866 " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3867 " else if (gl_FragCoord.x > " +
3868 de::toString(testConfig.imageSize.x() / 2) +
3869 " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) +
3870 ")\n"
3871 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3872 " else if (gl_FragCoord.x <= " +
3873 de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " +
3874 de::toString(testConfig.imageSize.y() / 2) +
3875 ")\n"
3876 " o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
3877 " else\n"
3878 " o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
3879 ""
3880 "}\n");
3881 }
3882 else
3883 {
3884 if (renderPassNdx % 2 == 0)
3885 {
3886 // Blur previous pass horizontally
3887 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3888 "#version 450\n"
3889 "layout(binding = 0) uniform sampler2D previousPass;\n"
3890 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3891 "layout(location = 0) out highp vec4 o_color;\n"
3892 "void main (void)\n"
3893 "{\n"
3894 " vec2 step = vec2(1.0 / " +
3895 de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) +
3896 ");\n"
3897 " vec2 minCoord = vec2(0.0, 0.0);\n"
3898 " vec2 maxCoord = vec2(1.0, 1.0);\n"
3899 " vec4 blurColor = vec4(0.0);\n"
3900 " for(int sampleNdx = 0; sampleNdx < " +
3901 de::toString(testConfig.blurKernel + 1) +
3902 "; sampleNdx++)\n"
3903 " {\n"
3904 " vec2 sampleCoord = vec2((vtxTexCoords.x - " +
3905 de::toString(testConfig.blurKernel / 2) +
3906 " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
3907 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3908 " }\n"
3909 " o_color = blurColor;\n"
3910 "}\n");
3911 }
3912 else
3913 {
3914 // Blur previous pass vertically
3915 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3916 "#version 450\n"
3917 "layout(binding = 0) uniform highp sampler2D previousPass;\n"
3918 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3919 "layout(location = 0) out highp vec4 o_color;\n"
3920 "void main (void)\n"
3921 "{\n"
3922 " vec2 step = vec2(1.0 / " +
3923 de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) +
3924 ");\n"
3925 " vec2 minCoord = vec2(0.0, 0.0);\n"
3926 " vec2 maxCoord = vec2(1.0, 1.0);\n"
3927 " vec4 blurColor = vec4(0.0);\n"
3928 " for(int sampleNdx = 0; sampleNdx < " +
3929 de::toString(testConfig.blurKernel + 1) +
3930 "; sampleNdx++)\n"
3931 " {\n"
3932 " vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " +
3933 de::toString(testConfig.blurKernel / 2) +
3934 " * step.y) + step.y * sampleNdx);\n"
3935 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3936 " }\n"
3937 " o_color = blurColor;\n"
3938 "}\n");
3939 }
3940 }
3941 }
3942 }
3943 };
3944
3945 template <typename TestConfig>
checkSupport(Context & context,TestConfig config)3946 void checkSupport(Context &context, TestConfig config)
3947 {
3948 const InstanceInterface &vki = context.getInstanceInterface();
3949 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
3950
3951 checkPipelineConstructionRequirements(vki, physicalDevice, config.groupParams->pipelineConstructionType);
3952 if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
3953 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
3954 else if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3955 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
3956 }
3957
3958 // Shader programs for testing dependencies between subpasses
3959 struct SubpassPrograms
3960 {
initvkt::__anonc414995a0111::SubpassPrograms3961 void init(vk::SourceCollections &dst, SubpassTestConfig testConfig) const
3962 {
3963 size_t subpassCount = testConfig.renderPass.getSubpasses().size();
3964
3965 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
3966 {
3967 if (subpassNdx == 0)
3968 {
3969 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx))
3970 << glu::VertexSource("#version 450\n"
3971 "highp float;\n"
3972 "layout(location = 0) in highp vec4 position;\n"
3973 "void main (void)\n"
3974 "{\n"
3975 " gl_Position = position;\n"
3976 "}\n");
3977 }
3978 else
3979 {
3980 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3981 "#version 450\n"
3982 "highp float;\n"
3983 "void main (void)\n"
3984 "{\n"
3985 " vec4 position;"
3986 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3987 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3988 " gl_Position = position;\n"
3989 "}\n");
3990 }
3991
3992 if (isDepthStencilFormat(testConfig.format))
3993 {
3994 if (subpassNdx == 0)
3995 {
3996 // Empty fragment shader: Fragment depth unmodified.
3997 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx))
3998 << glu::FragmentSource("#version 450\n"
3999 "void main (void)\n"
4000 "{\n"
4001 "}\n");
4002 }
4003 else
4004 {
4005 // Use fragment depth from previous depth rendering result.
4006 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
4007 "#version 450\n"
4008 "layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
4009 "void main (void)\n"
4010 "{\n"
4011 " float inputDepth = subpassLoad(depthStencil).x;\n"
4012 " gl_FragDepth = inputDepth - 0.02;\n"
4013 "}\n");
4014 }
4015 }
4016 else
4017 DE_FATAL("Unimplemented");
4018 }
4019 }
4020 };
4021
4022 // Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
4023 struct SubpassSelfDependencyBackwardsPrograms
4024 {
initvkt::__anonc414995a0111::SubpassSelfDependencyBackwardsPrograms4025 void init(vk::SourceCollections &dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
4026 {
4027 DE_UNREF(testConfig);
4028
4029 dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4030 "layout(location = 0) in highp vec4 position;\n"
4031 "out gl_PerVertex {\n"
4032 " vec4 gl_Position;\n"
4033 "};\n"
4034 "void main (void)\n"
4035 "{\n"
4036 " gl_Position = position;\n"
4037 "}\n");
4038
4039 dst.glslSources.add("geom") << glu::GeometrySource("#version 450\n"
4040 "layout(points) in;\n"
4041 "layout(triangle_strip, max_vertices = 4) out;\n"
4042 "\n"
4043 "in gl_PerVertex {\n"
4044 " vec4 gl_Position;\n"
4045 "} gl_in[];\n"
4046 "\n"
4047 "out gl_PerVertex {\n"
4048 " vec4 gl_Position;\n"
4049 "};\n"
4050 "layout (binding = 0) buffer IndirectBuffer\n"
4051 "{\n"
4052 " uint vertexCount;\n"
4053 " uint instanceCount;\n"
4054 " uint firstVertex;\n"
4055 " uint firstInstance;\n"
4056 "} indirectBuffer;\n"
4057 "\n"
4058 "void main (void) {\n"
4059 " vec4 p = gl_in[0].gl_Position;\n"
4060 " float offset = 0.03f;\n"
4061 " gl_Position = p + vec4(-offset, offset, 0, 0);\n"
4062 " EmitVertex();\n"
4063 " gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
4064 " EmitVertex();\n"
4065 " gl_Position = p + vec4(offset, offset, 0, 0);\n"
4066 " EmitVertex();\n"
4067 " gl_Position = p + vec4(offset, -offset, 0, 0);\n"
4068 " EmitVertex();\n"
4069 " EndPrimitive();\n"
4070 " indirectBuffer.vertexCount = 64;\n"
4071 " indirectBuffer.instanceCount = 1;\n"
4072 " indirectBuffer.firstVertex = 64;\n"
4073 " indirectBuffer.firstInstance = 0;\n"
4074 "}\n");
4075
4076 dst.glslSources.add("frag") << glu::FragmentSource("#version 450\n"
4077 "layout(location = 0) out highp vec4 fragColor;\n"
4078 "void main (void)\n"
4079 "{\n"
4080 " fragColor = vec4(1, 0, 0, 1);\n"
4081 "}\n");
4082 }
4083 };
4084
4085 struct SeparateChannelsPrograms
4086 {
initvkt::__anonc414995a0111::SeparateChannelsPrograms4087 void init(vk::SourceCollections &dst, SeparateChannelsTestConfig testConfig) const
4088 {
4089 dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4090 "layout(location = 0) in highp vec4 position;\n"
4091 "void main (void)\n"
4092 "{\n"
4093 " gl_Position = position;\n"
4094 "}\n");
4095
4096 if (isDepthStencilFormat(testConfig.format))
4097 {
4098 dst.glslSources.add("frag") << glu::FragmentSource("#version 450\n"
4099 "layout(location = 0) out highp vec4 fragColor;\n"
4100 "void main (void)\n"
4101 "{\n"
4102 " fragColor = vec4(1);\n"
4103 "}\n");
4104 }
4105 else
4106 {
4107 dst.glslSources.add("frag") << glu::FragmentSource(
4108 "#version 450\n"
4109 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
4110 "layout(location = 0) out highp vec4 fragColor;\n"
4111 "void main (void)\n"
4112 "{\n"
4113 " vec4 inputColor = subpassLoad(inputAtt);\n"
4114 " fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
4115 "}\n");
4116 }
4117 }
4118 };
4119
4120 struct SingleAttachmentPrograms
4121 {
initvkt::__anonc414995a0111::SingleAttachmentPrograms4122 void init(vk::SourceCollections &dst, SingleAttachmentTestConfig testConfig) const
4123 {
4124 DE_UNREF(testConfig);
4125
4126 dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4127 "layout(location = 0) in highp vec4 position;\n"
4128 "void main (void)\n"
4129 "{\n"
4130 " gl_Position = position;\n"
4131 "}\n");
4132
4133 dst.glslSources.add("frag_solid_color")
4134 << glu::FragmentSource("#version 450\n"
4135 "layout(location = 0) out highp vec4 fragColor;\n"
4136 "void main (void)\n"
4137 "{\n"
4138 " fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
4139 "}\n");
4140
4141 dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
4142 "#version 450\n"
4143 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
4144 "layout(location = 0) out highp vec4 fragColor;\n"
4145 "void main (void)\n"
4146 "{\n"
4147 " vec4 inputColor = subpassLoad(inputAtt);\n"
4148 " fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
4149 "}\n");
4150
4151 dst.glslSources.add("frag_combined_image_sampler")
4152 << glu::FragmentSource("#version 450\n"
4153 "layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
4154 "layout(location = 0) out highp vec4 fragColor;\n"
4155 "void main (void)\n"
4156 "{\n"
4157 " vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
4158 " vec4 inputColor = texture(tex, uv);\n"
4159 " fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
4160 "}\n");
4161 }
4162 };
4163
formatToName(VkFormat format)4164 std::string formatToName(VkFormat format)
4165 {
4166 const std::string formatStr = de::toString(format);
4167 const std::string prefix = "VK_FORMAT_";
4168
4169 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4170
4171 return de::toLower(formatStr.substr(prefix.length()));
4172 }
4173
initTests(tcu::TestCaseGroup * group,const renderpass::SharedGroupParams groupParams)4174 void initTests(tcu::TestCaseGroup *group, const renderpass::SharedGroupParams groupParams)
4175 {
4176 tcu::TestContext &testCtx(group->getTestContext());
4177
4178 // Test external subpass dependencies
4179 if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4180 {
4181 const uint32_t renderPassCounts[] = {2u, 3u, 5u};
4182
4183 const UVec2 renderSizes[] = {UVec2(64, 64), UVec2(128, 128), UVec2(512, 512)};
4184
4185 de::MovePtr<tcu::TestCaseGroup> externalGroup(new tcu::TestCaseGroup(testCtx, "external_subpass"));
4186
4187 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4188 {
4189 string groupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4190 de::toString(renderSizes[renderSizeNdx].y()));
4191 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
4192
4193 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts);
4194 renderPassCountNdx++)
4195 {
4196 vector<RenderPass> renderPasses;
4197
4198 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
4199 {
4200 vector<Attachment> attachments;
4201 vector<AttachmentReference> colorAttachmentReferences;
4202
4203 const VkFormat format(VK_FORMAT_R8G8B8A8_UNORM);
4204 const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4205 const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4206 const VkAttachmentStoreOp storeOp(VK_ATTACHMENT_STORE_OP_STORE);
4207 const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4208 const VkAttachmentStoreOp stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE);
4209 const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4210 const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4211 const VkImageLayout subpassLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4212
4213 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
4214 stencilStoreOp, initialLayout, finalLayout));
4215 colorAttachmentReferences.push_back(AttachmentReference((uint32_t)0, subpassLayout));
4216
4217 const VkImageLayout depthStencilLayout(VK_IMAGE_LAYOUT_GENERAL);
4218 const vector<Subpass> subpasses(
4219 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
4220 colorAttachmentReferences, vector<AttachmentReference>(),
4221 AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
4222 vector<SubpassDependency> deps;
4223
4224 deps.push_back(SubpassDependency(
4225 VK_SUBPASS_EXTERNAL, // uint32_t srcPass
4226 0, // uint32_t dstPass
4227 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
4228 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4229 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
4230 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4231 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
4232 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
4233 0)); // VkDependencyFlags flags
4234
4235 deps.push_back(SubpassDependency(
4236 0, // uint32_t srcPass
4237 VK_SUBPASS_EXTERNAL, // uint32_t dstPass
4238 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4239 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
4240 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
4241 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
4242 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4243 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
4244 0)); // VkDependencyFlags flags
4245
4246 RenderPass renderPass(attachments, subpasses, deps);
4247
4248 renderPasses.push_back(renderPass);
4249 }
4250
4251 const uint32_t blurKernel(12u);
4252 string testName("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4253 ExternalTestConfig testConfig{VK_FORMAT_R8G8B8A8_UNORM,
4254 renderSizes[renderSizeNdx],
4255 renderPasses,
4256 groupParams,
4257 SYNCHRONIZATION_TYPE_LEGACY,
4258 blurKernel};
4259
4260 renderSizeGroup->addChild(
4261 new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4262 testCtx, testName.c_str(), testConfig));
4263 if (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
4264 {
4265 testName += "_sync_2";
4266 testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
4267 renderSizeGroup->addChild(
4268 new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4269 testCtx, testName.c_str(), testConfig));
4270 }
4271 }
4272
4273 externalGroup->addChild(renderSizeGroup.release());
4274 }
4275
4276 group->addChild(externalGroup.release());
4277 }
4278
4279 // Test implicit subpass dependencies
4280 if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4281 {
4282 const uint32_t renderPassCounts[] = {2u, 3u, 5u};
4283
4284 de::MovePtr<tcu::TestCaseGroup> implicitGroup(new tcu::TestCaseGroup(testCtx, "implicit_dependencies"));
4285
4286 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts);
4287 renderPassCountNdx++)
4288 {
4289 vector<RenderPass> renderPasses;
4290
4291 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
4292 {
4293 vector<Attachment> attachments;
4294 vector<AttachmentReference> colorAttachmentReferences;
4295
4296 const VkFormat format(VK_FORMAT_R8G8B8A8_UNORM);
4297 const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4298 const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4299 const VkAttachmentStoreOp storeOp(VK_ATTACHMENT_STORE_OP_STORE);
4300 const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4301 const VkAttachmentStoreOp stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE);
4302 const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4303 const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4304 const VkImageLayout subpassLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4305
4306 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
4307 initialLayout, finalLayout));
4308 colorAttachmentReferences.push_back(AttachmentReference((uint32_t)0, subpassLayout));
4309
4310 const VkImageLayout depthStencilLayout(VK_IMAGE_LAYOUT_GENERAL);
4311 const vector<Subpass> subpasses(
4312 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
4313 colorAttachmentReferences, vector<AttachmentReference>(),
4314 AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
4315 vector<SubpassDependency> deps;
4316
4317 // The first render pass lets the implementation add all subpass dependencies implicitly.
4318 // On the following passes only the dependency from external to first subpass is defined as
4319 // we need to make sure we have the image ready from previous render pass. In this case
4320 // the dependency from subpass 0 to external is added implicitly by the implementation.
4321 if (renderPassNdx > 0)
4322 {
4323 deps.push_back(SubpassDependency(
4324 VK_SUBPASS_EXTERNAL, // uint32_t srcPass
4325 0, // uint32_t dstPass
4326 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
4327 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
4328 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
4329 0, // VkAccessFlags srcAccessMask
4330 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT |
4331 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
4332 0)); // VkDependencyFlags flags
4333 }
4334
4335 RenderPass renderPass(attachments, subpasses, deps);
4336
4337 renderPasses.push_back(renderPass);
4338 }
4339
4340 const uint32_t blurKernel(12u);
4341 const ExternalTestConfig testConfig(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, groupParams,
4342 SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
4343 const string testName("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4344
4345 implicitGroup->addChild(
4346 new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4347 testCtx, testName.c_str(), testConfig));
4348 }
4349
4350 group->addChild(implicitGroup.release());
4351 }
4352
4353 // Test late fragment operations using depth_stencil attachments in multipass rendering
4354 if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4355 {
4356 const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(64, 64), UVec2(128, 128)};
4357
4358 const uint32_t subpassCounts[] = {2u, 3u, 5u};
4359
4360 // Implementations must support at least one of the following formats
4361 // for depth_stencil attachments
4362 const VkFormat formats[] = {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
4363
4364 de::MovePtr<tcu::TestCaseGroup> lateFragmentTestsGroup(new tcu::TestCaseGroup(testCtx, "late_fragment_tests"));
4365
4366 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4367 {
4368 string renderSizeGroupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4369 de::toString(renderSizes[renderSizeNdx].y()));
4370 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(
4371 new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str()));
4372
4373 for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
4374 {
4375 string subpassGroupName("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
4376 de::MovePtr<tcu::TestCaseGroup> subpassCountGroup(
4377 new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str()));
4378
4379 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
4380 {
4381 const uint32_t subpassCount(subpassCounts[subpassCountNdx]);
4382 const uint32_t attachmentCount(subpassCount);
4383 vector<Subpass> subpasses;
4384 vector<Attachment> attachments;
4385 vector<SubpassDependency> deps;
4386
4387 // Attachments
4388 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4389 {
4390 const VkFormat format(formats[formatNdx]);
4391 const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4392 const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR);
4393 const VkAttachmentStoreOp storeOp((attachmentNdx == attachmentCount - 1) ?
4394 VK_ATTACHMENT_STORE_OP_STORE :
4395 VK_ATTACHMENT_STORE_OP_DONT_CARE);
4396 const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_CLEAR);
4397 const VkAttachmentStoreOp stencilStoreOp((attachmentNdx == attachmentCount - 1) ?
4398 VK_ATTACHMENT_STORE_OP_STORE :
4399 VK_ATTACHMENT_STORE_OP_DONT_CARE);
4400 const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4401 const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
4402
4403 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
4404 stencilStoreOp, initialLayout, finalLayout));
4405 }
4406
4407 // Subpasses
4408 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
4409 {
4410 vector<AttachmentReference> inputAttachmentReferences;
4411 const VkImageAspectFlags inputAttachmentAspectMask(
4412 (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
4413 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
4414 static_cast<VkImageAspectFlags>(0));
4415
4416 // Input attachment references
4417 if (subpassNdx > 0)
4418 inputAttachmentReferences.push_back(AttachmentReference(
4419 (uint32_t)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4420 inputAttachmentAspectMask));
4421
4422 subpasses.push_back(Subpass(
4423 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
4424 vector<AttachmentReference>(), vector<AttachmentReference>(),
4425 AttachmentReference((uint32_t)subpassNdx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4426 vector<uint32_t>()));
4427
4428 // Subpass dependencies from current subpass to previous subpass.
4429 // Subpasses will wait for the late fragment operations before reading the contents
4430 // of previous subpass.
4431 if (subpassNdx > 0)
4432 {
4433 deps.push_back(SubpassDependency(
4434 (uint32_t)subpassNdx - 1, // uint32_t srcPass
4435 (uint32_t)subpassNdx, // uint32_t dstPass
4436 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
4437 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4438 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
4439 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4440 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
4441 VK_DEPENDENCY_BY_REGION_BIT)); // VkDependencyFlags flags
4442 }
4443 }
4444 deps.push_back(SubpassDependency(
4445 (uint32_t)subpassCount - 1, // uint32_t srcPass
4446 VK_SUBPASS_EXTERNAL, // uint32_t dstPass
4447 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
4448 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
4449 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4450 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
4451 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
4452 VK_DEPENDENCY_BY_REGION_BIT)); // VkDependencyFlags flags
4453
4454 const RenderPass renderPass(attachments, subpasses, deps);
4455 const SubpassTestConfig testConfig(formats[formatNdx], renderSizes[renderSizeNdx], renderPass,
4456 groupParams);
4457 const string format(formatToName(formats[formatNdx]).c_str());
4458
4459 subpassCountGroup->addChild(
4460 new InstanceFactory1WithSupport<SubpassDependencyTestInstance, SubpassTestConfig,
4461 FunctionSupport1<SubpassTestConfig>, SubpassPrograms>(
4462 testCtx, format, testConfig,
4463 typename FunctionSupport1<SubpassTestConfig>::Args(checkSupport<SubpassTestConfig>,
4464 testConfig)));
4465 }
4466
4467 renderSizeGroup->addChild(subpassCountGroup.release());
4468 }
4469
4470 lateFragmentTestsGroup->addChild(renderSizeGroup.release());
4471 }
4472
4473 group->addChild(lateFragmentTestsGroup.release());
4474 }
4475
4476 // Test subpass self dependency
4477 if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4478 {
4479 const UVec2 renderSizes[] = {UVec2(64, 64), UVec2(128, 128), UVec2(512, 512)};
4480
4481 de::MovePtr<tcu::TestCaseGroup> selfDependencyGroup(new tcu::TestCaseGroup(testCtx, "self_dependency"));
4482
4483 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4484 {
4485 string groupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4486 de::toString(renderSizes[renderSizeNdx].y()));
4487 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
4488
4489 const SubpassSelfDependencyBackwardsTestConfig testConfig(
4490 VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], groupParams->renderingType);
4491 renderSizeGroup->addChild(
4492 new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance,
4493 SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(
4494 testCtx, "geometry_to_indirectdraw", testConfig));
4495
4496 selfDependencyGroup->addChild(renderSizeGroup.release());
4497 }
4498
4499 group->addChild(selfDependencyGroup.release());
4500 }
4501
4502 // Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
4503 {
4504 de::MovePtr<tcu::TestCaseGroup> separateChannelsGroup(new tcu::TestCaseGroup(testCtx, "separate_channels"));
4505
4506 struct TestConfig
4507 {
4508 string name;
4509 VkFormat format;
4510 } configs[] = {{"r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM},
4511 {"r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT},
4512 {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
4513 {"d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT}};
4514
4515 for (uint32_t configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4516 {
4517 const SeparateChannelsTestConfig testConfig(configs[configIdx].format, groupParams);
4518
4519 separateChannelsGroup->addChild(
4520 new InstanceFactory1WithSupport<SeparateChannelsTestInstance, SeparateChannelsTestConfig,
4521 FunctionSupport1<SeparateChannelsTestConfig>, SeparateChannelsPrograms>(
4522 testCtx, configs[configIdx].name, testConfig,
4523 typename FunctionSupport1<SeparateChannelsTestConfig>::Args(
4524 checkSupport<SeparateChannelsTestConfig>, testConfig)));
4525 }
4526
4527 group->addChild(separateChannelsGroup.release());
4528 }
4529
4530 // Test using a single attachment for input and output.
4531 {
4532 de::MovePtr<tcu::TestCaseGroup> singleAttachmentGroup(new tcu::TestCaseGroup(testCtx, "single_attachment"));
4533
4534 struct TestConfig
4535 {
4536 string name;
4537 VkFormat format;
4538 } configs[] = {{"r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM},
4539 {"b8g8r8a8_unorm", VK_FORMAT_B8G8R8A8_UNORM},
4540 {"r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT},
4541 {"r5g6b5_unorm_pack16", VK_FORMAT_R5G6B5_UNORM_PACK16},
4542 {"a1r5g5b5_unorm_pack16", VK_FORMAT_A1R5G5B5_UNORM_PACK16}};
4543
4544 for (uint32_t configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4545 {
4546 const SingleAttachmentTestConfig testConfig(configs[configIdx].format, groupParams);
4547
4548 singleAttachmentGroup->addChild(
4549 new InstanceFactory1WithSupport<SingleAttachmentTestInstance, SingleAttachmentTestConfig,
4550 FunctionSupport1<SingleAttachmentTestConfig>, SingleAttachmentPrograms>(
4551 testCtx, configs[configIdx].name, testConfig,
4552 typename FunctionSupport1<SingleAttachmentTestConfig>::Args(
4553 checkSupport<SingleAttachmentTestConfig>, testConfig)));
4554 }
4555
4556 group->addChild(singleAttachmentGroup.release());
4557 }
4558 }
4559 } // namespace
4560
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)4561 tcu::TestCaseGroup *createRenderPassSubpassDependencyTests(tcu::TestContext &testCtx,
4562 const renderpass::SharedGroupParams groupParams)
4563 {
4564 return createTestGroup(testCtx, "subpass_dependencies", initTests, groupParams);
4565 }
4566
4567 } // namespace vkt
4568