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::__anon675baf4b0111::ExternalTestConfig384 ExternalTestConfig (VkFormat format_,
385 UVec2 imageSize_,
386 vector<RenderPass> renderPasses_,
387 RenderPassType renderPassType_,
388 SynchronizationType synchronizationType_,
389 deUint32 blurKernel_ = 4)
390 : format (format_)
391 , imageSize (imageSize_)
392 , renderPasses (renderPasses_)
393 , renderPassType (renderPassType_)
394 , synchronizationType (synchronizationType_)
395 , blurKernel (blurKernel_)
396 {
397 }
398
399 VkFormat format;
400 UVec2 imageSize;
401 vector<RenderPass> renderPasses;
402 RenderPassType renderPassType;
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 RenderPassType renderPassType,
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 RenderPassType m_renderPassType;
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.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
500 , m_synchronization2Supported ((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) && context.requireDeviceFunctionality("VK_KHR_synchronization2"))
501 , m_renderPassType (testConfig.renderPassType)
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.renderPassType, 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 RenderPassType renderPassType,const SynchronizationType synchronizationType)612 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface& vkd,
613 VkDevice device,
614 vector<RenderPass> renderPassInfos,
615 const RenderPassType renderPassType,
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, renderPassType, 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_renderPassType)
790 {
791 case RENDERPASS_TYPE_LEGACY:
792 return iterateInternal<RenderpassSubpass1>();
793 case RENDERPASS_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::__anon675baf4b0111::SubpassTestConfig990 SubpassTestConfig (VkFormat format_,
991 UVec2 imageSize_,
992 RenderPass renderPass_,
993 RenderPassType renderPassType_)
994 : format (format_)
995 , imageSize (imageSize_)
996 , renderPass (renderPass_)
997 , renderPassType (renderPassType_)
998 {
999 }
1000
1001 VkFormat format;
1002 UVec2 imageSize;
1003 RenderPass renderPass;
1004 RenderPassType renderPassType;
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 RenderPassType m_renderPassType;
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.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1099 , m_renderPassInfo (testConfig.renderPass)
1100 , m_renderPassType (testConfig.renderPassType)
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.renderPassType))
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_renderPassType)
1442 {
1443 case RENDERPASS_TYPE_LEGACY:
1444 return iterateInternal<RenderpassSubpass1>();
1445 case RENDERPASS_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::__anon675baf4b0111::SubpassSelfDependencyBackwardsTestConfig1810 SubpassSelfDependencyBackwardsTestConfig (VkFormat format_,
1811 UVec2 imageSize_,
1812 RenderPassType renderPassType_)
1813 : format (format_)
1814 , imageSize (imageSize_)
1815 , renderPassType (renderPassType_)
1816 {
1817 }
1818
1819 VkFormat format;
1820 UVec2 imageSize;
1821 RenderPassType renderPassType;
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 RenderPassType m_renderPassType;
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.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1851 , m_featuresSupported (context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
1852 , m_renderPassType (testConfig.renderPassType)
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_renderPassType)
1866 {
1867 case RENDERPASS_TYPE_LEGACY:
1868 return iterateInternal<RenderpassSubpass1>();
1869 case RENDERPASS_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_renderPassType);
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::__anon675baf4b0111::SeparateChannelsTestConfig2273 SeparateChannelsTestConfig (VkFormat format_,
2274 RenderPassType renderPassType_)
2275 : format (format_)
2276 , renderPassType (renderPassType_)
2277 {
2278 }
2279
2280 VkFormat format;
2281 RenderPassType renderPassType;
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 RenderPassType m_renderPassType;
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.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2310 , m_renderPassType (testConfig.renderPassType)
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_renderPassType)
2324 {
2325 case RENDERPASS_TYPE_LEGACY:
2326 return iterateInternal<RenderpassSubpass1>();
2327 case RENDERPASS_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> outputImageView;
2360 Move<VkImageView> inputImageView;
2361 Move<VkImageView> dsImageView;
2362 Move<VkPipelineLayout> pipelineLayout;
2363 Move<VkPipeline> renderPipeline;
2364 Move<VkFramebuffer> framebuffer;
2365 Move<VkRenderPass> renderPass;
2366 Move<VkBuffer> resultBuffer0;
2367 de::MovePtr<Allocation> resultBuffer0Memory;
2368 Move<VkBuffer> resultBuffer1;
2369 de::MovePtr<Allocation> resultBuffer1Memory;
2370 Move<VkBuffer> vertexBuffer;
2371 de::MovePtr<Allocation> vertexBufferMemory;
2372
2373 const VkExtent3D imageExtent =
2374 {
2375 m_width, // deUint32 width
2376 m_height, // deUint32 height
2377 1u // deUint32 depth
2378 };
2379
2380 // Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
2381 {
2382 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;
2383
2384 const VkImageCreateInfo imageCreateInfo =
2385 {
2386 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2387 DE_NULL, // const void* pNext
2388 0u, // VkImageCreateFlags flags
2389 VK_IMAGE_TYPE_2D, // VkImageType imageType
2390 colorFormat, // VkFormat format
2391 imageExtent, // VkExtent3D extent
2392 1u, // uint32_t mipLevels
2393 1u, // uint32_t arrayLayers
2394 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2395 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2396 usage, // VkImageUsageFlags usage
2397 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2398 1u, // uint32_t queueFamilyIndexCount
2399 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2400 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2401 };
2402
2403 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2404
2405 colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2406 colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2407 VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
2408 }
2409
2410 // Create depth/stencil image
2411 if (isDSFormat)
2412 {
2413 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2414
2415 const VkImageCreateInfo imageCreateInfo =
2416 {
2417 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2418 DE_NULL, // const void* pNext
2419 0u, // VkImageCreateFlags flags
2420 VK_IMAGE_TYPE_2D, // VkImageType imageType
2421 m_format, // VkFormat format
2422 imageExtent, // VkExtent3D extent
2423 1u, // uint32_t mipLevels
2424 1u, // uint32_t arrayLayers
2425 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2426 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2427 usage, // VkImageUsageFlags usage
2428 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2429 1u, // uint32_t queueFamilyIndexCount
2430 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2431 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2432 };
2433
2434 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2435
2436 dsImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2437 dsImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *dsImage), MemoryRequirement::Any);
2438 VK_CHECK(vkd.bindImageMemory(device, *dsImage, dsImageAllocation->getMemory(), dsImageAllocation->getOffset()));
2439
2440 // Initialize depth / stencil image
2441 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);
2442 }
2443
2444 // Initialize color image
2445 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);
2446
2447 // Create color image views
2448 {
2449 const VkImageViewCreateInfo imageViewCreateInfo =
2450 {
2451 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2452 DE_NULL, // const void* pNext
2453 0u, // VkImageViewCreateFlags flags
2454 *colorImage, // VkImage image
2455 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2456 colorFormat, // VkFormat format
2457 makeComponentMappingRGBA(), // VkComponentMapping components
2458 { // VkImageSubresourceRange subresourceRange
2459 VK_IMAGE_ASPECT_COLOR_BIT,
2460 0u,
2461 1u,
2462 0u,
2463 1u
2464 }
2465 };
2466
2467 if (!isDSFormat) inputImageView = createImageView(vkd, device, &imageViewCreateInfo);
2468 outputImageView = createImageView(vkd, device, &imageViewCreateInfo);
2469 }
2470
2471 // Create depth/stencil image view
2472 if (isDSFormat)
2473 {
2474 const VkImageViewCreateInfo imageViewCreateInfo =
2475 {
2476 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2477 DE_NULL, // const void* pNext
2478 0u, // VkImageViewCreateFlags flags
2479 *dsImage, // VkImage image
2480 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2481 m_format, // VkFormat format
2482 makeComponentMappingRGBA(), // VkComponentMapping components
2483 { // VkImageSubresourceRange subresourceRange
2484 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
2485 0u,
2486 1u,
2487 0u,
2488 1u
2489 }
2490 };
2491
2492 dsImageView = createImageView(vkd, device, &imageViewCreateInfo);
2493 }
2494
2495 // Create result buffers.
2496 {
2497 resultBuffer0 = createBuffer(vkd, device, m_format, m_width, m_height);
2498 resultBuffer0Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer0);
2499 resultBuffer1 = createBuffer(vkd, device, m_format, m_width, m_height);
2500 resultBuffer1Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer1);
2501 }
2502
2503 // Create descriptor set layout.
2504 Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
2505 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
2506 .build(vkd, device));
2507 // Create descriptor pool.
2508 Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
2509 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
2510 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
2511 // Create descriptor set.
2512 Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
2513
2514 // Update descriptor set information.
2515 if (!isDSFormat)
2516 {
2517 VkDescriptorImageInfo descInputAttachment = makeDescriptorImageInfo(DE_NULL, *inputImageView, VK_IMAGE_LAYOUT_GENERAL);
2518
2519 DescriptorSetUpdateBuilder()
2520 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
2521 .update(vkd, device);
2522 }
2523
2524 // Create render pipeline layout.
2525 {
2526 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
2527 {
2528 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
2529 DE_NULL, // const void* pNext
2530 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
2531 1u, // deUint32 setLayoutCount
2532 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts
2533 0u, // deUint32 pushConstantRangeCount
2534 DE_NULL // const VkPushConstantRange* pPushConstantRanges
2535 };
2536
2537 pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2538 }
2539
2540 // Create render pass.
2541 {
2542 vector<Attachment> attachments;
2543 vector<AttachmentReference> colorAttachmentReferences;
2544 vector<AttachmentReference> inputAttachmentReferences;
2545 AttachmentReference dsAttachmentReference (1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
2546
2547 const VkImageAspectFlags inputAttachmentAspectMask ((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
2548 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
2549 : static_cast<VkImageAspectFlags>(0));
2550
2551 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));
2552 colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));
2553
2554 if (isDSFormat)
2555 {
2556 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));
2557 }
2558 else
2559 {
2560 attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
2561 inputAttachmentReferences.push_back(AttachmentReference(1u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
2562 }
2563
2564 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>()));
2565
2566 renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
2567 }
2568
2569 // Create render pipeline.
2570 {
2571 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2572 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2573
2574 const VkVertexInputBindingDescription vertexBinding0 =
2575 {
2576 0u, // deUint32 binding
2577 sizeof(Vec4), // deUint32 strideInBytes
2578 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate
2579 };
2580
2581 const VkVertexInputAttributeDescription attr0 =
2582 {
2583 0u, // deUint32 location
2584 0u, // deUint32 binding
2585 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
2586 0u // deUint32 offsetInBytes
2587 };
2588
2589 const VkPipelineVertexInputStateCreateInfo vertexInputState =
2590 {
2591 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
2592 DE_NULL, // const void* pNext
2593 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
2594 1u, // deUint32 vertexBindingDescriptionCount
2595 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
2596 1u, // deUint32 vertexAttributeDescriptionCount
2597 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
2598 };
2599
2600 // Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
2601 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2602 {
2603 VK_FALSE, // VkBool32 blendEnable
2604 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
2605 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
2606 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
2607 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
2608 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
2609 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
2610 VK_COLOR_COMPONENT_B_BIT
2611 | VK_COLOR_COMPONENT_A_BIT // VkColorComponentFlags colorWriteMask
2612 };
2613
2614 const VkPipelineColorBlendStateCreateInfo colorBlendState =
2615 {
2616 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
2617 DE_NULL, // const void* pNext
2618 0u, // VkPipelineColorBlendStateCreateFlags flags
2619 VK_FALSE, // VkBool32 logicOpEnable
2620 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
2621 1u, // deUint32 attachmentCount
2622 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
2623 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
2624 };
2625
2626 const VkStencilOpState stencilOpState =
2627 {
2628 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp
2629 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
2630 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp
2631 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
2632 0xff, // deUint32 compareMask
2633 0xff, // deUint32 writeMask
2634 stencilRefValue // deUint32 reference
2635 };
2636
2637 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2638 {
2639 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
2640 DE_NULL, // const void* pNext
2641 0u, // VkPipelineDepthStencilStateCreateFlags flags
2642 VK_TRUE, // VkBool32 depthTestEnable
2643 VK_FALSE, // VkBool32 depthWriteEnable
2644 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
2645 VK_FALSE, // VkBool32 depthBoundsTestEnable
2646 VK_TRUE, // VkBool32 stencilTestEnable
2647 stencilOpState, // VkStencilOpState front
2648 stencilOpState, // VkStencilOpState back
2649 0.0f, // float minDepthBounds
2650 1.0f // float maxDepthBounds
2651 };
2652
2653 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_width, m_height)));
2654 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_width, m_height)));
2655
2656 renderPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
2657 device, // const VkDevice device
2658 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2659 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2660 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2661 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2662 DE_NULL, // const VkShaderModule geometryShaderModule
2663 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2664 *renderPass, // const VkRenderPass renderPass
2665 viewports, // const std::vector<VkViewport>& viewports
2666 scissors, // const std::vector<VkRect2D>& scissors
2667 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
2668 0u, // const deUint32 subpass
2669 0u, // const deUint32 patchControlPoints
2670 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2671 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2672 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2673 isDSFormat ? &depthStencilState : DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
2674 isDSFormat ? DE_NULL : &colorBlendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
2675 }
2676
2677 // Create framebuffer.
2678 {
2679 const VkImageView attachments[] =
2680 {
2681 *outputImageView,
2682 isDSFormat ? *dsImageView : *inputImageView
2683 };
2684
2685 const VkFramebufferCreateInfo framebufferCreateInfo =
2686 {
2687 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
2688 DE_NULL, // const void* pNext
2689 0u, // VkFramebufferCreateFlags flags
2690 *renderPass, // VkRenderPass renderPass
2691 2u, // uint32_t attachmentCount
2692 attachments, // const VkImageView* pAttachments
2693 m_width, // uint32_t width
2694 m_height, // uint32_t height
2695 1u // uint32_t layers
2696 };
2697
2698 framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2699 }
2700
2701 // Generate quad vertices
2702 {
2703 const tcu::Vec4 lowerLeftVertex (-1.0f, -1.0f, 0.5f, 1.0f);
2704 const tcu::Vec4 lowerRightVertex (1.0f, -1.0f, 0.5f, 1.0f);
2705 const tcu::Vec4 upperLeftVertex (-1.0f, 1.0f, 0.5f, 1.0f);
2706 const tcu::Vec4 upperRightVertex (1.0f, 1.0f, 0.5f, 1.0f);
2707
2708 vertexData.push_back(lowerLeftVertex);
2709 vertexData.push_back(upperLeftVertex);
2710 vertexData.push_back(lowerRightVertex);
2711 vertexData.push_back(upperRightVertex);
2712 }
2713
2714 // Upload vertex data.
2715 {
2716 const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
2717
2718 const VkBufferCreateInfo vertexBufferParams =
2719 {
2720 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
2721 DE_NULL, // const void* pNext
2722 0u, // VkBufferCreateFlags flags
2723 (VkDeviceSize)vertexDataSize, // VkDeviceSize size
2724 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
2725 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2726 1u, // deUint32 queueFamilyCount
2727 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices
2728 };
2729
2730 vertexBuffer = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2731 vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2732
2733 deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2734 flushAlloc(vkd, device, *vertexBufferMemory);
2735 }
2736
2737 beginCommandBuffer(vkd, *commandBuffer);
2738 vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2739
2740 if (!isDSFormat)
2741 vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2742
2743 // Begin render pass.
2744 {
2745 VkRect2D renderArea =
2746 {
2747 { 0u, 0u }, // VkOffset2D offset
2748 { m_width, m_height } // VkExtent2D extent
2749 };
2750
2751 const VkRenderPassBeginInfo beginInfo =
2752 {
2753 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
2754 DE_NULL, // const void* pNext
2755 *renderPass, // VkRenderPass renderPass
2756 *framebuffer, // VkFramebuffer framebuffer
2757 renderArea, // VkRect2D renderArea
2758 0u, // uint32_t clearValueCount
2759 DE_NULL // const VkClearValue* pClearValues
2760 };
2761
2762 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2763 }
2764
2765 const VkDeviceSize bindingOffset = 0;
2766
2767 vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2768 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2769 vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
2770 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2771
2772 // Copy results to a buffer.
2773 if (isDSFormat)
2774 {
2775 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);
2776 }
2777 else
2778 {
2779 copyImageToBuffer(vkd, *commandBuffer, *colorImage, *resultBuffer0, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
2780 }
2781
2782 endCommandBuffer(vkd, *commandBuffer);
2783 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2784 invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer0Memory->getMemory(), resultBuffer0Memory->getOffset(), VK_WHOLE_SIZE);
2785 invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer1Memory->getMemory(), resultBuffer1Memory->getOffset(), VK_WHOLE_SIZE);
2786
2787 // Verify result.
2788 {
2789 const tcu::TextureFormat format (mapVkFormat(m_format));
2790 tcu::TextureLevel reference (format, m_width, m_height);
2791
2792 if (isDSFormat)
2793 {
2794 const void* const ptrDepth (resultBuffer0Memory->getHostPtr());
2795 const void* const ptrStencil (resultBuffer1Memory->getHostPtr());
2796 const tcu::ConstPixelBufferAccess resultDepthAccess (getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
2797 const tcu::ConstPixelBufferAccess resultStencilAccess (getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
2798 const PixelBufferAccess referenceDepthAccess (tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
2799 const PixelBufferAccess referenceStencilAccess (tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
2800 const float depthThreshold (1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x());
2801
2802 for (deUint32 x = 0; x < m_width; x++)
2803 for (deUint32 y = 0; y < m_height; y++)
2804 {
2805 float depthValue = ((x / tileSize) % 2 != (y / tileSize) % 2) ? depthInitValues[0] : depthInitValues[1];
2806 referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
2807 referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? stencilRefValue : 0), x, y, 0);
2808 }
2809
2810 if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
2811 m_resultCollector.fail("Depth compare failed.");
2812
2813 if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
2814 m_resultCollector.fail("Stencil compare failed.");
2815 }
2816 else
2817 {
2818 const void* const ptrResult (resultBuffer0Memory->getHostPtr());
2819 const tcu::ConstPixelBufferAccess resultAccess (format, m_width, m_height, 1, ptrResult);
2820 const PixelBufferAccess referenceAccess (reference.getAccess());
2821
2822 for (deUint32 x = 0; x < m_width; x++)
2823 for (deUint32 y = 0; y < m_height; y++)
2824 {
2825 const tcu::Vec4 initValue = ((x / tileSize) % 2 != (y / tileSize) % 2) ? colorInitValues[0] : colorInitValues[1];
2826 const tcu::Vec4 refValue = tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);
2827
2828 referenceAccess.setPixel(refValue, x, y, 0);
2829 }
2830
2831 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
2832 "Rendered result", // imageSetName
2833 "", // imageSetDesc
2834 referenceAccess, // reference
2835 resultAccess, // result
2836 Vec4(0.01f), // threshold
2837 tcu::COMPARE_LOG_RESULT)) // logMode
2838 {
2839 m_resultCollector.fail("Image compare failed.");
2840 }
2841 }
2842
2843 }
2844
2845 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2846 }
2847
2848 struct SingleAttachmentTestConfig
2849 {
SingleAttachmentTestConfigvkt::__anon675baf4b0111::SingleAttachmentTestConfig2850 SingleAttachmentTestConfig (VkFormat format_,
2851 RenderPassType renderPassType_)
2852 : format (format_)
2853 , renderPassType (renderPassType_)
2854 {
2855 }
2856
2857 VkFormat format;
2858 RenderPassType renderPassType;
2859 };
2860
2861 class SingleAttachmentTestInstance : public TestInstance
2862 {
2863 public:
2864 SingleAttachmentTestInstance (Context& context,
2865 SingleAttachmentTestConfig testConfig);
2866
2867 ~SingleAttachmentTestInstance (void);
2868
2869 tcu::TestStatus iterate (void);
2870
2871 template<typename RenderpassSubpass>
2872 tcu::TestStatus iterateInternal (void);
2873
2874 private:
2875 const bool m_extensionSupported;
2876 const RenderPassType m_renderPassType;
2877
2878 const deUint32 m_width;
2879 const deUint32 m_height;
2880 const VkFormat m_format;
2881 tcu::ResultCollector m_resultCollector;
2882 };
2883
SingleAttachmentTestInstance(Context & context,SingleAttachmentTestConfig testConfig)2884 SingleAttachmentTestInstance::SingleAttachmentTestInstance (Context& context, SingleAttachmentTestConfig testConfig)
2885 : TestInstance (context)
2886 , m_extensionSupported ((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2887 , m_renderPassType (testConfig.renderPassType)
2888 , m_width (256u)
2889 , m_height (256u)
2890 , m_format (testConfig.format)
2891 {
2892 }
2893
~SingleAttachmentTestInstance(void)2894 SingleAttachmentTestInstance::~SingleAttachmentTestInstance (void)
2895 {
2896 }
2897
iterate(void)2898 tcu::TestStatus SingleAttachmentTestInstance::iterate (void)
2899 {
2900 switch (m_renderPassType)
2901 {
2902 case RENDERPASS_TYPE_LEGACY:
2903 return iterateInternal<RenderpassSubpass1>();
2904 case RENDERPASS_TYPE_RENDERPASS2:
2905 return iterateInternal<RenderpassSubpass2>();
2906 default:
2907 TCU_THROW(InternalError, "Impossible");
2908 }
2909 }
2910
2911 template<typename RenderpassSubpass>
iterateInternal(void)2912 tcu::TestStatus SingleAttachmentTestInstance::iterateInternal (void)
2913 {
2914 const DeviceInterface& vkd (m_context.getDeviceInterface());
2915 const VkDevice device = m_context.getDevice();
2916 const VkQueue queue = m_context.getUniversalQueue();
2917 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2918 const Unique<VkCommandPool> commandPool (createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2919 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2920 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2921 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
2922 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) };
2923 const VkExtent3D imageExtent = { m_width, m_height, 1u };
2924 vector<Vec4> vertexData;
2925 Move<VkImage> colorImage;
2926 Move<VkImage> resultImage;
2927 de::MovePtr<Allocation> colorImageAllocation;
2928 de::MovePtr<Allocation> resultImageAllocation;
2929 Move<VkImageView> imageViewInput;
2930 Move<VkImageView> imageViewResult;
2931 Move<VkPipelineLayout> pipelineLayoutInput;
2932 Move<VkPipelineLayout> pipelineLayoutImageSampler;
2933 Move<VkPipeline> pipelineSolidColor;
2934 Move<VkPipeline> pipelineInputAtt;
2935 Move<VkPipeline> pipelineImageSampler;
2936 Move<VkFramebuffer> framebuffer1;
2937 Move<VkFramebuffer> framebuffer0;
2938 Move<VkRenderPass> renderPass0;
2939 Move<VkRenderPass> renderPass1;
2940 Move<VkBuffer> resultBuffer;
2941 de::MovePtr<Allocation> resultBufferMemory;
2942 Move<VkBuffer> vertexBuffer;
2943 de::MovePtr<Allocation> vertexBufferMemory;
2944 Move<VkSampler> sampler;
2945
2946 // Create image used for both input and output.
2947 {
2948 VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
2949 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
2950 | VK_IMAGE_USAGE_SAMPLED_BIT;
2951
2952 const VkImageCreateInfo imageCreateInfo =
2953 {
2954 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2955 DE_NULL, // const void* pNext
2956 0u, // VkImageCreateFlags flags
2957 VK_IMAGE_TYPE_2D, // VkImageType imageType
2958 m_format, // VkFormat format
2959 imageExtent, // VkExtent3D extent
2960 1u, // uint32_t mipLevels
2961 1u, // uint32_t arrayLayers
2962 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2963 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2964 usage, // VkImageUsageFlags usage
2965 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2966 1u, // uint32_t queueFamilyIndexCount
2967 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2968 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2969 };
2970
2971 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2972
2973 colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2974 colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2975 VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
2976 }
2977
2978 // Create image used for final result.
2979 {
2980 VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2981
2982 const VkImageCreateInfo imageCreateInfo =
2983 {
2984 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2985 DE_NULL, // const void* pNext
2986 0u, // VkImageCreateFlags flags
2987 VK_IMAGE_TYPE_2D, // VkImageType imageType
2988 m_format, // VkFormat format
2989 imageExtent, // VkExtent3D extent
2990 1u, // uint32_t mipLevels
2991 1u, // uint32_t arrayLayers
2992 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2993 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2994 usage, // VkImageUsageFlags usage
2995 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2996 1u, // uint32_t queueFamilyIndexCount
2997 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2998 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2999 };
3000
3001 checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3002
3003 resultImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3004 resultImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *resultImage), MemoryRequirement::Any);
3005 VK_CHECK(vkd.bindImageMemory(device, *resultImage, resultImageAllocation->getMemory(), resultImageAllocation->getOffset()));
3006 }
3007
3008 // Initialize color image. This is expected to be cleared later.
3009 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);
3010 // Initialize result image. This will be overwritten later.
3011 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);
3012
3013 // Create image views.
3014 {
3015 const VkImageViewCreateInfo imageViewCreateInfo =
3016 {
3017 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
3018 DE_NULL, // const void* pNext
3019 0u, // VkImageViewCreateFlags flags
3020 *colorImage, // VkImage image
3021 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
3022 m_format, // VkFormat format
3023 makeComponentMappingRGBA(), // VkComponentMapping components
3024 { // VkImageSubresourceRange subresourceRange
3025 VK_IMAGE_ASPECT_COLOR_BIT,
3026 0u,
3027 1u,
3028 0u,
3029 1u
3030 }
3031 };
3032
3033 imageViewInput = createImageView(vkd, device, &imageViewCreateInfo);
3034 }
3035
3036 {
3037 const VkImageViewCreateInfo imageViewCreateInfo =
3038 {
3039 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
3040 DE_NULL, // const void* pNext
3041 0u, // VkImageViewCreateFlags flags
3042 *resultImage, // VkImage image
3043 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
3044 m_format, // VkFormat format
3045 makeComponentMappingRGBA(), // VkComponentMapping components
3046 { // VkImageSubresourceRange subresourceRange
3047 VK_IMAGE_ASPECT_COLOR_BIT,
3048 0u,
3049 1u,
3050 0u,
3051 1u
3052 }
3053 };
3054
3055 imageViewResult = createImageView(vkd, device, &imageViewCreateInfo);
3056 }
3057
3058 // Create result buffer.
3059 {
3060 resultBuffer = createBuffer(vkd, device, m_format, m_width, m_height);
3061 resultBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
3062 }
3063
3064 // Create sampler.
3065 {
3066 const VkSamplerCreateInfo samplerInfo =
3067 {
3068 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
3069 DE_NULL, // const void* pNext
3070 0u, // VkSamplerCreateFlags flags
3071 VK_FILTER_NEAREST, // VkFilter magFilter
3072 VK_FILTER_NEAREST, // VkFilter minFilter
3073 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
3074 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
3075 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
3076 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
3077 0.0f, // float mipLodBias
3078 VK_FALSE, // VkBool32 anisotropyEnable
3079 1.0f, // float maxAnisotropy
3080 VK_FALSE, // VkBool32 compareEnable
3081 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
3082 0.0f, // float minLod
3083 0.0f, // float maxLod
3084 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
3085 VK_FALSE, // VkBool32 unnormalizedCoordinates
3086 };
3087
3088 sampler = createSampler(vkd, device, &samplerInfo);
3089 }
3090
3091 // Create descriptor set layouts.
3092 Unique<VkDescriptorSetLayout> descriptorSetLayoutInput (DescriptorSetLayoutBuilder()
3093 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
3094 .build(vkd, device));
3095
3096 Unique<VkDescriptorSetLayout> descriptorSetLayoutImageSampler (DescriptorSetLayoutBuilder()
3097 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
3098 .build(vkd, device));
3099
3100 // Create descriptor pool.
3101 Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
3102 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
3103 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
3104 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u));
3105
3106 // Create desriptor sets.
3107 Unique<VkDescriptorSet> descriptorSetInput (makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutInput));
3108 Unique<VkDescriptorSet> descriptorSetImageSampler (makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutImageSampler));
3109
3110 // Update descriptor set information.
3111 VkDescriptorImageInfo descIOAttachment = makeDescriptorImageInfo(DE_NULL, *imageViewInput, VK_IMAGE_LAYOUT_GENERAL);
3112 VkDescriptorImageInfo descImageSampler = makeDescriptorImageInfo(*sampler, *imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3113
3114 DescriptorSetUpdateBuilder()
3115 .writeSingle(*descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
3116 .update(vkd, device);
3117
3118 DescriptorSetUpdateBuilder()
3119 .writeSingle(*descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
3120 .update(vkd, device);
3121
3122 // Create pipeline layouts.
3123 {
3124 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3125 {
3126 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
3127 DE_NULL, // const void* pNext
3128 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
3129 1u, // deUint32 setLayoutCount
3130 &descriptorSetLayoutInput.get(), // const VkDescriptorSetLayout* pSetLayouts
3131 0u, // deUint32 pushConstantRangeCount
3132 DE_NULL // const VkPushConstantRange* pPushConstantRanges
3133 };
3134
3135 pipelineLayoutInput = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3136 }
3137 {
3138 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3139 {
3140 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
3141 DE_NULL, // const void* pNext
3142 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
3143 1u, // deUint32 setLayoutCount
3144 &descriptorSetLayoutImageSampler.get(), // const VkDescriptorSetLayout* pSetLayouts
3145 0u, // deUint32 pushConstantRangeCount
3146 DE_NULL // const VkPushConstantRange* pPushConstantRanges
3147 };
3148
3149 pipelineLayoutImageSampler = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3150 }
3151
3152 // Create render passes.
3153 {
3154 vector<Attachment> attachments;
3155 vector<AttachmentReference> colorAttachmentReferences;
3156
3157 attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
3158 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
3159 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3160
3161 colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3162
3163 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
3164 colorAttachmentReferences, vector<AttachmentReference>(),
3165 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3166
3167 renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
3168 }
3169 {
3170 vector<Attachment> attachments;
3171 vector<AttachmentReference> colorAttachmentReferences;
3172 vector<AttachmentReference> inputAttachmentReferences;
3173
3174 const VkImageAspectFlags inputAttachmentAspectMask ((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
3175 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
3176 : static_cast<VkImageAspectFlags>(0));
3177
3178 attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
3179 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
3180
3181 colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL));
3182 inputAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
3183
3184 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
3185 colorAttachmentReferences, vector<AttachmentReference>(),
3186 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3187
3188 const vector<SubpassDependency> dependencies (1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3189 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3190 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
3191
3192 renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies), m_renderPassType);
3193 }
3194
3195 // Create pipelines.
3196 {
3197 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
3198 const Unique<VkShaderModule> fragmentShaderModuleInputAtt (createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u));
3199 const Unique<VkShaderModule> fragmentShaderModuleSolidColor (createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_solid_color"), 0u));
3200 const Unique<VkShaderModule> fragmentShaderModuleSampler (createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u));
3201
3202 const VkVertexInputBindingDescription vertexBinding0 =
3203 {
3204 0u, // deUint32 binding
3205 sizeof(Vec4), // deUint32 strideInBytes
3206 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate
3207 };
3208
3209 const VkVertexInputAttributeDescription attr0 =
3210 {
3211 0u, // deUint32 location
3212 0u, // deUint32 binding
3213 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
3214 0u // deUint32 offsetInBytes
3215 };
3216
3217 const VkPipelineVertexInputStateCreateInfo vertexInputState =
3218 {
3219 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
3220 DE_NULL, // const void* pNext
3221 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
3222 1u, // deUint32 vertexBindingDescriptionCount
3223 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
3224 1u, // deUint32 vertexAttributeDescriptionCount
3225 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
3226 };
3227
3228 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_width, m_height)));
3229 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_width, m_height)));
3230
3231 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
3232 {
3233 VK_TRUE, // VkBool32 blendEnable
3234 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor
3235 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
3236 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
3237 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
3238 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor
3239 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
3240 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
3241 | VK_COLOR_COMPONENT_G_BIT
3242 | VK_COLOR_COMPONENT_B_BIT
3243 | VK_COLOR_COMPONENT_A_BIT
3244 };
3245
3246 const VkPipelineColorBlendStateCreateInfo colorBlendState =
3247 {
3248 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
3249 DE_NULL, // const void* pNext
3250 0u, // VkPipelineColorBlendStateCreateFlags flags
3251 VK_FALSE, // VkBool32 logicOpEnable
3252 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
3253 1u, // deUint32 attachmentCount
3254 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
3255 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
3256 };
3257
3258 pipelineSolidColor = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
3259 device, // const VkDevice device
3260 *pipelineLayoutInput, // const VkPipelineLayout pipelineLayout
3261 *vertexShaderModule, // const VkShaderModule vertexShaderModule
3262 DE_NULL, // const VkShaderModule tessellationControlShaderModule
3263 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
3264 DE_NULL, // const VkShaderModule geometryShaderModule
3265 *fragmentShaderModuleSolidColor, // const VkShaderModule fragmentShaderModule
3266 *renderPass0, // const VkRenderPass renderPass
3267 viewports, // const std::vector<VkViewport>& viewports
3268 scissors, // const std::vector<VkRect2D>& scissors
3269 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
3270 0u, // const deUint32 subpass
3271 0u, // const deUint32 patchControlPoints
3272 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
3273 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3274 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
3275 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
3276 &colorBlendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
3277
3278 pipelineInputAtt = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
3279 device, // const VkDevice device
3280 *pipelineLayoutInput, // const VkPipelineLayout pipelineLayout
3281 *vertexShaderModule, // const VkShaderModule vertexShaderModule
3282 DE_NULL, // const VkShaderModule tessellationControlShaderModule
3283 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
3284 DE_NULL, // const VkShaderModule geometryShaderModule
3285 *fragmentShaderModuleInputAtt, // const VkShaderModule fragmentShaderModule
3286 *renderPass0, // const VkRenderPass renderPass
3287 viewports, // const std::vector<VkViewport>& viewports
3288 scissors, // const std::vector<VkRect2D>& scissors
3289 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
3290 0u, // const deUint32 subpass
3291 0u, // const deUint32 patchControlPoints
3292 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
3293 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3294 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
3295 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
3296 &colorBlendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
3297
3298 pipelineImageSampler = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
3299 device, // const VkDevice device
3300 *pipelineLayoutImageSampler, // const VkPipelineLayout pipelineLayout
3301 *vertexShaderModule, // const VkShaderModule vertexShaderModule
3302 DE_NULL, // const VkShaderModule tessellationControlShaderModule
3303 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
3304 DE_NULL, // const VkShaderModule geometryShaderModule
3305 *fragmentShaderModuleSampler, // const VkShaderModule fragmentShaderModule
3306 *renderPass1, // const VkRenderPass renderPass
3307 viewports, // const std::vector<VkViewport>& viewports
3308 scissors, // const std::vector<VkRect2D>& scissors
3309 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
3310 0u, // const deUint32 subpass
3311 0u, // const deUint32 patchControlPoints
3312 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
3313 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3314 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
3315 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
3316 &colorBlendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
3317 }
3318
3319 // Create framebuffers.
3320 {
3321 const VkFramebufferCreateInfo framebufferCreateInfo =
3322 {
3323 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
3324 DE_NULL, // const void* pNext
3325 0u, // VkFramebufferCreateFlags flags
3326 *renderPass0, // VkRenderPass renderPass
3327 1u, // uint32_t attachmentCount
3328 &imageViewInput.get(), // const VkImageView* pAttachments
3329 256u, // uint32_t width
3330 256u, // uint32_t height
3331 1u // uint32_t layers
3332 };
3333
3334 framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3335 }
3336 {
3337 const VkFramebufferCreateInfo framebufferCreateInfo =
3338 {
3339 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
3340 DE_NULL, // const void* pNext
3341 0u, // VkFramebufferCreateFlags flags
3342 *renderPass1, // VkRenderPass renderPass
3343 1u, // uint32_t attachmentCount
3344 &imageViewResult.get(), // const VkImageView* pAttachments
3345 m_width, // uint32_t width
3346 m_height, // uint32_t height
3347 1u // uint32_t layers
3348 };
3349
3350 framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3351 }
3352
3353 // Generate quad vertices.
3354 {
3355 const tcu::Vec4 lowerLeftVertex (-1.0f, -1.0f, 0.5f, 1.0f);
3356 const tcu::Vec4 lowerRightVertex (1.0f, -1.0f, 0.5f, 1.0f);
3357 const tcu::Vec4 upperLeftVertex (-1.0f, 1.0f, 0.5f, 1.0f);
3358 const tcu::Vec4 upperRightVertex (1.0f, 1.0f, 0.5f, 1.0f);
3359
3360 vertexData.push_back(lowerLeftVertex);
3361 vertexData.push_back(upperLeftVertex);
3362 vertexData.push_back(lowerRightVertex);
3363 vertexData.push_back(upperRightVertex);
3364 }
3365
3366 // Upload vertex data.
3367 {
3368 const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
3369
3370 const VkBufferCreateInfo vertexBufferParams =
3371 {
3372 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
3373 DE_NULL, // const void* pNext
3374 0u, // VkBufferCreateFlags flags
3375 (VkDeviceSize)vertexDataSize, // VkDeviceSize size
3376 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
3377 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
3378 1u, // deUint32 queueFamilyCount
3379 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices
3380 };
3381
3382 vertexBuffer = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
3383 vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
3384
3385 deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
3386 flushAlloc(vkd, device, *vertexBufferMemory);
3387 }
3388
3389 beginCommandBuffer(vkd, *commandBuffer);
3390
3391 // Begin render pass.
3392 {
3393 const VkRect2D renderArea =
3394 {
3395 { 0u, 0u }, // VkOffset2D offset
3396 { m_width, m_height } // VkExtent2D extent
3397 };
3398
3399 const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3400
3401 const VkRenderPassBeginInfo beginInfo =
3402 {
3403 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
3404 DE_NULL, // const void* pNext
3405 *renderPass0, // VkRenderPass renderPass
3406 *framebuffer0, // VkFramebuffer framebuffer
3407 renderArea, // VkRect2D renderArea
3408 1u, // uint32_t clearValueCount
3409 &clearValue // const VkClearValue* pClearValues
3410 };
3411
3412 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3413 }
3414
3415 // Bind pipeline.
3416 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSolidColor);
3417
3418 // Bind vertex buffer.
3419 const VkDeviceSize bindingOffset = 0;
3420 vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3421
3422 // Bind descriptor set.
3423 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3424
3425 // Draw solid color.
3426 vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3427
3428 // Bind pipeline.
3429 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineInputAtt);
3430
3431 // Bind descriptor set.
3432 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3433
3434 // Pipeline barrier to handle self dependency.
3435 {
3436 const VkImageMemoryBarrier imageBarrier =
3437 {
3438 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
3439 DE_NULL, // const void* pNext
3440 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3441 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
3442 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout
3443 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
3444 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
3445 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
3446 *colorImage, // VkImage image
3447 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange
3448 };
3449
3450 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);
3451 }
3452
3453 // Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
3454 vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3455
3456 // End render pass.
3457 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3458
3459 // Pipeline barrier.
3460 {
3461 const VkImageMemoryBarrier imageBarriers[] =
3462 {
3463 {
3464 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
3465 DE_NULL, // const void* pNext
3466 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
3467 | VK_ACCESS_TRANSFER_WRITE_BIT
3468 | VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask
3469 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask
3470 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout
3471 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout
3472 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
3473 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
3474 *colorImage, // VkImage image
3475 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange
3476 },
3477 {
3478 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
3479 DE_NULL, // const void* pNext
3480 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3481 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
3482 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
3483 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
3484 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
3485 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
3486 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
3487 *resultImage, // VkImage image
3488 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange
3489 }
3490 };
3491
3492 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);
3493 }
3494
3495 // Begin render pass.
3496 {
3497 const VkRect2D renderArea =
3498 {
3499 { 0, 0 }, // VkOffset2D offset
3500 { m_width, m_height } // VkExtent2D extent
3501 };
3502
3503 const VkRenderPassBeginInfo beginInfo =
3504 {
3505 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
3506 DE_NULL, // const void* pNext
3507 *renderPass1, // VkRenderPass renderPass
3508 *framebuffer1, // VkFramebuffer framebuffer
3509 renderArea, // VkRect2D renderArea
3510 0u, // uint32_t clearValueCount
3511 DE_NULL // const VkClearValue* pClearValues
3512 };
3513
3514 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3515 }
3516
3517 // Bind pipeline.
3518 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineImageSampler);
3519
3520 // Bind descriptor set.
3521 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutImageSampler, 0u, 1u, &*descriptorSetImageSampler, 0u, DE_NULL);
3522
3523 // Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
3524 vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3525
3526 // End render pass.
3527 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3528
3529 // Copy results to a buffer.
3530 copyImageToBuffer(vkd, *commandBuffer, *resultImage, *resultBuffer, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3531
3532 endCommandBuffer(vkd, *commandBuffer);
3533 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
3534 invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
3535
3536 // Verify results.
3537 {
3538 const tcu::TextureFormat format (mapVkFormat(m_format));
3539 tcu::TextureLevel reference (format, m_width, m_height);
3540 const void* const ptrResult (resultBufferMemory->getHostPtr());
3541 const tcu::ConstPixelBufferAccess resultAccess (format, m_width, m_height, 1, ptrResult);
3542 const PixelBufferAccess referenceAccess (reference.getAccess());
3543
3544 for (deUint32 x = 0; x < m_width; x++)
3545 for (deUint32 y = 0; y < m_height; y++)
3546 {
3547 referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
3548 }
3549
3550 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
3551 "Rendered result", // imageSetName
3552 "", // imageSetDesc
3553 referenceAccess, // reference
3554 resultAccess, // result
3555 Vec4(0.05f), // threshold
3556 tcu::COMPARE_LOG_RESULT)) // logMode
3557 {
3558 m_resultCollector.fail("Image compare failed.");
3559 }
3560 }
3561
3562 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
3563 }
3564
3565 // Shader programs for testing dependencies between render pass instances
3566 struct ExternalPrograms
3567 {
initvkt::__anon675baf4b0111::ExternalPrograms3568 void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
3569 {
3570 for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
3571 {
3572 dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
3573 "#version 450\n"
3574 "layout(location = 0) out highp vec2 vtxTexCoords;\n"
3575 "highp float;\n"
3576 "void main (void)\n"
3577 "{\n"
3578 " vec4 position;"
3579 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3580 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3581 " gl_Position = position;\n"
3582 " vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
3583 "}\n");
3584
3585 // First pass renders four quads of different color
3586 if (renderPassNdx == 0)
3587 {
3588 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3589 "#version 450\n"
3590 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3591 "layout(location = 0) out highp vec4 o_color;\n"
3592 "void main (void)\n"
3593 "{\n"
3594 " if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3595 " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3596 " else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3597 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3598 " else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3599 " o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
3600 " else\n"
3601 " o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
3602 ""
3603 "}\n");
3604 }
3605 else
3606 {
3607 if (renderPassNdx % 2 == 0)
3608 {
3609 // Blur previous pass horizontally
3610 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3611 "#version 450\n"
3612 "layout(binding = 0) uniform sampler2D previousPass;\n"
3613 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3614 "layout(location = 0) out highp vec4 o_color;\n"
3615 "void main (void)\n"
3616 "{\n"
3617 " vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3618 " vec2 minCoord = vec2(0.0, 0.0);\n"
3619 " vec2 maxCoord = vec2(1.0, 1.0);\n"
3620 " vec4 blurColor = vec4(0.0);\n"
3621 " for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3622 " {\n"
3623 " vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
3624 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3625 " }\n"
3626 " o_color = blurColor;\n"
3627 "}\n");
3628 }
3629 else
3630 {
3631 // Blur previous pass vertically
3632 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3633 "#version 450\n"
3634 "layout(binding = 0) uniform highp sampler2D previousPass;\n"
3635 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3636 "layout(location = 0) out highp vec4 o_color;\n"
3637 "void main (void)\n"
3638 "{\n"
3639 " vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3640 " vec2 minCoord = vec2(0.0, 0.0);\n"
3641 " vec2 maxCoord = vec2(1.0, 1.0);\n"
3642 " vec4 blurColor = vec4(0.0);\n"
3643 " for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3644 " {\n"
3645 " vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
3646 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3647 " }\n"
3648 " o_color = blurColor;\n"
3649 "}\n");
3650 }
3651 }
3652 }
3653 }
3654 };
3655
3656 // Shader programs for testing dependencies between subpasses
3657 struct SubpassPrograms
3658 {
initvkt::__anon675baf4b0111::SubpassPrograms3659 void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
3660 {
3661 size_t subpassCount = testConfig.renderPass.getSubpasses().size();
3662
3663 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
3664 {
3665 if (subpassNdx == 0)
3666 {
3667 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3668 "#version 450\n"
3669 "highp float;\n"
3670 "layout(location = 0) in highp vec4 position;\n"
3671 "void main (void)\n"
3672 "{\n"
3673 " gl_Position = position;\n"
3674 "}\n");
3675 }
3676 else
3677 {
3678 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3679 "#version 450\n"
3680 "highp float;\n"
3681 "void main (void)\n"
3682 "{\n"
3683 " vec4 position;"
3684 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3685 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3686 " gl_Position = position;\n"
3687 "}\n");
3688 }
3689
3690 if (isDepthStencilFormat(testConfig.format))
3691 {
3692 if (subpassNdx == 0)
3693 {
3694 // Empty fragment shader: Fragment depth unmodified.
3695 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3696 "#version 450\n"
3697 "void main (void)\n"
3698 "{\n"
3699 "}\n");
3700 }
3701 else
3702 {
3703 // Use fragment depth from previous depth rendering result.
3704 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3705 "#version 450\n"
3706 "layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
3707 "void main (void)\n"
3708 "{\n"
3709 " float inputDepth = subpassLoad(depthStencil).x;\n"
3710 " gl_FragDepth = inputDepth - 0.02;\n"
3711 "}\n");
3712 }
3713 }
3714 else
3715 DE_FATAL("Unimplemented");
3716 }
3717 }
3718 };
3719
3720 // Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
3721 struct SubpassSelfDependencyBackwardsPrograms
3722 {
initvkt::__anon675baf4b0111::SubpassSelfDependencyBackwardsPrograms3723 void init (vk::SourceCollections& dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
3724 {
3725 DE_UNREF(testConfig);
3726
3727 dst.glslSources.add("vert") << glu::VertexSource(
3728 "#version 450\n"
3729 "layout(location = 0) in highp vec4 position;\n"
3730 "out gl_PerVertex {\n"
3731 " vec4 gl_Position;\n"
3732 "};\n"
3733 "void main (void)\n"
3734 "{\n"
3735 " gl_Position = position;\n"
3736 "}\n");
3737
3738 dst.glslSources.add("geom") << glu::GeometrySource(
3739 "#version 450\n"
3740 "layout(points) in;\n"
3741 "layout(triangle_strip, max_vertices = 4) out;\n"
3742 "\n"
3743 "in gl_PerVertex {\n"
3744 " vec4 gl_Position;\n"
3745 "} gl_in[];\n"
3746 "\n"
3747 "out gl_PerVertex {\n"
3748 " vec4 gl_Position;\n"
3749 "};\n"
3750 "layout (binding = 0) buffer IndirectBuffer\n"
3751 "{\n"
3752 " uint vertexCount;\n"
3753 " uint instanceCount;\n"
3754 " uint firstVertex;\n"
3755 " uint firstInstance;\n"
3756 "} indirectBuffer;\n"
3757 "\n"
3758 "void main (void) {\n"
3759 " vec4 p = gl_in[0].gl_Position;\n"
3760 " float offset = 0.03f;\n"
3761 " gl_Position = p + vec4(-offset, offset, 0, 0);\n"
3762 " EmitVertex();\n"
3763 " gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
3764 " EmitVertex();\n"
3765 " gl_Position = p + vec4(offset, offset, 0, 0);\n"
3766 " EmitVertex();\n"
3767 " gl_Position = p + vec4(offset, -offset, 0, 0);\n"
3768 " EmitVertex();\n"
3769 " EndPrimitive();\n"
3770 " indirectBuffer.vertexCount = 64;\n"
3771 " indirectBuffer.instanceCount = 1;\n"
3772 " indirectBuffer.firstVertex = 64;\n"
3773 " indirectBuffer.firstInstance = 0;\n"
3774 "}\n");
3775
3776 dst.glslSources.add("frag") << glu::FragmentSource(
3777 "#version 450\n"
3778 "layout(location = 0) out highp vec4 fragColor;\n"
3779 "void main (void)\n"
3780 "{\n"
3781 " fragColor = vec4(1, 0, 0, 1);\n"
3782 "}\n");
3783 }
3784 };
3785
3786 struct SeparateChannelsPrograms
3787 {
initvkt::__anon675baf4b0111::SeparateChannelsPrograms3788 void init (vk::SourceCollections& dst, SeparateChannelsTestConfig testConfig) const
3789 {
3790 dst.glslSources.add("vert") << glu::VertexSource(
3791 "#version 450\n"
3792 "layout(location = 0) in highp vec4 position;\n"
3793 "void main (void)\n"
3794 "{\n"
3795 " gl_Position = position;\n"
3796 "}\n");
3797
3798 if (isDepthStencilFormat(testConfig.format))
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);\n"
3806 "}\n");
3807 }
3808 else
3809 {
3810 dst.glslSources.add("frag") << glu::FragmentSource(
3811 "#version 450\n"
3812 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3813 "layout(location = 0) out highp vec4 fragColor;\n"
3814 "void main (void)\n"
3815 "{\n"
3816 " vec4 inputColor = subpassLoad(inputAtt);\n"
3817 " fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
3818 "}\n");
3819 }
3820 }
3821 };
3822
3823 struct SingleAttachmentPrograms
3824 {
initvkt::__anon675baf4b0111::SingleAttachmentPrograms3825 void init (vk::SourceCollections& dst, SingleAttachmentTestConfig testConfig) const
3826 {
3827 DE_UNREF(testConfig);
3828
3829 dst.glslSources.add("vert") << glu::VertexSource(
3830 "#version 450\n"
3831 "layout(location = 0) in highp vec4 position;\n"
3832 "void main (void)\n"
3833 "{\n"
3834 " gl_Position = position;\n"
3835 "}\n");
3836
3837 dst.glslSources.add("frag_solid_color") << glu::FragmentSource(
3838 "#version 450\n"
3839 "layout(location = 0) out highp vec4 fragColor;\n"
3840 "void main (void)\n"
3841 "{\n"
3842 " fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
3843 "}\n");
3844
3845 dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
3846 "#version 450\n"
3847 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3848 "layout(location = 0) out highp vec4 fragColor;\n"
3849 "void main (void)\n"
3850 "{\n"
3851 " vec4 inputColor = subpassLoad(inputAtt);\n"
3852 " fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3853 "}\n");
3854
3855 dst.glslSources.add("frag_combined_image_sampler") << glu::FragmentSource(
3856 "#version 450\n"
3857 "layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
3858 "layout(location = 0) out highp vec4 fragColor;\n"
3859 "void main (void)\n"
3860 "{\n"
3861 " vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
3862 " vec4 inputColor = texture(tex, uv);\n"
3863 " fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3864 "}\n");
3865 }
3866 };
3867
formatToName(VkFormat format)3868 std::string formatToName (VkFormat format)
3869 {
3870 const std::string formatStr = de::toString(format);
3871 const std::string prefix = "VK_FORMAT_";
3872
3873 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
3874
3875 return de::toLower(formatStr.substr(prefix.length()));
3876 }
3877
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)3878 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
3879 {
3880 tcu::TestContext& testCtx(group->getTestContext());
3881
3882 // Test external subpass dependencies
3883 {
3884 const deUint32 renderPassCounts[] = { 2u, 3u, 5u};
3885
3886 const UVec2 renderSizes[] =
3887 {
3888 UVec2(64, 64),
3889 UVec2(128, 128),
3890 UVec2(512, 512)
3891 };
3892
3893 de::MovePtr<tcu::TestCaseGroup> externalGroup (new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));
3894
3895 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
3896 {
3897 string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
3898 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
3899
3900 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
3901 {
3902 vector<RenderPass> renderPasses;
3903
3904 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
3905 {
3906 vector<Attachment> attachments;
3907 vector<AttachmentReference> colorAttachmentReferences;
3908
3909 const VkFormat format (VK_FORMAT_R8G8B8A8_UNORM);
3910 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
3911 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3912 const VkAttachmentStoreOp storeOp (VK_ATTACHMENT_STORE_OP_STORE);
3913 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3914 const VkAttachmentStoreOp stencilStoreOp (VK_ATTACHMENT_STORE_OP_DONT_CARE);
3915 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
3916 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3917 const VkImageLayout subpassLayout (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3918
3919 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
3920 colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
3921
3922 const VkImageLayout depthStencilLayout (VK_IMAGE_LAYOUT_GENERAL);
3923 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
3924 AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
3925 vector<SubpassDependency> deps;
3926
3927 deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL, // deUint32 srcPass
3928 0, // deUint32 dstPass
3929 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
3930 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
3931 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3932 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
3933 0)); // VkDependencyFlags flags
3934
3935 deps.push_back(SubpassDependency(0, // deUint32 srcPass
3936 VK_SUBPASS_EXTERNAL, // deUint32 dstPass
3937 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
3938 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
3939 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3940 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
3941 0)); // VkDependencyFlags flags
3942
3943 RenderPass renderPass (attachments, subpasses, deps);
3944
3945 renderPasses.push_back(renderPass);
3946 }
3947
3948 const deUint32 blurKernel (12u);
3949 string testName ("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
3950 ExternalTestConfig testConfig
3951 {
3952 VK_FORMAT_R8G8B8A8_UNORM,
3953 renderSizes[renderSizeNdx],
3954 renderPasses,
3955 renderPassType,
3956 SYNCHRONIZATION_TYPE_LEGACY,
3957 blurKernel
3958 };
3959
3960 renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3961 if (renderPassType == RENDERPASS_TYPE_RENDERPASS2)
3962 {
3963 testName += "_sync_2";
3964 testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
3965 renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3966 }
3967 }
3968
3969 externalGroup->addChild(renderSizeGroup.release());
3970 }
3971
3972 group->addChild(externalGroup.release());
3973 }
3974
3975 // Test implicit subpass dependencies
3976 {
3977 const deUint32 renderPassCounts[] = { 2u, 3u, 5u };
3978
3979 de::MovePtr<tcu::TestCaseGroup> implicitGroup (new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));
3980
3981 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
3982 {
3983 vector<RenderPass> renderPasses;
3984
3985 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
3986 {
3987 vector<Attachment> attachments;
3988 vector<AttachmentReference> colorAttachmentReferences;
3989
3990 const VkFormat format (VK_FORMAT_R8G8B8A8_UNORM);
3991 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
3992 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3993 const VkAttachmentStoreOp storeOp (VK_ATTACHMENT_STORE_OP_STORE);
3994 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3995 const VkAttachmentStoreOp stencilStoreOp (VK_ATTACHMENT_STORE_OP_DONT_CARE);
3996 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
3997 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3998 const VkImageLayout subpassLayout (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3999
4000 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4001 colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
4002
4003 const VkImageLayout depthStencilLayout (VK_IMAGE_LAYOUT_GENERAL);
4004 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
4005 vector<SubpassDependency> deps;
4006
4007 // The first render pass lets the implementation add all subpass dependencies implicitly.
4008 // On the following passes only the dependency from external to first subpass is defined as
4009 // we need to make sure we have the image ready from previous render pass. In this case
4010 // the dependency from subpass 0 to external is added implicitly by the implementation.
4011 if (renderPassNdx > 0)
4012 {
4013 deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL, // deUint32 srcPass
4014 0, // deUint32 dstPass
4015 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
4016 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
4017 0, // VkAccessFlags srcAccessMask
4018 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
4019 0)); // VkDependencyFlags flags
4020 }
4021
4022 RenderPass renderPass (attachments, subpasses, deps);
4023
4024 renderPasses.push_back(renderPass);
4025 }
4026
4027 const deUint32 blurKernel (12u);
4028 const ExternalTestConfig testConfig (VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderPassType, SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
4029 const string testName ("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4030
4031 implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
4032 }
4033
4034 group->addChild(implicitGroup.release());
4035 }
4036
4037 // Test late fragment operations using depth_stencil attachments in multipass rendering
4038 {
4039 const UVec2 renderSizes[] =
4040 {
4041 UVec2(32, 32),
4042 UVec2(64, 64),
4043 UVec2(128, 128)
4044 };
4045
4046 const deUint32 subpassCounts[] = { 2u, 3u, 5u };
4047
4048 // Implementations must support at least one of the following formats
4049 // for depth_stencil attachments
4050 const VkFormat formats[] =
4051 {
4052 VK_FORMAT_D24_UNORM_S8_UINT,
4053 VK_FORMAT_D32_SFLOAT_S8_UINT
4054 };
4055
4056 de::MovePtr<tcu::TestCaseGroup> lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));
4057
4058 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4059 {
4060 string renderSizeGroupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4061 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup (new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));
4062
4063 for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
4064 {
4065 string subpassGroupName ("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
4066 de::MovePtr<tcu::TestCaseGroup> subpassCountGroup (new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));
4067
4068 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
4069 {
4070 const deUint32 subpassCount (subpassCounts[subpassCountNdx]);
4071 const deUint32 attachmentCount (subpassCount);
4072 vector<Subpass> subpasses;
4073 vector<Attachment> attachments;
4074 vector<SubpassDependency> deps;
4075
4076 // Attachments
4077 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4078 {
4079 const VkFormat format (formats[formatNdx]);
4080 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
4081 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_CLEAR);
4082 const VkAttachmentStoreOp storeOp ((attachmentNdx == attachmentCount - 1)
4083 ? VK_ATTACHMENT_STORE_OP_STORE
4084 : VK_ATTACHMENT_STORE_OP_DONT_CARE);
4085 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_CLEAR);
4086 const VkAttachmentStoreOp stencilStoreOp ((attachmentNdx == attachmentCount - 1)
4087 ? VK_ATTACHMENT_STORE_OP_STORE
4088 : VK_ATTACHMENT_STORE_OP_DONT_CARE);
4089 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
4090 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
4091
4092 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4093 }
4094
4095 // Subpasses
4096 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
4097 {
4098 vector<AttachmentReference> inputAttachmentReferences;
4099 const VkImageAspectFlags inputAttachmentAspectMask ((renderPassType == RENDERPASS_TYPE_RENDERPASS2)
4100 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
4101 : static_cast<VkImageAspectFlags>(0));
4102
4103 // Input attachment references
4104 if (subpassNdx > 0)
4105 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));
4106
4107 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>()));
4108
4109 // Subpass dependencies from current subpass to previous subpass.
4110 // Subpasses will wait for the late fragment operations before reading the contents
4111 // of previous subpass.
4112 if (subpassNdx > 0)
4113 {
4114 deps.push_back(SubpassDependency((deUint32)subpassNdx - 1, // deUint32 srcPass
4115 (deUint32)subpassNdx, // deUint32 dstPass
4116 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
4117 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4118 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
4119 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4120 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
4121 VK_DEPENDENCY_BY_REGION_BIT)); // VkDependencyFlags flags
4122 }
4123 }
4124 deps.push_back(SubpassDependency((deUint32)subpassCount - 1, // deUint32 srcPass
4125 VK_SUBPASS_EXTERNAL, // deUint32 dstPass
4126 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
4127 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
4128 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
4129 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
4130 VK_DEPENDENCY_BY_REGION_BIT)); // VkDependencyFlags flags
4131
4132 const RenderPass renderPass (attachments, subpasses, deps);
4133 const SubpassTestConfig testConfig (formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderPassType);
4134 const string format (formatToName(formats[formatNdx]).c_str());
4135
4136 subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
4137 }
4138
4139 renderSizeGroup->addChild(subpassCountGroup.release());
4140 }
4141
4142 lateFragmentTestsGroup->addChild(renderSizeGroup.release());
4143 }
4144
4145 group->addChild(lateFragmentTestsGroup.release());
4146 }
4147
4148 // Test subpass self dependency
4149 {
4150 const UVec2 renderSizes[] =
4151 {
4152 UVec2(64, 64),
4153 UVec2(128, 128),
4154 UVec2(512, 512)
4155 };
4156
4157 de::MovePtr<tcu::TestCaseGroup> selfDependencyGroup (new tcu::TestCaseGroup(testCtx, "self_dependency", "self_dependency"));
4158
4159 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4160 {
4161 string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4162 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
4163
4164 const SubpassSelfDependencyBackwardsTestConfig testConfig (VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderPassType);
4165 renderSizeGroup->addChild(new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance, SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "geometry_to_indirectdraw", "", testConfig));
4166
4167 selfDependencyGroup->addChild(renderSizeGroup.release());
4168 }
4169
4170 group->addChild(selfDependencyGroup.release());
4171 }
4172
4173 // Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
4174 {
4175 de::MovePtr<tcu::TestCaseGroup> separateChannelsGroup (new tcu::TestCaseGroup(testCtx, "separate_channels", "separate_channels"));
4176
4177 struct TestConfig
4178 {
4179 string name;
4180 VkFormat format;
4181 } configs[] =
4182 {
4183 { "r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM },
4184 { "r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT },
4185 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
4186 { "d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT }
4187 };
4188
4189 for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4190 {
4191 const SeparateChannelsTestConfig testConfig(configs[configIdx].format, renderPassType);
4192
4193 separateChannelsGroup->addChild(new InstanceFactory1<SeparateChannelsTestInstance, SeparateChannelsTestConfig, SeparateChannelsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4194 }
4195
4196 group->addChild(separateChannelsGroup.release());
4197 }
4198
4199 // Test using a single attachment for input and output.
4200 {
4201 de::MovePtr<tcu::TestCaseGroup> singleAttachmentGroup (new tcu::TestCaseGroup(testCtx, "single_attachment", "single_attachment"));
4202
4203 struct TestConfig
4204 {
4205 string name;
4206 VkFormat format;
4207 } configs[] =
4208 {
4209 { "r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM },
4210 { "b8g8r8a8_unorm", VK_FORMAT_B8G8R8A8_UNORM },
4211 { "r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT },
4212 { "r5g6b5_unorm_pack16", VK_FORMAT_R5G6B5_UNORM_PACK16 },
4213 { "a1r5g5b5_unorm_pack16", VK_FORMAT_A1R5G5B5_UNORM_PACK16 }
4214 };
4215
4216 for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4217 {
4218 const SingleAttachmentTestConfig testConfig(configs[configIdx].format, renderPassType);
4219
4220 singleAttachmentGroup->addChild(new InstanceFactory1<SingleAttachmentTestInstance, SingleAttachmentTestConfig, SingleAttachmentPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4221 }
4222
4223 group->addChild(singleAttachmentGroup.release());
4224 }
4225 }
4226 } // anonymous
4227
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx)4228 tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
4229 {
4230 return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_LEGACY);
4231 }
4232
createRenderPass2SubpassDependencyTests(tcu::TestContext & testCtx)4233 tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
4234 {
4235 return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
4236 }
4237 } // vkt
4238