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 sparse render target.
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
36 #include "tcuImageCompare.hpp"
37 #include "tcuResultCollector.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuTextureUtil.hpp"
40
41 #include "rrRenderer.hpp"
42 #include "deRandom.hpp"
43 #include "deMath.h"
44
45 using namespace vk;
46
47 using tcu::UVec4;
48 using tcu::Vec2;
49 using tcu::UVec2;
50 using tcu::Vec4;
51
52 using tcu::ConstPixelBufferAccess;
53 using tcu::PixelBufferAccess;
54
55 using tcu::TestLog;
56
57 using std::string;
58 using std::vector;
59 using de::SharedPtr;
60
61 typedef de::SharedPtr<Unique<VkImage> > SharedPtrVkImage;
62 typedef de::SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
63 typedef de::SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
64 typedef de::SharedPtr<Unique<VkSampler> > SharedPtrVkSampler;
65 typedef de::SharedPtr<Unique<VkRenderPass> > SharedPtrVkRenderPass;
66 typedef de::SharedPtr<Unique<VkFramebuffer> > SharedPtrVkFramebuffer;
67 typedef de::SharedPtr<Unique<VkDescriptorPool> > SharedPtrVkDescriptorPool;
68 typedef de::SharedPtr<Unique<VkDescriptorSetLayout> > SharedPtrVkDescriptorLayout;
69 typedef de::SharedPtr<Unique<VkDescriptorSet> > SharedPtrVkDescriptorSet;
70 typedef de::SharedPtr<Unique<VkPipelineLayout> > SharedPtrVkPipelineLayout;
71 typedef de::SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
72
73 namespace vkt
74 {
75 namespace
76 {
77 using namespace renderpass;
78
79 template<typename T>
makeSharedPtr(Move<T> move)80 inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
81 {
82 return SharedPtr<Unique<T> >(new Unique<T>(move));
83 }
84
85 // Reference renderer shaders
86 class DepthVertShader : public rr::VertexShader
87 {
88 public:
DepthVertShader(void)89 DepthVertShader (void)
90 : rr::VertexShader (1, 1)
91 {
92 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
93 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
94 }
95
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const96 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
97 {
98 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
99 {
100 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
101 packets[packetNdx]->instanceNdx,
102 packets[packetNdx]->vertexNdx);
103
104 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[0],
105 packets[packetNdx]->instanceNdx,
106 packets[packetNdx]->vertexNdx);
107 }
108 }
109 };
110
111 class DepthFragShader : public rr::FragmentShader
112 {
113 public:
DepthFragShader(void)114 DepthFragShader (void)
115 : rr::FragmentShader(1, 1)
116 {
117 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
118 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
119 }
120
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const121 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
122 {
123 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
124 {
125 rr::FragmentPacket& packet = packets[packetNdx];
126 for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
127 {
128 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
129
130 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
131 }
132 }
133 }
134 };
135
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)136 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
137 VkDevice device,
138 Allocator& allocator,
139 VkBuffer buffer)
140 {
141 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
142
143 VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
144
145 return allocation;
146 }
147
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)148 Move<VkImageView> createImageView (const DeviceInterface& vk,
149 VkDevice device,
150 VkImageViewCreateFlags flags,
151 VkImage image,
152 VkImageViewType viewType,
153 VkFormat format,
154 VkComponentMapping components,
155 VkImageSubresourceRange subresourceRange)
156 {
157 const VkImageViewCreateInfo pCreateInfo =
158 {
159 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
160 DE_NULL, // const void* pNext
161 flags, // VkImageViewCreateFlags flags
162 image, // VkImage image
163 viewType, // VkImageViewType viewType
164 format, // VkFormat format
165 components, // VkComponentMapping components
166 subresourceRange, // VkImageSubresourceRange subresourceRange
167 };
168
169 return createImageView(vk, device, &pCreateInfo);
170 }
171
createImageViews(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkImage> images,VkFormat format,VkImageAspectFlags aspect)172 vector<SharedPtrVkImageView> createImageViews (const DeviceInterface& vkd,
173 VkDevice device,
174 vector<SharedPtrVkImage> images,
175 VkFormat format,
176 VkImageAspectFlags aspect)
177 {
178 vector<SharedPtrVkImageView> imageViews;
179
180 for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
181 {
182 const VkImageSubresourceRange range =
183 {
184 aspect, // VkImageAspectFlags aspectMask
185 0u, // uint32_t baseMipLevel
186 1u, // uint32_t levelCount
187 0u, // uint32_t baseArrayLayer
188 1u // uint32_t layerCount
189 };
190
191 imageViews.push_back(makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range)));
192 }
193
194 return imageViews;
195 }
196
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)197 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
198 VkDevice device,
199 VkFormat format,
200 deUint32 width,
201 deUint32 height)
202 {
203 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
204 const VkDeviceSize pixelSize = mapVkFormat(format).getPixelSize();
205 const VkBufferCreateInfo createInfo =
206 {
207 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
208 DE_NULL, // const void* pNext
209 0u, // VkBufferCreateFlags flags
210 width * height * pixelSize, // VkDeviceSize size
211 bufferUsage, // VkBufferUsageFlags usage
212 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
213 0u, // uint32_t queueFamilyIndexCount
214 DE_NULL // const uint32_t* pQueueFamilyIndices
215 };
216
217 return createBuffer(vkd, device, &createInfo);
218 }
219
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkSampler> & samplers)220 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts (const DeviceInterface& vkd,
221 VkDevice device,
222 vector<SharedPtrVkSampler>& samplers)
223 {
224 vector<SharedPtrVkDescriptorLayout> layouts;
225
226 for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
227 {
228 const VkDescriptorSetLayoutBinding bindings =
229 {
230 0u, // uint32_t binding
231 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType
232 1u, // uint32_t descriptorCount
233 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
234 &**samplers[layoutNdx] // const VkSampler* pImmutableSamplers
235 };
236
237 const VkDescriptorSetLayoutCreateInfo createInfo =
238 {
239 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
240 DE_NULL, // const void* pNext
241 0u, // VkDescriptorSetLayoutCreateFlags flags
242 1u, // uint32_t bindingCount
243 &bindings // const VkDescriptorSetLayoutBinding* pBindings
244 };
245
246 layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
247 }
248
249 return layouts;
250 }
251
createDescriptorPools(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorLayout> & layouts,VkDescriptorType type)252 vector<SharedPtrVkDescriptorPool> createDescriptorPools (const DeviceInterface& vkd,
253 VkDevice device,
254 vector<SharedPtrVkDescriptorLayout>& layouts,
255 VkDescriptorType type)
256 {
257 vector<SharedPtrVkDescriptorPool> descriptorPools;
258
259 for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
260 {
261 const VkDescriptorPoolSize size =
262 {
263 type, // VkDescriptorType type
264 1u // uint32_t descriptorCount
265 };
266
267 const VkDescriptorPoolCreateInfo createInfo =
268 {
269 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
270 DE_NULL, // const void* pNext
271 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
272 1u, // uint32_t maxSets
273 1u, // uint32_t poolSizeCount
274 &size // const VkDescriptorPoolSize* pPoolSizes
275 };
276
277 descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
278 }
279
280 return descriptorPools;
281 }
282
283 struct ExternalTestConfig
284 {
ExternalTestConfigvkt::__anon104c10a40111::ExternalTestConfig285 ExternalTestConfig (VkFormat format_,
286 UVec2 imageSize_,
287 vector<RenderPass> renderPasses_,
288 RenderPassType renderPassType_,
289 deUint32 blurKernel_ = 4)
290 : format (format_)
291 , imageSize (imageSize_)
292 , renderPasses (renderPasses_)
293 , renderPassType (renderPassType_)
294 , blurKernel (blurKernel_)
295 {
296 }
297
298 VkFormat format;
299 UVec2 imageSize;
300 vector<RenderPass> renderPasses;
301 RenderPassType renderPassType;
302 deUint32 blurKernel;
303 };
304
305 class ExternalDependencyTestInstance : public TestInstance
306 {
307 public:
308 ExternalDependencyTestInstance (Context& context, ExternalTestConfig testConfig);
309 ~ExternalDependencyTestInstance (void);
310
311 vector<SharedPtrVkImage> createAndAllocateImages (const DeviceInterface& vk,
312 VkDevice device,
313 Allocator& allocator,
314 vector<de::SharedPtr<Allocation> >& imageMemories,
315 deUint32 universalQueueFamilyIndex,
316 VkFormat format,
317 deUint32 width,
318 deUint32 height,
319 vector<RenderPass> renderPasses);
320
321 vector<SharedPtrVkSampler> createSamplers (const DeviceInterface& vkd,
322 const VkDevice device,
323 vector<RenderPass>& renderPasses);
324
325 vector<SharedPtrVkRenderPass> createRenderPasses (const DeviceInterface& vkd,
326 VkDevice device,
327 vector<RenderPass> renderPassInfos,
328 const RenderPassType renderPassType);
329
330 vector<SharedPtrVkFramebuffer> createFramebuffers (const DeviceInterface& vkd,
331 VkDevice device,
332 vector<SharedPtrVkRenderPass>& renderPasses,
333 vector<SharedPtrVkImageView>& dstImageViews,
334 deUint32 width,
335 deUint32 height);
336
337 vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts (const DeviceInterface& vkd,
338 VkDevice device,
339 vector<SharedPtrVkRenderPass>& renderPasses,
340 vector<SharedPtrVkDescriptorLayout>& descriptorSetLayouts);
341
342 vector<SharedPtrVkPipeline> createRenderPipelines (const DeviceInterface& vkd,
343 VkDevice device,
344 vector<SharedPtrVkRenderPass>& renderPasses,
345 vector<SharedPtrVkPipelineLayout>& pipelineLayouts,
346 const BinaryCollection& binaryCollection,
347 deUint32 width,
348 deUint32 height);
349
350 vector<SharedPtrVkDescriptorSet> createDescriptorSets (const DeviceInterface& vkd,
351 VkDevice device,
352 vector<SharedPtrVkDescriptorPool>& pools,
353 vector<SharedPtrVkDescriptorLayout>& layouts,
354 vector<SharedPtrVkImageView>& imageViews,
355 vector<SharedPtrVkSampler>& samplers);
356
357 tcu::TestStatus iterate (void);
358
359 template<typename RenderpassSubpass>
360 tcu::TestStatus iterateInternal (void);
361
362 private:
363 const bool m_extensionSupported;
364 const RenderPassType m_renderPassType;
365
366 const deUint32 m_width;
367 const deUint32 m_height;
368 const deUint32 m_blurKernel;
369 const VkFormat m_format;
370
371 vector<de::SharedPtr<Allocation> > m_imageMemories;
372 vector<SharedPtrVkImage> m_images;
373 vector<SharedPtrVkImageView> m_imageViews;
374 vector<SharedPtrVkSampler> m_samplers;
375
376 const Unique<VkBuffer> m_dstBuffer;
377 const de::UniquePtr<Allocation> m_dstBufferMemory;
378
379 vector<SharedPtrVkRenderPass> m_renderPasses;
380 vector<SharedPtrVkFramebuffer> m_framebuffers;
381
382 vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
383 vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
384 vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
385
386 vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
387 vector<SharedPtrVkPipeline> m_renderPipelines;
388
389 const Unique<VkCommandPool> m_commandPool;
390 tcu::ResultCollector m_resultCollector;
391 };
392
ExternalDependencyTestInstance(Context & context,ExternalTestConfig testConfig)393 ExternalDependencyTestInstance::ExternalDependencyTestInstance (Context& context, ExternalTestConfig testConfig)
394 : TestInstance (context)
395 , m_extensionSupported ((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
396 , m_renderPassType (testConfig.renderPassType)
397 , m_width (testConfig.imageSize.x())
398 , m_height (testConfig.imageSize.y())
399 , m_blurKernel (testConfig.blurKernel)
400 , m_format (testConfig.format)
401 , m_images (createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width, m_height, testConfig.renderPasses))
402 , m_imageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
403 , m_samplers (createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
404 , m_dstBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
405 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
406 , m_renderPasses (createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses, testConfig.renderPassType))
407 , m_framebuffers (createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews, m_width, m_height))
408 , m_subpassDescriptorSetLayouts (createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
409 , m_subpassDescriptorPools (createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
410 , m_subpassDescriptorSets (createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews, m_samplers))
411 , m_renderPipelineLayouts (createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_subpassDescriptorSetLayouts))
412 , m_renderPipelines (createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_renderPipelineLayouts, context.getBinaryCollection(), m_width, m_height))
413 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
414 {
415 }
416
~ExternalDependencyTestInstance(void)417 ExternalDependencyTestInstance::~ExternalDependencyTestInstance (void)
418 {
419 }
420
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,VkFormat format,deUint32 width,deUint32 height,vector<RenderPass> renderPasses)421 vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages (const DeviceInterface& vk,
422 VkDevice device,
423 Allocator& allocator,
424 vector<de::SharedPtr<Allocation> >& imageMemories,
425 deUint32 universalQueueFamilyIndex,
426 VkFormat format,
427 deUint32 width,
428 deUint32 height,
429 vector<RenderPass> renderPasses)
430 {
431 vector<SharedPtrVkImage> images;
432
433 for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
434 {
435 const VkExtent3D imageExtent =
436 {
437 width, // uint32_t width
438 height, // uint32_t height
439 1u // uint32_t depth
440 };
441
442 const VkImageCreateInfo imageCreateInfo =
443 {
444 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
445 DE_NULL, // const void* pNext
446 0u, // VkImageCreateFlags flags
447 VK_IMAGE_TYPE_2D, // VkImageType imageType
448 format, // VkFormat format
449 imageExtent, // VkExtent3D extent
450 1u, // uint32_t mipLevels
451 1u, // uint32_t arrayLayers
452 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
453 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
454 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
455 | VK_IMAGE_USAGE_SAMPLED_BIT
456 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
457 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
458 1u, // uint32_t queueFamilyIndexCount
459 &universalQueueFamilyIndex, // const uint32_t* pQueueFamilyIndices
460 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
461 };
462
463 images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
464 imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
465 VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
466 }
467
468 return images;
469 }
470
createSamplers(const DeviceInterface & vkd,const VkDevice device,vector<RenderPass> & renderPasses)471 vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers (const DeviceInterface& vkd,
472 const VkDevice device,
473 vector<RenderPass>& renderPasses)
474 {
475 vector<SharedPtrVkSampler> samplers;
476
477 for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
478 {
479 const VkSamplerCreateInfo samplerInfo =
480 {
481 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
482 DE_NULL, // const void* pNext
483 0u, // VkSamplerCreateFlags flags
484 VK_FILTER_NEAREST, // VkFilter magFilter
485 VK_FILTER_NEAREST, // VkFilter minFilter
486 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
487 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
488 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
489 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
490 0.0f, // float mipLodBias
491 VK_FALSE, // VkBool32 anisotropyEnable
492 1.0f, // float maxAnisotropy
493 VK_FALSE, // VkBool32 compareEnable
494 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
495 0.0f, // float minLod
496 0.0f, // float maxLod
497 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
498 VK_FALSE, // VkBool32 unnormalizedCoordinates
499 };
500
501 samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
502 }
503
504 return samplers;
505 }
506
createRenderPasses(const DeviceInterface & vkd,VkDevice device,vector<RenderPass> renderPassInfos,const RenderPassType renderPassType)507 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface& vkd,
508 VkDevice device,
509 vector<RenderPass> renderPassInfos,
510 const RenderPassType renderPassType)
511 {
512 vector<SharedPtrVkRenderPass> renderPasses;
513
514 for (size_t renderPassNdx = 0; renderPassNdx < renderPassInfos.size(); renderPassNdx++)
515 {
516 renderPasses.push_back(makeSharedPtr(createRenderPass(vkd, device, renderPassInfos[renderPassNdx], renderPassType)));
517 }
518
519 return renderPasses;
520 }
521
createFramebuffers(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)522 vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers (const DeviceInterface& vkd,
523 VkDevice device,
524 vector<SharedPtrVkRenderPass>& renderPasses,
525 vector<SharedPtrVkImageView>& dstImageViews,
526 deUint32 width,
527 deUint32 height)
528 {
529 vector<SharedPtrVkFramebuffer> framebuffers;
530
531 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
532 {
533 VkRenderPass renderPass (**renderPasses[renderPassNdx]);
534
535 const VkFramebufferCreateInfo createInfo =
536 {
537 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
538 DE_NULL, // const void* pNext
539 0u, // VkFramebufferCreateFlags flags
540 renderPass, // VkRenderPass renderPass
541 1u, // uint32_t attachmentCount
542 &**dstImageViews[renderPassNdx], // const VkImageView* pAttachments
543 width, // uint32_t width
544 height, // uint32_t height
545 1u // uint32_t layers
546 };
547
548 framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
549 }
550
551 return framebuffers;
552 }
553
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews,vector<SharedPtrVkSampler> & samplers)554 vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets (const DeviceInterface& vkd,
555 VkDevice device,
556 vector<SharedPtrVkDescriptorPool>& pools,
557 vector<SharedPtrVkDescriptorLayout>& layouts,
558 vector<SharedPtrVkImageView>& imageViews,
559 vector<SharedPtrVkSampler>& samplers)
560 {
561 vector<SharedPtrVkDescriptorSet> descriptorSets;
562
563 for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
564 {
565 const VkDescriptorSetAllocateInfo allocateInfo =
566 {
567 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
568 DE_NULL, // const void* pNext
569 **pools[setNdx], // VkDescriptorPool descriptorPool
570 1u, // uint32_t descriptorSetCount
571 &**layouts[setNdx] // const VkDescriptorSetLayout* pSetLayouts
572 };
573
574 descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
575
576 {
577 const VkDescriptorImageInfo imageInfo =
578 {
579 **samplers[setNdx], // VkSampler sampler
580 **imageViews[setNdx], // VkImageView imageView
581 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout
582 };
583
584 const VkWriteDescriptorSet write =
585 {
586 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
587 DE_NULL, // const void* pNext
588 **descriptorSets[setNdx], // VkDescriptorSet dstSet
589 0u, // uint32_t dstBinding
590 0u, // uint32_t dstArrayElement
591 1u, // uint32_t descriptorCount
592 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType
593 &imageInfo, // const VkDescriptorImageInfo* pImageInfo
594 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
595 DE_NULL // const VkBufferView* pTexelBufferView
596 };
597
598 vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
599 }
600 }
601
602 return descriptorSets;
603 }
604
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkDescriptorLayout> & descriptorSetLayouts)605 vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface& vkd,
606 VkDevice device,
607 vector<SharedPtrVkRenderPass>& renderPasses,
608 vector<SharedPtrVkDescriptorLayout>& descriptorSetLayouts)
609 {
610 vector<SharedPtrVkPipelineLayout> pipelineLayouts;
611
612 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
613 {
614 const VkPipelineLayoutCreateInfo createInfo =
615 {
616 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
617 DE_NULL, // const void* pNext
618 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
619 renderPassNdx > 0 ? 1u : 0u, // deUint32 setLayoutCount
620 renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] : DE_NULL, // const VkDescriptorSetLayout* pSetLayouts
621 0u, // deUint32 pushConstantRangeCount
622 DE_NULL // const VkPushConstantRange* pPushConstantRanges
623 };
624
625 pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
626 }
627
628 return pipelineLayouts;
629 }
630
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)631 vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines (const DeviceInterface& vkd,
632 VkDevice device,
633 vector<SharedPtrVkRenderPass>& renderPasses,
634 vector<SharedPtrVkPipelineLayout>& pipelineLayouts,
635 const BinaryCollection& binaryCollection,
636 deUint32 width,
637 deUint32 height)
638 {
639 vector<SharedPtrVkPipeline> pipelines;
640
641 for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
642 {
643 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
644 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));
645
646 const VkPipelineVertexInputStateCreateInfo vertexInputState =
647 {
648 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
649 DE_NULL, // const void* pNext
650 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
651 0u, // uint32_t vertexBindingDescriptionCount
652 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
653 0u, // uint32_t vertexAttributeDescriptionCount
654 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
655 };
656
657 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
658 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
659 const VkRenderPass renderPass (**renderPasses[renderPassNdx]);
660 const VkPipelineLayout layout (**pipelineLayouts[renderPassNdx]);
661
662 pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd, // const DeviceInterface& vk
663 device, // const VkDevice device
664 layout, // const VkPipelineLayout pipelineLayout
665 *vertexShaderModule, // const VkShaderModule vertexShaderModule
666 DE_NULL, // const VkShaderModule tessellationControlShaderModule
667 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
668 DE_NULL, // const VkShaderModule geometryShaderModule
669 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
670 renderPass, // const VkRenderPass renderPass
671 viewports, // const std::vector<VkViewport>& viewports
672 scissors, // const std::vector<VkRect2D>& scissors
673 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
674 0u, // const deUint32 subpass
675 0u, // const deUint32 patchControlPoints
676 &vertexInputState))); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
677 }
678
679 return pipelines;
680 }
681
iterate(void)682 tcu::TestStatus ExternalDependencyTestInstance::iterate (void)
683 {
684 switch (m_renderPassType)
685 {
686 case RENDERPASS_TYPE_LEGACY:
687 return iterateInternal<RenderpassSubpass1>();
688 case RENDERPASS_TYPE_RENDERPASS2:
689 return iterateInternal<RenderpassSubpass2>();
690 default:
691 TCU_THROW(InternalError, "Impossible");
692 }
693 }
694
695 template<typename RenderpassSubpass>
iterateInternal(void)696 tcu::TestStatus ExternalDependencyTestInstance::iterateInternal (void)
697 {
698 const DeviceInterface& vkd (m_context.getDeviceInterface());
699 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
700 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
701 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
702
703 beginCommandBuffer(vkd, *commandBuffer);
704
705 for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
706 {
707 // Begin render pass
708 {
709 VkRect2D renderArea =
710 {
711 { 0u, 0u }, // VkOffset2D offset
712 { m_width, m_height } // VkExtent2D extent
713 };
714
715 const VkRenderPassBeginInfo beginInfo =
716 {
717 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
718 DE_NULL, // const void* pNext
719 **m_renderPasses[renderPassNdx], // VkRenderPass renderPass
720 **m_framebuffers[renderPassNdx], // VkFramebuffer framebuffer
721 renderArea, // VkRect2D renderArea
722 0u, // uint32_t clearValueCount
723 DE_NULL // const VkClearValue* pClearValues
724 };
725
726 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
727 }
728
729 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);
730
731 // Use results from the previous pass as input texture
732 if (renderPassNdx > 0)
733 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[renderPassNdx], 0, 1, &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);
734
735 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
736
737 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
738 }
739
740 // Memory barrier between rendering and copy
741 {
742 VkImageSubresourceRange imageSubresourceRange =
743 {
744 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
745 0u, // uint32_t baseMipLevel
746 1u, // uint32_t levelCount
747 0u, // uint32_t baseArrayLayer
748 1u // uint32_t layerCount
749 };
750
751 const VkImageMemoryBarrier barrier =
752 {
753 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
754 DE_NULL, // const void* pNext
755 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
756 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
757 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout oldLayout
758 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
759 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
760 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
761 **m_images[m_renderPasses.size() - 1], // VkImage image
762 imageSubresourceRange // VkImageSubresourceRange subresourceRange
763 };
764
765 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
766 }
767
768 // Copy image memory to buffer
769 {
770 const VkImageSubresourceLayers imageSubresourceLayers =
771 {
772 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
773 0u, // deUint32 mipLevel
774 0u, // deUint32 baseArrayLayer
775 1u // deUint32 layerCount
776 };
777
778 const VkBufferImageCopy region =
779 {
780 0u, // VkDeviceSize bufferOffset
781 0u, // uint32_t bufferRowLength
782 0u, // uint32_t bufferImageHeight
783 imageSubresourceLayers, // VkImageSubresourceLayers imageSubresource
784 { 0u, 0u, 0u }, // VkOffset3D imageOffset
785 { m_width, m_height, 1u } // VkExtent3D imageExtent
786 };
787
788 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, ®ion);
789 }
790
791 // Memory barrier between copy and host access
792 {
793 const VkBufferMemoryBarrier barrier =
794 {
795 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
796 DE_NULL, // const void* pNext
797 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
798 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
799 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
800 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
801 *m_dstBuffer, // VkBuffer buffer
802 0u, // VkDeviceSize offset
803 VK_WHOLE_SIZE // VkDeviceSize size
804 };
805
806 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
807 }
808
809 endCommandBuffer(vkd, *commandBuffer);
810 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
811 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(), m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);
812
813 {
814 const tcu::TextureFormat format (mapVkFormat(m_format));
815 const void* const ptr (m_dstBufferMemory->getHostPtr());
816 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
817 tcu::TextureLevel reference (format, m_width, m_height);
818 tcu::TextureLevel textureA (format, m_width, m_height);
819 tcu::TextureLevel textureB (format, m_width, m_height);
820
821 for (deUint32 renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
822 {
823 // First pass renders four quads of different color, which will be blurred in the following passes
824 if (renderPassNdx == 0)
825 {
826 for (deUint32 y = 0; y < m_height; y++)
827 for (deUint32 x = 0; x < m_width; x++)
828 {
829 if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
830 textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
831 else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
832 textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
833 else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
834 textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
835 else
836 textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
837 }
838 }
839 // Blur previous pass
840 else
841 {
842 for (deUint32 y = 0; y < m_height; y++)
843 for (deUint32 x = 0; x < m_width; x++)
844 {
845 Vec4 blurColor (Vec4(0.0));
846
847 for (deUint32 sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
848 {
849 if (renderPassNdx % 2 == 0)
850 {
851 // Do a horizontal blur
852 blurColor += 0.12f * textureB.getAccess().getPixel(deClamp32((deInt32)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
853 }
854 else
855 {
856 // Do a vertical blur
857 blurColor += 0.12f * textureA.getAccess().getPixel(x, deClamp32((deInt32)y - (m_blurKernel / 2) + sampleNdx, 0u, m_height - 1u));
858 }
859 }
860
861 renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) : textureB.getAccess().setPixel(blurColor, x, y);
862 }
863 }
864 }
865
866 reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;
867
868 {
869 // Allow error of 4 times the minimum presentable difference
870 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
871
872 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
873 m_resultCollector.fail("Compare failed.");
874 }
875 }
876
877 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
878 }
879
880 struct SubpassTestConfig
881 {
SubpassTestConfigvkt::__anon104c10a40111::SubpassTestConfig882 SubpassTestConfig (VkFormat format_,
883 UVec2 imageSize_,
884 RenderPass renderPass_,
885 RenderPassType renderPassType_)
886 : format (format_)
887 , imageSize (imageSize_)
888 , renderPass (renderPass_)
889 , renderPassType (renderPassType_)
890 {
891 }
892
893 VkFormat format;
894 UVec2 imageSize;
895 RenderPass renderPass;
896 RenderPassType renderPassType;
897 };
898
899 class SubpassDependencyTestInstance : public TestInstance
900 {
901 public:
902 SubpassDependencyTestInstance (Context& context,
903 SubpassTestConfig testConfig);
904
905 ~SubpassDependencyTestInstance (void);
906
907 vector<SharedPtrVkImage> createAndAllocateImages (const DeviceInterface& vk,
908 VkDevice device,
909 Allocator& allocator,
910 vector<de::SharedPtr<Allocation> >& imageMemories,
911 deUint32 universalQueueFamilyIndex,
912 RenderPass renderPassInfo,
913 VkFormat format,
914 deUint32 width,
915 deUint32 height);
916
917 vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts (const DeviceInterface& vkd,
918 VkDevice device,
919 RenderPass renderPassInfo,
920 vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts);
921
922 vector<SharedPtrVkPipeline> createRenderPipelines (const DeviceInterface& vkd,
923 VkDevice device,
924 RenderPass renderPassInfo,
925 VkRenderPass renderPass,
926 vector<SharedPtrVkPipelineLayout>& pipelineLayouts,
927 const BinaryCollection& binaryCollection,
928 VkFormat format,
929 deUint32 width,
930 deUint32 height);
931
932 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
933 VkDevice device,
934 RenderPass renderPassInfo,
935 VkRenderPass renderPass,
936 vector<SharedPtrVkImageView>& dstImageViews,
937 deUint32 width,
938 deUint32 height);
939
940 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts (const DeviceInterface& vkd,
941 VkDevice device,
942 RenderPass renderPassInfo);
943
944 vector<SharedPtrVkDescriptorSet> createDescriptorSets (const DeviceInterface& vkd,
945 VkDevice device,
946 VkFormat format,
947 vector<SharedPtrVkDescriptorPool>& pools,
948 vector<SharedPtrVkDescriptorLayout>& layouts,
949 vector<SharedPtrVkImageView>& imageViews);
950
951 tcu::TextureLevel getRepresentableDepthChannel (const ConstPixelBufferAccess& access);
952
953 bool verifyDepth (const ConstPixelBufferAccess& reference,
954 const ConstPixelBufferAccess& result,
955 const float threshold);
956
957 bool verifyStencil (const ConstPixelBufferAccess& reference,
958 const ConstPixelBufferAccess& result);
959
960 tcu::TestStatus iterate (void);
961
962 template<typename RenderpassSubpass>
963 tcu::TestStatus iterateInternal (void);
964
965 private:
966 const bool m_extensionSupported;
967 const RenderPass m_renderPassInfo;
968 const RenderPassType m_renderPassType;
969
970 const deUint32 m_width;
971 const deUint32 m_height;
972 const VkFormat m_format;
973
974 vector<de::SharedPtr<Allocation> > m_imageMemories;
975 vector<SharedPtrVkImage> m_images;
976 vector<SharedPtrVkImageView> m_imageViews;
977
978 const Unique<VkBuffer> m_primaryBuffer;
979 const Unique<VkBuffer> m_secondaryBuffer;
980 const de::UniquePtr<Allocation> m_primaryBufferMemory;
981 const de::UniquePtr<Allocation> m_secondaryBufferMemory;
982
983 const Unique<VkRenderPass> m_renderPass;
984 const Unique<VkFramebuffer> m_framebuffer;
985
986 vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
987 vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
988 vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
989
990 vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
991 vector<SharedPtrVkPipeline> m_renderPipelines;
992
993 const Unique<VkCommandPool> m_commandPool;
994 tcu::ResultCollector m_resultCollector;
995 };
996
SubpassDependencyTestInstance(Context & context,SubpassTestConfig testConfig)997 SubpassDependencyTestInstance::SubpassDependencyTestInstance (Context& context, SubpassTestConfig testConfig)
998 : TestInstance (context)
999 , m_extensionSupported ((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
1000 , m_renderPassInfo (testConfig.renderPass)
1001 , m_renderPassType (testConfig.renderPassType)
1002 , m_width (testConfig.imageSize.x())
1003 , m_height (testConfig.imageSize.y())
1004 , m_format (testConfig.format)
1005 , m_images (createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo, m_format, m_width, m_height))
1006 , m_imageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
1007 , m_primaryBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1008 , m_secondaryBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1009 , m_primaryBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_primaryBuffer))
1010 , m_secondaryBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_secondaryBuffer))
1011 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, testConfig.renderPassType))
1012 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_imageViews, m_width, m_height))
1013 , m_subpassDescriptorSetLayouts (createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
1014 , m_subpassDescriptorPools (createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
1015 , m_subpassDescriptorSets (createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format, m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews))
1016 , m_renderPipelineLayouts (createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, m_subpassDescriptorSetLayouts))
1017 , m_renderPipelines (createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(), m_format, m_width, m_height))
1018 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1019 {
1020 }
1021
~SubpassDependencyTestInstance(void)1022 SubpassDependencyTestInstance::~SubpassDependencyTestInstance (void)
1023 {
1024 }
1025
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,RenderPass renderPassInfo,VkFormat format,deUint32 width,deUint32 height)1026 vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages (const DeviceInterface& vk,
1027 VkDevice device,
1028 Allocator& allocator,
1029 vector<de::SharedPtr<Allocation> >& imageMemories,
1030 deUint32 universalQueueFamilyIndex,
1031 RenderPass renderPassInfo,
1032 VkFormat format,
1033 deUint32 width,
1034 deUint32 height)
1035 {
1036 // Verify format support
1037 {
1038 const VkFormatFeatureFlags flags = isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1039 const VkFormatProperties properties = vk::getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);
1040
1041 if ((properties.optimalTilingFeatures & flags) != flags)
1042 TCU_THROW(NotSupportedError, "Format not supported");
1043 }
1044
1045 vector<SharedPtrVkImage> images;
1046
1047 for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
1048 {
1049 const VkExtent3D imageExtent =
1050 {
1051 width, // uint32_t width
1052 height, // uint32_t height
1053 1u // uint32_t depth
1054 };
1055
1056 VkImageUsageFlags usage = ((isDepthStencilFormat(format)
1057 ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
1058 : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
1059 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1060 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1061
1062 const VkImageCreateInfo imageCreateInfo =
1063 {
1064 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1065 DE_NULL, // const void* pNext
1066 0u, // VkImageCreateFlags flags
1067 VK_IMAGE_TYPE_2D, // VkImageType imageType
1068 format, // VkFormat format
1069 imageExtent, // VkExtent3D extent
1070 1u, // uint32_t mipLevels
1071 1u, // uint32_t arrayLayers
1072 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1073 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1074 usage, // VkImageUsageFlags usage
1075 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1076 1u, // uint32_t queueFamilyIndexCount
1077 &universalQueueFamilyIndex, // const uint32_t* pQueueFamilyIndices
1078 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1079 };
1080
1081 images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
1082 imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
1083 VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
1084 }
1085
1086 return images;
1087 }
1088
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)1089 vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface& vkd,
1090 VkDevice device,
1091 RenderPass renderPassInfo,
1092 vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)
1093 {
1094 vector<SharedPtrVkPipelineLayout> pipelineLayouts;
1095 vector<VkDescriptorSetLayout> descriptorSetLayoutHandles;
1096 const size_t descriptorSetLayoutCount = descriptorSetLayouts.size();
1097
1098 for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
1099 descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));
1100
1101 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1102 {
1103 const VkPipelineLayoutCreateInfo createInfo =
1104 {
1105 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
1106 DE_NULL, // const void* pNext
1107 (vk::VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
1108 (deUint32)descriptorSetLayoutCount, // deUint32 setLayoutCount
1109 descriptorSetLayoutHandles.data(), // const VkDescriptorSetLayout* pSetLayouts
1110 0u, // deUint32 pushConstantRangeCount
1111 DE_NULL // const VkPushConstantRange* pPushConstantRanges
1112 };
1113
1114 pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
1115 }
1116
1117 return pipelineLayouts;
1118 }
1119
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,VkFormat format,deUint32 width,deUint32 height)1120 vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines (const DeviceInterface& vkd,
1121 VkDevice device,
1122 RenderPass renderPassInfo,
1123 VkRenderPass renderPass,
1124 vector<SharedPtrVkPipelineLayout>& pipelineLayouts,
1125 const BinaryCollection& binaryCollection,
1126 VkFormat format,
1127 deUint32 width,
1128 deUint32 height)
1129 {
1130 vector<SharedPtrVkPipeline> pipelines;
1131
1132 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1133 {
1134 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
1135 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));
1136
1137 const VkVertexInputBindingDescription vertexBinding0 =
1138 {
1139 0u, // deUint32 binding;
1140 sizeof(Vec4), // deUint32 strideInBytes;
1141 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1142 };
1143
1144 VkVertexInputAttributeDescription attr0 =
1145 {
1146 0u, // deUint32 location;
1147 0u, // deUint32 binding;
1148 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1149 0u // deUint32 offsetInBytes;
1150 };
1151
1152 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1153 {
1154 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1155 DE_NULL, // const void* pNext
1156 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags
1157 1u, // uint32_t vertexBindingDescriptionCount
1158 &vertexBinding0, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1159 1u, // uint32_t vertexAttributeDescriptionCount
1160 &attr0 // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1161 };
1162
1163 const VkStencilOpState stencilOpState =
1164 {
1165 VK_STENCIL_OP_KEEP, // stencilFailOp
1166 VK_STENCIL_OP_KEEP, // stencilPassOp
1167 VK_STENCIL_OP_KEEP, // stencilDepthFailOp
1168 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1169 0x0u, // stencilCompareMask
1170 0x0u, // stencilWriteMask
1171 0u // stencilReference
1172 };
1173
1174 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1175 {
1176 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1177 DE_NULL, // const void* pNext
1178 0u, // VkPipelineDepthStencilStateCreateFlags flags
1179 VK_TRUE, // VkBool32 depthTestEnable
1180 VK_TRUE, // VkBool32 depthWriteEnable
1181 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp
1182 VK_FALSE, // VkBool32 depthBoundsTestEnable
1183 VK_TRUE, // VkBool32 stencilTestEnable
1184 stencilOpState, // VkStencilOpState front
1185 stencilOpState, // VkStencilOpState back
1186 0.0f, // float minDepthBounds
1187 1.0f, // float maxDepthBounds
1188 };
1189
1190 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
1191 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
1192 const VkPipelineLayout layout (**pipelineLayouts[subpassNdx]);
1193 const VkPipelineDepthStencilStateCreateInfo depthStencilCreateInfo (isDepthStencilFormat(format)
1194 ? depthStencilStateCreateInfo
1195 : VkPipelineDepthStencilStateCreateInfo());
1196
1197 pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1198 device, // const VkDevice device
1199 layout, // const VkPipelineLayout pipelineLayout
1200 *vertexShaderModule, // const VkShaderModule vertexShaderModule
1201 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1202 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1203 DE_NULL, // const VkShaderModule geometryShaderModule
1204 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1205 renderPass, // const VkRenderPass renderPass
1206 viewports, // const std::vector<VkViewport>& viewports
1207 scissors, // const std::vector<VkRect2D>& scissors
1208 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1209 (deUint32)subpassNdx, // const deUint32 subpass
1210 0u, // const deUint32 patchControlPoints
1211 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1212 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1213 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1214 &depthStencilCreateInfo, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1215 DE_NULL))); // const VkPipelineDynamicStateCreateInfo* pDynamicState
1216 }
1217
1218 return pipelines;
1219 }
1220
createFramebuffer(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)1221 Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer (const DeviceInterface& vkd,
1222 VkDevice device,
1223 RenderPass renderPassInfo,
1224 VkRenderPass renderPass,
1225 vector<SharedPtrVkImageView>& dstImageViews,
1226 deUint32 width,
1227 deUint32 height)
1228 {
1229 const size_t attachmentCount (renderPassInfo.getAttachments().size());
1230 vector<VkImageView> attachmentHandles;
1231
1232 for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1233 attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));
1234
1235 const VkFramebufferCreateInfo createInfo =
1236 {
1237 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
1238 DE_NULL, // const void* pNext
1239 0u, // VkFramebufferCreateFlags flags
1240 renderPass, // VkRenderPass renderPass
1241 (deUint32)attachmentCount, // uint32_t attachmentCount
1242 attachmentHandles.data(), // const VkImageView* pAttachments
1243 width, // uint32_t width
1244 height, // uint32_t height
1245 1u // uint32_t layers
1246 };
1247
1248 return vk::createFramebuffer(vkd, device, &createInfo);
1249 }
1250
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo)1251 vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts (const DeviceInterface& vkd,
1252 VkDevice device,
1253 RenderPass renderPassInfo)
1254 {
1255 vector<SharedPtrVkDescriptorLayout> layouts;
1256
1257 size_t attachmentCount = renderPassInfo.getAttachments().size();
1258
1259 for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
1260 {
1261 const VkDescriptorSetLayoutBinding bindings =
1262 {
1263 0u, // uint32_t binding
1264 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1265 1u, // uint32_t descriptorCount
1266 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
1267 DE_NULL // const VkSampler* pImmutableSamplers
1268 };
1269
1270 const VkDescriptorSetLayoutCreateInfo createInfo =
1271 {
1272 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
1273 DE_NULL, // const void* pNext
1274 0u, // VkDescriptorSetLayoutCreateFlags flags
1275 1u, // uint32_t bindingCount
1276 &bindings // const VkDescriptorSetLayoutBinding* pBindings
1277 };
1278
1279 layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
1280 }
1281
1282 return layouts;
1283 }
1284
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,VkFormat format,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews)1285 vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets (const DeviceInterface& vkd,
1286 VkDevice device,
1287 VkFormat format,
1288 vector<SharedPtrVkDescriptorPool>& pools,
1289 vector<SharedPtrVkDescriptorLayout>& layouts,
1290 vector<SharedPtrVkImageView>& imageViews)
1291 {
1292 vector<SharedPtrVkDescriptorSet> descriptorSets;
1293
1294 for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
1295 {
1296 const VkDescriptorSetAllocateInfo allocateInfo =
1297 {
1298 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
1299 DE_NULL, // const void* pNext
1300 **pools[setNdx], // VkDescriptorPool descriptorPool
1301 1u, // uint32_t descriptorSetCount
1302 &**layouts[setNdx] // const VkDescriptorSetLayout* pSetLayouts
1303 };
1304
1305 descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
1306
1307 {
1308 VkImageLayout imageLayout = isDepthStencilFormat(format)
1309 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1310 : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1311
1312 const VkDescriptorImageInfo imageInfo =
1313 {
1314 DE_NULL, // VkSampler sampler
1315 **imageViews[setNdx], // VkImageView imageView
1316 imageLayout // VkImageLayout imageLayout
1317 };
1318
1319 const VkWriteDescriptorSet write =
1320 {
1321 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1322 DE_NULL, // const void* pNext
1323 **descriptorSets[setNdx], // VkDescriptorSet dstSet
1324 0u, // uint32_t dstBinding
1325 0u, // uint32_t dstArrayElement
1326 1u, // uint32_t descriptorCount
1327 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1328 &imageInfo, // const VkDescriptorImageInfo* pImageInfo
1329 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
1330 DE_NULL // const VkBufferView* pTexelBufferView
1331 };
1332
1333 vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
1334 }
1335 }
1336
1337 return descriptorSets;
1338 }
1339
getRepresentableDepthChannel(const ConstPixelBufferAccess & access)1340 tcu::TextureLevel SubpassDependencyTestInstance::getRepresentableDepthChannel (const ConstPixelBufferAccess& access)
1341 {
1342 tcu::TextureLevel depthChannel (mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());
1343
1344 for (int y = 0; y < access.getHeight(); y++)
1345 for (int x = 0; x < access.getWidth(); x++)
1346 depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);
1347
1348 return depthChannel;
1349 }
1350
verifyDepth(const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const float threshold)1351 bool SubpassDependencyTestInstance::verifyDepth (const ConstPixelBufferAccess& reference,
1352 const ConstPixelBufferAccess& result,
1353 const float threshold)
1354 {
1355 tcu::TestLog& log (m_context.getTestContext().getLog());
1356
1357 return tcu::floatThresholdCompare(log, // log
1358 "Depth channel", // imageSetName
1359 "Depth compare", // imageSetDesc
1360 getRepresentableDepthChannel(reference), // reference
1361 getRepresentableDepthChannel(result), // result
1362 Vec4(threshold), // threshold
1363 tcu::COMPARE_LOG_RESULT); // logMode
1364 }
1365
verifyStencil(const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result)1366 bool SubpassDependencyTestInstance::verifyStencil (const ConstPixelBufferAccess& reference,
1367 const ConstPixelBufferAccess& result)
1368 {
1369 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
1370 tcu::TestLog& log (m_context.getTestContext().getLog());
1371 bool stencilOk (DE_TRUE);
1372
1373 for (int y = 0; y < result.getHeight(); y++)
1374 for (int x = 0; x < result.getWidth(); x++)
1375 {
1376 if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
1377 {
1378 stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
1379 stencilOk = DE_FALSE;
1380 }
1381 else
1382 stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1383 }
1384
1385 log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
1386 << tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
1387 << tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);
1388
1389 if (!stencilOk)
1390 log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);
1391
1392 log << tcu::TestLog::EndImageSet;
1393
1394 return stencilOk;
1395 }
1396
iterate(void)1397 tcu::TestStatus SubpassDependencyTestInstance::iterate (void)
1398 {
1399 switch (m_renderPassType)
1400 {
1401 case RENDERPASS_TYPE_LEGACY:
1402 return iterateInternal<RenderpassSubpass1>();
1403 case RENDERPASS_TYPE_RENDERPASS2:
1404 return iterateInternal<RenderpassSubpass2>();
1405 default:
1406 TCU_THROW(InternalError, "Impossible");
1407 }
1408 }
1409
truncateCoord(int dim,int subPixelBits,float f)1410 static float truncateCoord(int dim, int subPixelBits, float f)
1411 {
1412 const float scale = (float)(dim << subPixelBits);
1413 const float coord = deFloatFloor(f * scale) / scale;
1414
1415 return coord;
1416 }
1417
1418 template<typename RenderpassSubpass>
iterateInternal(void)1419 tcu::TestStatus SubpassDependencyTestInstance::iterateInternal (void)
1420 {
1421 de::Random rand (5);
1422 const DeviceInterface& vkd (m_context.getDeviceInterface());
1423 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1424 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1425 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
1426 const size_t attachmentCount (m_renderPassInfo.getAttachments().size());
1427 const size_t subpassCount (m_renderPassInfo.getSubpasses().size());
1428 vector<VkClearValue> clearValues;
1429 vector<Vec4> vertexData;
1430
1431 beginCommandBuffer(vkd, *commandBuffer);
1432
1433 // Begin render pass
1434 {
1435 VkRect2D renderArea =
1436 {
1437 { 0u, 0u }, // VkOffset2D offset
1438 { m_width, m_height } // VkExtent2D extent
1439 };
1440
1441 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1442 clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) : makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
1443
1444 const VkRenderPassBeginInfo beginInfo =
1445 {
1446 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
1447 DE_NULL, // const void* pNext
1448 *m_renderPass, // VkRenderPass renderPass
1449 *m_framebuffer, // VkFramebuffer framebuffer
1450 renderArea, // VkRect2D renderArea
1451 (deUint32)attachmentCount, // uint32_t clearValueCount
1452 clearValues.data() // const VkClearValue* pClearValues
1453 };
1454
1455 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1456 }
1457
1458 // Generate vertices for 128 triangles with pseudorandom positions and depths values
1459 for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
1460 {
1461 float primitiveDepth = rand.getFloat();
1462
1463 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1464 {
1465 const int subPixelBits = m_context.getDeviceProperties().limits.subPixelPrecisionBits;
1466
1467 float x = 2.0f * truncateCoord(m_width, subPixelBits, rand.getFloat()) - 1.0f;
1468 float y = 2.0f * truncateCoord(m_height, subPixelBits, rand.getFloat()) - 1.0f;
1469
1470 vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
1471 }
1472 }
1473
1474 const size_t singleVertexDataSize = sizeof(Vec4);
1475 const size_t vertexCount = vertexData.size();
1476 const size_t vertexDataSize = vertexCount * singleVertexDataSize;
1477 const deUint32 queueFamilyIndices = m_context.getUniversalQueueFamilyIndex();
1478
1479 const VkBufferCreateInfo vertexBufferParams =
1480 {
1481 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1482 DE_NULL, // const void* pNext;
1483 0u, // VkBufferCreateFlags flags;
1484 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
1485 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1486 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1487 1u, // deUint32 queueFamilyCount;
1488 &queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
1489 };
1490
1491 const Unique<VkBuffer> vertexBuffer (createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
1492 const de::UniquePtr<Allocation> vertexBufferMemory (m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));
1493
1494 VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1495
1496 const VkDeviceSize bindingOffset = 0;
1497 vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
1498
1499 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1500 {
1501 if (subpassNdx > 0)
1502 {
1503 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1504 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[subpassNdx], 0, 1, &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
1505 }
1506
1507 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);
1508
1509 if (subpassNdx == 0)
1510 {
1511 // Upload vertex data
1512 {
1513 void* vertexBufPtr = vertexBufferMemory->getHostPtr();
1514 deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
1515 flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
1516 }
1517
1518 vkd.cmdDraw(*commandBuffer, (deUint32)vertexData.size(), 1u, 0u, 0u);
1519 }
1520 else
1521 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1522 }
1523
1524 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1525
1526 // Memory barrier between rendering and copy
1527 {
1528 const VkImageAspectFlags imageAspectFlags = isDepthStencilFormat(m_format)
1529 ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1530 const VkAccessFlags srcAccessMask = isDepthStencilFormat(m_format)
1531 ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1532 const VkImageLayout oldLayout = isDepthStencilFormat(m_format)
1533 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1534 const VkPipelineStageFlags srcStageMask = isDepthStencilFormat(m_format)
1535 ? VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1536
1537 VkImageSubresourceRange imageSubresourceRange =
1538 {
1539 imageAspectFlags, // VkImageAspectFlags aspectMask
1540 0u, // uint32_t baseMipLevel
1541 1u, // uint32_t levelCount
1542 0u, // uint32_t baseArrayLayer
1543 1u // uint32_t layerCount
1544 };
1545
1546 const VkImageMemoryBarrier barrier =
1547 {
1548 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1549 DE_NULL, // const void* pNext
1550 srcAccessMask, // VkAccessFlags srcAccessMask
1551 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1552 oldLayout, // VkImageLayout oldLayout
1553 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
1554 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1555 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1556 **m_images[attachmentCount - 1], // VkImage image
1557 imageSubresourceRange // VkImageSubresourceRange subresourceRange
1558 };
1559
1560 vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1561 }
1562
1563 // Copy image memory to buffer
1564 {
1565 if (isDepthStencilFormat(m_format))
1566 {
1567 // Copy depth
1568 const VkImageSubresourceLayers subresourceLayersDepth =
1569 {
1570 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
1571 0u, // deUint32 mipLevel
1572 0u, // deUint32 baseArrayLayer
1573 1u // deUint32 layerCount
1574 };
1575
1576 const VkBufferImageCopy regionDepth =
1577 {
1578 0u, // VkDeviceSize bufferOffset
1579 0u, // uint32_t bufferRowLength
1580 0u, // uint32_t bufferImageHeight
1581 subresourceLayersDepth, // VkImageSubresourceLayers imageSubresource
1582 { 0u, 0u, 0u }, // VkOffset3D imageOffset
1583 { m_width, m_height, 1u } // VkExtent3D imageExtent
1584 };
1585
1586 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, ®ionDepth);
1587
1588 // Copy stencil
1589 const VkImageSubresourceLayers subresourceLayersStencil =
1590 {
1591 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask
1592 0u, // deUint32 mipLevel
1593 0u, // deUint32 baseArrayLayer
1594 1u // deUint32 layerCount
1595 };
1596
1597 const VkBufferImageCopy regionStencil =
1598 {
1599 0u, // VkDeviceSize bufferOffset
1600 0u, // uint32_t bufferRowLength
1601 0u, // uint32_t bufferImageHeight
1602 subresourceLayersStencil, // VkImageSubresourceLayers imageSubresource
1603 { 0u, 0u, 0u }, // VkOffset3D imageOffset
1604 { m_width, m_height, 1u } // VkExtent3D imageExtent
1605 };
1606
1607 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, ®ionStencil);
1608 }
1609 else
1610 {
1611 // Copy color
1612 const VkImageSubresourceLayers imageSubresourceLayers =
1613 {
1614 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1615 0u, // deUint32 mipLevel
1616 0u, // deUint32 baseArrayLayer
1617 1u // deUint32 layerCount
1618 };
1619
1620 const VkBufferImageCopy region =
1621 {
1622 0u, // VkDeviceSize bufferOffset
1623 0u, // uint32_t bufferRowLength
1624 0u, // uint32_t bufferImageHeight
1625 imageSubresourceLayers, // VkImageSubresourceLayers imageSubresource
1626 { 0u, 0u, 0u }, // VkOffset3D imageOffset
1627 { m_width, m_height, 1u } // VkExtent3D imageExtent
1628 };
1629
1630 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, ®ion);
1631 }
1632 }
1633
1634 // Memory barrier between copy and host access
1635 {
1636 const VkBufferMemoryBarrier barrier =
1637 {
1638 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
1639 DE_NULL, // const void* pNext
1640 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1641 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
1642 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1643 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1644 *m_primaryBuffer, // VkBuffer buffer
1645 0u, // VkDeviceSize offset
1646 VK_WHOLE_SIZE // VkDeviceSize size
1647 };
1648
1649 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1650
1651 if (isDepthStencilFormat(m_format))
1652 {
1653 const VkBufferMemoryBarrier stencilBarrier =
1654 {
1655 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
1656 DE_NULL, // const void* pNext
1657 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1658 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
1659 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1660 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1661 *m_secondaryBuffer, // VkBuffer buffer
1662 0u, // VkDeviceSize offset
1663 VK_WHOLE_SIZE // VkDeviceSize size
1664 };
1665
1666 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
1667 }
1668 }
1669
1670 endCommandBuffer(vkd, *commandBuffer);
1671 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
1672 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(), m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1673 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1674
1675 // Verify result
1676 {
1677 const tcu::TextureFormat format (mapVkFormat(m_format));
1678
1679 if (isDepthStencilFormat(m_format))
1680 {
1681 const void* const ptrDepth (m_primaryBufferMemory->getHostPtr());
1682 const void* const ptrStencil (m_secondaryBufferMemory->getHostPtr());
1683 tcu::TextureLevel reference (format, m_width, m_height);
1684 tcu::TextureLevel colorBuffer (mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
1685 const tcu::ConstPixelBufferAccess resultDepthAccess (getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
1686 const tcu::ConstPixelBufferAccess resultStencilAccess (getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
1687 const PixelBufferAccess referenceDepthAccess (tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
1688 const PixelBufferAccess referenceStencilAccess (tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
1689
1690 tcu::clearDepth(referenceDepthAccess, 1.0f);
1691 tcu::clearStencil(referenceStencilAccess, 255);
1692
1693 // Setup and run reference renderer
1694 {
1695 const DepthVertShader vertShader;
1696 const DepthFragShader fragShader;
1697 const rr::Renderer renderer;
1698 const rr::Program program (&vertShader, &fragShader);
1699 const rr::MultisamplePixelBufferAccess depthBuffer (rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
1700 const rr::MultisamplePixelBufferAccess colorBufferAccess (rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
1701 const rr::RenderTarget renderTarget (rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer, rr::MultisamplePixelBufferAccess());
1702 const rr::PrimitiveType primitiveType (rr::PRIMITIVETYPE_TRIANGLES);
1703 const rr::PrimitiveList primitiveList (rr::PrimitiveList(primitiveType, (deUint32)vertexData.size(), 0));
1704 rr::RenderState renderState ((rr::ViewportState(depthBuffer)));
1705
1706 const rr::VertexAttrib vertices = rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);
1707
1708 renderState.fragOps.depthTestEnabled = DE_TRUE;
1709 renderState.fragOps.depthFunc = rr::TESTFUNC_LEQUAL;
1710
1711 renderer.draw(rr::DrawCommand(renderState,
1712 renderTarget,
1713 program,
1714 1u,
1715 &vertices,
1716 primitiveList));
1717 }
1718
1719 for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
1720 {
1721 for (int y = 0; y < reference.getHeight(); y++)
1722 for (int x = 0; x < reference.getWidth(); x++)
1723 reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
1724 }
1725
1726 // Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
1727 const float depthThreshold ((float)subpassCount * (1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(
1728 resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x()));
1729
1730 if (!verifyDepth(reference.getAccess(), resultDepthAccess, depthThreshold))
1731 m_resultCollector.fail("Depth compare failed.");
1732
1733 if (!verifyStencil(referenceStencilAccess, resultStencilAccess))
1734 m_resultCollector.fail("Stencil compare failed.");
1735 }
1736 else
1737 DE_FATAL("Not implemented");
1738 }
1739
1740 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1741 }
1742
1743 // Shader programs for testing dependencies between render pass instances
1744 struct ExternalPrograms
1745 {
initvkt::__anon104c10a40111::ExternalPrograms1746 void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
1747 {
1748 for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
1749 {
1750 dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
1751 "#version 450\n"
1752 "layout(location = 0) out highp vec2 vtxTexCoords;\n"
1753 "highp float;\n"
1754 "void main (void)\n"
1755 "{\n"
1756 " vec4 position;"
1757 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1758 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1759 " gl_Position = position;\n"
1760 " vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
1761 "}\n");
1762
1763 // First pass renders four quads of different color
1764 if (renderPassNdx == 0)
1765 {
1766 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1767 "#version 450\n"
1768 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
1769 "layout(location = 0) out highp vec4 o_color;\n"
1770 "void main (void)\n"
1771 "{\n"
1772 " if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1773 " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1774 " else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1775 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
1776 " else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1777 " o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
1778 " else\n"
1779 " o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1780 ""
1781 "}\n");
1782 }
1783 else
1784 {
1785 if (renderPassNdx % 2 == 0)
1786 {
1787 // Blur previous pass horizontally
1788 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1789 "#version 450\n"
1790 "layout(binding = 0) uniform sampler2D previousPass;\n"
1791 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
1792 "layout(location = 0) out highp vec4 o_color;\n"
1793 "void main (void)\n"
1794 "{\n"
1795 " vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
1796 " vec2 minCoord = vec2(0.0, 0.0);\n"
1797 " vec2 maxCoord = vec2(1.0, 1.0);\n"
1798 " vec4 blurColor = vec4(0.0);\n"
1799 " for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
1800 " {\n"
1801 " vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
1802 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
1803 " }\n"
1804 " o_color = blurColor;\n"
1805 "}\n");
1806 }
1807 else
1808 {
1809 // Blur previous pass vertically
1810 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1811 "#version 450\n"
1812 "layout(binding = 0) uniform highp sampler2D previousPass;\n"
1813 "layout(location = 0) in highp vec2 vtxTexCoords;\n"
1814 "layout(location = 0) out highp vec4 o_color;\n"
1815 "void main (void)\n"
1816 "{\n"
1817 " vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
1818 " vec2 minCoord = vec2(0.0, 0.0);\n"
1819 " vec2 maxCoord = vec2(1.0, 1.0);\n"
1820 " vec4 blurColor = vec4(0.0);\n"
1821 " for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
1822 " {\n"
1823 " vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
1824 " blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
1825 " }\n"
1826 " o_color = blurColor;\n"
1827 "}\n");
1828 }
1829 }
1830 }
1831 }
1832 };
1833
1834 // Shader programs for testing dependencies between subpasses
1835 struct SubpassPrograms
1836 {
initvkt::__anon104c10a40111::SubpassPrograms1837 void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
1838 {
1839 size_t subpassCount = testConfig.renderPass.getSubpasses().size();
1840
1841 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1842 {
1843 if (subpassNdx == 0)
1844 {
1845 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
1846 "#version 450\n"
1847 "highp float;\n"
1848 "layout(location = 0) in highp vec4 position;\n"
1849 "void main (void)\n"
1850 "{\n"
1851 " gl_Position = position;\n"
1852 "}\n");
1853 }
1854 else
1855 {
1856 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
1857 "#version 450\n"
1858 "highp float;\n"
1859 "void main (void)\n"
1860 "{\n"
1861 " vec4 position;"
1862 " position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1863 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1864 " gl_Position = position;\n"
1865 "}\n");
1866 }
1867
1868 if (isDepthStencilFormat(testConfig.format))
1869 {
1870 if (subpassNdx == 0)
1871 {
1872 // Empty fragment shader: Fragment depth unmodified.
1873 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
1874 "#version 450\n"
1875 "void main (void)\n"
1876 "{\n"
1877 "}\n");
1878 }
1879 else
1880 {
1881 // Use fragment depth from previous depth rendering result.
1882 dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
1883 "#version 450\n"
1884 "layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
1885 "void main (void)\n"
1886 "{\n"
1887 " float inputDepth = subpassLoad(depthStencil).x;\n"
1888 " gl_FragDepth = inputDepth - 0.02;\n"
1889 "}\n");
1890 }
1891 }
1892 else
1893 DE_FATAL("Unimplemented");
1894 }
1895 }
1896 };
1897
formatToName(VkFormat format)1898 std::string formatToName (VkFormat format)
1899 {
1900 const std::string formatStr = de::toString(format);
1901 const std::string prefix = "VK_FORMAT_";
1902
1903 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1904
1905 return de::toLower(formatStr.substr(prefix.length()));
1906 }
1907
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)1908 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
1909 {
1910 tcu::TestContext& testCtx(group->getTestContext());
1911
1912 // Test external subpass dependencies
1913 {
1914 const deUint32 renderPassCounts[] = { 2u, 3u, 5u};
1915
1916 const UVec2 renderSizes[] =
1917 {
1918 UVec2(64, 64),
1919 UVec2(128, 128),
1920 UVec2(512, 512)
1921 };
1922
1923 de::MovePtr<tcu::TestCaseGroup> externalGroup (new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));
1924
1925 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
1926 {
1927 string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
1928 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1929
1930 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
1931 {
1932 vector<RenderPass> renderPasses;
1933
1934 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
1935 {
1936 vector<Attachment> attachments;
1937 vector<AttachmentReference> colorAttachmentReferences;
1938
1939 const VkFormat format (VK_FORMAT_R8G8B8A8_UNORM);
1940 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
1941 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
1942 const VkAttachmentStoreOp storeOp (VK_ATTACHMENT_STORE_OP_STORE);
1943 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
1944 const VkAttachmentStoreOp stencilStoreOp (VK_ATTACHMENT_STORE_OP_DONT_CARE);
1945 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
1946 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1947 const VkImageLayout subpassLayout (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1948
1949 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
1950 colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
1951
1952 const VkImageLayout depthStencilLayout (VK_IMAGE_LAYOUT_GENERAL);
1953 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
1954 AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
1955 vector<SubpassDependency> deps;
1956
1957 deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL, // deUint32 srcPass
1958 0, // deUint32 dstPass
1959 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
1960 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
1961 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
1962 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
1963 0)); // VkDependencyFlags flags
1964
1965 deps.push_back(SubpassDependency(0, // deUint32 srcPass
1966 VK_SUBPASS_EXTERNAL, // deUint32 dstPass
1967 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags srcStageMask
1968 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
1969 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
1970 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
1971 0)); // VkDependencyFlags flags
1972
1973 RenderPass renderPass (attachments, subpasses, deps);
1974
1975 renderPasses.push_back(renderPass);
1976 }
1977
1978 const deUint32 blurKernel (12u);
1979 const ExternalTestConfig testConfig (VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderPasses, renderPassType, blurKernel);
1980 const string testName ("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
1981
1982 renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
1983 }
1984
1985 externalGroup->addChild(renderSizeGroup.release());
1986 }
1987
1988 group->addChild(externalGroup.release());
1989 }
1990
1991 // Test implicit subpass dependencies
1992 {
1993 const deUint32 renderPassCounts[] = { 2u, 3u, 5u };
1994
1995 de::MovePtr<tcu::TestCaseGroup> implicitGroup (new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));
1996
1997 for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
1998 {
1999 vector<RenderPass> renderPasses;
2000
2001 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
2002 {
2003 vector<Attachment> attachments;
2004 vector<AttachmentReference> colorAttachmentReferences;
2005
2006 const VkFormat format (VK_FORMAT_R8G8B8A8_UNORM);
2007 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
2008 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
2009 const VkAttachmentStoreOp storeOp (VK_ATTACHMENT_STORE_OP_STORE);
2010 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
2011 const VkAttachmentStoreOp stencilStoreOp (VK_ATTACHMENT_STORE_OP_DONT_CARE);
2012 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
2013 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
2014 const VkImageLayout subpassLayout (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
2015
2016 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
2017 colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
2018
2019 const VkImageLayout depthStencilLayout (VK_IMAGE_LAYOUT_GENERAL);
2020 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
2021 vector<SubpassDependency> deps;
2022
2023 // The first render pass lets the implementation add all subpass dependencies implicitly.
2024 // On the following passes only the dependency from external to first subpass is defined as
2025 // we need to make sure we have the image ready from previous render pass. In this case
2026 // the dependency from subpass 0 to external is added implicitly by the implementation.
2027 if (renderPassNdx > 0)
2028 {
2029 deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL, // deUint32 srcPass
2030 0, // deUint32 dstPass
2031 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
2032 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
2033 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2034 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
2035 0)); // VkDependencyFlags flags
2036 }
2037
2038 RenderPass renderPass (attachments, subpasses, deps);
2039
2040 renderPasses.push_back(renderPass);
2041 }
2042
2043 const deUint32 blurKernel (12u);
2044 const ExternalTestConfig testConfig (VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderPassType, blurKernel);
2045 const string testName ("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
2046
2047 implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2048 }
2049
2050 group->addChild(implicitGroup.release());
2051 }
2052
2053 // Test late fragment operations using depth_stencil attachments in multipass rendering
2054 {
2055 const UVec2 renderSizes[] =
2056 {
2057 UVec2(32, 32),
2058 UVec2(64, 64),
2059 UVec2(128, 128)
2060 };
2061
2062 const deUint32 subpassCounts[] = { 2u, 3u, 5u };
2063
2064 // Implementations must support at least one of the following formats
2065 // for depth_stencil attachments
2066 const VkFormat formats[] =
2067 {
2068 VK_FORMAT_D24_UNORM_S8_UINT,
2069 VK_FORMAT_D32_SFLOAT_S8_UINT
2070 };
2071
2072 de::MovePtr<tcu::TestCaseGroup> lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));
2073
2074 for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
2075 {
2076 string renderSizeGroupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
2077 de::MovePtr<tcu::TestCaseGroup> renderSizeGroup (new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));
2078
2079 for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
2080 {
2081 string subpassGroupName ("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
2082 de::MovePtr<tcu::TestCaseGroup> subpassCountGroup (new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));
2083
2084 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2085 {
2086 const deUint32 subpassCount (subpassCounts[subpassCountNdx]);
2087 const deUint32 attachmentCount (subpassCount);
2088 vector<Subpass> subpasses;
2089 vector<Attachment> attachments;
2090 vector<SubpassDependency> deps;
2091
2092 // Attachments
2093 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
2094 {
2095 const VkFormat format (formats[formatNdx]);
2096 const VkSampleCountFlagBits sampleCount (VK_SAMPLE_COUNT_1_BIT);
2097 const VkAttachmentLoadOp loadOp (VK_ATTACHMENT_LOAD_OP_CLEAR);
2098 const VkAttachmentStoreOp storeOp ((attachmentNdx == attachmentCount - 1)
2099 ? VK_ATTACHMENT_STORE_OP_STORE
2100 : VK_ATTACHMENT_STORE_OP_DONT_CARE);
2101 const VkAttachmentLoadOp stencilLoadOp (VK_ATTACHMENT_LOAD_OP_CLEAR);
2102 const VkAttachmentStoreOp stencilStoreOp ((attachmentNdx == attachmentCount - 1)
2103 ? VK_ATTACHMENT_STORE_OP_STORE
2104 : VK_ATTACHMENT_STORE_OP_DONT_CARE);
2105 const VkImageLayout initialLayout (VK_IMAGE_LAYOUT_UNDEFINED);
2106 const VkImageLayout finalLayout (VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
2107
2108 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
2109 }
2110
2111 // Subpasses
2112 for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
2113 {
2114 vector<AttachmentReference> inputAttachmentReferences;
2115 const VkImageAspectFlags inputAttachmentAspectMask ((renderPassType == RENDERPASS_TYPE_RENDERPASS2)
2116 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
2117 : static_cast<VkImageAspectFlags>(0));
2118
2119 // Input attachment references
2120 if (subpassNdx > 0)
2121 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));
2122
2123 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>()));
2124
2125 // Subpass dependencies from current subpass to previous subpass.
2126 // Subpasses will wait for the late fragment operations before reading the contents
2127 // of previous subpass.
2128 if (subpassNdx > 0)
2129 {
2130 deps.push_back(SubpassDependency((deUint32)subpassNdx - 1, // deUint32 srcPass
2131 (deUint32)subpassNdx, // deUint32 dstPass
2132 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
2133 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
2134 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
2135 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2136 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
2137 VK_DEPENDENCY_BY_REGION_BIT)); // VkDependencyFlags flags
2138 }
2139 }
2140
2141 const RenderPass renderPass (attachments, subpasses, deps);
2142 const SubpassTestConfig testConfig (formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderPassType);
2143 const string format (formatToName(formats[formatNdx]).c_str());
2144
2145 subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
2146 }
2147
2148 renderSizeGroup->addChild(subpassCountGroup.release());
2149 }
2150
2151 lateFragmentTestsGroup->addChild(renderSizeGroup.release());
2152 }
2153
2154 group->addChild(lateFragmentTestsGroup.release());
2155 }
2156 }
2157 } // anonymous
2158
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx)2159 tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
2160 {
2161 return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_LEGACY);
2162 }
2163
createRenderPass2SubpassDependencyTests(tcu::TestContext & testCtx)2164 tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
2165 {
2166 return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
2167 }
2168 } // vkt
2169