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