1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief RenderPass tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26 #include "vktRenderPassGroupParams.hpp"
27 #include "vktRenderPassMultisampleTests.hpp"
28 #include "vktRenderPassMultisampleResolveTests.hpp"
29 #include "vktRenderPassSampleReadTests.hpp"
30 #ifndef CTS_USES_VULKANSC
31 #include "vktRenderPassSparseRenderTargetTests.hpp"
32 #endif // CTS_USES_VULKANSC
33 #include "vktRenderPassSubpassDependencyTests.hpp"
34 #include "vktRenderPassUnusedAttachmentTests.hpp"
35 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
36 #include "vktRenderPassDepthStencilResolveTests.hpp"
37 #include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
38 #include "vktRenderPassFragmentDensityMapTests.hpp"
39 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
40 #ifndef CTS_USES_VULKANSC
41 #include "vktRenderPassLoadStoreOpNoneTests.hpp"
42 #include "vktDynamicRenderingTests.hpp"
43 #include "vktDynamicRenderingLocalReadTests.hpp"
44 #include "vktDynamicRenderingDepthStencilResolveTests.hpp"
45 #endif // CTS_USES_VULKANSC
46 #include "vktRenderPassDepthStencilWriteConditionsTests.hpp"
47 #include "vktRenderPassSubpassMergeFeedbackTests.hpp"
48 #include "vktDynamicRenderingRandomTests.hpp"
49 #include "vktRenderPassDitheringTests.hpp"
50 #include "vktDynamicRenderingUnusedAttachmentsTests.hpp"
51
52 #include "vktTestCaseUtil.hpp"
53 #include "vktTestGroupUtil.hpp"
54
55 #include "vkDefs.hpp"
56 #include "vkDeviceUtil.hpp"
57 #include "vkImageUtil.hpp"
58 #include "vkMemUtil.hpp"
59 #include "vkPlatform.hpp"
60 #include "vkPrograms.hpp"
61 #include "vkQueryUtil.hpp"
62 #include "vkRef.hpp"
63 #include "vkRefUtil.hpp"
64 #include "vkStrUtil.hpp"
65 #include "vkTypeUtil.hpp"
66 #include "vkCmdUtil.hpp"
67 #include "vkObjUtil.hpp"
68 #include "vkBufferWithMemory.hpp"
69 #include "vkImageWithMemory.hpp"
70 #include "vkBarrierUtil.hpp"
71
72 #include "tcuFloat.hpp"
73 #include "tcuFormatUtil.hpp"
74 #include "tcuMaybe.hpp"
75 #include "tcuResultCollector.hpp"
76 #include "tcuTestLog.hpp"
77 #include "tcuTextureUtil.hpp"
78 #include "tcuVectorUtil.hpp"
79
80 #include "deRandom.hpp"
81 #include "deSTLUtil.hpp"
82 #include "deSharedPtr.hpp"
83 #include "deStringUtil.hpp"
84 #include "deUniquePtr.hpp"
85
86 #include <limits>
87 #include <set>
88 #include <string>
89 #include <vector>
90 #include <numeric>
91 #include <memory>
92 #include <algorithm>
93 #include <iterator>
94
95 using namespace vk;
96
97 using tcu::BVec4;
98 using tcu::IVec2;
99 using tcu::IVec4;
100 using tcu::UVec2;
101 using tcu::UVec4;
102 using tcu::Vec2;
103 using tcu::Vec4;
104
105 using tcu::just;
106 using tcu::Maybe;
107
108 using tcu::ConstPixelBufferAccess;
109 using tcu::PixelBufferAccess;
110
111 using tcu::TestLog;
112
113 using de::UniquePtr;
114
115 using std::pair;
116 using std::set;
117 using std::string;
118 using std::vector;
119
120 namespace vkt
121 {
122 namespace
123 {
124 using namespace renderpass;
125
126 typedef vector<uint8_t> DepthValuesArray;
127
128 static const uint8_t DEPTH_VALUES[] = {0u, 255u, 1u};
129
getShaderNumChannels(tcu::TextureFormat::ChannelOrder order)130 int getShaderNumChannels(tcu::TextureFormat::ChannelOrder order)
131 {
132 if (order == tcu::TextureFormat::A)
133 return 4;
134 return tcu::getNumUsedChannels(order);
135 }
136
137 enum AllocationKind
138 {
139 ALLOCATION_KIND_SUBALLOCATED,
140 ALLOCATION_KIND_DEDICATED,
141 };
142
143 struct TestConfigExternal
144 {
TestConfigExternalvkt::__anon33b72dba0111::TestConfigExternal145 TestConfigExternal(AllocationKind allocationKind_, const SharedGroupParams groupParams_)
146 : allocationKind(allocationKind_)
147 , groupParams(groupParams_)
148 {
149 }
150
151 AllocationKind allocationKind;
152 const SharedGroupParams groupParams;
153 };
154
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)155 de::MovePtr<Allocation> allocateBuffer(const InstanceInterface &vki, const DeviceInterface &vkd,
156 const VkPhysicalDevice &physDevice, const VkDevice device,
157 const VkBuffer &buffer, const MemoryRequirement requirement,
158 Allocator &allocator, AllocationKind allocationKind)
159 {
160 switch (allocationKind)
161 {
162 case ALLOCATION_KIND_SUBALLOCATED:
163 {
164 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
165
166 return allocator.allocate(memoryRequirements, requirement);
167 }
168
169 case ALLOCATION_KIND_DEDICATED:
170 {
171 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
172 }
173
174 default:
175 {
176 TCU_THROW(InternalError, "Invalid allocation kind");
177 }
178 }
179 }
180
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)181 de::MovePtr<Allocation> allocateImage(const InstanceInterface &vki, const DeviceInterface &vkd,
182 const VkPhysicalDevice &physDevice, const VkDevice device, const VkImage &image,
183 const MemoryRequirement requirement, Allocator &allocator,
184 AllocationKind allocationKind)
185 {
186 switch (allocationKind)
187 {
188 case ALLOCATION_KIND_SUBALLOCATED:
189 {
190 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
191
192 return allocator.allocate(memoryRequirements, requirement);
193 }
194
195 case ALLOCATION_KIND_DEDICATED:
196 {
197 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
198 }
199
200 default:
201 {
202 TCU_THROW(InternalError, "Invalid allocation kind");
203 }
204 }
205 }
206
207 enum BoolOp
208 {
209 BOOLOP_AND,
210 BOOLOP_OR,
211 BOOLOP_EQ,
212 BOOLOP_NEQ
213 };
214
boolOpToString(BoolOp op)215 const char *boolOpToString(BoolOp op)
216 {
217 switch (op)
218 {
219 case BOOLOP_OR:
220 return "||";
221
222 case BOOLOP_AND:
223 return "&&";
224
225 case BOOLOP_EQ:
226 return "==";
227
228 case BOOLOP_NEQ:
229 return "!=";
230
231 default:
232 DE_FATAL("Unknown boolean operation.");
233 return DE_NULL;
234 }
235 }
236
performBoolOp(BoolOp op,bool a,bool b)237 bool performBoolOp(BoolOp op, bool a, bool b)
238 {
239 switch (op)
240 {
241 case BOOLOP_OR:
242 return a || b;
243
244 case BOOLOP_AND:
245 return a && b;
246
247 case BOOLOP_EQ:
248 return a == b;
249
250 case BOOLOP_NEQ:
251 return a != b;
252
253 default:
254 DE_FATAL("Unknown boolean operation.");
255 return false;
256 }
257 }
258
boolOpFromIndex(size_t index)259 BoolOp boolOpFromIndex(size_t index)
260 {
261 const BoolOp ops[] = {BOOLOP_OR, BOOLOP_AND, BOOLOP_EQ, BOOLOP_NEQ};
262
263 return ops[index % DE_LENGTH_OF_ARRAY(ops)];
264 }
265
requiredDepthEpsilon(VkFormat format)266 static float requiredDepthEpsilon(VkFormat format)
267 {
268 // Possible precision loss in the unorm depth pipeline means that we need to check depths
269 // that go in and back out of the depth buffer with an epsilon rather than an exact match
270 uint32_t unormBits = 0;
271
272 switch (format)
273 {
274 case VK_FORMAT_D16_UNORM:
275 unormBits = 16;
276 break;
277 case VK_FORMAT_X8_D24_UNORM_PACK32:
278 case VK_FORMAT_D24_UNORM_S8_UINT:
279 unormBits = 24;
280 break;
281 case VK_FORMAT_D32_SFLOAT:
282 case VK_FORMAT_D32_SFLOAT_S8_UINT:
283 default:
284 unormBits = 0;
285 break;
286 }
287
288 if (unormBits > 0)
289 return 1.0f / (float)((1 << unormBits) - 1);
290
291 return 0.0f; // Require exact match
292 }
293
depthsEqual(float a,float b,float epsilon)294 static bool depthsEqual(float a, float b, float epsilon)
295 {
296 return fabs(a - b) <= epsilon;
297 }
298
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkFramebufferCreateFlags pCreateInfo_flags,VkRenderPass pCreateInfo_renderPass,uint32_t pCreateInfo_attachmentCount,const VkImageView * pCreateInfo_pAttachments,uint32_t pCreateInfo_width,uint32_t pCreateInfo_height,uint32_t pCreateInfo_layers)299 Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vk, VkDevice device,
300 VkFramebufferCreateFlags pCreateInfo_flags, VkRenderPass pCreateInfo_renderPass,
301 uint32_t pCreateInfo_attachmentCount, const VkImageView *pCreateInfo_pAttachments,
302 uint32_t pCreateInfo_width, uint32_t pCreateInfo_height,
303 uint32_t pCreateInfo_layers)
304 {
305 const VkFramebufferCreateInfo pCreateInfo = {
306 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
307 DE_NULL,
308 pCreateInfo_flags,
309 pCreateInfo_renderPass,
310 pCreateInfo_attachmentCount,
311 pCreateInfo_pAttachments,
312 pCreateInfo_width,
313 pCreateInfo_height,
314 pCreateInfo_layers,
315 };
316 return createFramebuffer(vk, device, &pCreateInfo);
317 }
318
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags pCreateInfo_flags,VkImageType pCreateInfo_imageType,VkFormat pCreateInfo_format,VkExtent3D pCreateInfo_extent,uint32_t pCreateInfo_mipLevels,uint32_t pCreateInfo_arrayLayers,VkSampleCountFlagBits pCreateInfo_samples,VkImageTiling pCreateInfo_tiling,VkImageUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,uint32_t pCreateInfo_queueFamilyCount,const uint32_t * pCreateInfo_pQueueFamilyIndices,VkImageLayout pCreateInfo_initialLayout)319 Move<VkImage> createImage(const DeviceInterface &vk, VkDevice device, VkImageCreateFlags pCreateInfo_flags,
320 VkImageType pCreateInfo_imageType, VkFormat pCreateInfo_format, VkExtent3D pCreateInfo_extent,
321 uint32_t pCreateInfo_mipLevels, uint32_t pCreateInfo_arrayLayers,
322 VkSampleCountFlagBits pCreateInfo_samples, VkImageTiling pCreateInfo_tiling,
323 VkImageUsageFlags pCreateInfo_usage, VkSharingMode pCreateInfo_sharingMode,
324 uint32_t pCreateInfo_queueFamilyCount, const uint32_t *pCreateInfo_pQueueFamilyIndices,
325 VkImageLayout pCreateInfo_initialLayout)
326 {
327 const VkImageCreateInfo pCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
328 DE_NULL,
329 pCreateInfo_flags,
330 pCreateInfo_imageType,
331 pCreateInfo_format,
332 pCreateInfo_extent,
333 pCreateInfo_mipLevels,
334 pCreateInfo_arrayLayers,
335 pCreateInfo_samples,
336 pCreateInfo_tiling,
337 pCreateInfo_usage,
338 pCreateInfo_sharingMode,
339 pCreateInfo_queueFamilyCount,
340 pCreateInfo_pQueueFamilyIndices,
341 pCreateInfo_initialLayout};
342 return createImage(vk, device, &pCreateInfo);
343 }
344
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)345 void bindBufferMemory(const DeviceInterface &vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
346 VkDeviceSize memOffset)
347 {
348 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
349 }
350
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)351 void bindImageMemory(const DeviceInterface &vk, VkDevice device, VkImage image, VkDeviceMemory mem,
352 VkDeviceSize memOffset)
353 {
354 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
355 }
356
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags pCreateInfo_flags,VkImage pCreateInfo_image,VkImageViewType pCreateInfo_viewType,VkFormat pCreateInfo_format,VkComponentMapping pCreateInfo_components,VkImageSubresourceRange pCreateInfo_subresourceRange)357 Move<VkImageView> createImageView(const DeviceInterface &vk, VkDevice device, VkImageViewCreateFlags pCreateInfo_flags,
358 VkImage pCreateInfo_image, VkImageViewType pCreateInfo_viewType,
359 VkFormat pCreateInfo_format, VkComponentMapping pCreateInfo_components,
360 VkImageSubresourceRange pCreateInfo_subresourceRange)
361 {
362 const VkImageViewCreateInfo pCreateInfo = {
363 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
364 DE_NULL,
365 pCreateInfo_flags,
366 pCreateInfo_image,
367 pCreateInfo_viewType,
368 pCreateInfo_format,
369 pCreateInfo_components,
370 pCreateInfo_subresourceRange,
371 };
372 return createImageView(vk, device, &pCreateInfo);
373 }
374
createBuffer(const DeviceInterface & vk,VkDevice device,VkBufferCreateFlags pCreateInfo_flags,VkDeviceSize pCreateInfo_size,VkBufferUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,uint32_t pCreateInfo_queueFamilyCount,const uint32_t * pCreateInfo_pQueueFamilyIndices)375 Move<VkBuffer> createBuffer(const DeviceInterface &vk, VkDevice device, VkBufferCreateFlags pCreateInfo_flags,
376 VkDeviceSize pCreateInfo_size, VkBufferUsageFlags pCreateInfo_usage,
377 VkSharingMode pCreateInfo_sharingMode, uint32_t pCreateInfo_queueFamilyCount,
378 const uint32_t *pCreateInfo_pQueueFamilyIndices)
379 {
380 const VkBufferCreateInfo pCreateInfo = {
381 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
382 DE_NULL,
383 pCreateInfo_flags,
384 pCreateInfo_size,
385 pCreateInfo_usage,
386 pCreateInfo_sharingMode,
387 pCreateInfo_queueFamilyCount,
388 pCreateInfo_pQueueFamilyIndices,
389 };
390 return createBuffer(vk, device, &pCreateInfo);
391 }
392
createRenderPassBeginInfo(VkRenderPass pRenderPassBegin_renderPass,VkFramebuffer pRenderPassBegin_framebuffer,VkRect2D pRenderPassBegin_renderArea,uint32_t pRenderPassBegin_clearValueCount,const VkClearValue * pRenderPassBegin_pAttachmentClearValues)393 VkRenderPassBeginInfo createRenderPassBeginInfo(VkRenderPass pRenderPassBegin_renderPass,
394 VkFramebuffer pRenderPassBegin_framebuffer,
395 VkRect2D pRenderPassBegin_renderArea,
396 uint32_t pRenderPassBegin_clearValueCount,
397 const VkClearValue *pRenderPassBegin_pAttachmentClearValues)
398 {
399 const VkRenderPassBeginInfo renderPassBeginInfo = {
400 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
401 DE_NULL,
402 pRenderPassBegin_renderPass,
403 pRenderPassBegin_framebuffer,
404 pRenderPassBegin_renderArea,
405 pRenderPassBegin_clearValueCount,
406 pRenderPassBegin_pAttachmentClearValues,
407 };
408
409 return renderPassBeginInfo;
410 }
411
queueSubmit(const DeviceInterface & vk,VkQueue queue,uint32_t cmdBufferCount,const VkCommandBuffer * pCmdBuffers,VkFence fence)412 void queueSubmit(const DeviceInterface &vk, VkQueue queue, uint32_t cmdBufferCount, const VkCommandBuffer *pCmdBuffers,
413 VkFence fence)
414 {
415 const VkSubmitInfo submitInfo = {
416 VK_STRUCTURE_TYPE_SUBMIT_INFO,
417 DE_NULL,
418 0u, // waitSemaphoreCount
419 (const VkSemaphore *)DE_NULL, // pWaitSemaphores
420 (const VkPipelineStageFlags *)DE_NULL,
421 cmdBufferCount, // commandBufferCount
422 pCmdBuffers,
423 0u, // signalSemaphoreCount
424 (const VkSemaphore *)DE_NULL, // pSignalSemaphores
425 };
426 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
427 }
428
waitForFences(const DeviceInterface & vk,VkDevice device,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)429 void waitForFences(const DeviceInterface &vk, VkDevice device, uint32_t fenceCount, const VkFence *pFences,
430 VkBool32 waitAll, uint64_t timeout)
431 {
432 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
433 }
434
getImageAspectFlags(VkFormat vkFormat)435 VkImageAspectFlags getImageAspectFlags(VkFormat vkFormat)
436 {
437 const tcu::TextureFormat format = mapVkFormat(vkFormat);
438
439 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
440
441 switch (format.order)
442 {
443 case tcu::TextureFormat::DS:
444 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
445
446 case tcu::TextureFormat::D:
447 return VK_IMAGE_ASPECT_DEPTH_BIT;
448
449 case tcu::TextureFormat::S:
450 return VK_IMAGE_ASPECT_STENCIL_BIT;
451
452 default:
453 return VK_IMAGE_ASPECT_COLOR_BIT;
454 }
455 }
456
getAllMemoryReadFlags(void)457 VkAccessFlags getAllMemoryReadFlags(void)
458 {
459 return VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_HOST_READ_BIT |
460 VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
461 VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
462 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
463 }
464
getAllMemoryWriteFlags(void)465 VkAccessFlags getAllMemoryWriteFlags(void)
466 {
467 return VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT |
468 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
469 }
470
getMemoryFlagsForLayout(const VkImageLayout layout)471 VkAccessFlags getMemoryFlagsForLayout(const VkImageLayout layout)
472 {
473 switch (layout)
474 {
475 case VK_IMAGE_LAYOUT_GENERAL:
476 return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
477 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
478 return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
479 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
480 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
481 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
482 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
483 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
484 return VK_ACCESS_SHADER_READ_BIT;
485 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
486 return VK_ACCESS_TRANSFER_READ_BIT;
487 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
488 return VK_ACCESS_TRANSFER_WRITE_BIT;
489 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
490 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
491 VK_ACCESS_SHADER_READ_BIT;
492 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
493 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
494 VK_ACCESS_SHADER_READ_BIT;
495 default:
496 return (VkAccessFlags)0;
497 }
498 }
499
getAllPipelineStageFlags(void)500 VkPipelineStageFlags getAllPipelineStageFlags(void)
501 {
502 /* All relevant flags for a pipeline containing VS+PS. */
503 return VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
504 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
505 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
506 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
507 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_HOST_BIT;
508 }
509
510 class AttachmentReference
511 {
512 public:
AttachmentReference(uint32_t attachment,VkImageLayout layout,VkImageAspectFlags aspectMask=static_cast<VkImageAspectFlags> (0u))513 AttachmentReference(uint32_t attachment, VkImageLayout layout,
514 VkImageAspectFlags aspectMask = static_cast<VkImageAspectFlags>(0u))
515 : m_attachment(attachment)
516 , m_layout(layout)
517 , m_aspectMask(aspectMask)
518 {
519 }
520
getAttachment(void) const521 uint32_t getAttachment(void) const
522 {
523 return m_attachment;
524 }
getImageLayout(void) const525 VkImageLayout getImageLayout(void) const
526 {
527 return m_layout;
528 }
getAspectMask(void) const529 VkImageAspectFlags getAspectMask(void) const
530 {
531 return m_aspectMask;
532 }
setImageLayout(VkImageLayout layout)533 void setImageLayout(VkImageLayout layout)
534 {
535 m_layout = layout;
536 }
537
538 private:
539 uint32_t m_attachment;
540 VkImageLayout m_layout;
541 VkImageAspectFlags m_aspectMask;
542 };
543
544 class Subpass
545 {
546 public:
Subpass(VkPipelineBindPoint pipelineBindPoint,VkSubpassDescriptionFlags flags,const vector<AttachmentReference> & inputAttachments,const vector<AttachmentReference> & colorAttachments,const vector<AttachmentReference> & resolveAttachments,AttachmentReference depthStencilAttachment,const vector<uint32_t> & preserveAttachments,bool omitBlendState=false)547 Subpass(VkPipelineBindPoint pipelineBindPoint, VkSubpassDescriptionFlags flags,
548 const vector<AttachmentReference> &inputAttachments, const vector<AttachmentReference> &colorAttachments,
549 const vector<AttachmentReference> &resolveAttachments, AttachmentReference depthStencilAttachment,
550 const vector<uint32_t> &preserveAttachments, bool omitBlendState = false)
551 : m_pipelineBindPoint(pipelineBindPoint)
552 , m_flags(flags)
553 , m_inputAttachments(inputAttachments)
554 , m_colorAttachments(colorAttachments)
555 , m_resolveAttachments(resolveAttachments)
556 , m_depthStencilAttachment(depthStencilAttachment)
557 , m_preserveAttachments(preserveAttachments)
558 , m_omitBlendState(omitBlendState)
559 {
560 }
561
getPipelineBindPoint(void) const562 VkPipelineBindPoint getPipelineBindPoint(void) const
563 {
564 return m_pipelineBindPoint;
565 }
getFlags(void) const566 VkSubpassDescriptionFlags getFlags(void) const
567 {
568 return m_flags;
569 }
getInputAttachments(void) const570 const vector<AttachmentReference> &getInputAttachments(void) const
571 {
572 return m_inputAttachments;
573 }
getColorAttachments(void) const574 const vector<AttachmentReference> &getColorAttachments(void) const
575 {
576 return m_colorAttachments;
577 }
getResolveAttachments(void) const578 const vector<AttachmentReference> &getResolveAttachments(void) const
579 {
580 return m_resolveAttachments;
581 }
getDepthStencilAttachment(void) const582 const AttachmentReference &getDepthStencilAttachment(void) const
583 {
584 return m_depthStencilAttachment;
585 }
getPreserveAttachments(void) const586 const vector<uint32_t> &getPreserveAttachments(void) const
587 {
588 return m_preserveAttachments;
589 }
getOmitBlendState(void) const590 bool getOmitBlendState(void) const
591 {
592 return m_omitBlendState;
593 }
594
595 private:
596 VkPipelineBindPoint m_pipelineBindPoint;
597 VkSubpassDescriptionFlags m_flags;
598
599 vector<AttachmentReference> m_inputAttachments;
600 vector<AttachmentReference> m_colorAttachments;
601 vector<AttachmentReference> m_resolveAttachments;
602 AttachmentReference m_depthStencilAttachment;
603
604 vector<uint32_t> m_preserveAttachments;
605 bool m_omitBlendState;
606 };
607
608 class SubpassDependency
609 {
610 public:
SubpassDependency(uint32_t srcPass,uint32_t dstPass,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkDependencyFlags flags)611 SubpassDependency(uint32_t srcPass, uint32_t dstPass,
612
613 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
614
615 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
616
617 VkDependencyFlags flags)
618 : m_srcPass(srcPass)
619 , m_dstPass(dstPass)
620
621 , m_srcStageMask(srcStageMask)
622 , m_dstStageMask(dstStageMask)
623
624 , m_srcAccessMask(srcAccessMask)
625 , m_dstAccessMask(dstAccessMask)
626 , m_flags(flags)
627 {
628 }
629
getSrcPass(void) const630 uint32_t getSrcPass(void) const
631 {
632 return m_srcPass;
633 }
getDstPass(void) const634 uint32_t getDstPass(void) const
635 {
636 return m_dstPass;
637 }
638
getSrcStageMask(void) const639 VkPipelineStageFlags getSrcStageMask(void) const
640 {
641 return m_srcStageMask;
642 }
getDstStageMask(void) const643 VkPipelineStageFlags getDstStageMask(void) const
644 {
645 return m_dstStageMask;
646 }
647
getSrcAccessMask(void) const648 VkAccessFlags getSrcAccessMask(void) const
649 {
650 return m_srcAccessMask;
651 }
getDstAccessMask(void) const652 VkAccessFlags getDstAccessMask(void) const
653 {
654 return m_dstAccessMask;
655 }
656
getFlags(void) const657 VkDependencyFlags getFlags(void) const
658 {
659 return m_flags;
660 }
661
setSrcAccessMask(const VkAccessFlags & flags)662 void setSrcAccessMask(const VkAccessFlags &flags)
663 {
664 m_srcAccessMask = flags;
665 }
setDstAccessMask(const VkAccessFlags & flags)666 void setDstAccessMask(const VkAccessFlags &flags)
667 {
668 m_dstAccessMask = flags;
669 }
670
671 private:
672 uint32_t m_srcPass;
673 uint32_t m_dstPass;
674
675 VkPipelineStageFlags m_srcStageMask;
676 VkPipelineStageFlags m_dstStageMask;
677
678 VkAccessFlags m_srcAccessMask;
679 VkAccessFlags m_dstAccessMask;
680 VkDependencyFlags m_flags;
681 };
682
683 class Attachment
684 {
685 public:
Attachment(VkFormat format,VkSampleCountFlagBits samples,VkAttachmentLoadOp loadOp,VkAttachmentStoreOp storeOp,VkAttachmentLoadOp stencilLoadOp,VkAttachmentStoreOp stencilStoreOp,VkImageLayout initialLayout,VkImageLayout finalLayout)686 Attachment(VkFormat format, VkSampleCountFlagBits samples,
687
688 VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp,
689
690 VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp,
691
692 VkImageLayout initialLayout, VkImageLayout finalLayout)
693 : m_format(format)
694 , m_samples(samples)
695
696 , m_loadOp(loadOp)
697 , m_storeOp(storeOp)
698
699 , m_stencilLoadOp(stencilLoadOp)
700 , m_stencilStoreOp(stencilStoreOp)
701
702 , m_initialLayout(initialLayout)
703 , m_finalLayout(finalLayout)
704 {
705 }
706
getFormat(void) const707 VkFormat getFormat(void) const
708 {
709 return m_format;
710 }
getSamples(void) const711 VkSampleCountFlagBits getSamples(void) const
712 {
713 return m_samples;
714 }
715
getLoadOp(void) const716 VkAttachmentLoadOp getLoadOp(void) const
717 {
718 return m_loadOp;
719 }
getStoreOp(void) const720 VkAttachmentStoreOp getStoreOp(void) const
721 {
722 return m_storeOp;
723 }
724
getStencilLoadOp(void) const725 VkAttachmentLoadOp getStencilLoadOp(void) const
726 {
727 return m_stencilLoadOp;
728 }
getStencilStoreOp(void) const729 VkAttachmentStoreOp getStencilStoreOp(void) const
730 {
731 return m_stencilStoreOp;
732 }
733
getInitialLayout(void) const734 VkImageLayout getInitialLayout(void) const
735 {
736 return m_initialLayout;
737 }
getFinalLayout(void) const738 VkImageLayout getFinalLayout(void) const
739 {
740 return m_finalLayout;
741 }
742
743 private:
744 VkFormat m_format;
745 VkSampleCountFlagBits m_samples;
746
747 VkAttachmentLoadOp m_loadOp;
748 VkAttachmentStoreOp m_storeOp;
749
750 VkAttachmentLoadOp m_stencilLoadOp;
751 VkAttachmentStoreOp m_stencilStoreOp;
752
753 VkImageLayout m_initialLayout;
754 VkImageLayout m_finalLayout;
755 };
756
757 class RenderPass
758 {
759 public:
RenderPass(const vector<Attachment> & attachments,const vector<Subpass> & subpasses,const vector<SubpassDependency> & dependencies,const vector<VkInputAttachmentAspectReference> inputAspects=vector<VkInputAttachmentAspectReference> ())760 RenderPass(const vector<Attachment> &attachments, const vector<Subpass> &subpasses,
761 const vector<SubpassDependency> &dependencies,
762 const vector<VkInputAttachmentAspectReference> inputAspects = vector<VkInputAttachmentAspectReference>())
763 : m_attachments(attachments)
764 , m_subpasses(subpasses)
765 , m_dependencies(dependencies)
766 , m_inputAspects(inputAspects)
767 {
768 }
769
getAttachments(void) const770 const vector<Attachment> &getAttachments(void) const
771 {
772 return m_attachments;
773 }
getSubpasses(void) const774 const vector<Subpass> &getSubpasses(void) const
775 {
776 return m_subpasses;
777 }
getDependencies(void) const778 const vector<SubpassDependency> &getDependencies(void) const
779 {
780 return m_dependencies;
781 }
getInputAspects(void) const782 const vector<VkInputAttachmentAspectReference> &getInputAspects(void) const
783 {
784 return m_inputAspects;
785 }
786
787 private:
788 const vector<Attachment> m_attachments;
789 const vector<Subpass> m_subpasses;
790 const vector<SubpassDependency> m_dependencies;
791 const vector<VkInputAttachmentAspectReference> m_inputAspects;
792 };
793
794 struct TestConfig
795 {
796 enum RenderTypes
797 {
798 RENDERTYPES_NONE = 0,
799 RENDERTYPES_CLEAR = (1 << 1),
800 RENDERTYPES_DRAW = (1 << 2)
801 };
802
803 enum CommandBufferTypes
804 {
805 COMMANDBUFFERTYPES_INLINE = (1 << 0),
806 COMMANDBUFFERTYPES_SECONDARY = (1 << 1)
807 };
808
809 enum ImageMemory
810 {
811 IMAGEMEMORY_STRICT = (1 << 0),
812 IMAGEMEMORY_LAZY = (1 << 1)
813 };
814
TestConfigvkt::__anon33b72dba0111::TestConfig815 TestConfig(const RenderPass &renderPass_, RenderTypes renderTypes_, CommandBufferTypes commandBufferTypes_,
816 ImageMemory imageMemory_, const UVec2 &targetSize_, const UVec2 &renderPos_, const UVec2 &renderSize_,
817 bool useFormatCompCount_, uint32_t seed_, uint32_t drawStartNdx_, AllocationKind allocationKind_,
818 SharedGroupParams groupParams_,
819 vector<DeviceCoreFeature> requiredFeatures_ = vector<DeviceCoreFeature>())
820 : renderPass(renderPass_)
821 , renderTypes(renderTypes_)
822 , commandBufferTypes(commandBufferTypes_)
823 , imageMemory(imageMemory_)
824 , targetSize(targetSize_)
825 , renderPos(renderPos_)
826 , renderSize(renderSize_)
827 , useFormatCompCount(useFormatCompCount_)
828 , seed(seed_)
829 , drawStartNdx(drawStartNdx_)
830 , allocationKind(allocationKind_)
831 , groupParams(groupParams_)
832 , requiredFeatures(requiredFeatures_)
833 {
834 DepthValuesArray shuffledDepthValues(&DEPTH_VALUES[0], &DEPTH_VALUES[DE_LENGTH_OF_ARRAY(DEPTH_VALUES)]);
835 de::Random rng(seed + 1);
836
837 rng.shuffle(shuffledDepthValues.begin(), shuffledDepthValues.end());
838
839 depthValues.push_back(shuffledDepthValues[0]);
840 depthValues.push_back(shuffledDepthValues[1]);
841 }
842
843 RenderPass renderPass;
844 RenderTypes renderTypes;
845 CommandBufferTypes commandBufferTypes;
846 ImageMemory imageMemory;
847 UVec2 targetSize;
848 UVec2 renderPos;
849 UVec2 renderSize;
850 bool useFormatCompCount;
851 uint32_t seed;
852 uint32_t drawStartNdx;
853 AllocationKind allocationKind;
854 SharedGroupParams groupParams;
855 vector<DeviceCoreFeature> requiredFeatures;
856 DepthValuesArray depthValues;
857 };
858
operator |(TestConfig::RenderTypes a,TestConfig::RenderTypes b)859 TestConfig::RenderTypes operator|(TestConfig::RenderTypes a, TestConfig::RenderTypes b)
860 {
861 return (TestConfig::RenderTypes)(((uint32_t)a) | ((uint32_t)b));
862 }
863
operator |(TestConfig::CommandBufferTypes a,TestConfig::CommandBufferTypes b)864 TestConfig::CommandBufferTypes operator|(TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
865 {
866 return (TestConfig::CommandBufferTypes)(((uint32_t)a) | ((uint32_t)b));
867 }
868
operator |(TestConfig::ImageMemory a,TestConfig::ImageMemory b)869 TestConfig::ImageMemory operator|(TestConfig::ImageMemory a, TestConfig::ImageMemory b)
870 {
871 return (TestConfig::ImageMemory)(((uint32_t)a) | ((uint32_t)b));
872 }
873
checkSupport(Context & context,TestConfig config)874 void checkSupport(Context &context, TestConfig config)
875 {
876 for (size_t featureNdx = 0; featureNdx < config.requiredFeatures.size(); featureNdx++)
877 context.requireDeviceCoreFeature(config.requiredFeatures[featureNdx]);
878 }
879
logRenderPassInfo(TestLog & log,const RenderPass & renderPass)880 void logRenderPassInfo(TestLog &log, const RenderPass &renderPass)
881 {
882 const bool useExternalInputAspect = !renderPass.getInputAspects().empty();
883 const tcu::ScopedLogSection section(log, "RenderPass", "RenderPass");
884
885 {
886 const tcu::ScopedLogSection attachmentsSection(log, "Attachments", "Attachments");
887 const vector<Attachment> &attachments = renderPass.getAttachments();
888
889 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
890 {
891 const tcu::ScopedLogSection attachmentSection(log, "Attachment" + de::toString(attachmentNdx),
892 "Attachment " + de::toString(attachmentNdx));
893 const Attachment &attachment = attachments[attachmentNdx];
894
895 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
896 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
897
898 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
899 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
900
901 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
902 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
903
904 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
905 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
906 }
907 }
908
909 if (useExternalInputAspect)
910 {
911 const tcu::ScopedLogSection inputAspectSection(log, "InputAspects", "InputAspects");
912
913 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
914 {
915 const VkInputAttachmentAspectReference &inputAspect(renderPass.getInputAspects()[aspectNdx]);
916
917 log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
918 log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex
919 << TestLog::EndMessage;
920 log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask)
921 << TestLog::EndMessage;
922 }
923 }
924
925 {
926 const tcu::ScopedLogSection subpassesSection(log, "Subpasses", "Subpasses");
927 const vector<Subpass> &subpasses = renderPass.getSubpasses();
928
929 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
930 {
931 const tcu::ScopedLogSection subpassSection(log, "Subpass" + de::toString(subpassNdx),
932 "Subpass " + de::toString(subpassNdx));
933 const Subpass &subpass = subpasses[subpassNdx];
934
935 const vector<AttachmentReference> &inputAttachments = subpass.getInputAttachments();
936 const vector<AttachmentReference> &colorAttachments = subpass.getColorAttachments();
937 const vector<AttachmentReference> &resolveAttachments = subpass.getResolveAttachments();
938 const vector<uint32_t> &preserveAttachments = subpass.getPreserveAttachments();
939
940 if (!inputAttachments.empty())
941 {
942 const tcu::ScopedLogSection inputAttachmentsSection(log, "Inputs", "Inputs");
943
944 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
945 {
946 const tcu::ScopedLogSection inputAttachmentSection(log, "Input" + de::toString(inputNdx),
947 "Input " + de::toString(inputNdx));
948 const AttachmentReference &inputAttachment = inputAttachments[inputNdx];
949
950 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
951 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
952 if (!useExternalInputAspect)
953 log << TestLog::Message << "AspectMask: " << inputAttachment.getAspectMask()
954 << TestLog::EndMessage;
955 }
956 }
957
958 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
959 {
960 const tcu::ScopedLogSection depthStencilAttachmentSection(log, "DepthStencil", "DepthStencil");
961 const AttachmentReference &depthStencilAttachment = subpass.getDepthStencilAttachment();
962
963 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment()
964 << TestLog::EndMessage;
965 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
966 }
967
968 if (!colorAttachments.empty())
969 {
970 const tcu::ScopedLogSection colorAttachmentsSection(log, "Colors", "Colors");
971
972 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
973 {
974 const tcu::ScopedLogSection colorAttachmentSection(log, "Color" + de::toString(colorNdx),
975 "Color " + de::toString(colorNdx));
976 const AttachmentReference &colorAttachment = colorAttachments[colorNdx];
977
978 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
979 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
980 }
981 }
982
983 if (!resolveAttachments.empty())
984 {
985 const tcu::ScopedLogSection resolveAttachmentsSection(log, "Resolves", "Resolves");
986
987 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
988 {
989 const tcu::ScopedLogSection resolveAttachmentSection(log, "Resolve" + de::toString(resolveNdx),
990 "Resolve " + de::toString(resolveNdx));
991 const AttachmentReference &resolveAttachment = resolveAttachments[resolveNdx];
992
993 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment()
994 << TestLog::EndMessage;
995 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
996 }
997 }
998
999 if (!preserveAttachments.empty())
1000 {
1001 const tcu::ScopedLogSection preserveAttachmentsSection(log, "Preserves", "Preserves");
1002
1003 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
1004 {
1005 const tcu::ScopedLogSection preserveAttachmentSection(log, "Preserve" + de::toString(preserveNdx),
1006 "Preserve " + de::toString(preserveNdx));
1007 const uint32_t preserveAttachment = preserveAttachments[preserveNdx];
1008
1009 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
1010 }
1011 }
1012 }
1013 }
1014
1015 if (!renderPass.getDependencies().empty())
1016 {
1017 const tcu::ScopedLogSection dependenciesSection(log, "Dependencies", "Dependencies");
1018
1019 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
1020 {
1021 const tcu::ScopedLogSection dependencySection(log, "Dependency" + de::toString(depNdx),
1022 "Dependency " + de::toString(depNdx));
1023 const SubpassDependency &dep = renderPass.getDependencies()[depNdx];
1024
1025 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
1026 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
1027
1028 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
1029 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
1030
1031 log << TestLog::Message << "Input Mask: " << dep.getDstAccessMask() << TestLog::EndMessage;
1032 log << TestLog::Message << "Output Mask: " << dep.getSrcAccessMask() << TestLog::EndMessage;
1033 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags())
1034 << TestLog::EndMessage;
1035 }
1036 }
1037 }
1038
clearColorToString(VkFormat vkFormat,VkClearColorValue value,bool useFormatCompCount)1039 std::string clearColorToString(VkFormat vkFormat, VkClearColorValue value, bool useFormatCompCount)
1040 {
1041 const tcu::TextureFormat format = mapVkFormat(vkFormat);
1042 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
1043 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
1044 const auto numUsedChannels = static_cast<uint32_t>(getShaderNumChannels(format.order));
1045 const uint32_t componentCount = (useFormatCompCount ? numUsedChannels : 4u);
1046
1047 std::ostringstream stream;
1048
1049 stream << "(";
1050
1051 switch (channelClass)
1052 {
1053 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1054 for (uint32_t i = 0; i < componentCount; i++)
1055 {
1056 if (i > 0)
1057 stream << ", ";
1058
1059 if (channelMask[i])
1060 stream << value.int32[i];
1061 else
1062 stream << "Undef";
1063 }
1064 break;
1065
1066 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1067 for (uint32_t i = 0; i < componentCount; i++)
1068 {
1069 if (i > 0)
1070 stream << ", ";
1071
1072 if (channelMask[i])
1073 stream << value.uint32[i];
1074 else
1075 stream << "Undef";
1076 }
1077 break;
1078
1079 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1080 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1081 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1082 for (uint32_t i = 0; i < componentCount; i++)
1083 {
1084 if (i > 0)
1085 stream << ", ";
1086
1087 if (channelMask[i])
1088 stream << value.float32[i];
1089 else
1090 stream << "Undef";
1091 }
1092 break;
1093
1094 default:
1095 DE_FATAL("Unknown channel class");
1096 }
1097
1098 stream << ")";
1099
1100 return stream.str();
1101 }
1102
clearValueToString(VkFormat vkFormat,VkClearValue value,bool useFormatCompCount)1103 std::string clearValueToString(VkFormat vkFormat, VkClearValue value, bool useFormatCompCount)
1104 {
1105 const tcu::TextureFormat format = mapVkFormat(vkFormat);
1106
1107 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1108 {
1109 std::ostringstream stream;
1110
1111 stream << "(";
1112
1113 if (tcu::hasStencilComponent(format.order))
1114 stream << "stencil: " << value.depthStencil.stencil;
1115
1116 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
1117 stream << ", ";
1118
1119 if (tcu::hasDepthComponent(format.order))
1120 stream << "depth: " << value.depthStencil.depth;
1121
1122 stream << ")";
1123
1124 return stream.str();
1125 }
1126 else
1127 return clearColorToString(vkFormat, value.color, useFormatCompCount);
1128 }
1129
randomColorClearValue(const Attachment & attachment,de::Random & rng,bool useFormatCompCount)1130 VkClearColorValue randomColorClearValue(const Attachment &attachment, de::Random &rng, bool useFormatCompCount)
1131 {
1132 const float clearNan = tcu::Float32::nan().asFloat();
1133 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1134 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
1135 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
1136 const auto numUsedChannels = static_cast<uint32_t>(getShaderNumChannels(format.order));
1137 const uint32_t componentCount = (useFormatCompCount ? numUsedChannels : 4u);
1138 VkClearColorValue clearColor;
1139
1140 switch (channelClass)
1141 {
1142 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1143 {
1144 for (uint32_t ndx = 0; ndx < componentCount; ndx++)
1145 {
1146 if (!channelMask[ndx])
1147 clearColor.int32[ndx] = std::numeric_limits<int32_t>::min();
1148 else
1149 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1150 }
1151 break;
1152 }
1153
1154 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1155 {
1156 for (uint32_t ndx = 0; ndx < componentCount; ndx++)
1157 {
1158 if (!channelMask[ndx])
1159 clearColor.uint32[ndx] = std::numeric_limits<uint32_t>::max();
1160 else
1161 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1162 }
1163 break;
1164 }
1165
1166 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1167 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1168 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1169 {
1170 for (uint32_t ndx = 0; ndx < componentCount; ndx++)
1171 {
1172 if (!channelMask[ndx])
1173 clearColor.float32[ndx] = clearNan;
1174 else
1175 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1176 }
1177 break;
1178 }
1179
1180 default:
1181 DE_FATAL("Unknown channel class");
1182 }
1183
1184 return clearColor;
1185 }
1186
1187 template <typename AttachmentDesc>
createAttachmentDescription(const Attachment & attachment)1188 AttachmentDesc createAttachmentDescription(const Attachment &attachment)
1189 {
1190 const AttachmentDesc
1191 attachmentDescription // VkAttachmentDescription || VkAttachmentDescription2KHR
1192 (
1193 // || VkStructureType sType;
1194 DE_NULL, // || const void* pNext;
1195 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
1196 attachment.getFormat(), // VkFormat format; || VkFormat format;
1197 attachment.getSamples(), // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
1198 attachment.getLoadOp(), // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
1199 attachment.getStoreOp(), // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
1200 attachment.getStencilLoadOp(), // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
1201 attachment
1202 .getStencilStoreOp(), // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
1203 attachment.getInitialLayout(), // VkImageLayout initialLayout; || VkImageLayout initialLayout;
1204 attachment.getFinalLayout() // VkImageLayout finalLayout; || VkImageLayout finalLayout;
1205 );
1206
1207 return attachmentDescription;
1208 }
1209
1210 template <typename AttachmentRef>
createAttachmentReference(const AttachmentReference & referenceInfo)1211 AttachmentRef createAttachmentReference(const AttachmentReference &referenceInfo)
1212 {
1213 const AttachmentRef
1214 reference // VkAttachmentReference || VkAttachmentReference2KHR
1215 (
1216 // || VkStructureType sType;
1217 DE_NULL, // || const void* pNext;
1218 referenceInfo.getAttachment(), // uint32_t attachment; || uint32_t attachment;
1219 referenceInfo.getImageLayout(), // VkImageLayout layout; || VkImageLayout layout;
1220 referenceInfo.getAspectMask() // || VkImageAspectFlags aspectMask;
1221 );
1222
1223 return reference;
1224 }
1225
1226 template <typename SubpassDesc, typename AttachmentRef>
createSubpassDescription(const Subpass & subpass,vector<AttachmentRef> * attachmentReferenceLists,vector<uint32_t> * preserveAttachmentReferences)1227 SubpassDesc createSubpassDescription(const Subpass &subpass, vector<AttachmentRef> *attachmentReferenceLists,
1228 vector<uint32_t> *preserveAttachmentReferences)
1229 {
1230 vector<AttachmentRef> &inputAttachmentReferences = attachmentReferenceLists[0];
1231 vector<AttachmentRef> &colorAttachmentReferences = attachmentReferenceLists[1];
1232 vector<AttachmentRef> &resolveAttachmentReferences = attachmentReferenceLists[2];
1233 vector<AttachmentRef> &depthStencilAttachmentReferences = attachmentReferenceLists[3];
1234
1235 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1236 colorAttachmentReferences.push_back(
1237 createAttachmentReference<AttachmentRef>(subpass.getColorAttachments()[attachmentNdx]));
1238
1239 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1240 inputAttachmentReferences.push_back(
1241 createAttachmentReference<AttachmentRef>(subpass.getInputAttachments()[attachmentNdx]));
1242
1243 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1244 resolveAttachmentReferences.push_back(
1245 createAttachmentReference<AttachmentRef>(subpass.getResolveAttachments()[attachmentNdx]));
1246
1247 depthStencilAttachmentReferences.push_back(
1248 createAttachmentReference<AttachmentRef>(subpass.getDepthStencilAttachment()));
1249
1250 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1251 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1252
1253 DE_ASSERT(resolveAttachmentReferences.empty() ||
1254 colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1255
1256 {
1257 const SubpassDesc
1258 subpassDescription // VkSubpassDescription || VkSubpassDescription2KHR
1259 (
1260 // || VkStructureType sType;
1261 DE_NULL, // || const void* pNext;
1262 subpass.getFlags(), // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
1263 subpass
1264 .getPipelineBindPoint(), // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
1265 0u, // || uint32_t viewMask;
1266 (uint32_t)inputAttachmentReferences
1267 .size(), // uint32_t inputAttachmentCount; || uint32_t inputAttachmentCount;
1268 inputAttachmentReferences.empty() ?
1269 DE_NULL :
1270 &inputAttachmentReferences
1271 [0], // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
1272 (uint32_t)colorAttachmentReferences
1273 .size(), // uint32_t colorAttachmentCount; || uint32_t colorAttachmentCount;
1274 colorAttachmentReferences.empty() ?
1275 DE_NULL :
1276 &colorAttachmentReferences
1277 [0], // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
1278 resolveAttachmentReferences.empty() ?
1279 DE_NULL :
1280 &resolveAttachmentReferences
1281 [0], // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
1282 &depthStencilAttachmentReferences
1283 [0], // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
1284 (uint32_t)preserveAttachmentReferences
1285 ->size(), // uint32_t preserveAttachmentCount; || uint32_t preserveAttachmentCount;
1286 preserveAttachmentReferences->empty() ?
1287 DE_NULL :
1288 &(*preserveAttachmentReferences)
1289 [0] // const uint32_t* pPreserveAttachments; || const uint32_t* pPreserveAttachments;
1290 );
1291
1292 return subpassDescription;
1293 }
1294 }
1295
1296 template <typename SubpassDep>
createSubpassDependency(const SubpassDependency & dependencyInfo)1297 SubpassDep createSubpassDependency(const SubpassDependency &dependencyInfo)
1298 {
1299 const SubpassDep
1300 dependency // VkSubpassDependency || VkSubpassDependency2KHR
1301 (
1302 // || VkStructureType sType;
1303 DE_NULL, // || const void* pNext;
1304 dependencyInfo.getSrcPass(), // uint32_t srcSubpass; || uint32_t srcSubpass;
1305 dependencyInfo.getDstPass(), // uint32_t dstSubpass; || uint32_t dstSubpass;
1306 dependencyInfo
1307 .getSrcStageMask(), // VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
1308 dependencyInfo
1309 .getDstStageMask(), // VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
1310 dependencyInfo.getSrcAccessMask(), // VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
1311 dependencyInfo.getDstAccessMask(), // VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
1312 dependencyInfo.getFlags(), // VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
1313 0u // || int32_t viewOffset;
1314 );
1315
1316 return dependency;
1317 }
1318
createRenderPassInputAttachmentAspectCreateInfo(const RenderPass & renderPassInfo)1319 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> createRenderPassInputAttachmentAspectCreateInfo(
1320 const RenderPass &renderPassInfo)
1321 {
1322 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> result(DE_NULL);
1323
1324 if (!renderPassInfo.getInputAspects().empty())
1325 {
1326 const VkRenderPassInputAttachmentAspectCreateInfo inputAspectCreateInfo = {
1327 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
1328 DE_NULL,
1329
1330 (uint32_t)renderPassInfo.getInputAspects().size(),
1331 renderPassInfo.getInputAspects().data(),
1332 };
1333
1334 result = de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>(
1335 new VkRenderPassInputAttachmentAspectCreateInfo(inputAspectCreateInfo));
1336 }
1337
1338 return result;
1339 }
1340
1341 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
1342 typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice device,const RenderPass & renderPassInfo)1343 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice device, const RenderPass &renderPassInfo)
1344 {
1345 const size_t perSubpassAttachmentReferenceLists = 4;
1346 vector<AttachmentDesc> attachments;
1347 vector<SubpassDesc> subpasses;
1348 vector<SubpassDep> dependencies;
1349 vector<vector<AttachmentRef>> attachmentReferenceLists(renderPassInfo.getSubpasses().size() *
1350 perSubpassAttachmentReferenceLists);
1351 vector<vector<uint32_t>> preserveAttachments(renderPassInfo.getSubpasses().size());
1352 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> inputAspectCreateInfo(
1353 createRenderPassInputAttachmentAspectCreateInfo(renderPassInfo));
1354
1355 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1356 attachments.push_back(
1357 createAttachmentDescription<AttachmentDesc>(renderPassInfo.getAttachments()[attachmentNdx]));
1358
1359 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1360 subpasses.push_back(createSubpassDescription<SubpassDesc>(
1361 renderPassInfo.getSubpasses()[subpassNdx],
1362 &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]),
1363 &preserveAttachments[subpassNdx]));
1364
1365 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1366 dependencies.push_back(createSubpassDependency<SubpassDep>(renderPassInfo.getDependencies()[depNdx]));
1367
1368 const RenderPassCreateInfo
1369 renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
1370 (
1371 // VkStructureType sType; || VkStructureType sType;
1372 inputAspectCreateInfo.get(), // const void* pNext; || const void* pNext;
1373 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
1374 (uint32_t)attachments.size(), // uint32_t attachmentCount; || uint32_t attachmentCount;
1375 (attachments.empty() ?
1376 DE_NULL :
1377 &attachments
1378 [0]), // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
1379 (uint32_t)subpasses.size(), // uint32_t subpassCount; || uint32_t subpassCount;
1380 (subpasses.empty() ?
1381 DE_NULL :
1382 &subpasses
1383 [0]), // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
1384 (uint32_t)dependencies.size(), // uint32_t dependencyCount; || uint32_t dependencyCount;
1385 (dependencies.empty() ?
1386 DE_NULL :
1387 &dependencies
1388 [0]), // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
1389 0u, // || uint32_t correlatedViewMaskCount;
1390 DE_NULL // || const uint32_t* pCorrelatedViewMasks;
1391 );
1392
1393 return renderPassCreator.createRenderPass(vk, device);
1394 }
1395
createRenderPass(const DeviceInterface & vk,VkDevice device,const RenderPass & renderPassInfo,const RenderingType renderPassType)1396 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice device, const RenderPass &renderPassInfo,
1397 const RenderingType renderPassType)
1398 {
1399 switch (renderPassType)
1400 {
1401 case RENDERING_TYPE_RENDERPASS_LEGACY:
1402 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1,
1403 RenderPassCreateInfo1>(vk, device, renderPassInfo);
1404 case RENDERING_TYPE_RENDERPASS2:
1405 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2,
1406 RenderPassCreateInfo2>(vk, device, renderPassInfo);
1407 default:
1408 TCU_THROW(InternalError, "Impossible");
1409 }
1410 }
1411
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkRenderPass renderPass,const UVec2 & size,const vector<VkImageView> & attachments)1412 Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vk, VkDevice device, VkRenderPass renderPass,
1413 const UVec2 &size, const vector<VkImageView> &attachments)
1414 {
1415 return createFramebuffer(vk, device, 0u, renderPass, (uint32_t)attachments.size(),
1416 attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1417 }
1418
createAttachmentImage(const DeviceInterface & vk,VkDevice device,uint32_t queueIndex,const UVec2 & size,VkFormat format,VkSampleCountFlagBits samples,VkImageUsageFlags usageFlags,VkImageLayout layout)1419 Move<VkImage> createAttachmentImage(const DeviceInterface &vk, VkDevice device, uint32_t queueIndex, const UVec2 &size,
1420 VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usageFlags,
1421 VkImageLayout layout)
1422 {
1423 VkImageUsageFlags targetUsageFlags = 0;
1424 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1425
1426 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) ||
1427 tcu::hasStencilComponent(vk::mapVkFormat(format).order)) ||
1428 ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1429
1430 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) ||
1431 tcu::hasStencilComponent(vk::mapVkFormat(format).order)) ||
1432 ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1433
1434 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1435 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1436 else
1437 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1438
1439 return createImage(vk, device, (VkImageCreateFlags)0, VK_IMAGE_TYPE_2D, format,
1440 vk::makeExtent3D(size.x(), size.y(), 1u), 1u /* mipLevels */, 1u /* arraySize */, samples,
1441 VK_IMAGE_TILING_OPTIMAL, usageFlags | targetUsageFlags, VK_SHARING_MODE_EXCLUSIVE, 1,
1442 &queueIndex, layout);
1443 }
1444
createImageMemory(const InstanceInterface & vki,const VkPhysicalDevice & vkd,const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image,bool lazy,AllocationKind allocationKind)1445 de::MovePtr<Allocation> createImageMemory(const InstanceInterface &vki, const VkPhysicalDevice &vkd,
1446 const DeviceInterface &vk, VkDevice device, Allocator &allocator,
1447 VkImage image, bool lazy, AllocationKind allocationKind)
1448 {
1449 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1450 de::MovePtr<Allocation> allocation =
1451 allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1452
1453 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1454
1455 return allocation;
1456 }
1457
createImageAttachmentView(const DeviceInterface & vk,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)1458 Move<VkImageView> createImageAttachmentView(const DeviceInterface &vk, VkDevice device, VkImage image, VkFormat format,
1459 VkImageAspectFlags aspect)
1460 {
1461 const VkImageSubresourceRange range = {aspect, 0, 1, 0, 1};
1462
1463 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1464 }
1465
randomClearValue(const Attachment & attachment,de::Random & rng,bool useFormatCompCount,const DepthValuesArray & depthValues)1466 VkClearValue randomClearValue(const Attachment &attachment, de::Random &rng, bool useFormatCompCount,
1467 const DepthValuesArray &depthValues)
1468 {
1469 const float clearNan = tcu::Float32::nan().asFloat();
1470 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1471
1472 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1473 {
1474 VkClearValue clearValue;
1475
1476 clearValue.depthStencil.depth = clearNan;
1477 clearValue.depthStencil.stencil = 0xCDu;
1478
1479 if (tcu::hasStencilComponent(format.order))
1480 clearValue.depthStencil.stencil = rng.getBool() ? 0xFFu : 0x0u;
1481
1482 if (tcu::hasDepthComponent(format.order))
1483 clearValue.depthStencil.depth = float(depthValues[rng.getBool() ? 1 : 0]) / 255.0f;
1484
1485 return clearValue;
1486 }
1487 else
1488 {
1489 VkClearValue clearValue;
1490
1491 clearValue.color = randomColorClearValue(attachment, rng, useFormatCompCount);
1492
1493 return clearValue;
1494 }
1495 }
1496
1497 class AttachmentResources
1498 {
1499 public:
AttachmentResources(const InstanceInterface & vki,const VkPhysicalDevice & physDevice,const DeviceInterface & vk,VkDevice device,Allocator & allocator,uint32_t queueIndex,const UVec2 & size,const Attachment & attachmentInfo,VkImageUsageFlags usageFlags,const AllocationKind allocationKind)1500 AttachmentResources(const InstanceInterface &vki, const VkPhysicalDevice &physDevice, const DeviceInterface &vk,
1501 VkDevice device, Allocator &allocator, uint32_t queueIndex, const UVec2 &size,
1502 const Attachment &attachmentInfo, VkImageUsageFlags usageFlags,
1503 const AllocationKind allocationKind)
1504 : m_image(createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(),
1505 attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1506 , m_imageMemory(createImageMemory(vki, physDevice, vk, device, allocator, *m_image,
1507 ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0),
1508 allocationKind))
1509 , m_attachmentView(createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(),
1510 getImageAspectFlags(attachmentInfo.getFormat())))
1511 {
1512 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1513 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1514 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1515
1516 if (isDepthFormat && isStencilFormat)
1517 {
1518 m_depthInputAttachmentView =
1519 createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1520 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(),
1521 VK_IMAGE_ASPECT_STENCIL_BIT);
1522
1523 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1524 }
1525 else
1526 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1527
1528 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1529 {
1530 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1531 {
1532 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1533 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1534
1535 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1536 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1537
1538 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1539 VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1540 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible,
1541 allocator, allocationKind);
1542
1543 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1544
1545 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1546 VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1547 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer,
1548 MemoryRequirement::HostVisible, allocator, allocationKind);
1549
1550 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(),
1551 m_secondaryBufferMemory->getOffset());
1552 }
1553 else
1554 {
1555 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1556
1557 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1558 VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1559 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible,
1560 allocator, allocationKind);
1561
1562 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1563 }
1564 }
1565 }
1566
getInputAttachmentViews(void) const1567 const pair<VkImageView, VkImageView> &getInputAttachmentViews(void) const
1568 {
1569 return m_inputAttachmentViews;
1570 }
1571
~AttachmentResources(void)1572 ~AttachmentResources(void)
1573 {
1574 }
1575
getAttachmentView(void) const1576 VkImageView getAttachmentView(void) const
1577 {
1578 return *m_attachmentView;
1579 }
1580
getImage(void) const1581 VkImage getImage(void) const
1582 {
1583 return *m_image;
1584 }
1585
getBuffer(void) const1586 VkBuffer getBuffer(void) const
1587 {
1588 DE_ASSERT(*m_buffer != DE_NULL);
1589 return *m_buffer;
1590 }
1591
getBufferSize(void) const1592 VkDeviceSize getBufferSize(void) const
1593 {
1594 DE_ASSERT(*m_buffer != DE_NULL);
1595 return m_bufferSize;
1596 }
1597
getResultMemory(void) const1598 const Allocation &getResultMemory(void) const
1599 {
1600 DE_ASSERT(m_bufferMemory);
1601 return *m_bufferMemory;
1602 }
1603
getSecondaryBuffer(void) const1604 VkBuffer getSecondaryBuffer(void) const
1605 {
1606 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1607 return *m_secondaryBuffer;
1608 }
1609
getSecondaryBufferSize(void) const1610 VkDeviceSize getSecondaryBufferSize(void) const
1611 {
1612 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1613 return m_secondaryBufferSize;
1614 }
1615
getSecondaryResultMemory(void) const1616 const Allocation &getSecondaryResultMemory(void) const
1617 {
1618 DE_ASSERT(m_secondaryBufferMemory);
1619 return *m_secondaryBufferMemory;
1620 }
1621
1622 private:
1623 const Unique<VkImage> m_image;
1624 const UniquePtr<Allocation> m_imageMemory;
1625 const Unique<VkImageView> m_attachmentView;
1626
1627 Move<VkImageView> m_depthInputAttachmentView;
1628 Move<VkImageView> m_stencilInputAttachmentView;
1629 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1630
1631 Move<VkBuffer> m_buffer;
1632 VkDeviceSize m_bufferSize;
1633 de::MovePtr<Allocation> m_bufferMemory;
1634
1635 Move<VkBuffer> m_secondaryBuffer;
1636 VkDeviceSize m_secondaryBufferSize;
1637 de::MovePtr<Allocation> m_secondaryBufferMemory;
1638 };
1639
uploadBufferData(const DeviceInterface & vk,VkDevice device,const Allocation & memory,size_t size,const void * data,VkDeviceSize nonCoherentAtomSize)1640 void uploadBufferData(const DeviceInterface &vk, VkDevice device, const Allocation &memory, size_t size,
1641 const void *data, VkDeviceSize nonCoherentAtomSize)
1642 {
1643 // Expand the range to flush to account for the nonCoherentAtomSize
1644 const VkDeviceSize roundedOffset = de::roundDown(memory.getOffset(), nonCoherentAtomSize);
1645 const VkDeviceSize roundedSize =
1646 de::roundUp(memory.getOffset() - roundedOffset + static_cast<VkDeviceSize>(size), nonCoherentAtomSize);
1647
1648 const VkMappedMemoryRange range = {
1649 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1650 DE_NULL, // pNext;
1651 memory.getMemory(), // mem;
1652 roundedOffset, // offset;
1653 roundedSize, // size;
1654 };
1655 void *const ptr = memory.getHostPtr();
1656
1657 deMemcpy(ptr, data, size);
1658 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1659 }
1660
getPrimaryImageAspect(tcu::TextureFormat::ChannelOrder order)1661 VkImageAspectFlagBits getPrimaryImageAspect(tcu::TextureFormat::ChannelOrder order)
1662 {
1663 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
1664
1665 switch (order)
1666 {
1667 case tcu::TextureFormat::D:
1668 case tcu::TextureFormat::DS:
1669 return VK_IMAGE_ASPECT_DEPTH_BIT;
1670
1671 case tcu::TextureFormat::S:
1672 return VK_IMAGE_ASPECT_STENCIL_BIT;
1673
1674 default:
1675 return VK_IMAGE_ASPECT_COLOR_BIT;
1676 }
1677 }
1678
getAttachmentNdx(const vector<AttachmentReference> & colorAttachments,size_t ndx)1679 uint32_t getAttachmentNdx(const vector<AttachmentReference> &colorAttachments, size_t ndx)
1680 {
1681 return (colorAttachments[ndx].getAttachment() == VK_ATTACHMENT_UNUSED) ? (uint32_t)ndx :
1682 colorAttachments[ndx].getAttachment();
1683 }
1684
1685 class RenderQuad
1686 {
1687 public:
RenderQuad(const Vec2 & posA,const Vec2 & posB)1688 RenderQuad(const Vec2 &posA, const Vec2 &posB) : m_vertices(6)
1689 {
1690 m_vertices[0] = posA;
1691 m_vertices[1] = Vec2(posA[0], posB[1]);
1692 m_vertices[2] = posB;
1693
1694 m_vertices[3] = posB;
1695 m_vertices[4] = Vec2(posB[0], posA[1]);
1696 m_vertices[5] = posA;
1697 }
1698
getCornerA(void) const1699 const Vec2 &getCornerA(void) const
1700 {
1701 return m_vertices[0];
1702 }
1703
getCornerB(void) const1704 const Vec2 &getCornerB(void) const
1705 {
1706 return m_vertices[2];
1707 }
1708
getVertexPointer(void) const1709 const void *getVertexPointer(void) const
1710 {
1711 return &m_vertices[0];
1712 }
1713
getVertexDataSize(void) const1714 size_t getVertexDataSize(void) const
1715 {
1716 return sizeof(Vec2) * m_vertices.size();
1717 }
1718
1719 private:
1720 vector<Vec2> m_vertices;
1721 };
1722
1723 class ColorClear
1724 {
1725 public:
ColorClear(const UVec2 & offset,const UVec2 & size,const VkClearColorValue & color)1726 ColorClear(const UVec2 &offset, const UVec2 &size, const VkClearColorValue &color)
1727 : m_offset(offset)
1728 , m_size(size)
1729 , m_color(color)
1730 {
1731 }
1732
getOffset(void) const1733 const UVec2 &getOffset(void) const
1734 {
1735 return m_offset;
1736 }
getSize(void) const1737 const UVec2 &getSize(void) const
1738 {
1739 return m_size;
1740 }
getColor(void) const1741 const VkClearColorValue &getColor(void) const
1742 {
1743 return m_color;
1744 }
1745
1746 private:
1747 UVec2 m_offset;
1748 UVec2 m_size;
1749 VkClearColorValue m_color;
1750 };
1751
1752 class DepthStencilClear
1753 {
1754 public:
DepthStencilClear(const UVec2 & offset,const UVec2 & size,float depth,uint32_t stencil)1755 DepthStencilClear(const UVec2 &offset, const UVec2 &size, float depth, uint32_t stencil)
1756 : m_offset(offset)
1757 , m_size(size)
1758 , m_depth(depth)
1759 , m_stencil(stencil)
1760 {
1761 }
1762
getOffset(void) const1763 const UVec2 &getOffset(void) const
1764 {
1765 return m_offset;
1766 }
getSize(void) const1767 const UVec2 &getSize(void) const
1768 {
1769 return m_size;
1770 }
getDepth(void) const1771 float getDepth(void) const
1772 {
1773 return m_depth;
1774 }
getStencil(void) const1775 uint32_t getStencil(void) const
1776 {
1777 return m_stencil;
1778 }
1779
1780 private:
1781 const UVec2 m_offset;
1782 const UVec2 m_size;
1783
1784 const float m_depth;
1785 const uint32_t m_stencil;
1786 };
1787
1788 class SubpassRenderInfo
1789 {
1790 public:
SubpassRenderInfo(const RenderPass & renderPass,uint32_t subpassIndex,uint32_t drawStartNdx,bool isSecondary_,bool omitBlendState_,const UVec2 & viewportOffset,const UVec2 & viewportSize,const Maybe<RenderQuad> & renderQuad,const vector<ColorClear> & colorClears,const Maybe<DepthStencilClear> & depthStencilClear)1791 SubpassRenderInfo(const RenderPass &renderPass, uint32_t subpassIndex, uint32_t drawStartNdx,
1792
1793 bool isSecondary_, bool omitBlendState_,
1794
1795 const UVec2 &viewportOffset, const UVec2 &viewportSize,
1796
1797 const Maybe<RenderQuad> &renderQuad, const vector<ColorClear> &colorClears,
1798 const Maybe<DepthStencilClear> &depthStencilClear)
1799 : m_viewportOffset(viewportOffset)
1800 , m_viewportSize(viewportSize)
1801 , m_subpassIndex(subpassIndex)
1802 , m_drawStartNdx(drawStartNdx)
1803 , m_isSecondary(isSecondary_)
1804 , m_omitBlendState(omitBlendState_)
1805 , m_flags(renderPass.getSubpasses()[subpassIndex].getFlags())
1806 , m_renderQuad(renderQuad)
1807 , m_colorClears(colorClears)
1808 , m_depthStencilClear(depthStencilClear)
1809 , m_colorAttachments(renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1810 , m_inputAttachments(renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1811 {
1812 for (uint32_t attachmentNdx = 0; attachmentNdx < (uint32_t)m_colorAttachments.size(); attachmentNdx++)
1813 m_colorAttachmentInfo.push_back(
1814 renderPass.getAttachments()[getAttachmentNdx(m_colorAttachments, attachmentNdx)]);
1815
1816 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1817 {
1818 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1819 m_depthStencilAttachmentInfo =
1820 tcu::just(renderPass.getAttachments()
1821 [renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1822 }
1823 }
1824
getViewportOffset(void) const1825 const UVec2 &getViewportOffset(void) const
1826 {
1827 return m_viewportOffset;
1828 }
getViewportSize(void) const1829 const UVec2 &getViewportSize(void) const
1830 {
1831 return m_viewportSize;
1832 }
1833
getSubpassIndex(void) const1834 uint32_t getSubpassIndex(void) const
1835 {
1836 return m_subpassIndex;
1837 }
getDrawStartNdx(void) const1838 uint32_t getDrawStartNdx(void) const
1839 {
1840 return m_drawStartNdx;
1841 }
isSecondary(void) const1842 bool isSecondary(void) const
1843 {
1844 return m_isSecondary;
1845 }
getOmitBlendState(void) const1846 bool getOmitBlendState(void) const
1847 {
1848 return m_omitBlendState;
1849 }
1850
getRenderQuad(void) const1851 const Maybe<RenderQuad> &getRenderQuad(void) const
1852 {
1853 return m_renderQuad;
1854 }
getColorClears(void) const1855 const vector<ColorClear> &getColorClears(void) const
1856 {
1857 return m_colorClears;
1858 }
getDepthStencilClear(void) const1859 const Maybe<DepthStencilClear> &getDepthStencilClear(void) const
1860 {
1861 return m_depthStencilClear;
1862 }
1863
getInputAttachmentCount(void) const1864 uint32_t getInputAttachmentCount(void) const
1865 {
1866 return (uint32_t)m_inputAttachments.size();
1867 }
getInputAttachmentIndex(uint32_t attachmentNdx) const1868 uint32_t getInputAttachmentIndex(uint32_t attachmentNdx) const
1869 {
1870 return m_inputAttachments[attachmentNdx].getAttachment();
1871 }
getInputAttachmentLayout(uint32_t attachmentNdx) const1872 VkImageLayout getInputAttachmentLayout(uint32_t attachmentNdx) const
1873 {
1874 return m_inputAttachments[attachmentNdx].getImageLayout();
1875 }
1876
getColorAttachmentCount(void) const1877 uint32_t getColorAttachmentCount(void) const
1878 {
1879 return (uint32_t)m_colorAttachments.size();
1880 }
getColorAttachmentLayout(uint32_t attachmentNdx) const1881 VkImageLayout getColorAttachmentLayout(uint32_t attachmentNdx) const
1882 {
1883 return m_colorAttachments[attachmentNdx].getImageLayout();
1884 }
getColorAttachmentIndex(uint32_t attachmentNdx) const1885 uint32_t getColorAttachmentIndex(uint32_t attachmentNdx) const
1886 {
1887 return m_colorAttachments[attachmentNdx].getAttachment();
1888 }
getColorAttachment(uint32_t attachmentNdx) const1889 const Attachment &getColorAttachment(uint32_t attachmentNdx) const
1890 {
1891 return m_colorAttachmentInfo[attachmentNdx];
1892 }
getDepthStencilAttachmentLayout(void) const1893 Maybe<VkImageLayout> getDepthStencilAttachmentLayout(void) const
1894 {
1895 return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::Nothing;
1896 }
getDepthStencilAttachmentIndex(void) const1897 Maybe<uint32_t> getDepthStencilAttachmentIndex(void) const
1898 {
1899 return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::Nothing;
1900 }
getDepthStencilAttachment(void) const1901 const Maybe<Attachment> &getDepthStencilAttachment(void) const
1902 {
1903 return m_depthStencilAttachmentInfo;
1904 }
getSubpassFlags(void) const1905 VkSubpassDescriptionFlags getSubpassFlags(void) const
1906 {
1907 return m_flags;
1908 }
1909
1910 private:
1911 UVec2 m_viewportOffset;
1912 UVec2 m_viewportSize;
1913
1914 uint32_t m_subpassIndex;
1915 uint32_t m_drawStartNdx;
1916 bool m_isSecondary;
1917 bool m_omitBlendState;
1918 VkSubpassDescriptionFlags m_flags;
1919
1920 Maybe<RenderQuad> m_renderQuad;
1921 vector<ColorClear> m_colorClears;
1922 Maybe<DepthStencilClear> m_depthStencilClear;
1923
1924 vector<AttachmentReference> m_colorAttachments;
1925 vector<Attachment> m_colorAttachmentInfo;
1926
1927 Maybe<AttachmentReference> m_depthStencilAttachment;
1928 Maybe<Attachment> m_depthStencilAttachmentInfo;
1929
1930 vector<AttachmentReference> m_inputAttachments;
1931 };
1932
findColorAttachments(const RenderPass & renderPassInfo,std::vector<uint32_t> & colorAttachmentIndices,std::vector<VkFormat> & colorAttachmentFormats)1933 void findColorAttachments(const RenderPass &renderPassInfo, std::vector<uint32_t> &colorAttachmentIndices,
1934 std::vector<VkFormat> &colorAttachmentFormats)
1935 {
1936 // make sure that colorAttachmentIndices and colorAttachmentFormats are empty
1937 DE_ASSERT(colorAttachmentIndices.empty() && colorAttachmentFormats.empty());
1938
1939 const auto &allAttachments = renderPassInfo.getAttachments();
1940 const auto &allSubapsses = renderPassInfo.getSubpasses();
1941
1942 // find all unique color attachments
1943 for (const auto &subpass : allSubapsses)
1944 {
1945 for (const auto &colorAttachment : subpass.getColorAttachments())
1946 {
1947 uint32_t index = colorAttachment.getAttachment();
1948
1949 // skip unused attachments
1950 if (index == VK_ATTACHMENT_UNUSED)
1951 continue;
1952
1953 // skip attachments that were already memorized
1954 if (std::find(colorAttachmentIndices.begin(), colorAttachmentIndices.end(), index) !=
1955 colorAttachmentIndices.end())
1956 continue;
1957
1958 colorAttachmentIndices.push_back(index);
1959 colorAttachmentFormats.push_back(allAttachments[index].getFormat());
1960 }
1961 }
1962 }
1963
1964 #ifndef CTS_USES_VULKANSC
1965
findDepthStencilAttachments(const vector<Attachment> & allAttachments,VkFormat & depthFormat,VkFormat & stencilFormat,uint32_t & gloabalDepthAttachmentIndex,uint32_t & gloabalStencilAttachmentIndex)1966 void findDepthStencilAttachments(const vector<Attachment> &allAttachments, VkFormat &depthFormat,
1967 VkFormat &stencilFormat, uint32_t &gloabalDepthAttachmentIndex,
1968 uint32_t &gloabalStencilAttachmentIndex)
1969 {
1970 for (uint32_t i = 0; i < allAttachments.size(); ++i)
1971 {
1972 const auto &attachment = allAttachments[i];
1973 VkFormat vkFormat = attachment.getFormat();
1974 const auto format = mapVkFormat(vkFormat);
1975
1976 if (tcu::hasDepthComponent(format.order))
1977 {
1978 depthFormat = vkFormat;
1979 gloabalDepthAttachmentIndex = i;
1980 }
1981 if (tcu::hasStencilComponent(format.order))
1982 {
1983 stencilFormat = vkFormat;
1984 gloabalStencilAttachmentIndex = i;
1985 }
1986 }
1987 }
1988
fillRenderingAttachmentLocationsInfo(const std::vector<AttachmentReference> & subpassColorAttachments,const std::vector<uint32_t> & colorAttachmentIndices,std::vector<uint32_t> & colorAttachmentLocations,VkRenderingAttachmentLocationInfoKHR & renderingAttachmentLocationInfo)1989 void fillRenderingAttachmentLocationsInfo(const std::vector<AttachmentReference> &subpassColorAttachments,
1990 const std::vector<uint32_t> &colorAttachmentIndices,
1991 std::vector<uint32_t> &colorAttachmentLocations,
1992 VkRenderingAttachmentLocationInfoKHR &renderingAttachmentLocationInfo)
1993 {
1994 // make sure that colorAttachmentLocations vector has proper size
1995 DE_ASSERT(colorAttachmentLocations.size() == colorAttachmentIndices.size());
1996
1997 renderingAttachmentLocationInfo.colorAttachmentCount = (uint32_t)colorAttachmentLocations.size();
1998 renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
1999
2000 // fill color attachment locations for specified subpass
2001 for (uint32_t i = 0; i < (uint32_t)subpassColorAttachments.size(); ++i)
2002 {
2003 // translate index from list of all attachments to index in list of color attachments
2004 uint32_t index = subpassColorAttachments[i].getAttachment();
2005 for (uint32_t cai = 0; cai < (uint32_t)colorAttachmentIndices.size(); ++cai)
2006 {
2007 if (index != colorAttachmentIndices[cai])
2008 continue;
2009 colorAttachmentLocations[cai] = i;
2010 break;
2011 }
2012 }
2013 }
2014
fillRenderingInputAttachmentIndexInfo(const std::vector<AttachmentReference> & subpassInputAttachments,const std::vector<uint32_t> & colorAttachmentIndices,uint32_t globalDdepthAttachmentIndex,uint32_t globalStencilAttachmentIndex,uint32_t & localDepthAttachmentIndex,uint32_t & localStencilAttachmentIndex,std::vector<uint32_t> & colorAttachmentInputIndices,VkRenderingInputAttachmentIndexInfoKHR & renderingInputAttachmentIndexInfo)2015 void fillRenderingInputAttachmentIndexInfo(const std::vector<AttachmentReference> &subpassInputAttachments,
2016 const std::vector<uint32_t> &colorAttachmentIndices,
2017 uint32_t globalDdepthAttachmentIndex, uint32_t globalStencilAttachmentIndex,
2018 uint32_t &localDepthAttachmentIndex, uint32_t &localStencilAttachmentIndex,
2019 std::vector<uint32_t> &colorAttachmentInputIndices,
2020 VkRenderingInputAttachmentIndexInfoKHR &renderingInputAttachmentIndexInfo)
2021 {
2022 localDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
2023 localStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2024
2025 for (uint32_t i = 0; i < (uint32_t)subpassInputAttachments.size(); ++i)
2026 {
2027 uint32_t index = subpassInputAttachments[i].getAttachment();
2028
2029 if (index == globalDdepthAttachmentIndex)
2030 localDepthAttachmentIndex = i;
2031 if (index == globalStencilAttachmentIndex)
2032 localStencilAttachmentIndex = i;
2033
2034 // translate index from list of all attachments to index in list of color attachments
2035 for (uint32_t cai = 0; cai < (uint32_t)colorAttachmentIndices.size(); ++cai)
2036 {
2037 if (index != colorAttachmentIndices[cai])
2038 continue;
2039 colorAttachmentInputIndices[cai] = i;
2040 break;
2041 }
2042 }
2043
2044 renderingInputAttachmentIndexInfo.colorAttachmentCount = (uint32_t)colorAttachmentInputIndices.size();
2045 renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputIndices.data();
2046 renderingInputAttachmentIndexInfo.pDepthInputAttachmentIndex =
2047 (globalDdepthAttachmentIndex == VK_ATTACHMENT_UNUSED) ? DE_NULL : &localDepthAttachmentIndex;
2048 renderingInputAttachmentIndexInfo.pStencilInputAttachmentIndex =
2049 (globalStencilAttachmentIndex == VK_ATTACHMENT_UNUSED) ? DE_NULL : &localStencilAttachmentIndex;
2050 }
2051
prepareAttachmentRemapping(const Subpass & subpass,const std::vector<Attachment> & allAttachments,const std::vector<uint32_t> & colorAttachmentIndices,std::vector<uint32_t> & colorAttachmentLocations,std::vector<uint32_t> & colorAttachmentInputIndices,uint32_t & localDepthAttachmentIndex,uint32_t & localStencilAttachmentIndex,VkRenderingAttachmentLocationInfoKHR & renderingAttachmentLocationInfo,VkRenderingInputAttachmentIndexInfoKHR & renderingInputAttachmentIndexInfo)2052 void prepareAttachmentRemapping(const Subpass &subpass, const std::vector<Attachment> &allAttachments,
2053 const std::vector<uint32_t> &colorAttachmentIndices,
2054 std::vector<uint32_t> &colorAttachmentLocations,
2055 std::vector<uint32_t> &colorAttachmentInputIndices, uint32_t &localDepthAttachmentIndex,
2056 uint32_t &localStencilAttachmentIndex,
2057 VkRenderingAttachmentLocationInfoKHR &renderingAttachmentLocationInfo,
2058 VkRenderingInputAttachmentIndexInfoKHR &renderingInputAttachmentIndexInfo)
2059 {
2060 VkFormat depthFormat = VK_FORMAT_UNDEFINED;
2061 VkFormat stencilFormat = VK_FORMAT_UNDEFINED;
2062 uint32_t globalDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
2063 uint32_t globalStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2064
2065 findDepthStencilAttachments(allAttachments, depthFormat, stencilFormat, globalDepthAttachmentIndex,
2066 globalStencilAttachmentIndex);
2067
2068 fillRenderingAttachmentLocationsInfo(subpass.getColorAttachments(), colorAttachmentIndices,
2069 colorAttachmentLocations, renderingAttachmentLocationInfo);
2070
2071 fillRenderingInputAttachmentIndexInfo(subpass.getInputAttachments(), colorAttachmentIndices,
2072 globalDepthAttachmentIndex, globalStencilAttachmentIndex,
2073 localDepthAttachmentIndex, localStencilAttachmentIndex,
2074 colorAttachmentInputIndices, renderingInputAttachmentIndexInfo);
2075 }
2076
2077 #endif // CTS_USES_VULKANSC
2078
beginCommandBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkRenderPass pInheritanceInfo_renderPass,uint32_t pInheritanceInfo_subpass,VkFramebuffer pInheritanceInfo_framebuffer,VkBool32 pInheritanceInfo_occlusionQueryEnable,VkQueryControlFlags pInheritanceInfo_queryFlags,VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics,const RenderPass * pRenderPassInfo=0,const SubpassRenderInfo * pSubpassInfo=0,bool dynamicRenderPass=false,bool secondaryCmdBufferCompletelyContainsRenderpass=false)2079 void beginCommandBuffer(const DeviceInterface &vk, VkCommandBuffer cmdBuffer, VkRenderPass pInheritanceInfo_renderPass,
2080 uint32_t pInheritanceInfo_subpass, VkFramebuffer pInheritanceInfo_framebuffer,
2081 VkBool32 pInheritanceInfo_occlusionQueryEnable, VkQueryControlFlags pInheritanceInfo_queryFlags,
2082 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics,
2083 const RenderPass *pRenderPassInfo = 0, const SubpassRenderInfo *pSubpassInfo = 0,
2084 bool dynamicRenderPass = false, bool secondaryCmdBufferCompletelyContainsRenderpass = false)
2085 {
2086 VkCommandBufferUsageFlags usageFlags = (VkCommandBufferUsageFlags)0;
2087 VkCommandBufferInheritanceInfo pInheritanceInfo{
2088 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2089 DE_NULL,
2090 pInheritanceInfo_renderPass,
2091 pInheritanceInfo_subpass,
2092 pInheritanceInfo_framebuffer,
2093 pInheritanceInfo_occlusionQueryEnable,
2094 pInheritanceInfo_queryFlags,
2095 pInheritanceInfo_pipelineStatistics,
2096 };
2097
2098 #ifndef CTS_USES_VULKANSC
2099
2100 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo = initVulkanStructure();
2101 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
2102 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo =
2103 initVulkanStructure(&renderingAttachmentLocationInfo);
2104 std::vector<uint32_t> colorAttachmentIndices;
2105 std::vector<VkFormat> colorAttachmentFormats;
2106 std::vector<uint32_t> colorAttachmentLocations;
2107 std::vector<uint32_t> colorAttachmentInputIndices;
2108 uint32_t localDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
2109 uint32_t localStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2110
2111 if (dynamicRenderPass && pSubpassInfo)
2112 {
2113 findColorAttachments(*pRenderPassInfo, colorAttachmentIndices, colorAttachmentFormats);
2114
2115 const auto subpassIndex = pSubpassInfo->getSubpassIndex();
2116 const auto &allAttachments = pRenderPassInfo->getAttachments();
2117 const auto &subpass = pRenderPassInfo->getSubpasses()[subpassIndex];
2118 uint32_t colorAttachmentCount = (uint32_t)colorAttachmentIndices.size();
2119
2120 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
2121 {
2122 colorAttachmentLocations.push_back(VK_ATTACHMENT_UNUSED);
2123 colorAttachmentInputIndices.push_back(VK_ATTACHMENT_UNUSED);
2124 }
2125
2126 if (secondaryCmdBufferCompletelyContainsRenderpass)
2127 inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2128 else
2129 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2130
2131 inheritanceRenderingInfo.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentFormats.size());
2132 inheritanceRenderingInfo.pColorAttachmentFormats = colorAttachmentFormats.data();
2133 if (pSubpassInfo->getDepthStencilAttachment())
2134 {
2135 const VkFormat dsFormat = pSubpassInfo->getDepthStencilAttachment()->getFormat();
2136 inheritanceRenderingInfo.depthAttachmentFormat =
2137 tcu::hasDepthComponent(mapVkFormat(dsFormat).order) ? dsFormat : VK_FORMAT_UNDEFINED;
2138 inheritanceRenderingInfo.stencilAttachmentFormat =
2139 tcu::hasStencilComponent(mapVkFormat(dsFormat).order) ? dsFormat : VK_FORMAT_UNDEFINED;
2140 }
2141
2142 if (pSubpassInfo->getColorAttachmentCount())
2143 inheritanceRenderingInfo.rasterizationSamples = pSubpassInfo->getColorAttachment(0).getSamples();
2144 else if (pSubpassInfo->getDepthStencilAttachment())
2145 inheritanceRenderingInfo.rasterizationSamples = pSubpassInfo->getDepthStencilAttachment()->getSamples();
2146 else
2147 inheritanceRenderingInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2148
2149 pInheritanceInfo.pNext = &inheritanceRenderingInfo;
2150
2151 if (subpassIndex > 0)
2152 {
2153 prepareAttachmentRemapping(subpass, allAttachments, colorAttachmentIndices, colorAttachmentLocations,
2154 colorAttachmentInputIndices, localDepthAttachmentIndex,
2155 localStencilAttachmentIndex, renderingAttachmentLocationInfo,
2156 renderingInputAttachmentIndexInfo);
2157
2158 inheritanceRenderingInfo.pNext = &renderingInputAttachmentIndexInfo;
2159 }
2160 }
2161 else if (!secondaryCmdBufferCompletelyContainsRenderpass)
2162 usageFlags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2163 #else
2164
2165 DE_UNREF(pRenderPassInfo);
2166 DE_UNREF(pSubpassInfo);
2167 DE_UNREF(dynamicRenderPass);
2168 DE_UNREF(secondaryCmdBufferCompletelyContainsRenderpass);
2169
2170 usageFlags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2171
2172 #endif // CTS_USES_VULKANSC
2173
2174 const VkCommandBufferBeginInfo pBeginInfo{
2175 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2176 DE_NULL,
2177 usageFlags,
2178 &pInheritanceInfo,
2179 };
2180 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
2181 }
2182
2183 #ifndef CTS_USES_VULKANSC
beginDynamicRendering(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const RenderPass & renderPassInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const VkRect2D & renderArea,const vector<Maybe<VkClearValue>> & renderPassClearValues,const VkRenderingFlagsKHR renderingFlags=0u)2184 void beginDynamicRendering(const DeviceInterface &vk, VkCommandBuffer commandBuffer, const RenderPass &renderPassInfo,
2185 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
2186 const VkRect2D &renderArea, const vector<Maybe<VkClearValue>> &renderPassClearValues,
2187 const VkRenderingFlagsKHR renderingFlags = 0u)
2188 {
2189 const float clearNan = tcu::Float32::nan().asFloat();
2190 const VkClearValue clearValueNan = makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan);
2191 const auto &allSubpasses = renderPassInfo.getSubpasses();
2192
2193 // define helper lambda that will check if attachment is used as an input for one of subpasses
2194 auto isAttachmentUsedAsInput = [&allSubpasses](uint32_t attachment)
2195 {
2196 for (const auto &subpass : allSubpasses)
2197 {
2198 for (const auto &inputAttachment : subpass.getInputAttachments())
2199 {
2200 if (inputAttachment.getAttachment() == attachment)
2201 return true;
2202 }
2203 }
2204 return false;
2205 };
2206
2207 // find all color attachments and their resolve attachments
2208 struct ColorAttachmentData
2209 {
2210 uint32_t colorAttachmentIndex;
2211 VkImageLayout colorImageLayout;
2212 uint32_t resolveAttachmentIndex;
2213 VkImageLayout resolveImageLayout;
2214
2215 // constructor needed for emplace_back
2216 ColorAttachmentData(uint32_t ci, VkImageLayout cl, uint32_t ri, VkImageLayout rl)
2217 : colorAttachmentIndex(ci)
2218 , colorImageLayout(cl)
2219 , resolveAttachmentIndex(ri)
2220 , resolveImageLayout(rl)
2221 {
2222 }
2223 };
2224 std::vector<ColorAttachmentData> colorAttachmentsData;
2225 for (const auto &subpass : allSubpasses)
2226 {
2227 const auto &colorAttachmentsInfo = subpass.getColorAttachments();
2228 const auto &resolveAttachmentsInfo = subpass.getResolveAttachments();
2229
2230 for (uint32_t i = 0; i < (uint32_t)colorAttachmentsInfo.size(); ++i)
2231 {
2232 const AttachmentReference *colorAttachment = &colorAttachmentsInfo[i];
2233 uint32_t colorAttachmentIndex = colorAttachment->getAttachment();
2234
2235 // check if this attachment is already in colorAttachmentsData,
2236 // we are interested only in first occurrence
2237 bool skipAttachement = false;
2238 for (const auto &cad : colorAttachmentsData)
2239 {
2240 skipAttachement = (colorAttachmentIndex == cad.colorAttachmentIndex);
2241 if (skipAttachement)
2242 break;
2243 }
2244 if (skipAttachement)
2245 continue;
2246
2247 VkImageLayout colorImageLayout = colorAttachment->getImageLayout();
2248 if (isAttachmentUsedAsInput(colorAttachmentIndex))
2249 colorImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2250
2251 uint32_t resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
2252 VkImageLayout resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2253 if (!resolveAttachmentsInfo.empty())
2254 {
2255 // assume that if there are resolve attachments then there will be
2256 // as much of them as there are color attachments and index will match
2257 DE_ASSERT(colorAttachmentsInfo.size() == resolveAttachmentsInfo.size());
2258
2259 resolveAttachmentIndex = resolveAttachmentsInfo[i].getAttachment();
2260 resolveImageLayout = resolveAttachmentsInfo[i].getImageLayout();
2261 if (isAttachmentUsedAsInput(resolveAttachmentIndex))
2262 resolveImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2263 }
2264
2265 colorAttachmentsData.emplace_back(colorAttachmentIndex, colorImageLayout, resolveAttachmentIndex,
2266 resolveImageLayout);
2267 }
2268 }
2269
2270 // alocate space for all needed rendering attachments
2271 VkRenderingAttachmentInfoKHR depthAttachment{
2272 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2273 DE_NULL, // const void* pNext;
2274 DE_NULL, // VkImageView imageView;
2275 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2276 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2277 DE_NULL, // VkImageView resolveImageView;
2278 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2279 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2280 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2281 clearValueNan // VkClearValue clearValue;
2282 };
2283 VkRenderingAttachmentInfoKHR stencilAttachment = depthAttachment;
2284 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachmentVect(colorAttachmentsData.size(), depthAttachment);
2285
2286 // translate structures that were prepared to construct renderpass object to structures needed for dynamic rendering
2287 const auto &allAttachments = renderPassInfo.getAttachments();
2288 for (uint32_t i = 0; i < (uint32_t)colorAttachmentsData.size(); ++i)
2289 {
2290 auto &colorAttachment = colorAttachmentVect[i];
2291 const auto &colorAttachmentData = colorAttachmentsData[i];
2292 const uint32_t colorAttachmentIndex = colorAttachmentData.colorAttachmentIndex;
2293 const uint32_t resolveAttachmentIndex = colorAttachmentData.resolveAttachmentIndex;
2294
2295 colorAttachment.imageView = attachmentResources[colorAttachmentIndex]->getAttachmentView();
2296 colorAttachment.imageLayout = colorAttachmentData.colorImageLayout;
2297 colorAttachment.loadOp = allAttachments[colorAttachmentIndex].getLoadOp();
2298 colorAttachment.storeOp = allAttachments[colorAttachmentIndex].getStoreOp();
2299
2300 if (renderPassClearValues[colorAttachmentIndex])
2301 colorAttachment.clearValue = *renderPassClearValues[colorAttachmentIndex];
2302
2303 if (resolveAttachmentIndex != VK_ATTACHMENT_UNUSED)
2304 {
2305 colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
2306 colorAttachment.resolveImageView = attachmentResources[resolveAttachmentIndex]->getAttachmentView();
2307 colorAttachment.resolveImageLayout = colorAttachmentData.resolveImageLayout;
2308 }
2309 }
2310
2311 uint32_t dsAttachmentIndex = VK_ATTACHMENT_UNUSED;
2312 VkImageLayout dsAttachmentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2313 VkRenderingAttachmentInfoKHR *pDepthAttachment = DE_NULL;
2314 VkRenderingAttachmentInfoKHR *pStencilAttachment = DE_NULL;
2315
2316 // find depth/stencil attachment and translate its data to dynamic rendering attachment
2317 for (const Subpass &subpass : allSubpasses)
2318 {
2319 const auto &depthStencilAttachmentReference = subpass.getDepthStencilAttachment();
2320 dsAttachmentIndex = depthStencilAttachmentReference.getAttachment();
2321 dsAttachmentLayout = depthStencilAttachmentReference.getImageLayout();
2322 if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
2323 break;
2324 }
2325
2326 if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
2327 {
2328 const Attachment &dsAttachmentInfo = allAttachments[dsAttachmentIndex];
2329 const tcu::TextureFormat format = mapVkFormat(dsAttachmentInfo.getFormat());
2330
2331 if (tcu::hasDepthComponent(format.order))
2332 {
2333 depthAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2334 depthAttachment.imageLayout = dsAttachmentLayout;
2335 depthAttachment.loadOp = dsAttachmentInfo.getLoadOp();
2336 depthAttachment.storeOp = dsAttachmentInfo.getStoreOp();
2337
2338 if (isAttachmentUsedAsInput(dsAttachmentIndex))
2339 depthAttachment.imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2340 if (renderPassClearValues[dsAttachmentIndex])
2341 depthAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2342
2343 pDepthAttachment = &depthAttachment;
2344 }
2345
2346 if (tcu::hasStencilComponent(format.order))
2347 {
2348 stencilAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2349 stencilAttachment.imageLayout = dsAttachmentLayout;
2350 stencilAttachment.loadOp = dsAttachmentInfo.getStencilLoadOp();
2351 stencilAttachment.storeOp = dsAttachmentInfo.getStencilStoreOp();
2352
2353 if (isAttachmentUsedAsInput(dsAttachmentIndex))
2354 stencilAttachment.imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2355 if (renderPassClearValues[dsAttachmentIndex])
2356 stencilAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2357
2358 pStencilAttachment = &stencilAttachment;
2359 }
2360 }
2361
2362 VkRenderingInfoKHR renderingInfo{
2363 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2364 DE_NULL,
2365 renderingFlags, // VkRenderingFlagsKHR flags;
2366 renderArea, // VkRect2D renderArea;
2367 1u, // uint32_t layerCount;
2368 0u, // uint32_t viewMask;
2369 static_cast<uint32_t>(colorAttachmentVect.size()), // uint32_t colorAttachmentCount;
2370 de::dataOrNull(colorAttachmentVect), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2371 pDepthAttachment, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2372 pStencilAttachment // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2373 };
2374
2375 vk.cmdBeginRendering(commandBuffer, &renderingInfo);
2376 }
2377
endDynamicRendering(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2378 void endDynamicRendering(const DeviceInterface &vk, VkCommandBuffer commandBuffer)
2379 {
2380 vk.cmdEndRendering(commandBuffer);
2381 }
2382
2383 #endif // CTS_USES_VULKANSC
2384
2385 class SubpassRenderer
2386 {
2387 public:
SubpassRenderer(Context & context,const DeviceInterface & vk,VkDevice device,Allocator & allocator,const RenderPass & renderPassInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const VkRect2D & renderArea,const vector<Maybe<VkClearValue>> & renderPassClearValues,VkRenderPass renderPass,VkFramebuffer framebuffer,VkCommandPool commandBufferPool,uint32_t queueFamilyIndex,const vector<VkImage> & attachmentImages,const vector<pair<VkImageView,VkImageView>> & attachmentViews,const SubpassRenderInfo & renderInfo,const TestConfig & config)2388 SubpassRenderer(Context &context, const DeviceInterface &vk, VkDevice device, Allocator &allocator,
2389 const RenderPass &renderPassInfo,
2390 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources, const VkRect2D &renderArea,
2391 const vector<Maybe<VkClearValue>> &renderPassClearValues, VkRenderPass renderPass,
2392 VkFramebuffer framebuffer, VkCommandPool commandBufferPool, uint32_t queueFamilyIndex,
2393 const vector<VkImage> &attachmentImages,
2394 const vector<pair<VkImageView, VkImageView>> &attachmentViews, const SubpassRenderInfo &renderInfo,
2395 const TestConfig &config)
2396 : m_renderInfo(renderInfo)
2397 , m_renderPassInfo(renderPassInfo)
2398 , m_pipeline(context.getInstanceInterface(), vk, context.getPhysicalDevice(), device,
2399 context.getDeviceExtensions(), config.groupParams->pipelineConstructionType)
2400 {
2401 // unreference values not used by Vulkan SC, no need to put this under ifdef
2402 DE_UNREF(attachmentResources);
2403 DE_UNREF(renderArea);
2404 DE_UNREF(renderPassClearValues);
2405
2406 const InstanceInterface &vki = context.getInstanceInterface();
2407 const VkPhysicalDevice &physDevice = context.getPhysicalDevice();
2408 const vector<Attachment> &attachmentInfos = m_renderPassInfo.getAttachments();
2409 const uint32_t subpassIndex = renderInfo.getSubpassIndex();
2410 const bool dynamicRendering(config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
2411 vector<VkDescriptorSetLayoutBinding> bindings;
2412
2413 for (uint32_t colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();
2414 colorAttachmentNdx++)
2415 {
2416 const uint32_t attachmentNdx =
2417 (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ?
2418 colorAttachmentNdx :
2419 renderInfo.getColorAttachmentIndex(colorAttachmentNdx);
2420
2421 m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
2422 }
2423
2424 if (renderInfo.getDepthStencilAttachmentIndex())
2425 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
2426
2427 if (renderInfo.getRenderQuad())
2428 {
2429 const RenderQuad &renderQuad = *renderInfo.getRenderQuad();
2430
2431 if (renderInfo.getInputAttachmentCount() > 0)
2432 {
2433 uint32_t bindingIndex = 0;
2434
2435 for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount();
2436 inputAttachmentNdx++)
2437 {
2438 const Attachment attachmentInfo =
2439 attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2440 const VkImageLayout layout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2441 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2442 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2443 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2444 const uint32_t bindingCount =
2445 (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) &&
2446 (isStencilFormat &&
2447 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) ?
2448 2u :
2449 1u;
2450
2451 for (uint32_t bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
2452 {
2453 const VkDescriptorSetLayoutBinding binding = {bindingIndex,
2454 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u,
2455 vk::VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL};
2456
2457 bindings.push_back(binding);
2458 bindingIndex++;
2459 }
2460 }
2461
2462 const VkDescriptorSetLayoutCreateInfo createInfo = {
2463 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, DE_NULL,
2464
2465 0u, (uint32_t)bindings.size(), &bindings[0]};
2466
2467 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
2468 }
2469
2470 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
2471
2472 m_vertexShaderModule =
2473 ShaderWrapper(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
2474 m_fragmentShaderModule =
2475 ShaderWrapper(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
2476 m_pipelineLayout = PipelineLayoutWrapper(config.groupParams->pipelineConstructionType, vk, device,
2477 (m_descriptorSetLayout ? descriptorSetLayout : DE_NULL));
2478 createSubpassPipeline(renderPass);
2479
2480 // Round up the vertex buffer size to honor nonCoherentAtomSize.
2481 const auto properties =
2482 vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2483 const auto vertexBufferSize = de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()),
2484 properties.limits.nonCoherentAtomSize);
2485
2486 m_vertexBuffer = createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
2487 VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2488 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer,
2489 MemoryRequirement::HostVisible, allocator, config.allocationKind);
2490
2491 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(),
2492 m_vertexBufferMemory->getOffset());
2493
2494 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(),
2495 renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);
2496
2497 if (renderInfo.getInputAttachmentCount() > 0)
2498 {
2499 {
2500 const VkDescriptorPoolSize poolSize = {
2501 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2502 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2503 renderInfo.getInputAttachmentCount() * 2u};
2504 const VkDescriptorPoolCreateInfo createInfo = {
2505 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, DE_NULL,
2506 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2507
2508 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2509 renderInfo.getInputAttachmentCount() * 2u, 1u, &poolSize};
2510
2511 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2512 }
2513 {
2514 const VkDescriptorSetAllocateInfo allocateInfo = {
2515 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, DE_NULL,
2516
2517 *m_descriptorPool, 1u, &descriptorSetLayout};
2518
2519 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2520 }
2521 {
2522 vector<VkWriteDescriptorSet> writes(bindings.size());
2523 vector<VkDescriptorImageInfo> imageInfos(bindings.size());
2524 uint32_t bindingIndex = 0;
2525
2526 for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount();
2527 inputAttachmentNdx++)
2528 {
2529 const Attachment attachmentInfo =
2530 attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2531 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2532 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2533 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2534 VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2535
2536 if (isDepthFormat && isStencilFormat)
2537 {
2538 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2539 {
2540 imageInfos[bindingIndex] = {
2541 (VkSampler)0,
2542 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2543 inputAttachmentLayout};
2544 #ifndef CTS_USES_VULKANSC
2545 if (dynamicRendering)
2546 imageInfos[bindingIndex].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2547 #endif
2548 {
2549 const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2550 DE_NULL,
2551
2552 *m_descriptorSet,
2553 bindingIndex,
2554 0u,
2555 1u,
2556 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2557 &imageInfos[bindingIndex],
2558 DE_NULL,
2559 DE_NULL};
2560 writes[bindingIndex] = write;
2561
2562 bindingIndex++;
2563 }
2564 }
2565
2566 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2567 {
2568 imageInfos[bindingIndex] = {
2569 (VkSampler)0,
2570 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2571 inputAttachmentLayout};
2572 #ifndef CTS_USES_VULKANSC
2573 if (dynamicRendering)
2574 imageInfos[bindingIndex].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2575 #endif
2576 {
2577 const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2578 DE_NULL,
2579
2580 *m_descriptorSet,
2581 bindingIndex,
2582 0u,
2583 1u,
2584 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2585 &imageInfos[bindingIndex],
2586 DE_NULL,
2587 DE_NULL};
2588 writes[bindingIndex] = write;
2589
2590 bindingIndex++;
2591 }
2592 }
2593 }
2594 else
2595 {
2596 imageInfos[bindingIndex] = {
2597 (VkSampler)0,
2598 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2599 inputAttachmentLayout};
2600 #ifndef CTS_USES_VULKANSC
2601 if (dynamicRendering)
2602 imageInfos[bindingIndex].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2603 #endif
2604 {
2605 const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2606 DE_NULL,
2607
2608 *m_descriptorSet,
2609 bindingIndex,
2610 0u,
2611 1u,
2612 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2613 &imageInfos[bindingIndex],
2614 DE_NULL,
2615 DE_NULL};
2616 writes[bindingIndex] = write;
2617
2618 bindingIndex++;
2619 }
2620 }
2621 }
2622
2623 vk.updateDescriptorSets(device, (uint32_t)writes.size(), &writes[0], 0u, DE_NULL);
2624 }
2625 }
2626 }
2627
2628 if (renderInfo.isSecondary())
2629 {
2630 bool secondaryCmdBufferCompletelyContainsDynamicRenderpass =
2631 (config.commandBufferTypes == TestConfig::COMMANDBUFFERTYPES_SECONDARY) &&
2632 config.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass;
2633
2634 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2635
2636 beginCommandBuffer(vk, *m_commandBuffer, renderPass, subpassIndex, framebuffer, VK_FALSE,
2637 (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0, &m_renderPassInfo, &renderInfo,
2638 dynamicRendering, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
2639
2640 if (dynamicRendering && secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2641 {
2642 #ifndef CTS_USES_VULKANSC
2643 beginDynamicRendering(vk, *m_commandBuffer, m_renderPassInfo, attachmentResources, renderArea,
2644 renderPassClearValues);
2645 pushRenderCommands(vk, *m_commandBuffer, true, dynamicRendering);
2646 endDynamicRendering(vk, *m_commandBuffer);
2647 #endif // CTS_USES_VULKANSC
2648 }
2649 else
2650 pushRenderCommands(vk, *m_commandBuffer, true, dynamicRendering);
2651
2652 endCommandBuffer(vk, *m_commandBuffer);
2653 }
2654 }
2655
isSecondary(void) const2656 bool isSecondary(void) const
2657 {
2658 return !!m_commandBuffer;
2659 }
2660
getCommandBuffer(void) const2661 VkCommandBuffer getCommandBuffer(void) const
2662 {
2663 DE_ASSERT(isSecondary());
2664 return *m_commandBuffer;
2665 }
2666
pushRenderCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const bool secondaryCommandBuffer,const bool dynamicRendering)2667 void pushRenderCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer, const bool secondaryCommandBuffer,
2668 const bool dynamicRendering)
2669 {
2670 DE_UNREF(secondaryCommandBuffer);
2671
2672 VkImageLayout inputAttachmenLayout = VK_IMAGE_LAYOUT_GENERAL;
2673
2674 std::vector<uint32_t> colorAttachmentIndices;
2675 std::vector<VkFormat> colorAttachmentFormats;
2676 findColorAttachments(m_renderPassInfo, colorAttachmentIndices, colorAttachmentFormats);
2677
2678 #ifndef CTS_USES_VULKANSC
2679 if (dynamicRendering && (m_renderPassInfo.getSubpasses().size() > 1u))
2680 {
2681 inputAttachmenLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2682 if (!secondaryCommandBuffer)
2683 {
2684 const uint32_t subpassIndex = m_renderInfo.getSubpassIndex();
2685 const std::vector<Subpass> &allSubapsses = m_renderPassInfo.getSubpasses();
2686 const auto &allAttachments = m_renderPassInfo.getAttachments();
2687 const auto &subpass = allSubapsses[subpassIndex];
2688 uint32_t colorAttachmentCount = (uint32_t)colorAttachmentIndices.size();
2689 std::vector<uint32_t> colorAttachmentLocations(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
2690 std::vector<uint32_t> colorAttachmentInputIndices(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
2691 uint32_t localDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
2692 uint32_t localStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2693 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
2694 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
2695
2696 prepareAttachmentRemapping(subpass, allAttachments, colorAttachmentIndices, colorAttachmentLocations,
2697 colorAttachmentInputIndices, localDepthAttachmentIndex,
2698 localStencilAttachmentIndex, renderingAttachmentLocationInfo,
2699 renderingInputAttachmentIndexInfo);
2700
2701 vk.cmdSetRenderingAttachmentLocationsKHR(commandBuffer, &renderingAttachmentLocationInfo);
2702 vk.cmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, &renderingInputAttachmentIndexInfo);
2703 }
2704 }
2705 #endif // CTS_USES_VULKANSC
2706
2707 if (!m_renderInfo.getColorClears().empty())
2708 {
2709 const vector<ColorClear> &colorClears(m_renderInfo.getColorClears());
2710
2711 for (uint32_t attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2712 {
2713 uint32_t colorAttachment = attachmentNdx;
2714
2715 // for dynamic rendering we need to translate color attachment index from list of all attachments
2716 // to index related to all color attachments specified in dynammic renderpass
2717 if (dynamicRendering)
2718 {
2719 for (colorAttachment = 0; colorAttachment < colorAttachmentIndices.size(); colorAttachment++)
2720 {
2721 if (colorAttachmentIndices[colorAttachment] ==
2722 m_renderInfo.getColorAttachmentIndex(attachmentNdx))
2723 break;
2724 }
2725 }
2726
2727 const ColorClear &colorClear = colorClears[attachmentNdx];
2728 const VkClearAttachment attachment{
2729 VK_IMAGE_ASPECT_COLOR_BIT,
2730 colorAttachment,
2731 makeClearValue(colorClear.getColor()),
2732 };
2733 const VkClearRect rect{
2734 {{(int32_t)colorClear.getOffset().x(), (int32_t)colorClear.getOffset().y()},
2735 {colorClear.getSize().x(), colorClear.getSize().y()}}, // rect
2736 0u, // baseArrayLayer
2737 1u, // layerCount
2738 };
2739
2740 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2741 }
2742 }
2743
2744 if (m_renderInfo.getDepthStencilClear())
2745 {
2746 const DepthStencilClear &depthStencilClear = *m_renderInfo.getDepthStencilClear();
2747 const uint32_t attachmentNdx = m_renderInfo.getColorAttachmentCount();
2748 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2749 const VkImageLayout layout = *m_renderInfo.getDepthStencilAttachmentLayout();
2750 const VkClearAttachment attachment = {
2751 (VkImageAspectFlags)((hasDepthComponent(format.order) &&
2752 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ?
2753 VK_IMAGE_ASPECT_DEPTH_BIT :
2754 0) |
2755 (hasStencilComponent(format.order) &&
2756 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ?
2757 VK_IMAGE_ASPECT_STENCIL_BIT :
2758 0)),
2759 attachmentNdx,
2760 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())};
2761 const VkClearRect rect = {
2762 {{(int32_t)depthStencilClear.getOffset().x(), (int32_t)depthStencilClear.getOffset().y()},
2763 {depthStencilClear.getSize().x(), depthStencilClear.getSize().y()}}, // rect
2764 0u, // baseArrayLayer
2765 1u, // layerCount
2766 };
2767
2768 if ((tcu::hasDepthComponent(format.order) &&
2769 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) ||
2770 (tcu::hasStencilComponent(format.order) &&
2771 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
2772 {
2773 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2774 }
2775 }
2776
2777 vector<VkImageMemoryBarrier> selfDeps;
2778 VkPipelineStageFlags srcStages = 0;
2779 VkPipelineStageFlags dstStages = 0;
2780
2781 for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount();
2782 inputAttachmentNdx++)
2783 {
2784 for (uint32_t colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount();
2785 colorAttachmentNdx++)
2786 {
2787 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) ==
2788 m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2789 {
2790 const VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2791 DE_NULL, // pNext
2792
2793 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2794 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2795
2796 inputAttachmenLayout, // oldLayout
2797 inputAttachmenLayout, // newLayout
2798
2799 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2800 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2801
2802 m_colorAttachmentImages[colorAttachmentNdx], // image
2803 {
2804 // subresourceRange
2805 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2806 0, // baseMipLevel
2807 1, // mipLevels
2808 0, // baseArraySlice
2809 1 // arraySize
2810 }};
2811
2812 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2813 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2814
2815 selfDeps.push_back(barrier);
2816 }
2817 }
2818
2819 if (m_renderInfo.getDepthStencilAttachmentIndex() &&
2820 (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) ==
2821 *m_renderInfo.getDepthStencilAttachmentIndex()))
2822 {
2823 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2824 const bool hasDepth = hasDepthComponent(format.order);
2825 const bool hasStencil = hasStencilComponent(format.order);
2826 const VkImageMemoryBarrier barrier = {
2827 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2828 DE_NULL, // pNext;
2829
2830 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2831 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2832
2833 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // oldLayout
2834 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // newLayout;
2835
2836 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2837 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2838
2839 m_depthStencilAttachmentImage, // image;
2840 {
2841 // subresourceRange;
2842 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
2843 (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2844 0, // baseMipLevel;
2845 1, // mipLevels;
2846 0, // baseArraySlice;
2847 1 // arraySize;
2848 }};
2849
2850 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2851 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2852
2853 selfDeps.push_back(barrier);
2854 }
2855 }
2856
2857 if (!selfDeps.empty())
2858 {
2859 DE_ASSERT(srcStages != 0);
2860 DE_ASSERT(dstStages != 0);
2861 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0,
2862 DE_NULL, (uint32_t)selfDeps.size(), &selfDeps[0]);
2863 }
2864
2865 if (m_renderInfo.getRenderQuad())
2866 {
2867 const VkDeviceSize offset = 0;
2868 const VkBuffer vertexBuffer = *m_vertexBuffer;
2869
2870 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
2871
2872 if (m_descriptorSet)
2873 {
2874 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2875 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u,
2876 &descriptorSet, 0u, NULL);
2877 }
2878
2879 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2880 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2881 }
2882 }
2883
2884 protected:
createSubpassPipeline(VkRenderPass renderPass)2885 void createSubpassPipeline(VkRenderPass renderPass)
2886 {
2887 // At this point we dont know how many blend states we will need
2888 // so we just create maximal number of potentialy needed states
2889 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates(
2890 m_renderPassInfo.getAttachments().size(),
2891 {
2892 VK_FALSE, // blendEnable
2893 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
2894 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
2895 VK_BLEND_OP_ADD, // blendOpColor
2896 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
2897 VK_BLEND_FACTOR_ONE, // destBlendAlpha
2898 VK_BLEND_OP_ADD, // blendOpAlpha
2899 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
2900 VK_COLOR_COMPONENT_A_BIT // colorWriteMask
2901 });
2902
2903 Maybe<VkSampleCountFlagBits> rasterSamples;
2904 for (uint32_t attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2905 {
2906 const Attachment &attachment = m_renderInfo.getColorAttachment(attachmentNdx);
2907
2908 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
2909
2910 rasterSamples = attachment.getSamples();
2911
2912 if (attachmentNdx < m_renderInfo.getDrawStartNdx())
2913 attachmentBlendStates[attachmentNdx].colorWriteMask = (uint32_t)0;
2914 }
2915
2916 if (m_renderInfo.getDepthStencilAttachment())
2917 {
2918 const Attachment &attachment = *m_renderInfo.getDepthStencilAttachment();
2919
2920 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
2921 rasterSamples = attachment.getSamples();
2922 }
2923
2924 // If there are no attachment use single sample
2925 if (!rasterSamples)
2926 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
2927
2928 const VkVertexInputBindingDescription vertexBinding{
2929 0u, // binding
2930 (uint32_t)sizeof(tcu::Vec2), // strideInBytes
2931 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
2932 };
2933
2934 const VkVertexInputAttributeDescription vertexAttrib{
2935 0u, // location
2936 0u, // binding
2937 VK_FORMAT_R32G32_SFLOAT, // format
2938 0u, // offsetInBytes
2939 };
2940
2941 const VkPipelineVertexInputStateCreateInfo vertexInputState{
2942 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
2943 DE_NULL, // pNext
2944 (VkPipelineVertexInputStateCreateFlags)0u,
2945 1u, // bindingCount
2946 &vertexBinding, // pVertexBindingDescriptions
2947 1u, // attributeCount
2948 &vertexAttrib, // pVertexAttributeDescriptions
2949 };
2950
2951 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{
2952 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType
2953 DE_NULL, // const void* pNext
2954 0u, // VkPipelineInputAssemblyStateCreateFlags flags
2955 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology
2956 VK_FALSE // VkBool32 primitiveRestartEnable
2957 };
2958
2959 const std::vector<VkViewport> viewports{
2960 {(float)m_renderInfo.getViewportOffset().x(), (float)m_renderInfo.getViewportOffset().y(),
2961 (float)m_renderInfo.getViewportSize().x(), (float)m_renderInfo.getViewportSize().y(), 0.0f, 1.0f}};
2962
2963 const std::vector<VkRect2D> scissors{
2964 {{(int32_t)m_renderInfo.getViewportOffset().x(), (int32_t)m_renderInfo.getViewportOffset().y()},
2965 {m_renderInfo.getViewportSize().x(), m_renderInfo.getViewportSize().y()}}};
2966
2967 const VkPipelineRasterizationStateCreateInfo rasterizationState{
2968 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
2969 DE_NULL, // const void* pNext
2970 0u, // VkPipelineRasterizationStateCreateFlags flags
2971 VK_FALSE, // VkBool32 depthClampEnable
2972 VK_FALSE, // VkBool32 rasterizerDiscardEnable
2973 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
2974 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
2975 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
2976 VK_FALSE, // VkBool32 depthBiasEnable
2977 0.0f, // float depthBiasConstantFactor
2978 0.0f, // float depthBiasClamp
2979 0.0f, // float depthBiasSlopeFactor
2980 1.0f // float lineWidth
2981 };
2982
2983 const VkPipelineMultisampleStateCreateInfo multisampleState{
2984 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
2985 DE_NULL, // pNext
2986 (VkPipelineMultisampleStateCreateFlags)0u,
2987 *rasterSamples, // rasterSamples
2988 VK_FALSE, // sampleShadingEnable
2989 0.0f, // minSampleShading
2990 DE_NULL, // pSampleMask
2991 VK_FALSE, // alphaToCoverageEnable
2992 VK_FALSE, // alphaToOneEnable
2993 };
2994 const uint32_t subpassIndex = m_renderInfo.getSubpassIndex();
2995
2996 const VkBool32 writeDepth = m_renderInfo.getDepthStencilAttachmentLayout() &&
2997 *m_renderInfo.getDepthStencilAttachmentLayout() !=
2998 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
2999 *m_renderInfo.getDepthStencilAttachmentLayout() !=
3000 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ?
3001 VK_TRUE :
3002 VK_FALSE;
3003
3004 const VkBool32 writeStencil = m_renderInfo.getDepthStencilAttachmentLayout() &&
3005 *m_renderInfo.getDepthStencilAttachmentLayout() !=
3006 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
3007 *m_renderInfo.getDepthStencilAttachmentLayout() !=
3008 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ?
3009 VK_TRUE :
3010 VK_FALSE;
3011
3012 VkStencilOp stencilOp = writeStencil ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP;
3013
3014 const VkPipelineDepthStencilStateCreateInfo depthStencilState{
3015 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
3016 DE_NULL, // pNext
3017 (VkPipelineDepthStencilStateCreateFlags)0u,
3018 writeDepth, // depthTestEnable
3019 writeDepth, // depthWriteEnable
3020 VK_COMPARE_OP_ALWAYS, // depthCompareOp
3021 VK_FALSE, // depthBoundsEnable
3022 writeStencil, // stencilTestEnable
3023 {
3024 stencilOp, // stencilFailOp
3025 stencilOp, // stencilPassOp
3026 stencilOp, // stencilDepthFailOp
3027 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
3028 ~0u, // stencilCompareMask
3029 ~0u, // stencilWriteMask
3030 ((subpassIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
3031 }, // front
3032 {
3033 stencilOp, // stencilFailOp
3034 stencilOp, // stencilPassOp
3035 stencilOp, // stencilDepthFailOp
3036 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
3037 ~0u, // stencilCompareMask
3038 ~0u, // stencilWriteMask
3039 ((subpassIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
3040 }, // back
3041
3042 0.0f, // minDepthBounds;
3043 1.0f // maxDepthBounds;
3044 };
3045
3046 VkPipelineColorBlendStateCreateInfo blendState{
3047 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
3048 DE_NULL, // pNext
3049 (VkPipelineColorBlendStateCreateFlags)0u,
3050 VK_FALSE, // logicOpEnable
3051 VK_LOGIC_OP_COPY, // logicOp
3052 (uint32_t)m_renderInfo.getColorAttachmentCount(), // attachmentCount
3053 de::dataOrNull(attachmentBlendStates), // pAttachments
3054 {0.0f, 0.0f, 0.0f, 0.0f} // blendConst
3055 };
3056
3057 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
3058 RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfoWrapper;
3059 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
3060
3061 #ifndef CTS_USES_VULKANSC
3062
3063 std::vector<uint32_t> colorAttachmentIndices;
3064 std::vector<VkFormat> colorAttachmentFormats;
3065 findColorAttachments(m_renderPassInfo, colorAttachmentIndices, colorAttachmentFormats);
3066
3067 uint32_t colorAttachmentCount = (uint32_t)colorAttachmentFormats.size();
3068 std::vector<uint32_t> colorAttachmentLocations(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
3069 std::vector<uint32_t> colorAttachmentInputIndices(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
3070
3071 VkFormat depthFormat = VK_FORMAT_UNDEFINED;
3072 VkFormat stencilFormat = VK_FORMAT_UNDEFINED;
3073 uint32_t gloabalDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
3074 uint32_t gloabalStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
3075 uint32_t localDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
3076 uint32_t localStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
3077
3078 VkPipelineRenderingCreateInfoKHR renderingCreateInfo = initVulkanStructure();
3079 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
3080 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
3081
3082 if (renderPass == DE_NULL)
3083 {
3084 findDepthStencilAttachments(m_renderPassInfo.getAttachments(), depthFormat, stencilFormat,
3085 gloabalDepthAttachmentIndex, gloabalStencilAttachmentIndex);
3086
3087 renderingCreateInfo.colorAttachmentCount = colorAttachmentCount;
3088 renderingCreateInfo.pColorAttachmentFormats = colorAttachmentFormats.data();
3089 renderingCreateInfo.depthAttachmentFormat = depthFormat;
3090 renderingCreateInfo.stencilAttachmentFormat = stencilFormat;
3091 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
3092
3093 // pColorBlendState->attachmentCount must be equal to VkPipelineRenderingCreateInfo::colorAttachmentCount
3094 blendState.attachmentCount = colorAttachmentCount;
3095
3096 // remap attachments for multi pass tests
3097 const std::vector<Subpass> &allSubapsses = m_renderPassInfo.getSubpasses();
3098 if (allSubapsses.size() > 1u)
3099 {
3100 const auto &subpass = allSubapsses[subpassIndex];
3101 fillRenderingAttachmentLocationsInfo(subpass.getColorAttachments(), colorAttachmentIndices,
3102 colorAttachmentLocations, renderingAttachmentLocationInfo);
3103
3104 fillRenderingInputAttachmentIndexInfo(subpass.getInputAttachments(), colorAttachmentIndices,
3105 gloabalDepthAttachmentIndex, gloabalStencilAttachmentIndex,
3106 localDepthAttachmentIndex, localStencilAttachmentIndex,
3107 colorAttachmentInputIndices, renderingInputAttachmentIndexInfo);
3108
3109 renderingAttachmentLocationInfoWrapper.ptr = &renderingAttachmentLocationInfo;
3110 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
3111 }
3112 }
3113 #endif // CTS_USES_VULKANSC
3114
3115 m_pipeline.setupVertexInputState(&vertexInputState, &inputAssemblyState)
3116 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayout, renderPass, subpassIndex,
3117 m_vertexShaderModule, &rasterizationState, ShaderWrapper(),
3118 ShaderWrapper(), ShaderWrapper(), DE_NULL, DE_NULL,
3119 renderingCreateInfoWrapper)
3120 .setupFragmentShaderState(m_pipelineLayout, renderPass, subpassIndex, m_fragmentShaderModule,
3121 &depthStencilState, &multisampleState, 0, 0, {},
3122 renderingInputAttachmentIndexInfoWrapper)
3123 .setupFragmentOutputState(renderPass, subpassIndex,
3124 (m_renderInfo.getOmitBlendState() ? DE_NULL : &blendState), &multisampleState, 0,
3125 0, renderingAttachmentLocationInfoWrapper)
3126 .setMonolithicPipelineLayout(m_pipelineLayout)
3127 .buildPipeline();
3128 }
3129
3130 private:
3131 const SubpassRenderInfo m_renderInfo;
3132 const RenderPass &m_renderPassInfo;
3133 Move<VkCommandBuffer> m_commandBuffer;
3134 GraphicsPipelineWrapper m_pipeline;
3135 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
3136 PipelineLayoutWrapper m_pipelineLayout;
3137
3138 ShaderWrapper m_vertexShaderModule;
3139 ShaderWrapper m_fragmentShaderModule;
3140
3141 Move<VkDescriptorPool> m_descriptorPool;
3142 Move<VkDescriptorSet> m_descriptorSet;
3143 Move<VkBuffer> m_vertexBuffer;
3144 de::MovePtr<Allocation> m_vertexBufferMemory;
3145 vector<VkImage> m_colorAttachmentImages;
3146 VkImage m_depthStencilAttachmentImage;
3147 };
3148
pushImageInitializationCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const vector<Attachment> & attachmentInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,uint32_t queueIndex,const vector<Maybe<VkClearValue>> & clearValues)3149 void pushImageInitializationCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer,
3150 const vector<Attachment> &attachmentInfo,
3151 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
3152 uint32_t queueIndex, const vector<Maybe<VkClearValue>> &clearValues)
3153 {
3154 {
3155 vector<VkImageMemoryBarrier> initializeLayouts;
3156
3157 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3158 {
3159 if (!clearValues[attachmentNdx])
3160 continue;
3161
3162 const VkImageMemoryBarrier barrier = {
3163 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
3164 DE_NULL, // pNext;
3165
3166 (VkAccessFlags)0, // srcAccessMask
3167 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
3168
3169 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3170 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
3171
3172 queueIndex, // srcQueueFamilyIndex;
3173 queueIndex, // destQueueFamilyIndex;
3174
3175 attachmentResources[attachmentNdx]->getImage(), // image;
3176 {
3177 // subresourceRange;
3178 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
3179 0, // baseMipLevel;
3180 1, // mipLevels;
3181 0, // baseArraySlice;
3182 1 // arraySize;
3183 }};
3184
3185 initializeLayouts.push_back(barrier);
3186 }
3187
3188 if (!initializeLayouts.empty())
3189 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3190 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
3191 0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3192 (uint32_t)initializeLayouts.size(), &initializeLayouts[0]);
3193 }
3194
3195 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3196 {
3197 if (!clearValues[attachmentNdx])
3198 continue;
3199
3200 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
3201
3202 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
3203 {
3204 const float clearNan =
3205 0.f; // The use of NaN here would require VK_EXT_depth_range_unrestricted; however, just use 0
3206 // since This value is only used for channels that are not used (e.g., for the depth channel
3207 // if the format is stencil-only) and the value of unused channels are never read and
3208 // verified on the host.
3209 const float clearDepth =
3210 hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
3211 const uint32_t clearStencil =
3212 hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
3213 const VkClearDepthStencilValue depthStencil = {clearDepth, clearStencil};
3214 const VkImageSubresourceRange range = {
3215 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
3216 (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
3217 0, 1, 0, 1};
3218
3219 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
3220 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
3221 }
3222 else
3223 {
3224 const VkImageSubresourceRange range = {
3225 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
3226 0, // baseMipLevel;
3227 1, // mipLevels;
3228 0, // baseArrayLayer;
3229 1 // layerCount;
3230 };
3231 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
3232
3233 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
3234 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
3235 }
3236 }
3237
3238 {
3239 vector<VkImageMemoryBarrier> renderPassLayouts;
3240
3241 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3242 {
3243 const VkImageLayout oldLayout =
3244 clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
3245 const VkImageMemoryBarrier barrier = {
3246 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
3247 DE_NULL, // pNext;
3248
3249 getMemoryFlagsForLayout(oldLayout), // srcAccessMask
3250 getAllMemoryReadFlags() |
3251 getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
3252
3253 oldLayout, // oldLayout
3254 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
3255
3256 queueIndex, // srcQueueFamilyIndex;
3257 queueIndex, // destQueueFamilyIndex;
3258
3259 attachmentResources[attachmentNdx]->getImage(), // image;
3260 {
3261 // subresourceRange;
3262 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
3263 0, // baseMipLevel;
3264 1, // mipLevels;
3265 0, // baseArraySlice;
3266 1 // arraySize;
3267 }};
3268
3269 renderPassLayouts.push_back(barrier);
3270 }
3271
3272 if (!renderPassLayouts.empty())
3273 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3274 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
3275 0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3276 (uint32_t)renderPassLayouts.size(), &renderPassLayouts[0]);
3277 }
3278 }
3279
3280 template <typename RenderpassSubpass>
pushRenderPassCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkRenderPass renderPass,VkFramebuffer framebuffer,const vector<de::SharedPtr<SubpassRenderer>> & subpassRenderers,const VkRect2D & renderArea,const vector<Maybe<VkClearValue>> & renderPassClearValues,const TestConfig & config)3281 void pushRenderPassCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer, VkRenderPass renderPass,
3282 VkFramebuffer framebuffer, const vector<de::SharedPtr<SubpassRenderer>> &subpassRenderers,
3283 const VkRect2D &renderArea, const vector<Maybe<VkClearValue>> &renderPassClearValues,
3284 const TestConfig &config)
3285 {
3286 const float clearNan = tcu::Float32::nan().asFloat();
3287 vector<VkClearValue> attachmentClearValues;
3288 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
3289
3290 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
3291 {
3292 if (renderPassClearValues[attachmentNdx])
3293 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
3294 else
3295 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
3296 }
3297
3298 {
3299 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
3300 {
3301 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ?
3302 VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS :
3303 VK_SUBPASS_CONTENTS_INLINE;
3304 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, contents);
3305 const VkRenderPassBeginInfo renderPassBeginInfo =
3306 createRenderPassBeginInfo(renderPass, framebuffer, renderArea, (uint32_t)attachmentClearValues.size(),
3307 attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);
3308
3309 if (subpassNdx == 0)
3310 RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
3311 else
3312 RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);
3313
3314 if (config.renderTypes)
3315 {
3316 if (contents == VK_SUBPASS_CONTENTS_INLINE)
3317 {
3318 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer, false, false);
3319 }
3320 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
3321 {
3322 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
3323 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
3324 }
3325 else
3326 DE_FATAL("Invalid contents");
3327 }
3328 }
3329
3330 RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
3331 }
3332 }
3333
3334 #ifndef CTS_USES_VULKANSC
pushDynamicRenderingCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const RenderPass & renderPassInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<de::SharedPtr<SubpassRenderer>> & subpassRenderers,const VkRect2D & renderArea,const vector<Maybe<VkClearValue>> & renderPassClearValues,uint32_t queueIndex,const TestConfig & config,bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)3335 void pushDynamicRenderingCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer,
3336 const RenderPass &renderPassInfo,
3337 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
3338 const vector<de::SharedPtr<SubpassRenderer>> &subpassRenderers,
3339 const VkRect2D &renderArea, const vector<Maybe<VkClearValue>> &renderPassClearValues,
3340 uint32_t queueIndex, const TestConfig &config,
3341 bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3342 {
3343 // helper lambda that returns true when attachment is input attachment for specified subpass
3344 auto isAttachmentUsedAsSubpassInput = [](uint32_t attachmentIndex, const Subpass &subpass)
3345 {
3346 for (const AttachmentReference &inputAttachment : subpass.getInputAttachments())
3347 {
3348 if (attachmentIndex == inputAttachment.getAttachment())
3349 return true;
3350 }
3351 return false;
3352 };
3353
3354 VkImageMemoryBarrier defaultBarrier = initVulkanStructure();
3355 defaultBarrier.srcQueueFamilyIndex = queueIndex;
3356 defaultBarrier.dstQueueFamilyIndex = queueIndex;
3357 defaultBarrier.subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
3358
3359 const std::vector<Attachment> &allAttachments(renderPassInfo.getAttachments());
3360 const uint32_t allAttachmentsCount((uint32_t)allAttachments.size());
3361 vector<VkImageMemoryBarrier> imageBarriersBeforeRendering(allAttachmentsCount, defaultBarrier);
3362 vector<VkImageMemoryBarrier> imageBarriersAfterRendering(allAttachmentsCount, defaultBarrier);
3363
3364 for (uint32_t attachmentIndex = 0; attachmentIndex < allAttachmentsCount; ++attachmentIndex)
3365 {
3366 const Attachment &attachment = allAttachments[attachmentIndex];
3367 const VkFormat format = attachment.getFormat();
3368 const auto textureFormat = mapVkFormat(format);
3369 const bool isDepthAttachment = hasDepthComponent(textureFormat.order);
3370 const bool isStencilAttachment = hasStencilComponent(textureFormat.order);
3371
3372 VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3373 VkImageLayout initialLayout = attachment.getInitialLayout();
3374 VkImageLayout renderingLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3375 VkImageLayout finalLayout = attachment.getFinalLayout();
3376
3377 if (isDepthAttachment || isStencilAttachment)
3378 {
3379 aspectMask =
3380 (isDepthAttachment * VK_IMAGE_ASPECT_DEPTH_BIT) | (isStencilAttachment * VK_IMAGE_ASPECT_STENCIL_BIT);
3381
3382 // iterate over all subpasses
3383 for (const Subpass &subpass : renderPassInfo.getSubpasses())
3384 {
3385 if (renderingLayout == VK_IMAGE_LAYOUT_UNDEFINED)
3386 {
3387 // find first subpass in which ds attachment is used
3388 const AttachmentReference &dsAttachmentReference = subpass.getDepthStencilAttachment();
3389 if (attachmentIndex == dsAttachmentReference.getAttachment())
3390 renderingLayout = dsAttachmentReference.getImageLayout();
3391 }
3392 else if (isAttachmentUsedAsSubpassInput(attachmentIndex, subpass))
3393 {
3394 renderingLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3395 break;
3396 }
3397 }
3398 }
3399 else
3400 {
3401 // iterate over all subpasses
3402 for (const Subpass &subpass : renderPassInfo.getSubpasses())
3403 {
3404 if (renderingLayout == VK_IMAGE_LAYOUT_UNDEFINED)
3405 {
3406 // find first subpass in which ds attachment is used
3407 for (const AttachmentReference &attachmentReference : subpass.getColorAttachments())
3408 {
3409 if (attachmentIndex == attachmentReference.getAttachment())
3410 {
3411 renderingLayout = attachmentReference.getImageLayout();
3412 break;
3413 }
3414 }
3415 }
3416 else if (isAttachmentUsedAsSubpassInput(attachmentIndex, subpass))
3417 {
3418 renderingLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3419 break;
3420 }
3421 }
3422 }
3423
3424 // handle attachment that is not used by any subpass
3425 if (renderingLayout == VK_IMAGE_LAYOUT_UNDEFINED)
3426 renderingLayout = VK_IMAGE_LAYOUT_GENERAL;
3427
3428 VkImageMemoryBarrier &beforeBarrier = imageBarriersBeforeRendering[attachmentIndex];
3429 beforeBarrier.srcAccessMask = getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout);
3430 beforeBarrier.dstAccessMask = getMemoryFlagsForLayout(renderingLayout);
3431 beforeBarrier.oldLayout = initialLayout;
3432 beforeBarrier.newLayout = renderingLayout;
3433 beforeBarrier.image = attachmentResources[attachmentIndex]->getImage();
3434 beforeBarrier.subresourceRange.aspectMask = aspectMask;
3435
3436 VkImageMemoryBarrier &afterBarrier = imageBarriersAfterRendering[attachmentIndex];
3437 afterBarrier.srcAccessMask = getMemoryFlagsForLayout(renderingLayout);
3438 afterBarrier.dstAccessMask = getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout);
3439 afterBarrier.oldLayout = renderingLayout;
3440 afterBarrier.newLayout = finalLayout;
3441 afterBarrier.image = beforeBarrier.image;
3442 afterBarrier.subresourceRange.aspectMask = aspectMask;
3443 }
3444
3445 if (!imageBarriersBeforeRendering.empty())
3446 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
3447 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3448 (const VkBufferMemoryBarrier *)DE_NULL, allAttachmentsCount,
3449 imageBarriersBeforeRendering.data());
3450
3451 bool executeRenderCommands = (config.renderTypes != TestConfig::RENDERTYPES_NONE);
3452
3453 if (secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3454 {
3455 // when secondary command buffer completely contains dynamic renderpass
3456 // then we need to execute it even when render type is none
3457 executeRenderCommands = true;
3458 }
3459 else
3460 {
3461 VkRenderingFlagsKHR renderingFlags = 0u;
3462 if (subpassRenderers[0]->isSecondary())
3463 renderingFlags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR;
3464
3465 beginDynamicRendering(vk, commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues,
3466 renderingFlags);
3467 }
3468
3469 if (executeRenderCommands)
3470 {
3471 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
3472 {
3473 if (subpassNdx != 0)
3474 {
3475 const auto &subpass = renderPassInfo.getSubpasses()[subpassNdx];
3476 const auto &inputAttachments = subpass.getInputAttachments();
3477 VkMemoryBarrier memoryBarrier =
3478 makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
3479 VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3480
3481 // check if one of inputs is depth/stencil format
3482 for (const auto &inputAttachment : inputAttachments)
3483 {
3484 VkFormat format = allAttachments[inputAttachment.getAttachment()].getFormat();
3485 const auto textureFormat = mapVkFormat(format);
3486 if (hasDepthComponent(textureFormat.order) || hasStencilComponent(textureFormat.order))
3487 {
3488 srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
3489 memoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3490 break;
3491 }
3492 }
3493
3494 if (!inputAttachments.empty())
3495 {
3496 vk.cmdPipelineBarrier(commandBuffer, srcStageMask, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
3497 VK_DEPENDENCY_BY_REGION_BIT, 1u, &memoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
3498 }
3499 }
3500
3501 if (subpassRenderers[subpassNdx]->isSecondary())
3502 {
3503 if (subpassNdx > 0)
3504 {
3505 std::vector<uint32_t> colorAttachmentIndices;
3506 std::vector<VkFormat> colorAttachmentFormats;
3507
3508 findColorAttachments(renderPassInfo, colorAttachmentIndices, colorAttachmentFormats);
3509
3510 uint32_t colorAttachmentCount((uint32_t)colorAttachmentIndices.size());
3511 std::vector<uint32_t> colorAttachmentLocations(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
3512 std::vector<uint32_t> colorAttachmentInputIndices(colorAttachmentCount, VK_ATTACHMENT_UNUSED);
3513 uint32_t localDepthAttachmentIndex = VK_ATTACHMENT_UNUSED;
3514 uint32_t localStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
3515 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
3516 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
3517
3518 prepareAttachmentRemapping(renderPassInfo.getSubpasses()[subpassNdx], allAttachments,
3519 colorAttachmentIndices, colorAttachmentLocations,
3520 colorAttachmentInputIndices, localDepthAttachmentIndex,
3521 localStencilAttachmentIndex, renderingAttachmentLocationInfo,
3522 renderingInputAttachmentIndexInfo);
3523
3524 vk.cmdSetRenderingAttachmentLocationsKHR(commandBuffer, &renderingAttachmentLocationInfo);
3525 vk.cmdSetRenderingInputAttachmentIndicesKHR(commandBuffer, &renderingInputAttachmentIndexInfo);
3526 }
3527
3528 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
3529 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
3530 }
3531 else
3532 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer, false, true);
3533 }
3534 }
3535
3536 if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3537 endDynamicRendering(vk, commandBuffer);
3538
3539 if (!imageBarriersAfterRendering.empty())
3540 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
3541 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3542 (const VkBufferMemoryBarrier *)DE_NULL, allAttachmentsCount,
3543 imageBarriersAfterRendering.data());
3544 }
3545 #endif // CTS_USES_VULKANSC
3546
pushRenderPassCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkRenderPass renderPass,const RenderPass & renderPassInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,VkFramebuffer framebuffer,const vector<de::SharedPtr<SubpassRenderer>> & subpassRenderers,const VkRect2D & renderArea,const vector<Maybe<VkClearValue>> & renderPassClearValues,uint32_t queueIndex,const TestConfig & config,bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)3547 void pushRenderPassCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer, VkRenderPass renderPass,
3548 const RenderPass &renderPassInfo,
3549 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
3550 VkFramebuffer framebuffer, const vector<de::SharedPtr<SubpassRenderer>> &subpassRenderers,
3551 const VkRect2D &renderArea, const vector<Maybe<VkClearValue>> &renderPassClearValues,
3552 uint32_t queueIndex, const TestConfig &config,
3553 bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3554 {
3555 // unreference arguments not used by Vulkan SC, no need to put them under ifdef
3556 DE_UNREF(renderPassInfo);
3557 DE_UNREF(attachmentResources);
3558 DE_UNREF(queueIndex);
3559 DE_UNREF(secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3560
3561 switch (config.groupParams->renderingType)
3562 {
3563 case RENDERING_TYPE_RENDERPASS_LEGACY:
3564 return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers,
3565 renderArea, renderPassClearValues, config);
3566 case RENDERING_TYPE_RENDERPASS2:
3567 return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers,
3568 renderArea, renderPassClearValues, config);
3569
3570 #ifndef CTS_USES_VULKANSC
3571 case RENDERING_TYPE_DYNAMIC_RENDERING:
3572 return pushDynamicRenderingCommands(vk, commandBuffer, renderPassInfo, attachmentResources, subpassRenderers,
3573 renderArea, renderPassClearValues, queueIndex, config,
3574 secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3575 #endif // CTS_USES_VULKANSC
3576
3577 default:
3578 TCU_THROW(InternalError, "Impossible");
3579 }
3580 }
3581
pushReadImagesToBuffers(const DeviceInterface & vk,VkCommandBuffer commandBuffer,uint32_t queueIndex,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<Attachment> & attachmentInfo,const vector<bool> & isLazy,const UVec2 & targetSize)3582 void pushReadImagesToBuffers(const DeviceInterface &vk, VkCommandBuffer commandBuffer, uint32_t queueIndex,
3583
3584 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
3585 const vector<Attachment> &attachmentInfo, const vector<bool> &isLazy,
3586
3587 const UVec2 &targetSize)
3588 {
3589 {
3590 vector<VkImageMemoryBarrier> imageBarriers;
3591
3592 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3593 {
3594 if (isLazy[attachmentNdx])
3595 continue;
3596
3597 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
3598 const VkImageMemoryBarrier barrier = {
3599 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
3600 DE_NULL, // pNext
3601
3602 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
3603 getAllMemoryReadFlags(), // dstAccessMask
3604
3605 oldLayout, // oldLayout
3606 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
3607
3608 queueIndex, // srcQueueFamilyIndex
3609 queueIndex, // destQueueFamilyIndex
3610
3611 attachmentResources[attachmentNdx]->getImage(), // image
3612 {
3613 // subresourceRange
3614 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
3615 0, // baseMipLevel
3616 1, // mipLevels
3617 0, // baseArraySlice
3618 1 // arraySize
3619 }};
3620
3621 imageBarriers.push_back(barrier);
3622 }
3623
3624 if (!imageBarriers.empty())
3625 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
3626 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3627 (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)imageBarriers.size(),
3628 &imageBarriers[0]);
3629 }
3630
3631 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3632 {
3633 if (isLazy[attachmentNdx])
3634 continue;
3635
3636 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3637 const VkBufferImageCopy rect = {
3638 0, // bufferOffset
3639 0, // bufferRowLength
3640 0, // bufferImageHeight
3641 {
3642 // imageSubresource
3643 (vk::VkImageAspectFlags)getPrimaryImageAspect(
3644 mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
3645 0, // mipLevel
3646 0, // arraySlice
3647 1 // arraySize
3648 },
3649 {0, 0, 0}, // imageOffset
3650 {targetSize.x(), targetSize.y(), 1u} // imageExtent
3651 };
3652
3653 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
3654 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(),
3655 1, &rect);
3656
3657 if (tcu::TextureFormat::DS == order)
3658 {
3659 const VkBufferImageCopy stencilRect = {
3660 0, // bufferOffset
3661 0, // bufferRowLength
3662 0, // bufferImageHeight
3663 {
3664 // imageSubresource
3665 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
3666 0, // mipLevel
3667 0, // arraySlice
3668 1 // arraySize
3669 },
3670 {0, 0, 0}, // imageOffset
3671 {targetSize.x(), targetSize.y(), 1u} // imageExtent
3672 };
3673
3674 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
3675 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3676 attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
3677 }
3678 }
3679
3680 {
3681 vector<VkBufferMemoryBarrier> bufferBarriers;
3682
3683 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3684 {
3685 if (isLazy[attachmentNdx])
3686 continue;
3687
3688 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3689 const VkBufferMemoryBarrier bufferBarrier = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3690 DE_NULL,
3691
3692 getAllMemoryWriteFlags(),
3693 getAllMemoryReadFlags(),
3694
3695 queueIndex,
3696 queueIndex,
3697
3698 attachmentResources[attachmentNdx]->getBuffer(),
3699 0,
3700 attachmentResources[attachmentNdx]->getBufferSize()};
3701
3702 bufferBarriers.push_back(bufferBarrier);
3703
3704 if (tcu::TextureFormat::DS == order)
3705 {
3706 const VkBufferMemoryBarrier secondaryBufferBarrier = {
3707 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3708 DE_NULL,
3709
3710 getAllMemoryWriteFlags(),
3711 getAllMemoryReadFlags(),
3712
3713 queueIndex,
3714 queueIndex,
3715
3716 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
3717 0,
3718 attachmentResources[attachmentNdx]->getSecondaryBufferSize()};
3719
3720 bufferBarriers.push_back(secondaryBufferBarrier);
3721 }
3722 }
3723
3724 if (!bufferBarriers.empty())
3725 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
3726 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL,
3727 (uint32_t)bufferBarriers.size(), &bufferBarriers[0], 0,
3728 (const VkImageMemoryBarrier *)DE_NULL);
3729 }
3730 }
3731
3732 class PixelValue
3733 {
3734 public:
3735 PixelValue(const Maybe<bool> &x = tcu::Nothing, const Maybe<bool> &y = tcu::Nothing,
3736 const Maybe<bool> &z = tcu::Nothing, const Maybe<bool> &w = tcu::Nothing);
3737
3738 void setUndefined(size_t ndx);
3739 void setValue(size_t ndx, bool value);
3740 Maybe<bool> getValue(size_t ndx) const;
3741
3742 private:
3743 uint16_t m_status;
3744 };
3745
PixelValue(const Maybe<bool> & x,const Maybe<bool> & y,const Maybe<bool> & z,const Maybe<bool> & w)3746 PixelValue::PixelValue(const Maybe<bool> &x, const Maybe<bool> &y, const Maybe<bool> &z, const Maybe<bool> &w)
3747 : m_status(0)
3748 {
3749 const Maybe<bool> values[] = {x, y, z, w};
3750
3751 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
3752 {
3753 if (values[ndx])
3754 setValue(ndx, *values[ndx]);
3755 else
3756 setUndefined(ndx);
3757 }
3758
3759 DE_ASSERT(m_status <= 0xFFu);
3760 }
3761
setUndefined(size_t ndx)3762 void PixelValue::setUndefined(size_t ndx)
3763 {
3764 DE_ASSERT(ndx < 4);
3765 DE_ASSERT(m_status <= 0xFFu);
3766
3767 m_status &= (uint16_t) ~(0x1u << (uint16_t)(ndx * 2));
3768 DE_ASSERT(m_status <= 0xFFu);
3769 }
3770
setValue(size_t ndx,bool value)3771 void PixelValue::setValue(size_t ndx, bool value)
3772 {
3773 DE_ASSERT(ndx < 4);
3774 DE_ASSERT(m_status <= 0xFFu);
3775
3776 m_status = (uint16_t)(m_status | (uint16_t)(0x1u << (ndx * 2)));
3777
3778 if (value)
3779 m_status = (uint16_t)(m_status | (uint16_t)(0x1u << (ndx * 2 + 1)));
3780 else
3781 m_status &= (uint16_t) ~(0x1u << (uint16_t)(ndx * 2 + 1));
3782
3783 DE_ASSERT(m_status <= 0xFFu);
3784 }
3785
getValue(size_t ndx) const3786 Maybe<bool> PixelValue::getValue(size_t ndx) const
3787 {
3788 DE_ASSERT(ndx < 4);
3789 DE_ASSERT(m_status <= 0xFFu);
3790
3791 if ((m_status & (0x1u << (uint16_t)(ndx * 2))) != 0)
3792 {
3793 return just((m_status & (0x1u << (uint32_t)(ndx * 2 + 1))) != 0);
3794 }
3795 else
3796 return tcu::Nothing;
3797 }
3798
clearReferenceValues(vector<PixelValue> & values,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size,const BVec4 & mask,const PixelValue & value)3799 void clearReferenceValues(vector<PixelValue> &values, const UVec2 &targetSize, const UVec2 &offset, const UVec2 &size,
3800 const BVec4 &mask, const PixelValue &value)
3801 {
3802 DE_ASSERT(targetSize.x() * targetSize.y() == (uint32_t)values.size());
3803 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
3804 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
3805
3806 for (uint32_t y = offset.y(); y < offset.y() + size.y(); y++)
3807 for (uint32_t x = offset.x(); x < offset.x() + size.x(); x++)
3808 {
3809 for (int compNdx = 0; compNdx < 4; compNdx++)
3810 {
3811 if (mask[compNdx])
3812 {
3813 if (value.getValue(compNdx))
3814 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
3815 else
3816 values[x + y * targetSize.x()].setUndefined(compNdx);
3817 }
3818 }
3819 }
3820 }
3821
markUndefined(vector<PixelValue> & values,const BVec4 & mask,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size)3822 void markUndefined(vector<PixelValue> &values, const BVec4 &mask, const UVec2 &targetSize, const UVec2 &offset,
3823 const UVec2 &size)
3824 {
3825 DE_ASSERT(targetSize.x() * targetSize.y() == (uint32_t)values.size());
3826
3827 for (uint32_t y = offset.y(); y < offset.y() + size.y(); y++)
3828 for (uint32_t x = offset.x(); x < offset.x() + size.x(); x++)
3829 {
3830 for (int compNdx = 0; compNdx < 4; compNdx++)
3831 {
3832 if (mask[compNdx])
3833 values[x + y * targetSize.x()].setUndefined(compNdx);
3834 }
3835 }
3836 }
3837
clearValueToPixelValue(const VkClearValue & value,const tcu::TextureFormat & format,const DepthValuesArray & depthValues)3838 PixelValue clearValueToPixelValue(const VkClearValue &value, const tcu::TextureFormat &format,
3839 const DepthValuesArray &depthValues)
3840 {
3841 const bool isDepthAttachment = hasDepthComponent(format.order);
3842 const bool isStencilAttachment = hasStencilComponent(format.order);
3843 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
3844 PixelValue pixelValue;
3845
3846 if (isDepthOrStencilAttachment)
3847 {
3848 if (isDepthAttachment)
3849 {
3850 if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
3851 pixelValue.setValue(0, true);
3852 else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
3853 pixelValue.setValue(0, false);
3854 else
3855 DE_FATAL("Unknown depth value");
3856 }
3857
3858 if (isStencilAttachment)
3859 {
3860 if (value.depthStencil.stencil == 0xFFu)
3861 pixelValue.setValue(1, true);
3862 else if (value.depthStencil.stencil == 0x0u)
3863 pixelValue.setValue(1, false);
3864 else
3865 DE_FATAL("Unknown stencil value");
3866 }
3867 }
3868 else
3869 {
3870 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3871 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3872
3873 switch (channelClass)
3874 {
3875 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3876 for (int i = 0; i < 4; i++)
3877 {
3878 if (channelMask[i])
3879 {
3880 if (value.color.int32[i] == 1)
3881 pixelValue.setValue(i, true);
3882 else if (value.color.int32[i] == 0)
3883 pixelValue.setValue(i, false);
3884 else
3885 DE_FATAL("Unknown clear color value");
3886 }
3887 }
3888 break;
3889
3890 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3891 for (int i = 0; i < 4; i++)
3892 {
3893 if (channelMask[i])
3894 {
3895 if (value.color.uint32[i] == 1u)
3896 pixelValue.setValue(i, true);
3897 else if (value.color.uint32[i] == 0u)
3898 pixelValue.setValue(i, false);
3899 else
3900 DE_FATAL("Unknown clear color value");
3901 }
3902 }
3903 break;
3904
3905 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3906 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3907 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3908 for (int i = 0; i < 4; i++)
3909 {
3910 if (channelMask[i])
3911 {
3912 if (value.color.float32[i] == 1.0f)
3913 pixelValue.setValue(i, true);
3914 else if (value.color.float32[i] == 0.0f)
3915 pixelValue.setValue(i, false);
3916 else
3917 DE_FATAL("Unknown clear color value");
3918 }
3919 }
3920 break;
3921
3922 default:
3923 DE_FATAL("Unknown channel class");
3924 }
3925 }
3926
3927 return pixelValue;
3928 }
3929
renderReferenceValues(vector<vector<PixelValue>> & referenceAttachments,const RenderPass & renderPassInfo,const UVec2 & targetSize,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & renderPos,const UVec2 & renderSize,const uint32_t drawStartNdx,const DepthValuesArray & depthValues)3930 void renderReferenceValues(vector<vector<PixelValue>> &referenceAttachments, const RenderPass &renderPassInfo,
3931 const UVec2 &targetSize, const vector<Maybe<VkClearValue>> &imageClearValues,
3932 const vector<Maybe<VkClearValue>> &renderPassClearValues,
3933 const vector<SubpassRenderInfo> &subpassRenderInfo, const UVec2 &renderPos,
3934 const UVec2 &renderSize, const uint32_t drawStartNdx, const DepthValuesArray &depthValues)
3935 {
3936 const vector<Subpass> &subpasses = renderPassInfo.getSubpasses();
3937 vector<bool> attachmentUsed(renderPassInfo.getAttachments().size(), false);
3938
3939 referenceAttachments.resize(renderPassInfo.getAttachments().size());
3940
3941 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3942 {
3943 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3944 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3945 vector<PixelValue> &reference = referenceAttachments[attachmentNdx];
3946
3947 reference.resize(targetSize.x() * targetSize.y());
3948
3949 if (imageClearValues[attachmentNdx])
3950 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true),
3951 clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
3952 }
3953
3954 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3955 {
3956 const Subpass &subpass = subpasses[subpassNdx];
3957 const SubpassRenderInfo &renderInfo = subpassRenderInfo[subpassNdx];
3958 const vector<AttachmentReference> &colorAttachments = subpass.getColorAttachments();
3959
3960 // Apply load op if attachment was used for the first time
3961 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
3962 {
3963 const uint32_t attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);
3964
3965 if (!attachmentUsed[attachmentIndex] &&
3966 colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
3967 {
3968 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
3969 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
3970 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3971
3972 DE_ASSERT(!tcu::hasDepthComponent(format.order));
3973 DE_ASSERT(!tcu::hasStencilComponent(format.order));
3974
3975 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3976 clearReferenceValues(
3977 reference, targetSize, renderPos, renderSize, BVec4(true),
3978 clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3979 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3980 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3981
3982 attachmentUsed[attachmentIndex] = true;
3983 }
3984 }
3985
3986 // Apply load op to depth/stencil attachment if it was used for the first time
3987 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3988 {
3989 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3990
3991 // Apply load op if attachment was used for the first time
3992 if (!attachmentUsed[attachmentIndex])
3993 {
3994 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
3995 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
3996 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3997
3998 if (tcu::hasDepthComponent(format.order))
3999 {
4000 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4001 clearReferenceValues(
4002 reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false),
4003 clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
4004 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
4005 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
4006 }
4007
4008 if (tcu::hasStencilComponent(format.order))
4009 {
4010 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4011 clearReferenceValues(
4012 reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false),
4013 clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
4014 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
4015 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
4016 }
4017
4018 attachmentUsed[attachmentIndex] = true;
4019 }
4020 }
4021
4022 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
4023 {
4024 const ColorClear &colorClear = renderInfo.getColorClears()[colorClearNdx];
4025 const UVec2 offset = colorClear.getOffset();
4026 const UVec2 size = colorClear.getSize();
4027 const uint32_t attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
4028 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4029 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4030 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4031 VkClearValue value;
4032
4033 value.color = colorClear.getColor();
4034
4035 clearReferenceValues(reference, targetSize, offset, size, BVec4(true),
4036 clearValueToPixelValue(value, format, depthValues));
4037 }
4038
4039 if (renderInfo.getDepthStencilClear())
4040 {
4041 const DepthStencilClear &dsClear = *renderInfo.getDepthStencilClear();
4042 const UVec2 offset = dsClear.getOffset();
4043 const UVec2 size = dsClear.getSize();
4044 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4045 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
4046 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4047 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4048 const bool hasStencil = tcu::hasStencilComponent(format.order) &&
4049 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
4050 const bool hasDepth = tcu::hasDepthComponent(format.order) &&
4051 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
4052 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4053 VkClearValue value;
4054
4055 value.depthStencil.depth = dsClear.getDepth();
4056 value.depthStencil.stencil = dsClear.getStencil();
4057
4058 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false),
4059 clearValueToPixelValue(value, format, depthValues));
4060 }
4061
4062 if (renderInfo.getRenderQuad())
4063 {
4064 const RenderQuad &renderQuad = *renderInfo.getRenderQuad();
4065 const Vec2 posA = renderQuad.getCornerA();
4066 const Vec2 posB = renderQuad.getCornerB();
4067 const Vec2 origin =
4068 Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) +
4069 Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
4070 const Vec2 p =
4071 Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
4072 const IVec2 posAI(deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
4073 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
4074 const IVec2 posBI(deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
4075 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
4076
4077 DE_ASSERT(posAI.x() < posBI.x());
4078 DE_ASSERT(posAI.y() < posBI.y());
4079
4080 if (subpass.getInputAttachments().empty())
4081 {
4082 for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size();
4083 attachmentRefNdx++)
4084 {
4085 const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
4086
4087 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4088 continue;
4089
4090 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4091 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4092 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
4093 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4094
4095 for (int y = posAI.y(); y < (int)posBI.y(); y++)
4096 for (int x = posAI.x(); x < (int)posBI.x(); x++)
4097 {
4098 for (int compNdx = 0; compNdx < 4; compNdx++)
4099 {
4100 const size_t index = subpassNdx + attachmentIndex + compNdx;
4101 const BoolOp op = boolOpFromIndex(index);
4102 const bool boolX = x % 2 == (int)(index % 2);
4103 const bool boolY = y % 2 == (int)((index / 2) % 2);
4104
4105 if (channelMask[compNdx])
4106 reference[x + y * targetSize.x()].setValue(compNdx,
4107 performBoolOp(op, boolX, boolY));
4108 }
4109 }
4110 }
4111
4112 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4113 {
4114 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4115 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
4116 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4117 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4118 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4119
4120 for (int y = posAI.y(); y < (int)posBI.y(); y++)
4121 for (int x = posAI.x(); x < (int)posBI.x(); x++)
4122 {
4123 if (tcu::hasDepthComponent(format.order) &&
4124 layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4125 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4126 {
4127 const size_t index = subpassNdx + 1;
4128 const BoolOp op = boolOpFromIndex(index);
4129 const bool boolX = x % 2 == (int)(index % 2);
4130 const bool boolY = y % 2 == (int)((index / 2) % 2);
4131
4132 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
4133 }
4134
4135 if (tcu::hasStencilComponent(format.order) &&
4136 layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4137 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4138 {
4139 const size_t index = subpassNdx;
4140 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
4141 }
4142 }
4143 }
4144 }
4145 else
4146 {
4147 size_t outputComponentCount = 0;
4148 vector<Maybe<bool>> inputs;
4149
4150 DE_ASSERT(posAI.x() < posBI.x());
4151 DE_ASSERT(posAI.y() < posBI.y());
4152
4153 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size();
4154 attachmentRefNdx++)
4155 {
4156 const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
4157 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4158 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4159 const int componentCount = getShaderNumChannels(format.order);
4160
4161 outputComponentCount += (size_t)componentCount;
4162 }
4163
4164 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
4165 subpass.getDepthStencilAttachment().getImageLayout() !=
4166 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4167 subpass.getDepthStencilAttachment().getImageLayout() !=
4168 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4169 {
4170 const Attachment &attachment(
4171 renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
4172 const tcu::TextureFormat format(mapVkFormat(attachment.getFormat()));
4173
4174 if (tcu::hasDepthComponent(format.order))
4175 outputComponentCount++;
4176 }
4177
4178 if (outputComponentCount > 0)
4179 {
4180 for (int y = posAI.y(); y < (int)posBI.y(); y++)
4181 for (int x = posAI.x(); x < (int)posBI.x(); x++)
4182 {
4183 for (size_t inputAttachmentNdx = 0;
4184 inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
4185 {
4186 const uint32_t attachmentIndex =
4187 subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
4188 const VkImageLayout layout =
4189 subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
4190 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4191 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4192 const int componentCount = getShaderNumChannels(format.order);
4193
4194 for (int compNdx = 0; compNdx < componentCount; compNdx++)
4195 {
4196 if ((compNdx != 0 ||
4197 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) &&
4198 (compNdx != 1 ||
4199 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
4200 {
4201 inputs.push_back(
4202 referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(
4203 compNdx));
4204 }
4205 }
4206 }
4207
4208 const size_t inputsPerOutput = inputs.size() >= outputComponentCount ?
4209 ((inputs.size() / outputComponentCount) +
4210 ((inputs.size() % outputComponentCount) != 0 ? 1 : 0)) :
4211 1;
4212
4213 size_t outputValueNdx = 0;
4214
4215 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size();
4216 attachmentRefNdx++)
4217 {
4218 const uint32_t attachmentIndex =
4219 subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
4220 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4221 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4222 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4223 const int componentCount = getShaderNumChannels(format.order);
4224
4225 for (int compNdx = 0; compNdx < componentCount; compNdx++)
4226 {
4227 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
4228 const BoolOp op = boolOpFromIndex(index);
4229 const bool boolX = x % 2 == (int)(index % 2);
4230 const bool boolY = y % 2 == (int)((index / 2) % 2);
4231 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
4232
4233 for (size_t i = 0; i < inputsPerOutput; i++)
4234 {
4235 if (!output)
4236 break;
4237 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) %
4238 inputs.size()])
4239 output = tcu::Nothing;
4240 else
4241 output = (*output) ==
4242 (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) %
4243 inputs.size()]);
4244 }
4245
4246 if (output)
4247 reference[x + y * targetSize.x()].setValue(compNdx, *output);
4248 else
4249 reference[x + y * targetSize.x()].setUndefined(compNdx);
4250 }
4251
4252 outputValueNdx += componentCount;
4253 }
4254
4255 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
4256 subpass.getDepthStencilAttachment().getImageLayout() !=
4257 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4258 subpass.getDepthStencilAttachment().getImageLayout() !=
4259 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4260 {
4261 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4262 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4263 const size_t index = subpassNdx + attachmentIndex;
4264 const BoolOp op = boolOpFromIndex(index);
4265 const bool boolX = x % 2 == (int)(index % 2);
4266 const bool boolY = y % 2 == (int)((index / 2) % 2);
4267 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
4268
4269 for (size_t i = 0; i < inputsPerOutput; i++)
4270 {
4271 if (!output)
4272 break;
4273 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
4274 output = (*output) ==
4275 (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
4276 else
4277 output = tcu::Nothing;
4278 }
4279
4280 if (output)
4281 reference[x + y * targetSize.x()].setValue(0, *output);
4282 else
4283 reference[x + y * targetSize.x()].setUndefined(0);
4284 }
4285
4286 inputs.clear();
4287 }
4288 }
4289
4290 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
4291 subpass.getDepthStencilAttachment().getImageLayout() !=
4292 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4293 subpass.getDepthStencilAttachment().getImageLayout() !=
4294 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4295 {
4296 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4297 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentIndex];
4298 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4299 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4300
4301 if (tcu::hasStencilComponent(format.order))
4302 {
4303 for (int y = posAI.y(); y < (int)posBI.y(); y++)
4304 for (int x = posAI.x(); x < (int)posBI.x(); x++)
4305 {
4306 const size_t index = subpassNdx;
4307 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
4308 }
4309 }
4310 }
4311 }
4312 }
4313 }
4314
4315 // Mark all attachments that were used but not stored as undefined
4316 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
4317 {
4318 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
4319 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4320 vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
4321 const bool isStencilAttachment = hasStencilComponent(format.order);
4322 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
4323
4324 if (attachmentUsed[attachmentIndex] &&
4325 renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
4326 {
4327 if (isDepthOrStencilAttachment)
4328 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
4329 else
4330 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
4331 }
4332
4333 if (attachmentUsed[attachmentIndex] && isStencilAttachment &&
4334 renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
4335 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
4336 }
4337 }
4338
renderReferenceImagesFromValues(vector<tcu::TextureLevel> & referenceImages,const vector<vector<PixelValue>> & referenceValues,const UVec2 & targetSize,const RenderPass & renderPassInfo,const DepthValuesArray & depthValues)4339 void renderReferenceImagesFromValues(vector<tcu::TextureLevel> &referenceImages,
4340 const vector<vector<PixelValue>> &referenceValues, const UVec2 &targetSize,
4341 const RenderPass &renderPassInfo, const DepthValuesArray &depthValues)
4342 {
4343 referenceImages.resize(referenceValues.size());
4344
4345 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4346 {
4347 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
4348 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4349 const vector<PixelValue> &reference = referenceValues[attachmentNdx];
4350 const bool hasDepth = tcu::hasDepthComponent(format.order);
4351 const bool hasStencil = tcu::hasStencilComponent(format.order);
4352 const bool hasDepthOrStencil = hasDepth || hasStencil;
4353 tcu::TextureLevel &referenceImage = referenceImages[attachmentNdx];
4354
4355 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
4356
4357 if (hasDepthOrStencil)
4358 {
4359 if (hasDepth)
4360 {
4361 const PixelBufferAccess depthAccess(
4362 tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
4363
4364 for (uint32_t y = 0; y < targetSize.y(); y++)
4365 for (uint32_t x = 0; x < targetSize.x(); x++)
4366 {
4367 if (reference[x + y * targetSize.x()].getValue(0))
4368 {
4369 if (*reference[x + y * targetSize.x()].getValue(0))
4370 depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
4371 else
4372 depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
4373 }
4374 else // Fill with 3x3 grid
4375 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
4376 }
4377 }
4378
4379 if (hasStencil)
4380 {
4381 const PixelBufferAccess stencilAccess(
4382 tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
4383
4384 for (uint32_t y = 0; y < targetSize.y(); y++)
4385 for (uint32_t x = 0; x < targetSize.x(); x++)
4386 {
4387 if (reference[x + y * targetSize.x()].getValue(1))
4388 {
4389 if (*reference[x + y * targetSize.x()].getValue(1))
4390 stencilAccess.setPixStencil(0xFFu, x, y);
4391 else
4392 stencilAccess.setPixStencil(0x0u, x, y);
4393 }
4394 else // Fill with 3x3 grid
4395 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
4396 }
4397 }
4398 }
4399 else
4400 {
4401 for (uint32_t y = 0; y < targetSize.y(); y++)
4402 for (uint32_t x = 0; x < targetSize.x(); x++)
4403 {
4404 tcu::Vec4 color;
4405
4406 for (int compNdx = 0; compNdx < 4; compNdx++)
4407 {
4408 if (reference[x + y * targetSize.x()].getValue(compNdx))
4409 {
4410 if (*reference[x + y * targetSize.x()].getValue(compNdx))
4411 color[compNdx] = 1.0f;
4412 else
4413 color[compNdx] = 0.0f;
4414 }
4415 else // Fill with 3x3 grid
4416 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
4417 }
4418
4419 referenceImage.getAccess().setPixel(color, x, y);
4420 }
4421 }
4422 }
4423 }
4424
verifyColorAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const bool useFormatCompCount)4425 bool verifyColorAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
4426 const PixelBufferAccess &errorImage, const bool useFormatCompCount)
4427 {
4428 const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
4429 const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
4430 bool ok = true;
4431
4432 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4433 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4434 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4435
4436 for (int y = 0; y < result.getHeight(); y++)
4437 for (int x = 0; x < result.getWidth(); x++)
4438 {
4439 const Vec4 resultColor = result.getPixel(x, y);
4440 const PixelValue &referenceValue = reference[x + y * result.getWidth()];
4441 bool pixelOk = true;
4442 const uint32_t componentCount =
4443 useFormatCompCount ? static_cast<uint32_t>(getShaderNumChannels(result.getFormat().order)) : 4;
4444
4445 for (uint32_t compNdx = 0; compNdx < componentCount; compNdx++)
4446 {
4447 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
4448
4449 if (maybeValue)
4450 {
4451 const bool value = *maybeValue;
4452
4453 if ((value && (resultColor[compNdx] != 1.0f)) || (!value && resultColor[compNdx] != 0.0f))
4454 pixelOk = false;
4455 }
4456 }
4457
4458 if (!pixelOk)
4459 {
4460 errorImage.setPixel(red, x, y);
4461 ok = false;
4462 }
4463 else
4464 errorImage.setPixel(green, x, y);
4465 }
4466
4467 return ok;
4468 }
4469
4470 // Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
4471 const tcu::Vec4 kDefaultColorForLog{0.0f, 0.0f, 0.0f, 1.0f};
4472 const float kTrueComponent = 1.0f;
4473 const float kFalseComponent = 0.5f;
4474 const float kUnsetComponentLow = 0.0f;
4475 const float kUnsetComponentHigh = 0.25f;
4476
renderColorImageForLog(const ConstPixelBufferAccess & image,int numChannels)4477 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog(const ConstPixelBufferAccess &image, int numChannels)
4478 {
4479 // Same channel order, but using UNORM_INT8 for the color format.
4480 const auto order = image.getFormat().order;
4481 const tcu::TextureFormat loggableFormat{order, tcu::TextureFormat::UNORM_INT8};
4482 const int width = image.getWidth();
4483 const int height = image.getHeight();
4484 std::unique_ptr<tcu::TextureLevel> result{new tcu::TextureLevel{loggableFormat, width, height}};
4485 auto access = result->getAccess();
4486 tcu::Vec4 outColor = kDefaultColorForLog;
4487
4488 for (int x = 0; x < width; ++x)
4489 for (int y = 0; y < height; ++y)
4490 {
4491 const auto value = image.getPixel(x, y);
4492 for (int c = 0; c < numChannels; ++c)
4493 {
4494 if (value[c] == 1.0f)
4495 outColor[c] = kTrueComponent;
4496 else
4497 outColor[c] = kFalseComponent;
4498 }
4499 access.setPixel(outColor, x, y);
4500 }
4501
4502 return result;
4503 }
4504
renderColorImageForLog(const vector<PixelValue> & reference,const UVec2 & targetSize,int numChannels)4505 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog(const vector<PixelValue> &reference, const UVec2 &targetSize,
4506 int numChannels)
4507 {
4508 const tcu::TextureFormat loggableFormat{tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
4509 const int width = static_cast<int>(targetSize.x());
4510 const int height = static_cast<int>(targetSize.y());
4511 std::unique_ptr<tcu::TextureLevel> result{new tcu::TextureLevel{loggableFormat, width, height}};
4512 auto access = result->getAccess();
4513 tcu::Vec4 outColor = kDefaultColorForLog;
4514
4515 for (int x = 0; x < width; ++x)
4516 for (int y = 0; y < height; ++y)
4517 {
4518 const int index = x + y * width;
4519 for (int c = 0; c < numChannels; ++c)
4520 {
4521 const auto maybeValue = reference[index].getValue(c);
4522 if (maybeValue)
4523 outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
4524 else
4525 outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
4526 }
4527 access.setPixel(outColor, x, y);
4528 }
4529
4530 return result;
4531 }
4532
verifyDepthAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const DepthValuesArray & depthValues,float epsilon)4533 bool verifyDepthAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
4534 const PixelBufferAccess &errorImage, const DepthValuesArray &depthValues, float epsilon)
4535 {
4536 const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
4537 const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
4538 bool ok = true;
4539
4540 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4541 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4542 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4543
4544 for (int y = 0; y < result.getHeight(); y++)
4545 for (int x = 0; x < result.getWidth(); x++)
4546 {
4547 bool pixelOk = true;
4548
4549 const float resultDepth = result.getPixDepth(x, y);
4550 const PixelValue &referenceValue = reference[x + y * result.getWidth()];
4551 const Maybe<bool> maybeValue = referenceValue.getValue(0);
4552
4553 if (maybeValue)
4554 {
4555 const bool value = *maybeValue;
4556
4557 if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon)) ||
4558 (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
4559 pixelOk = false;
4560 }
4561
4562 if (!pixelOk)
4563 {
4564 errorImage.setPixel(red, x, y);
4565 ok = false;
4566 }
4567 else
4568 errorImage.setPixel(green, x, y);
4569 }
4570
4571 return ok;
4572 }
4573
verifyStencilAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)4574 bool verifyStencilAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
4575 const PixelBufferAccess &errorImage)
4576 {
4577 const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
4578 const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
4579 bool ok = true;
4580
4581 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4582 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4583 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4584
4585 for (int y = 0; y < result.getHeight(); y++)
4586 for (int x = 0; x < result.getWidth(); x++)
4587 {
4588 bool pixelOk = true;
4589
4590 const uint32_t resultStencil = result.getPixStencil(x, y);
4591 const PixelValue &referenceValue = reference[x + y * result.getWidth()];
4592 const Maybe<bool> maybeValue = referenceValue.getValue(1);
4593
4594 if (maybeValue)
4595 {
4596 const bool value = *maybeValue;
4597
4598 if ((value && (resultStencil != 0xFFu)) || (!value && resultStencil != 0x0u))
4599 pixelOk = false;
4600 }
4601
4602 if (!pixelOk)
4603 {
4604 errorImage.setPixel(red, x, y);
4605 ok = false;
4606 }
4607 else
4608 errorImage.setPixel(green, x, y);
4609 }
4610
4611 return ok;
4612 }
4613
logAndVerifyImages(TestLog & log,const DeviceInterface & vk,VkDevice device,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<bool> & attachmentIsLazy,const RenderPass & renderPassInfo,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & targetSize,const TestConfig & config)4614 bool logAndVerifyImages(TestLog &log, const DeviceInterface &vk, VkDevice device,
4615 const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
4616 const vector<bool> &attachmentIsLazy, const RenderPass &renderPassInfo,
4617 const vector<Maybe<VkClearValue>> &renderPassClearValues,
4618 const vector<Maybe<VkClearValue>> &imageClearValues,
4619 const vector<SubpassRenderInfo> &subpassRenderInfo, const UVec2 &targetSize,
4620 const TestConfig &config)
4621 {
4622 vector<vector<PixelValue>> referenceValues;
4623 vector<tcu::TextureLevel> referenceAttachments;
4624 bool isOk = true;
4625
4626 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
4627
4628 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues,
4629 subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx,
4630 config.depthValues);
4631 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo,
4632 config.depthValues);
4633
4634 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4635 {
4636 if (!attachmentIsLazy[attachmentNdx])
4637 {
4638 bool attachmentOK = true;
4639 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
4640 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4641
4642 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
4643 {
4644 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
4645 void *const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4646
4647 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
4648 void *const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
4649
4650 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4651 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());
4652
4653 {
4654 bool depthOK = true;
4655 bool stencilOK = true;
4656 const ConstPixelBufferAccess depthAccess(depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
4657 const ConstPixelBufferAccess stencilAccess(stencilFormat, targetSize.x(), targetSize.y(), 1,
4658 stencilPtr);
4659 tcu::TextureLevel depthErrorImage(
4660 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
4661 targetSize.y());
4662 tcu::TextureLevel stencilErrorImage(
4663 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
4664 targetSize.y());
4665
4666 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE &&
4667 !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(),
4668 config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4669 {
4670 depthOK = false;
4671 }
4672
4673 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
4674 VK_ATTACHMENT_STORE_OP_STORE &&
4675 !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess,
4676 stencilErrorImage.getAccess()))
4677 {
4678 stencilOK = false;
4679 }
4680
4681 if (!depthOK || !stencilOK)
4682 {
4683 const auto attachmentNdxStr = de::toString(attachmentNdx);
4684
4685 // Output images.
4686 log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr,
4687 "Output depth and stencil attachments " + attachmentNdxStr);
4688 log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth",
4689 "Attachment " + attachmentNdxStr + " Depth", depthAccess);
4690 log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil",
4691 "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
4692 log << TestLog::EndImageSet;
4693
4694 // Reference images. These will be logged as image sets due to having depth and stencil aspects.
4695 log << TestLog::Image("AttachmentReferences" + attachmentNdxStr,
4696 "Reference images " + attachmentNdxStr,
4697 referenceAttachments[attachmentNdx].getAccess());
4698
4699 // Error masks.
4700 log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
4701 if (!depthOK)
4702 log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr,
4703 "Depth Attachment Error " + attachmentNdxStr,
4704 depthErrorImage.getAccess());
4705 if (!stencilOK)
4706 log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr,
4707 "Stencil Attachment Error " + attachmentNdxStr,
4708 stencilErrorImage.getAccess());
4709 log << TestLog::EndImageSet;
4710
4711 attachmentOK = false;
4712 }
4713 }
4714 }
4715 else
4716 {
4717 void *const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4718
4719 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4720
4721 bool depthOK = true;
4722 bool stencilOK = true;
4723 bool colorOK = true;
4724 const ConstPixelBufferAccess access(format, targetSize.x(), targetSize.y(), 1, ptr);
4725 tcu::TextureLevel errorImage(
4726 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
4727 targetSize.y());
4728
4729 if (tcu::hasDepthComponent(format.order))
4730 {
4731 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
4732 renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
4733 VK_ATTACHMENT_STORE_OP_STORE) &&
4734 !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(),
4735 config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4736 {
4737 depthOK = false;
4738 }
4739 }
4740 else if (tcu::hasStencilComponent(format.order))
4741 {
4742 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
4743 renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
4744 VK_ATTACHMENT_STORE_OP_STORE) &&
4745 !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
4746 {
4747 stencilOK = false;
4748 }
4749 }
4750 else
4751 {
4752 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
4753 renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
4754 VK_ATTACHMENT_STORE_OP_STORE) &&
4755 !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(),
4756 config.useFormatCompCount))
4757 {
4758 colorOK = false;
4759 }
4760 }
4761
4762 if (!depthOK || !stencilOK || !colorOK)
4763 {
4764 log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
4765 if (!depthOK || !stencilOK)
4766 {
4767 // Log without conversions.
4768 log << TestLog::Image("Attachment" + de::toString(attachmentNdx),
4769 "Attachment " + de::toString(attachmentNdx), access);
4770 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx),
4771 "Attachment reference " + de::toString(attachmentNdx),
4772 referenceAttachments[attachmentNdx].getAccess());
4773 }
4774 else
4775 {
4776 // Convert color images to better reflect test status and output in any format.
4777 const auto numChannels = getShaderNumChannels(access.getFormat().order);
4778 const auto attachmentForLog = renderColorImageForLog(access, numChannels);
4779 const auto referenceForLog =
4780 renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);
4781
4782 log << TestLog::Message
4783 << "Check the attachment formats and test data to verify which components affect the test "
4784 "result."
4785 << TestLog::EndMessage;
4786 log << TestLog::Message
4787 << "In the reference image, unset pixel components are marked with a 3x3 grid storing "
4788 "values 0.0 and 0.25, pixel components set to false are stored as 0.5 and pixel "
4789 "components set to true are stored as 1.0."
4790 << TestLog::EndMessage;
4791 log << TestLog::Message
4792 << "Output attachment pixel components are always set to 0.5 or 1.0 but may not be taken "
4793 "into account if not set in the reference image."
4794 << TestLog::EndMessage;
4795
4796 log << TestLog::Image("Attachment" + de::toString(attachmentNdx),
4797 "Attachment " + de::toString(attachmentNdx),
4798 attachmentForLog->getAccess());
4799 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx),
4800 "Attachment reference " + de::toString(attachmentNdx),
4801 referenceForLog->getAccess());
4802 }
4803 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx),
4804 "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
4805 log << TestLog::EndImageSet;
4806
4807 attachmentOK = false;
4808 }
4809 }
4810
4811 if (!attachmentOK)
4812 isOk = false;
4813 }
4814 }
4815
4816 return isOk;
4817 }
4818
getInputAttachmentType(VkFormat vkFormat)4819 std::string getInputAttachmentType(VkFormat vkFormat)
4820 {
4821 const tcu::TextureFormat format = mapVkFormat(vkFormat);
4822 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4823
4824 switch (channelClass)
4825 {
4826 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4827 return "isubpassInput";
4828
4829 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4830 return "usubpassInput";
4831
4832 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4833 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4834 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4835 return "subpassInput";
4836
4837 default:
4838 DE_FATAL("Unknown channel class");
4839 return "";
4840 }
4841 }
4842
getAttachmentType(VkFormat vkFormat,bool useFormatCompCount)4843 std::string getAttachmentType(VkFormat vkFormat, bool useFormatCompCount)
4844 {
4845 const tcu::TextureFormat format = mapVkFormat(vkFormat);
4846 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4847 const size_t componentCount = (size_t)getShaderNumChannels(format.order);
4848
4849 switch (channelClass)
4850 {
4851 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4852 if (useFormatCompCount)
4853 return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
4854 else
4855 return "ivec4";
4856
4857 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4858 if (useFormatCompCount)
4859 return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
4860 else
4861 return "uvec4";
4862
4863 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4864 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4865 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4866 if (useFormatCompCount)
4867 return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
4868 else
4869 return "vec4";
4870
4871 default:
4872 DE_FATAL("Unknown channel class");
4873 return "";
4874 }
4875 }
4876
createTestShaders(SourceCollections & dst,TestConfig config)4877 void createTestShaders(SourceCollections &dst, TestConfig config)
4878 {
4879 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4880 {
4881 const vector<Subpass> &subpasses = config.renderPass.getSubpasses();
4882
4883 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4884 {
4885 const Subpass &subpass = subpasses[subpassNdx];
4886 uint32_t inputAttachmentBinding = 0;
4887 std::ostringstream vertexShader;
4888 std::ostringstream fragmentShader;
4889
4890 vertexShader << "#version 310 es\n"
4891 << "layout(location = 0) in highp vec2 a_position;\n"
4892 << "void main (void) {\n"
4893 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
4894 << "}\n";
4895
4896 fragmentShader << "#version 310 es\n"
4897 << "precision highp float;\n";
4898
4899 bool hasAnyDepthFormats = false;
4900
4901 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size();
4902 attachmentNdx++)
4903 {
4904 const uint32_t attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4905 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4906 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4907 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4908 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
4909 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
4910
4911 if (isDepthFormat || isStencilFormat)
4912 {
4913 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4914 {
4915 hasAnyDepthFormats = true;
4916 fragmentShader << "layout(input_attachment_index = " << attachmentNdx
4917 << ", set=0, binding=" << inputAttachmentBinding
4918 << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
4919 inputAttachmentBinding++;
4920 }
4921
4922 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4923 {
4924 fragmentShader << "layout(input_attachment_index = " << attachmentNdx
4925 << ", set=0, binding=" << inputAttachmentBinding
4926 << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
4927 inputAttachmentBinding++;
4928 }
4929 }
4930 else
4931 {
4932 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
4933
4934 fragmentShader << "layout(input_attachment_index = " << attachmentNdx
4935 << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp "
4936 << attachmentType << " i_color" << attachmentNdx << ";\n";
4937 inputAttachmentBinding++;
4938 }
4939 }
4940
4941 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
4942 attachmentNdx++)
4943 {
4944 const std::string attachmentType = getAttachmentType(
4945 config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)]
4946 .getFormat(),
4947 config.useFormatCompCount);
4948 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType
4949 << " o_color" << attachmentNdx << ";\n";
4950 }
4951
4952 if (hasAnyDepthFormats)
4953 fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
4954 << "\treturn abs(a - b) <= epsilon;\n}\n\n";
4955
4956 fragmentShader << "void main (void) {\n";
4957
4958 if (subpass.getInputAttachments().empty())
4959 {
4960 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
4961 attachmentNdx++)
4962 {
4963 const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4964
4965 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4966 continue;
4967
4968 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4969 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4970 const size_t componentCount =
4971 config.useFormatCompCount ? (size_t)getShaderNumChannels(format.order) : 4;
4972 const std::string attachmentType =
4973 getAttachmentType(attachment.getFormat(), config.useFormatCompCount);
4974
4975 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "("
4976 << attachmentType + "(";
4977
4978 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4979 {
4980 const size_t index = subpassNdx + attachmentIndex + compNdx;
4981 const BoolOp op = boolOpFromIndex(index);
4982
4983 if (compNdx > 0)
4984 fragmentShader << ",\n\t\t";
4985
4986 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2) << ") " << boolOpToString(op)
4987 << " ("
4988 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ") ? 1.0 : 0.0)";
4989 }
4990
4991 fragmentShader << "));\n";
4992 }
4993
4994 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
4995 subpass.getDepthStencilAttachment().getImageLayout() !=
4996 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
4997 subpass.getDepthStencilAttachment().getImageLayout() !=
4998 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4999 {
5000 const size_t index = subpassNdx + 1;
5001 const BoolOp op = boolOpFromIndex(index);
5002
5003 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2) << ") "
5004 << boolOpToString(op) << " ("
5005 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ") ? "
5006 << uint32_t(config.depthValues[1])
5007 << ".0f/255.0f : " << uint32_t(config.depthValues[0]) << ".0f/255.0f);\n";
5008 }
5009 }
5010 else
5011 {
5012 size_t inputComponentCount = 0;
5013 size_t outputComponentCount = 0;
5014
5015 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size();
5016 attachmentNdx++)
5017 {
5018 const uint32_t attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
5019 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
5020 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
5021 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5022 const size_t componentCount = (size_t)getShaderNumChannels(format.order);
5023
5024 if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5025 inputComponentCount += 1;
5026 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
5027 inputComponentCount += 1;
5028 else
5029 inputComponentCount += componentCount;
5030 }
5031
5032 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
5033 attachmentNdx++)
5034 {
5035 const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
5036 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
5037 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5038 const size_t componentCount = (size_t)getShaderNumChannels(format.order);
5039
5040 outputComponentCount += componentCount;
5041 }
5042
5043 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
5044 subpass.getDepthStencilAttachment().getImageLayout() !=
5045 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
5046 subpass.getDepthStencilAttachment().getImageLayout() !=
5047 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5048 {
5049 outputComponentCount++;
5050 }
5051
5052 if (outputComponentCount > 0)
5053 {
5054 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount ?
5055 ((inputComponentCount / outputComponentCount) +
5056 ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0)) :
5057 1;
5058
5059 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
5060
5061 if (outputComponentCount > 0)
5062 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
5063
5064 size_t inputValueNdx = 0;
5065
5066 for (size_t attachmentNdx = config.drawStartNdx;
5067 attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
5068 {
5069 const char *const components[] = {"x", "y", "z", "w"};
5070 const uint32_t attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
5071 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
5072 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
5073 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5074 const size_t componentCount = (size_t)getShaderNumChannels(format.order);
5075 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
5076 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
5077
5078 if (isDepthFormat || isStencilFormat)
5079 {
5080 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
5081 {
5082 fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual("
5083 << uint32_t(config.depthValues[1])
5084 << ".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), "
5085 << std::fixed << std::setprecision(12)
5086 << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
5087 inputValueNdx++;
5088 }
5089
5090 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5091 {
5092 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil"
5093 << attachmentNdx << ").x;\n";
5094 inputValueNdx++;
5095 }
5096 }
5097 else
5098 {
5099 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
5100 {
5101 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color"
5102 << attachmentNdx << ")." << components[compNdx] << ");\n";
5103 inputValueNdx++;
5104 }
5105 }
5106 }
5107
5108 size_t outputValueNdx = 0;
5109
5110 for (size_t attachmentNdx = config.drawStartNdx;
5111 attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
5112 {
5113 const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
5114 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
5115 const std::string attachmentType = getAttachmentType(
5116 config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
5117 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5118 const size_t componentCount = (size_t)getShaderNumChannels(format.order);
5119
5120 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
5121 {
5122 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
5123 const BoolOp op = boolOpFromIndex(index);
5124
5125 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
5126 << "(int(gl_FragCoord.x) % 2 == " << (index % 2) << ") "
5127 << boolOpToString(op) << " ("
5128 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ");\n";
5129
5130 for (size_t i = 0; i < inputsPerOutput; i++)
5131 fragmentShader
5132 << "\toutputs[" << outputValueNdx + compNdx << "] = outputs["
5133 << outputValueNdx + compNdx << "] == inputs["
5134 << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount
5135 << "];\n";
5136 }
5137
5138 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
5139
5140 for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
5141 {
5142 if (compNdx > 0)
5143 fragmentShader << ", ";
5144
5145 if (compNdx < componentCount)
5146 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
5147 else
5148 fragmentShader << "0";
5149 }
5150
5151 outputValueNdx += componentCount;
5152
5153 fragmentShader << ");\n";
5154 }
5155
5156 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
5157 subpass.getDepthStencilAttachment().getImageLayout() !=
5158 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
5159 subpass.getDepthStencilAttachment().getImageLayout() !=
5160 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5161 {
5162 const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
5163 const size_t index = subpassNdx + attachmentIndex;
5164 const BoolOp op = boolOpFromIndex(index);
5165
5166 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
5167 << "(int(gl_FragCoord.x) % 2 == " << (index % 2) << ") " << boolOpToString(op)
5168 << " ("
5169 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ");\n";
5170
5171 for (size_t i = 0; i < inputsPerOutput; i++)
5172 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx
5173 << "] == inputs["
5174 << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
5175
5176 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? "
5177 << uint32_t(config.depthValues[1])
5178 << ".0f/255.0f : " << uint32_t(config.depthValues[0]) << ".0f/255.0f;\n";
5179 }
5180 }
5181 }
5182
5183 fragmentShader << "}\n";
5184
5185 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
5186 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
5187 }
5188 }
5189 }
5190
initializeAttachmentIsLazy(vector<bool> & attachmentIsLazy,const vector<Attachment> & attachments,TestConfig::ImageMemory imageMemory)5191 void initializeAttachmentIsLazy(vector<bool> &attachmentIsLazy, const vector<Attachment> &attachments,
5192 TestConfig::ImageMemory imageMemory)
5193 {
5194 bool lastAttachmentWasLazy = false;
5195
5196 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5197 {
5198 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD &&
5199 attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE &&
5200 attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD &&
5201 attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
5202 {
5203 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY ||
5204 (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
5205 {
5206 attachmentIsLazy.push_back(true);
5207
5208 lastAttachmentWasLazy = true;
5209 }
5210 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
5211 {
5212 attachmentIsLazy.push_back(false);
5213 lastAttachmentWasLazy = false;
5214 }
5215 else
5216 DE_FATAL("Unknown imageMemory");
5217 }
5218 else
5219 attachmentIsLazy.push_back(false);
5220 }
5221 }
5222
5223 enum AttachmentRefType
5224 {
5225 ATTACHMENTREFTYPE_COLOR,
5226 ATTACHMENTREFTYPE_DEPTH_STENCIL,
5227 ATTACHMENTREFTYPE_INPUT,
5228 ATTACHMENTREFTYPE_RESOLVE,
5229 };
5230
getImageUsageFromLayout(VkImageLayout layout)5231 VkImageUsageFlags getImageUsageFromLayout(VkImageLayout layout)
5232 {
5233 switch (layout)
5234 {
5235 case VK_IMAGE_LAYOUT_GENERAL:
5236 case VK_IMAGE_LAYOUT_PREINITIALIZED:
5237 return 0;
5238
5239 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
5240 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
5241
5242 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
5243 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
5244 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
5245
5246 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
5247 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5248
5249 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
5250 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
5251
5252 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
5253 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
5254
5255 default:
5256 DE_FATAL("Unexpected image layout");
5257 return 0;
5258 }
5259 }
5260
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,size_t count,const AttachmentReference * references)5261 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> &attachmentImageUsage, AttachmentRefType refType,
5262 size_t count, const AttachmentReference *references)
5263 {
5264 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
5265 {
5266 const uint32_t attachment = references[referenceNdx].getAttachment();
5267
5268 if (attachment != VK_ATTACHMENT_UNUSED)
5269 {
5270 VkImageUsageFlags usage;
5271
5272 switch (refType)
5273 {
5274 case ATTACHMENTREFTYPE_COLOR:
5275 case ATTACHMENTREFTYPE_RESOLVE:
5276 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
5277 break;
5278
5279 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
5280 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
5281 break;
5282
5283 case ATTACHMENTREFTYPE_INPUT:
5284 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5285 break;
5286
5287 default:
5288 DE_FATAL("Unexpected attachment reference type");
5289 usage = 0;
5290 break;
5291 }
5292
5293 attachmentImageUsage[attachment] |= usage;
5294 }
5295 }
5296 }
5297
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,const vector<AttachmentReference> & references)5298 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> &attachmentImageUsage, AttachmentRefType refType,
5299 const vector<AttachmentReference> &references)
5300 {
5301 if (!references.empty())
5302 {
5303 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
5304 }
5305 }
5306
initializeAttachmentImageUsage(Context & context,vector<VkImageUsageFlags> & attachmentImageUsage,const RenderPass & renderPassInfo,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & clearValues)5307 void initializeAttachmentImageUsage(Context &context, vector<VkImageUsageFlags> &attachmentImageUsage,
5308 const RenderPass &renderPassInfo, const vector<bool> &attachmentIsLazy,
5309 const vector<Maybe<VkClearValue>> &clearValues)
5310 {
5311 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
5312
5313 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
5314 {
5315 const Subpass &subpass = renderPassInfo.getSubpasses()[subpassNdx];
5316
5317 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR,
5318 subpass.getColorAttachments());
5319 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1,
5320 &subpass.getDepthStencilAttachment());
5321 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT,
5322 subpass.getInputAttachments());
5323 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE,
5324 subpass.getResolveAttachments());
5325 }
5326
5327 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5328 {
5329 const Attachment &attachment = renderPassInfo.getAttachments()[attachmentNdx];
5330 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(
5331 context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
5332 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
5333
5334 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
5335 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
5336
5337 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
5338 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
5339
5340 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
5341 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
5342
5343 if (!attachmentIsLazy[attachmentNdx])
5344 {
5345 if (clearValues[attachmentNdx])
5346 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
5347
5348 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
5349 }
5350 else
5351 {
5352 const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(
5353 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
5354 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
5355
5356 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
5357 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
5358 }
5359 }
5360 }
5361
initializeSubpassIsSecondary(vector<bool> & subpassIsSecondary,const vector<Subpass> & subpasses,TestConfig::CommandBufferTypes commandBuffer)5362 void initializeSubpassIsSecondary(vector<bool> &subpassIsSecondary, const vector<Subpass> &subpasses,
5363 TestConfig::CommandBufferTypes commandBuffer)
5364 {
5365 bool lastSubpassWasSecondary = false;
5366
5367 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
5368 {
5369 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY ||
5370 (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
5371 {
5372 subpassIsSecondary.push_back(true);
5373 lastSubpassWasSecondary = true;
5374 }
5375 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
5376 {
5377 subpassIsSecondary.push_back(false);
5378 lastSubpassWasSecondary = false;
5379 }
5380 else
5381 DE_FATAL("Unknown commandBuffer");
5382 }
5383 }
5384
initializeImageClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,const vector<bool> & isLazy,bool useFormatCompCount,const DepthValuesArray & depthValues)5385 void initializeImageClearValues(de::Random &rng, vector<Maybe<VkClearValue>> &clearValues,
5386 const vector<Attachment> &attachments, const vector<bool> &isLazy,
5387 bool useFormatCompCount, const DepthValuesArray &depthValues)
5388 {
5389 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5390 {
5391 if (!isLazy[attachmentNdx])
5392 clearValues.push_back(
5393 just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
5394 else
5395 clearValues.push_back(tcu::Nothing);
5396 }
5397 }
5398
initializeRenderPassClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,bool useFormatCompCount,const DepthValuesArray & depthValues)5399 void initializeRenderPassClearValues(de::Random &rng, vector<Maybe<VkClearValue>> &clearValues,
5400 const vector<Attachment> &attachments, bool useFormatCompCount,
5401 const DepthValuesArray &depthValues)
5402 {
5403 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5404 {
5405 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR ||
5406 attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
5407 {
5408 clearValues.push_back(
5409 just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
5410 }
5411 else
5412 clearValues.push_back(tcu::Nothing);
5413 }
5414 }
5415
logSubpassRenderInfo(TestLog & log,const SubpassRenderInfo & info,TestConfig config)5416 void logSubpassRenderInfo(TestLog &log, const SubpassRenderInfo &info, TestConfig config)
5417 {
5418 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize()
5419 << TestLog::EndMessage;
5420
5421 if (info.isSecondary())
5422 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
5423 else
5424 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
5425
5426 for (uint32_t attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
5427 {
5428 const ColorClear &colorClear = info.getColorClears()[attachmentNdx];
5429
5430 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
5431 << ". Offset: " << colorClear.getOffset() << ", Size: " << colorClear.getSize() << ", Color: "
5432 << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(),
5433 config.useFormatCompCount)
5434 << TestLog::EndMessage;
5435 }
5436
5437 if (info.getDepthStencilClear())
5438 {
5439 const DepthStencilClear &depthStencilClear = *info.getDepthStencilClear();
5440
5441 log << TestLog::Message << "Clearing depth stencil attachment"
5442 << ". Offset: " << depthStencilClear.getOffset() << ", Size: " << depthStencilClear.getSize()
5443 << ", Depth: " << depthStencilClear.getDepth() << ", Stencil: " << depthStencilClear.getStencil()
5444 << TestLog::EndMessage;
5445 }
5446
5447 if (info.getRenderQuad())
5448 {
5449 const RenderQuad &renderQuad = *info.getRenderQuad();
5450
5451 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> "
5452 << renderQuad.getCornerB() << TestLog::EndMessage;
5453 }
5454 }
5455
logTestCaseInfo(TestLog & log,const TestConfig & config,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo)5456 void logTestCaseInfo(TestLog &log, const TestConfig &config, const vector<bool> &attachmentIsLazy,
5457 const vector<Maybe<VkClearValue>> &imageClearValues,
5458 const vector<Maybe<VkClearValue>> &renderPassClearValues,
5459 const vector<SubpassRenderInfo> &subpassRenderInfo)
5460 {
5461 const RenderPass &renderPass = config.renderPass;
5462
5463 logRenderPassInfo(log, renderPass);
5464
5465 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
5466 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
5467 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
5468
5469 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
5470 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize
5471 << TestLog::EndMessage;
5472
5473 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
5474 {
5475 const tcu::ScopedLogSection section(log, "Attachment" + de::toString(attachmentNdx),
5476 "Attachment " + de::toString(attachmentNdx));
5477
5478 if (attachmentIsLazy[attachmentNdx])
5479 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
5480
5481 if (imageClearValues[attachmentNdx])
5482 log << TestLog::Message << "Image is cleared to "
5483 << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
5484 *imageClearValues[attachmentNdx], config.useFormatCompCount)
5485 << " before rendering." << TestLog::EndMessage;
5486
5487 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR &&
5488 renderPassClearValues[attachmentNdx])
5489 log << TestLog::Message << "Attachment is cleared to "
5490 << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
5491 *renderPassClearValues[attachmentNdx], config.useFormatCompCount)
5492 << " in the beginning of the render pass." << TestLog::EndMessage;
5493 }
5494
5495 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
5496 {
5497 const tcu::ScopedLogSection section(log, "Subpass" + de::toString(subpassNdx),
5498 "Subpass " + de::toString(subpassNdx));
5499
5500 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
5501 }
5502 }
5503
roundToViewport(float x,uint32_t offset,uint32_t size)5504 float roundToViewport(float x, uint32_t offset, uint32_t size)
5505 {
5506 const float origin = (float)(offset) + ((float(size) / 2.0f));
5507 const float p = (float)(size) / 2.0f;
5508 const int32_t xi = deRoundFloatToInt32(origin + (p * x));
5509
5510 return (((float)xi) - origin) / p;
5511 }
5512
initializeSubpassRenderInfo(vector<SubpassRenderInfo> & renderInfos,de::Random & rng,const RenderPass & renderPass,const TestConfig & config)5513 void initializeSubpassRenderInfo(vector<SubpassRenderInfo> &renderInfos, de::Random &rng, const RenderPass &renderPass,
5514 const TestConfig &config)
5515 {
5516 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
5517 const vector<Subpass> &subpasses = renderPass.getSubpasses();
5518 bool lastSubpassWasSecondary = false;
5519
5520 // mixing using secondary command buffers and recording draw calls inline
5521 // is legal with renderpasses (as the render pass contents was set per subpass),
5522 // but for dynamic rendering the contents flag is set on the whole dynamic render
5523 const bool isMultiPassDynamicRendering =
5524 (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) && (subpasses.size() > 1u);
5525 const bool alternateSecondaryCmdBuff =
5526 (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY) && !isMultiPassDynamicRendering;
5527
5528 for (uint32_t subpassNdx = 0; subpassNdx < (uint32_t)subpasses.size(); subpassNdx++)
5529 {
5530 const Subpass &subpass = subpasses[subpassNdx];
5531 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY ||
5532 (alternateSecondaryCmdBuff && !lastSubpassWasSecondary) ?
5533 true :
5534 false;
5535 const bool omitBlendState = subpass.getOmitBlendState();
5536 const UVec2 viewportSize((config.renderSize * UVec2(2)) / UVec2(3));
5537 const UVec2 viewportOffset(config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
5538 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
5539
5540 vector<ColorClear> colorClears;
5541 Maybe<DepthStencilClear> depthStencilClear;
5542 Maybe<RenderQuad> renderQuad;
5543
5544 lastSubpassWasSecondary = subpassIsSecondary;
5545
5546 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
5547 {
5548 const vector<AttachmentReference> &colorAttachments = subpass.getColorAttachments();
5549
5550 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
5551 {
5552 const AttachmentReference &attachmentRef = colorAttachments[attachmentRefNdx];
5553 const Attachment &attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
5554 const UVec2 size((viewportSize * UVec2(2)) / UVec2(3));
5555 const UVec2 offset(viewportOffset.x() + ((uint32_t)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
5556 viewportOffset.y() +
5557 (((uint32_t)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
5558 const VkClearColorValue color = randomColorClearValue(attachment, rng, config.useFormatCompCount);
5559
5560 colorClears.push_back(ColorClear(offset, size, color));
5561 }
5562
5563 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
5564 {
5565 const Attachment &attachment =
5566 renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
5567 const UVec2 size((viewportSize * UVec2(2)) / UVec2(3));
5568 const UVec2 offset(
5569 viewportOffset.x() + ((uint32_t)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
5570 viewportOffset.y() + (((uint32_t)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
5571 const VkClearValue value =
5572 randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);
5573
5574 depthStencilClear =
5575 tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
5576 }
5577 }
5578
5579 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
5580 {
5581 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
5582 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
5583
5584 const float x0 =
5585 roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
5586 const float x1 =
5587 roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
5588
5589 const float y0 =
5590 roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
5591 const float y1 =
5592 roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
5593
5594 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
5595 }
5596
5597 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary,
5598 omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears,
5599 depthStencilClear));
5600 }
5601 }
5602
checkTextureFormatSupport(TestLog & log,const InstanceInterface & vk,VkPhysicalDevice device,const vector<Attachment> & attachments)5603 void checkTextureFormatSupport(TestLog &log, const InstanceInterface &vk, VkPhysicalDevice device,
5604 const vector<Attachment> &attachments)
5605 {
5606 bool supported = true;
5607
5608 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5609 {
5610 const Attachment &attachment = attachments[attachmentNdx];
5611 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5612 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
5613 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT :
5614 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
5615 VkFormatProperties properties;
5616
5617 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
5618
5619 if ((properties.optimalTilingFeatures & flags) != flags)
5620 {
5621 supported = false;
5622 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as "
5623 << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment")
5624 << TestLog::EndMessage;
5625 }
5626 }
5627
5628 if (!supported)
5629 TCU_THROW(NotSupportedError, "Format not supported");
5630 }
5631
renderPassTest(Context & context,TestConfig config)5632 tcu::TestStatus renderPassTest(Context &context, TestConfig config)
5633 {
5634 const UVec2 targetSize = config.targetSize;
5635 const UVec2 renderPos = config.renderPos;
5636 const UVec2 renderSize = config.renderSize;
5637 const RenderPass &renderPassInfo = config.renderPass;
5638 const InstanceInterface &vki = context.getInstanceInterface();
5639 const VkPhysicalDevice &physDevice = context.getPhysicalDevice();
5640 const auto &properties = getPhysicalDeviceProperties(vki, physDevice);
5641
5642 TestLog &log = context.getTestContext().getLog();
5643 de::Random rng(config.seed);
5644
5645 vector<bool> attachmentIsLazy;
5646 vector<VkImageUsageFlags> attachmentImageUsage;
5647 vector<Maybe<VkClearValue>> imageClearValues;
5648 vector<Maybe<VkClearValue>> renderPassClearValues;
5649
5650 vector<bool> subpassIsSecondary;
5651 vector<SubpassRenderInfo> subpassRenderInfo;
5652
5653 #ifndef CTS_USES_VULKANSC
5654 for (const auto &att : renderPassInfo.getAttachments())
5655 {
5656 if (att.getFormat() == VK_FORMAT_A8_UNORM_KHR)
5657 {
5658 context.requireDeviceFunctionality("VK_KHR_maintenance5");
5659 break;
5660 }
5661 }
5662 #endif // CTS_USES_VULKANSC
5663
5664 if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
5665 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
5666
5667 if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5668 {
5669 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
5670
5671 // check if thare are multiple subpasses
5672 if (renderPassInfo.getSubpasses().size() > 1u)
5673 {
5674 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
5675
5676 std::vector<uint32_t> colorAttachmentIndices;
5677 std::vector<VkFormat> colorAttachmentFormats;
5678 findColorAttachments(renderPassInfo, colorAttachmentIndices, colorAttachmentFormats);
5679 if (colorAttachmentIndices.size() > (size_t)properties.limits.maxColorAttachments)
5680 TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");
5681 }
5682 }
5683
5684 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
5685 {
5686 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
5687 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
5688 }
5689
5690 if (!renderPassInfo.getInputAspects().empty())
5691 {
5692 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5693 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
5694 }
5695
5696 checkPipelineConstructionRequirements(vki, physDevice, config.groupParams->pipelineConstructionType);
5697
5698 {
5699 bool requireDepthStencilLayout = false;
5700
5701 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5702 {
5703 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() ==
5704 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5705 renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() ==
5706 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
5707 renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() ==
5708 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5709 renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() ==
5710 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5711 {
5712 requireDepthStencilLayout = true;
5713 break;
5714 }
5715 }
5716
5717 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout;
5718 subpassNdx++)
5719 {
5720 const Subpass &subpass(renderPassInfo.getSubpasses()[subpassNdx]);
5721
5722 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
5723 {
5724 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() ==
5725 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5726 subpass.getColorAttachments()[attachmentNdx].getImageLayout() ==
5727 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5728 {
5729 requireDepthStencilLayout = true;
5730 break;
5731 }
5732 }
5733
5734 for (size_t attachmentNdx = 0;
5735 !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
5736 {
5737 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() ==
5738 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5739 subpass.getInputAttachments()[attachmentNdx].getImageLayout() ==
5740 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5741 {
5742 requireDepthStencilLayout = true;
5743 break;
5744 }
5745 }
5746
5747 for (size_t attachmentNdx = 0;
5748 !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
5749 {
5750 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() ==
5751 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5752 subpass.getResolveAttachments()[attachmentNdx].getImageLayout() ==
5753 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5754 {
5755 requireDepthStencilLayout = true;
5756 break;
5757 }
5758 }
5759
5760 if (subpass.getDepthStencilAttachment().getImageLayout() ==
5761 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
5762 subpass.getDepthStencilAttachment().getImageLayout() ==
5763 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5764 {
5765 requireDepthStencilLayout = true;
5766 break;
5767 }
5768 }
5769
5770 if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5771 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
5772 }
5773
5774 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
5775 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy,
5776 config.useFormatCompCount, config.depthValues);
5777 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
5778 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(),
5779 config.useFormatCompCount, config.depthValues);
5780
5781 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
5782 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
5783
5784 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
5785
5786 checkTextureFormatSupport(log, vki, physDevice, config.renderPass.getAttachments());
5787
5788 {
5789 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments
5790 << TestLog::EndMessage;
5791
5792 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5793 {
5794 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() >
5795 (size_t)properties.limits.maxColorAttachments)
5796 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
5797 }
5798 }
5799
5800 {
5801 const VkDevice device = context.getDevice();
5802 const DeviceInterface &vk = context.getDeviceInterface();
5803 const VkQueue queue = context.getUniversalQueue();
5804 const uint32_t queueIndex = context.getUniversalQueueFamilyIndex();
5805 Allocator &allocator = context.getDefaultAllocator();
5806
5807 const Unique<VkCommandPool> commandBufferPool(createCommandPool(vk, device, 0, queueIndex));
5808 const Unique<VkCommandBuffer> initializeImagesCommandBuffer(
5809 allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5810 const Unique<VkCommandBuffer> renderCommandBuffer(
5811 allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5812 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer(
5813 allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5814
5815 vector<de::SharedPtr<AttachmentResources>> attachmentResources;
5816 vector<de::SharedPtr<SubpassRenderer>> subpassRenderers;
5817 vector<VkImage> attachmentImages;
5818 vector<VkImageView> attachmentViews;
5819 vector<pair<VkImageView, VkImageView>> inputAttachmentViews;
5820
5821 Move<VkRenderPass> renderPass;
5822 if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5823 renderPass = createRenderPass(vk, device, renderPassInfo, config.groupParams->renderingType);
5824
5825 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5826 {
5827 const Attachment &attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
5828
5829 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(
5830 new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo,
5831 attachmentImageUsage[attachmentNdx], config.allocationKind)));
5832 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
5833 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
5834
5835 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
5836 }
5837
5838 beginCommandBuffer(vk, *initializeImagesCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0,
5839 (VkQueryPipelineStatisticFlags)0);
5840 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(),
5841 attachmentResources, queueIndex, imageClearValues);
5842 endCommandBuffer(vk, *initializeImagesCommandBuffer);
5843
5844 {
5845 Move<VkFramebuffer> framebuffer;
5846 if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5847 framebuffer = createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews);
5848
5849 const VkRect2D renderArea{{(int32_t)renderPos.x(), (int32_t)renderPos.y()},
5850 {renderSize.x(), renderSize.y()}};
5851 const bool secondaryCmdBufferCompletelyContainsDynamicRenderpass =
5852 (config.commandBufferTypes == TestConfig::COMMANDBUFFERTYPES_SECONDARY) &&
5853 config.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass;
5854
5855 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5856 {
5857 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(
5858 context, vk, device, allocator, renderPassInfo, attachmentResources, renderArea,
5859 renderPassClearValues, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages,
5860 inputAttachmentViews, subpassRenderInfo[subpassNdx], config)));
5861 }
5862
5863 beginCommandBuffer(vk, *renderCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0,
5864 (VkQueryPipelineStatisticFlags)0);
5865 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, renderPassInfo, attachmentResources,
5866 *framebuffer, subpassRenderers, renderArea, renderPassClearValues, queueIndex,
5867 config, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
5868 endCommandBuffer(vk, *renderCommandBuffer);
5869
5870 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE,
5871 (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5872 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources,
5873 renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
5874 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
5875 {
5876 const VkCommandBuffer commandBuffers[] = {*initializeImagesCommandBuffer, *renderCommandBuffer,
5877 *readImagesToBuffersCommandBuffer};
5878 const Unique<VkFence> fence(createFence(vk, device, 0u));
5879
5880 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
5881 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
5882 }
5883 }
5884 #ifdef CTS_USES_VULKANSC
5885 if (!context.getTestContext().getCommandLine().isSubProcess())
5886 return tcu::TestStatus::pass("Pass");
5887 #endif
5888 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo,
5889 renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
5890 return tcu::TestStatus::pass("Pass");
5891 else
5892 return tcu::TestStatus::fail("Result verification failed");
5893 }
5894 }
5895
5896 class RenderPassNoDrawLoadStoreTestCase : public vkt::TestCase
5897 {
5898 public:
5899 RenderPassNoDrawLoadStoreTestCase(tcu::TestContext &context, const std::string &name,
5900 const SharedGroupParams groupParams);
5901 TestInstance *createInstance(Context &context) const override;
5902 void checkSupport(Context &context) const override;
5903
5904 private:
5905 const SharedGroupParams m_groupParams;
5906 };
5907
5908 class RenderPassNoDrawLoadStoreTestInstance : public vkt::TestInstance
5909 {
5910 public:
5911 RenderPassNoDrawLoadStoreTestInstance(Context &context, const SharedGroupParams groupParams);
5912
5913 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
5914 typename RenderPassCreateInfo>
5915 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice vkDevice, RenderingType type);
5916 virtual tcu::TestStatus iterate(void);
5917
5918 private:
5919 const SharedGroupParams m_groupParams;
5920 };
5921
RenderPassNoDrawLoadStoreTestCase(tcu::TestContext & context,const std::string & name,const SharedGroupParams groupParams)5922 RenderPassNoDrawLoadStoreTestCase::RenderPassNoDrawLoadStoreTestCase(tcu::TestContext &context, const std::string &name,
5923 const SharedGroupParams groupParams)
5924 : vkt::TestCase(context, name)
5925 , m_groupParams(groupParams)
5926 {
5927 }
5928
RenderPassNoDrawLoadStoreTestInstance(Context & context,const SharedGroupParams groupParams)5929 RenderPassNoDrawLoadStoreTestInstance::RenderPassNoDrawLoadStoreTestInstance(Context &context,
5930 const SharedGroupParams groupParams)
5931 : vkt::TestInstance(context)
5932 , m_groupParams(groupParams)
5933 {
5934 }
5935
createInstance(Context & context) const5936 TestInstance *RenderPassNoDrawLoadStoreTestCase::createInstance(Context &context) const
5937 {
5938 return new RenderPassNoDrawLoadStoreTestInstance(context, m_groupParams);
5939 }
5940
checkSupport(Context & context) const5941 void RenderPassNoDrawLoadStoreTestCase::checkSupport(Context &context) const
5942 {
5943 if (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
5944 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
5945
5946 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5947 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
5948 }
5949
5950 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
5951 typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,RenderingType type)5952 Move<VkRenderPass> RenderPassNoDrawLoadStoreTestInstance::createRenderPass(const DeviceInterface &vk, VkDevice vkDevice,
5953 RenderingType type)
5954 {
5955 const VkImageAspectFlags aspectMask = type == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
5956
5957 const AttachmentDesc attachmentDescription =
5958 // Result attachment
5959 AttachmentDesc(nullptr, // const void* pNext
5960 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
5961 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
5962 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
5963 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
5964 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
5965 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
5966 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
5967 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
5968 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
5969 );
5970
5971 const AttachmentRef resultAttachmentRefSubpass0(
5972 nullptr, // const void* pNext
5973 0u, // uint32_t attachment
5974 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
5975 aspectMask // VkImageAspectFlags aspectMask
5976 );
5977
5978 const SubpassDesc subpassDescription =
5979 SubpassDesc(nullptr,
5980 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
5981 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
5982 0u, // uint32_t viewMask
5983 0u, // uint32_t inputAttachmentCount
5984 nullptr, // const VkAttachmentReference* pInputAttachments
5985 1u, // uint32_t colorAttachmentCount
5986 &resultAttachmentRefSubpass0, // const VkAttachmentReference* pColorAttachments
5987 nullptr, // const VkAttachmentReference* pResolveAttachments
5988 nullptr, // const VkAttachmentReference* pDepthStencilAttachment
5989 0u, // uint32_t preserveAttachmentCount
5990 nullptr // const uint32_t* pPreserveAttachments
5991 );
5992
5993 const RenderPassCreateInfo renderPassInfo(nullptr, // const void* pNext
5994 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
5995 1u, // uint32_t attachmentCount
5996 &attachmentDescription, // const VkAttachmentDescription* pAttachments
5997 1u, // uint32_t subpassCount
5998 &subpassDescription, // const VkSubpassDescription* pSubpasses
5999 0u, // uint32_t dependencyCount
6000 nullptr, // const VkSubpassDependency* pDependencies
6001 0u, // uint32_t correlatedViewMaskCount
6002 nullptr // const uint32_t* pCorrelatedViewMasks
6003 );
6004 return renderPassInfo.createRenderPass(vk, vkDevice);
6005 }
6006
iterate()6007 tcu::TestStatus RenderPassNoDrawLoadStoreTestInstance::iterate()
6008 {
6009 const auto &vkd = m_context.getDeviceInterface();
6010 const auto device = m_context.getDevice();
6011 auto &alloc = m_context.getDefaultAllocator();
6012
6013 auto imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
6014 auto imageExtent = makeExtent3D(1, 1, 1u);
6015
6016 const tcu::IVec3 imageDim(static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height),
6017 static_cast<int>(imageExtent.depth));
6018 const tcu::IVec2 imageSize(imageDim.x(), imageDim.y());
6019
6020 const std::vector<VkViewport> viewports{makeViewport(imageExtent)};
6021 const std::vector<VkRect2D> scissors{makeRect2D(imageExtent)};
6022
6023 de::MovePtr<ImageWithMemory> colorAttachment;
6024
6025 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
6026
6027 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
6028 const auto imageUsage =
6029 static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
6030 const VkImageCreateInfo imageCreateInfo = {
6031 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6032 nullptr, // const void* pNext;
6033 0u, // VkImageCreateFlags flags;
6034 VK_IMAGE_TYPE_2D, // VkImageType imageType;
6035 imageFormat, // VkFormat format;
6036 imageExtent, // VkExtent3D extent;
6037 1u, // uint32_t mipLevels;
6038 1u, // uint32_t arrayLayers;
6039 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
6040 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
6041 imageUsage, // VkImageUsageFlags usage;
6042 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6043 0u, // uint32_t queueFamilyIndexCount;
6044 nullptr, // const uint32_t* pQueueFamilyIndices;
6045 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6046 };
6047
6048 colorAttachment =
6049 de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
6050 auto colorAttachmentView =
6051 makeImageView(vkd, device, colorAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
6052
6053 const auto tcuFormat = mapVkFormat(imageFormat);
6054 const auto outBufferSize = static_cast<VkDeviceSize>(static_cast<uint32_t>(tcu::getPixelSize(tcuFormat)) *
6055 imageExtent.width * imageExtent.height);
6056
6057 BufferWithMemory outBuffer(vkd, device, alloc,
6058 makeBufferCreateInfo(outBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
6059 MemoryRequirement::HostVisible);
6060 auto &outBufferAlloc = outBuffer.getAllocation();
6061 void *outBufferData = outBufferAlloc.getHostPtr();
6062
6063 Move<VkRenderPass> renderPass;
6064 if (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
6065 {
6066 renderPass =
6067 createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1,
6068 RenderPassCreateInfo1>(vkd, device, RENDERING_TYPE_RENDERPASS_LEGACY);
6069 }
6070 else if (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6071 {
6072 renderPass =
6073 createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2,
6074 RenderPassCreateInfo2>(vkd, device, RENDERING_TYPE_RENDERPASS2);
6075 }
6076
6077 // Framebuffer.
6078 Move<VkFramebuffer> framebuffer;
6079 if (m_groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
6080 framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), imageExtent.width,
6081 imageExtent.height);
6082
6083 const auto clearValueColor = makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
6084
6085 auto graphicsPipelineLayout = makePipelineLayout(vkd, device);
6086 auto commandPool = createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, qIndex);
6087 auto commandBuffer = allocateCommandBuffer(vkd, device, commandPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6088
6089 beginCommandBuffer(vkd, commandBuffer.get());
6090
6091 #ifndef CTS_USES_VULKANSC
6092 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
6093 {
6094 VkRenderingAttachmentInfo colorAttachmentInfo{
6095 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
6096 DE_NULL, // const void* pNext;
6097 colorAttachmentView.get(), // VkImageView imageView;
6098 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
6099 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
6100 DE_NULL, // VkImageView resolveImageView;
6101 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
6102 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
6103 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
6104 clearValueColor // VkClearValue clearValue;
6105 };
6106 VkRenderingInfo renderingInfo{
6107 VK_STRUCTURE_TYPE_RENDERING_INFO,
6108 DE_NULL,
6109 0u, // VkRenderingFlagsKHR flags;
6110 scissors[0], // VkRect2D renderArea;
6111 1u, // uint32_t layerCount;
6112 0u, // uint32_t viewMask;
6113 1u, // uint32_t colorAttachmentCount;
6114 &colorAttachmentInfo, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
6115 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
6116 DE_NULL // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
6117 };
6118
6119 VkImageMemoryBarrier imageBarrier =
6120 makeImageMemoryBarrier(0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
6121 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, **colorAttachment, subresourceRange);
6122 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6123 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u,
6124 DE_NULL, 1u, &imageBarrier);
6125
6126 vkd.cmdBeginRendering(*commandBuffer, &renderingInfo);
6127 vkd.cmdEndRendering(*commandBuffer);
6128 }
6129 else
6130 #endif // CTS_USES_VULKANSC
6131 {
6132 const VkRenderPassBeginInfo renderPassBeginInfo{
6133 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
6134 nullptr, // const void* pNext;
6135 *renderPass, // VkRenderPass renderPass;
6136 *framebuffer, // VkFramebuffer framebuffer;
6137 scissors.at(0), // VkRect2D renderArea;
6138 1, // uint32_t clearValueCount;
6139 &clearValueColor, // const VkClearValue* pClearValues;
6140 };
6141 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
6142 vkd.cmdEndRenderPass(*commandBuffer);
6143 }
6144
6145 auto barrier = makeImageMemoryBarrier(
6146 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6147 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorAttachment->get(), subresourceRange);
6148 cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6149 VK_PIPELINE_STAGE_TRANSFER_BIT, &barrier);
6150 copyImageToBuffer(vkd, commandBuffer.get(), colorAttachment.get()->get(), outBuffer.get(), imageSize);
6151 endCommandBuffer(vkd, commandBuffer.get());
6152 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), commandBuffer.get());
6153 invalidateAlloc(vkd, device, outBufferAlloc);
6154
6155 tcu::ConstPixelBufferAccess outPixels(tcuFormat, imageDim, outBufferData);
6156 auto pixel = outPixels.getPixel(0, 0);
6157 auto expected = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
6158
6159 if (pixel != expected)
6160 {
6161 std::stringstream output("Pixel isn't equal to clear color: ");
6162 output << pixel << " instead of " << expected;
6163 return tcu::TestStatus::fail(output.str());
6164 }
6165
6166 return tcu::TestStatus::pass("Pass");
6167 }
6168
6169 static const VkFormat s_coreColorFormats[] = {VK_FORMAT_R5G6B5_UNORM_PACK16,
6170 VK_FORMAT_R8_UNORM,
6171 VK_FORMAT_R8_SNORM,
6172 VK_FORMAT_R8_UINT,
6173 VK_FORMAT_R8_SINT,
6174 VK_FORMAT_R8G8_UNORM,
6175 VK_FORMAT_R8G8_SNORM,
6176 VK_FORMAT_R8G8_UINT,
6177 VK_FORMAT_R8G8_SINT,
6178 VK_FORMAT_R8G8B8A8_UNORM,
6179 VK_FORMAT_R8G8B8A8_SNORM,
6180 VK_FORMAT_R8G8B8A8_UINT,
6181 VK_FORMAT_R8G8B8A8_SINT,
6182 VK_FORMAT_R8G8B8A8_SRGB,
6183 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
6184 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
6185 VK_FORMAT_A8B8G8R8_UINT_PACK32,
6186 VK_FORMAT_A8B8G8R8_SINT_PACK32,
6187 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
6188 VK_FORMAT_B8G8R8A8_UNORM,
6189 VK_FORMAT_B8G8R8A8_SRGB,
6190 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
6191 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
6192 VK_FORMAT_A2B10G10R10_UINT_PACK32,
6193 VK_FORMAT_R16_UNORM,
6194 VK_FORMAT_R16_SNORM,
6195 VK_FORMAT_R16_UINT,
6196 VK_FORMAT_R16_SINT,
6197 VK_FORMAT_R16_SFLOAT,
6198 VK_FORMAT_R16G16_UNORM,
6199 VK_FORMAT_R16G16_SNORM,
6200 VK_FORMAT_R16G16_UINT,
6201 VK_FORMAT_R16G16_SINT,
6202 VK_FORMAT_R16G16_SFLOAT,
6203 VK_FORMAT_R16G16B16A16_UNORM,
6204 VK_FORMAT_R16G16B16A16_SNORM,
6205 VK_FORMAT_R16G16B16A16_UINT,
6206 VK_FORMAT_R16G16B16A16_SINT,
6207 VK_FORMAT_R16G16B16A16_SFLOAT,
6208 VK_FORMAT_R32_UINT,
6209 VK_FORMAT_R32_SINT,
6210 VK_FORMAT_R32_SFLOAT,
6211 VK_FORMAT_R32G32_UINT,
6212 VK_FORMAT_R32G32_SINT,
6213 VK_FORMAT_R32G32_SFLOAT,
6214 VK_FORMAT_R32G32B32A32_UINT,
6215 VK_FORMAT_R32G32B32A32_SINT,
6216 VK_FORMAT_R32G32B32A32_SFLOAT};
6217
6218 static const VkFormat s_coreDepthStencilFormats[] = {VK_FORMAT_D16_UNORM,
6219
6220 VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT,
6221
6222 VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
6223
addAttachmentTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6224 void addAttachmentTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
6225 {
6226 const uint32_t attachmentCounts[] = {1, 3, 4, 8};
6227 const VkAttachmentLoadOp loadOps[] = {VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR,
6228 VK_ATTACHMENT_LOAD_OP_DONT_CARE};
6229
6230 const VkAttachmentStoreOp storeOps[] = {VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE};
6231
6232 const VkImageLayout initialAndFinalColorLayouts[] = {
6233 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
6234 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
6235
6236 const VkImageLayout initialAndFinalColorLayoutsLazy[] = {
6237 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6238
6239 const VkImageLayout initialAndFinalDepthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
6240 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6241 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
6242 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
6243 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6244 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
6245
6246 const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] = {
6247 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6248 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6249
6250 const VkImageLayout subpassLayouts[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
6251
6252 const VkImageLayout depthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
6253 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
6254
6255 const TestConfig::RenderTypes renderCommands[] = {
6256 TestConfig::RENDERTYPES_NONE,
6257 TestConfig::RENDERTYPES_CLEAR,
6258 TestConfig::RENDERTYPES_DRAW,
6259 TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW,
6260 };
6261
6262 const TestConfig::CommandBufferTypes commandBuffers[] = {
6263 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::COMMANDBUFFERTYPES_SECONDARY,
6264 TestConfig::COMMANDBUFFERTYPES_INLINE | TestConfig::COMMANDBUFFERTYPES_SECONDARY};
6265
6266 const TestConfig::ImageMemory imageMemories[] = {TestConfig::IMAGEMEMORY_STRICT, TestConfig::IMAGEMEMORY_LAZY,
6267 TestConfig::IMAGEMEMORY_STRICT | TestConfig::IMAGEMEMORY_LAZY};
6268
6269 const UVec2 targetSizes[] = {UVec2(64, 64), UVec2(63, 65)};
6270
6271 const UVec2 renderPositions[] = {UVec2(0, 0), UVec2(3, 17)};
6272
6273 const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(60, 47)};
6274
6275 tcu::TestContext &testCtx(group->getTestContext());
6276 bool useDynamicRendering(testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
6277 de::Random rng(1433774382u);
6278
6279 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
6280 {
6281 const uint32_t attachmentCount = attachmentCounts[attachmentCountNdx];
6282 const uint32_t testCaseCount = (attachmentCount == 1 ? 100 : 200);
6283 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(
6284 new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str()));
6285
6286 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
6287 {
6288 const bool useDepthStencil = rng.getBool();
6289 const TestConfig::ImageMemory imageMemory =
6290 rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6291 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
6292 vector<Attachment> attachments;
6293 vector<AttachmentReference> colorAttachmentReferences;
6294
6295 // we want to make sure that dynamic rendering test cases have corresponding renderpass
6296 // cases as this will allow drivers to easily compare GPU batches; since configurations
6297 // for those tests are generated we need to generate configurations for all cases
6298 // even when we know earlier that for dynamic rendering we will skip it
6299 bool executeForDynamicRendering = true;
6300
6301 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6302 {
6303 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6304 const VkFormat format =
6305 rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6306 const VkAttachmentLoadOp loadOp =
6307 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6308 const VkAttachmentStoreOp storeOp =
6309 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6310
6311 const VkImageLayout initialLayout =
6312 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6313 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
6314 DE_ARRAY_END(initialAndFinalColorLayouts)) :
6315 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
6316 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
6317 VkImageLayout finalizeLayout =
6318 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6319 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
6320 DE_ARRAY_END(initialAndFinalColorLayouts)) :
6321 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
6322 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
6323 const VkImageLayout subpassLayout =
6324 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
6325
6326 const VkAttachmentLoadOp stencilLoadOp =
6327 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6328 const VkAttachmentStoreOp stencilStoreOp =
6329 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6330
6331 if (useDynamicRendering)
6332 {
6333 // with renderpass we can have automatic layout transitions; to do the same with dynamic rendering cases
6334 // we would need to add addtional barries but since those tests won't add coverage we are skipping them
6335 if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
6336 (initialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL))
6337 finalizeLayout = initialLayout;
6338 else
6339 executeForDynamicRendering = false;
6340 }
6341
6342 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
6343 initialLayout, finalizeLayout));
6344 colorAttachmentReferences.push_back(AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
6345 }
6346
6347 if (useDepthStencil)
6348 {
6349 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6350 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats),
6351 DE_ARRAY_END(s_coreDepthStencilFormats));
6352 const VkAttachmentLoadOp loadOp =
6353 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6354 const VkAttachmentStoreOp storeOp =
6355 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6356
6357 const VkImageLayout initialLayout =
6358 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6359 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
6360 DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
6361 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy),
6362 DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
6363 VkImageLayout finalizeLayout =
6364 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6365 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
6366 DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
6367 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy),
6368 DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
6369
6370 const VkAttachmentLoadOp stencilLoadOp =
6371 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6372 const VkAttachmentStoreOp stencilStoreOp =
6373 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6374
6375 if (useDynamicRendering)
6376 {
6377 if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
6378 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) ||
6379 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
6380 finalizeLayout = initialLayout;
6381 else
6382 executeForDynamicRendering = false;
6383 }
6384
6385 depthStencilLayout =
6386 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
6387 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
6388 initialLayout, finalizeLayout));
6389 }
6390
6391 {
6392 const TestConfig::RenderTypes render =
6393 rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6394 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
6395 DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6396 const vector<Subpass> subpasses(
6397 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
6398 colorAttachmentReferences, vector<AttachmentReference>(),
6399 AttachmentReference(
6400 (useDepthStencil ? (uint32_t)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED),
6401 depthStencilLayout),
6402 vector<uint32_t>()));
6403 const vector<SubpassDependency> deps;
6404 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
6405 const RenderPass renderPass(attachments, subpasses, deps);
6406 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6407 const UVec2 renderPos =
6408 rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6409 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6410
6411 if (useDynamicRendering)
6412 {
6413 // skip dynamic rendering cases (that don't add coverage) this can be done not earlier than after grabbing all
6414 // random numbers as we need to make sure that those tests that will be created for dynamic rendering have
6415 // corresponding renderpass tests with the same name
6416 if (!executeForDynamicRendering)
6417 continue;
6418
6419 // dont repeat non secondary buffer cases when testing secondaryCmdBufferCompletelyContainsDynamicRenderpass flag
6420 if (testConfigExternal.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass &&
6421 (commandBuffer != TestConfig::COMMANDBUFFERTYPES_SECONDARY))
6422 {
6423 continue;
6424 }
6425 }
6426
6427 const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
6428 renderSize, false, 1293809, 0, testConfigExternal.allocationKind,
6429 testConfigExternal.groupParams);
6430
6431 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(),
6432 createTestShaders, renderPassTest, testConfig);
6433 }
6434 }
6435
6436 group->addChild(attachmentCountGroup.release());
6437 }
6438 }
6439
addAttachmentWriteMaskTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6440 void addAttachmentWriteMaskTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
6441 {
6442 const uint32_t attachmentCounts[] = {1, 2, 3, 4, 8};
6443
6444 const VkFormat attachmentFormats[] = {VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM,
6445 VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_R8G8_UNORM};
6446
6447 tcu::TestContext &testCtx = group->getTestContext();
6448
6449 for (uint32_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts);
6450 attachmentCountNdx++)
6451 {
6452 const uint32_t attachmentCount = attachmentCounts[attachmentCountNdx];
6453 const string groupName = "attachment_count_" + de::toString(attachmentCount);
6454
6455 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
6456
6457 for (uint32_t drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
6458 {
6459 uint32_t formatNdx = 0;
6460 vector<Attachment> attachments;
6461 vector<AttachmentReference> colorAttachmentReferences;
6462
6463 for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6464 {
6465 const VkFormat format = attachmentFormats[formatNdx];
6466 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6467 const VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6468 const VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE;
6469 const VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6470 const VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
6471 const VkImageLayout initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6472 const VkImageLayout finalizeLayout =
6473 (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) ?
6474 initialLayout :
6475 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6476 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
6477
6478 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
6479 initialLayout, finalizeLayout));
6480 colorAttachmentReferences.push_back(AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
6481
6482 if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
6483 formatNdx = 0;
6484 }
6485
6486 {
6487 const VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
6488 const vector<Subpass> subpass(
6489 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
6490 colorAttachmentReferences, vector<AttachmentReference>(),
6491 AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
6492 const vector<SubpassDependency> deps;
6493
6494 const string testCaseName = "start_index_" + de::toString(drawStartNdx);
6495 const RenderPass renderPass(attachments, subpass, deps);
6496
6497 const TestConfig::RenderTypes render = TestConfig::RENDERTYPES_DRAW;
6498 const TestConfig::CommandBufferTypes commandBuffer = TestConfig::COMMANDBUFFERTYPES_INLINE;
6499 const TestConfig::ImageMemory imageMemory = TestConfig::IMAGEMEMORY_LAZY;
6500 const UVec2 targetSize = UVec2(64, 64);
6501 const UVec2 renderPos = UVec2(0, 0);
6502 const UVec2 renderSize = UVec2(64, 64);
6503 const bool useFormatCompCount = true;
6504 const vector<DeviceCoreFeature> requiredFeatures = {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
6505 const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
6506 renderSize, useFormatCompCount, 1293809, drawStartNdx,
6507 testConfigExternal.allocationKind, testConfigExternal.groupParams,
6508 requiredFeatures);
6509
6510 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), checkSupport,
6511 createTestShaders, renderPassTest, testConfig);
6512 }
6513 }
6514
6515 group->addChild(attachmentCountGroup.release());
6516 }
6517 }
6518
6519 template <typename T>
chooseRandom(de::Random & rng,const set<T> & values)6520 T chooseRandom(de::Random &rng, const set<T> &values)
6521 {
6522 size_t ndx = ((size_t)rng.getUint32()) % values.size();
6523 typename set<T>::const_iterator iter = values.begin();
6524
6525 for (; ndx > 0; ndx--)
6526 iter++;
6527
6528 return *iter;
6529 }
6530
addAttachmentAllocationTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6531 void addAttachmentAllocationTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
6532 {
6533 const uint32_t attachmentCounts[] = {4, 8};
6534 const VkAttachmentLoadOp loadOps[] = {VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR,
6535 VK_ATTACHMENT_LOAD_OP_DONT_CARE};
6536
6537 const VkAttachmentStoreOp storeOps[] = {VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE};
6538
6539 const VkImageLayout initialAndFinalColorLayouts[] = {
6540 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
6541 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
6542
6543 const VkImageLayout initialAndFinalColorLayoutsLazy[] = {
6544 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6545
6546 const VkImageLayout initialAndFinalDepthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
6547 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6548 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
6549 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
6550 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6551 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
6552
6553 const VkImageLayout subpassLayoutsColor[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
6554
6555 const VkImageLayout subpassLayoutsDepthStencil[] = {VK_IMAGE_LAYOUT_GENERAL,
6556 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
6557
6558 const VkImageLayout subpassLayoutsInput[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6559
6560 enum AllocationType
6561 {
6562 // Each pass uses one more attachmen than previous one
6563 ALLOCATIONTYPE_GROW,
6564 // Each pass uses one less attachment than previous one
6565 ALLOCATIONTYPE_SHRINK,
6566 // Each pass drops one attachment and picks up new one
6567 ALLOCATIONTYPE_ROLL,
6568 // Start by growing and end by shrinking
6569 ALLOCATIONTYPE_GROW_SHRINK,
6570 // Each subpass has single input and single output attachment
6571 ALLOCATIONTYPE_IO_CHAIN,
6572 // Each subpass has multiple inputs and multiple outputs attachment
6573 ALLOCATIONTYPE_IO_GENERIC
6574 };
6575
6576 const AllocationType allocationTypes[] = {ALLOCATIONTYPE_GROW, ALLOCATIONTYPE_SHRINK,
6577 ALLOCATIONTYPE_ROLL, ALLOCATIONTYPE_GROW_SHRINK,
6578 ALLOCATIONTYPE_IO_CHAIN, ALLOCATIONTYPE_IO_GENERIC};
6579
6580 const char *const allocationTypeStr[] = {
6581 "grow", "shrink", "roll", "grow_shrink", "input_output_chain", "input_output",
6582 };
6583
6584 const TestConfig::RenderTypes renderCommands[] = {
6585 TestConfig::RENDERTYPES_NONE,
6586 TestConfig::RENDERTYPES_CLEAR,
6587 TestConfig::RENDERTYPES_DRAW,
6588 TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW,
6589 };
6590
6591 const TestConfig::CommandBufferTypes commandBuffers[] = {
6592 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::COMMANDBUFFERTYPES_SECONDARY,
6593 TestConfig::COMMANDBUFFERTYPES_INLINE | TestConfig::COMMANDBUFFERTYPES_SECONDARY};
6594
6595 const TestConfig::ImageMemory imageMemories[] = {TestConfig::IMAGEMEMORY_STRICT, TestConfig::IMAGEMEMORY_LAZY,
6596 TestConfig::IMAGEMEMORY_STRICT | TestConfig::IMAGEMEMORY_LAZY};
6597
6598 const UVec2 targetSizes[] = {UVec2(64, 64), UVec2(63, 65)};
6599
6600 const UVec2 renderPositions[] = {UVec2(0, 0), UVec2(3, 17)};
6601
6602 const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(60, 47)};
6603
6604 tcu::TestContext &testCtx = group->getTestContext();
6605 de::Random rng(3700649827u);
6606
6607 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
6608 {
6609 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
6610 const size_t testCaseCount = 100;
6611 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup(
6612 new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx]));
6613
6614 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
6615 {
6616 const TestConfig::ImageMemory imageMemory =
6617 rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6618 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
6619 {
6620 const uint32_t attachmentCount = 4u + rng.getUint32() % 31u;
6621 const uint32_t subpassCount = 4u + rng.getUint32() % 31u;
6622 vector<Attachment> attachments;
6623
6624 set<uint32_t> definedAttachments;
6625
6626 vector<Subpass> subpasses;
6627 set<uint32_t> colorAttachments;
6628 set<uint32_t> depthStencilAttachments;
6629
6630 for (uint32_t attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
6631 {
6632 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
6633 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6634 const VkAttachmentLoadOp loadOp =
6635 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6636 const VkAttachmentStoreOp storeOp =
6637 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6638
6639 const VkImageLayout initialLayout =
6640 isDepthStencilAttachment ?
6641 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
6642 DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
6643 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6644 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
6645 DE_ARRAY_END(initialAndFinalColorLayouts)) :
6646 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
6647 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
6648 const VkImageLayout finalizeLayout =
6649 isDepthStencilAttachment ?
6650 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
6651 DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
6652 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
6653 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
6654 DE_ARRAY_END(initialAndFinalColorLayouts)) :
6655 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
6656 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
6657
6658 const VkAttachmentLoadOp stencilLoadOp =
6659 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6660 const VkAttachmentStoreOp stencilStoreOp =
6661 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6662
6663 if (isDepthStencilAttachment)
6664 {
6665 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats),
6666 DE_ARRAY_END(s_coreDepthStencilFormats));
6667
6668 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR ||
6669 stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6670 definedAttachments.insert(attachmentIndex);
6671
6672 depthStencilAttachments.insert(attachmentIndex);
6673
6674 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
6675 stencilStoreOp, initialLayout, finalizeLayout));
6676 }
6677 else
6678 {
6679 const VkFormat format =
6680 rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6681
6682 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6683 definedAttachments.insert(attachmentIndex);
6684
6685 colorAttachments.insert(attachmentIndex);
6686
6687 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
6688 stencilStoreOp, initialLayout, finalizeLayout));
6689 }
6690 }
6691 vector<Maybe<uint32_t>> lastUseOfAttachment(attachments.size(), tcu::Nothing);
6692 vector<SubpassDependency> deps;
6693
6694 for (uint32_t subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
6695 {
6696 const uint32_t colorAttachmentCount =
6697 depthStencilAttachments.empty() ?
6698 1 + rng.getUint32() % de::min(4u, (uint32_t)colorAttachments.size()) :
6699 rng.getUint32() % (de::min(4u, (uint32_t)colorAttachments.size()) + 1u);
6700 const uint32_t inputAttachmentCount =
6701 rng.getUint32() % (uint32_t)(de::min<size_t>(4, definedAttachments.size()) + 1);
6702 const bool useDepthStencilAttachment =
6703 !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
6704 std::vector<uint32_t> subpassColorAttachments(colorAttachmentCount);
6705 std::vector<uint32_t> subpassInputAttachments(inputAttachmentCount);
6706 Maybe<uint32_t> depthStencilAttachment(
6707 useDepthStencilAttachment ? just(chooseRandom(rng, depthStencilAttachments)) : tcu::Nothing);
6708 std::vector<uint32_t> subpassPreserveAttachments;
6709
6710 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(),
6711 colorAttachmentCount);
6712 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(),
6713 inputAttachmentCount);
6714
6715 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size();
6716 colorAttachmentNdx++)
6717 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
6718
6719 if (depthStencilAttachment)
6720 definedAttachments.insert(*depthStencilAttachment);
6721
6722 {
6723 std::vector<AttachmentReference> inputAttachmentReferences;
6724 std::vector<AttachmentReference> colorAttachmentReferences;
6725 AttachmentReference depthStencilAttachmentReference(VK_ATTACHMENT_UNUSED,
6726 VK_IMAGE_LAYOUT_GENERAL);
6727
6728 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size();
6729 colorAttachmentNdx++)
6730 {
6731 const uint32_t colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
6732
6733 if (lastUseOfAttachment[colorAttachmentIndex])
6734 {
6735 bool foundDuplicate = false;
6736
6737 const uint32_t srcPass = *lastUseOfAttachment[colorAttachmentIndex];
6738 const uint32_t dstPass = subpassIndex;
6739 const VkDependencyFlags dependencyFlags =
6740 rng.getBool() ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6741
6742 const SubpassDependency newDependency(
6743 srcPass, dstPass,
6744 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6745 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6746 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6747 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6748
6749 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6750 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6751 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6752 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6753
6754 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
6755
6756 dependencyFlags);
6757
6758 for (SubpassDependency &dependency : deps)
6759 {
6760 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6761 {
6762 const VkAccessFlags newDstFlags =
6763 dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
6764 dependency.setDstAccessMask(newDstFlags);
6765 foundDuplicate = true;
6766 break;
6767 }
6768 }
6769
6770 if (!foundDuplicate)
6771 {
6772 deps.push_back(newDependency);
6773 }
6774 }
6775
6776 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
6777
6778 colorAttachmentReferences.push_back(AttachmentReference(
6779 (uint32_t)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
6780 }
6781
6782 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size();
6783 inputAttachmentNdx++)
6784 {
6785 const uint32_t inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
6786
6787 if (lastUseOfAttachment[inputAttachmentIndex])
6788 {
6789 bool foundDuplicate = false;
6790
6791 const uint32_t srcPass = *lastUseOfAttachment[inputAttachmentIndex];
6792 const uint32_t dstPass = subpassIndex;
6793 const VkDependencyFlags dependencyFlags =
6794 ((srcPass == subpassIndex) || rng.getBool()) ?
6795 (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT :
6796 0u;
6797
6798 const SubpassDependency newDependency(
6799 srcPass, dstPass,
6800 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6801 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6802 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6803 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6804
6805 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6806 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6807 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6808 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6809
6810 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6811 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6812
6813 dependencyFlags);
6814 for (SubpassDependency &dependency : deps)
6815 {
6816 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6817 {
6818 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() |
6819 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6820 const VkAccessFlags newDstFlags =
6821 dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6822 dependency.setDstAccessMask(newSrcFlags);
6823 dependency.setDstAccessMask(newDstFlags);
6824 foundDuplicate = true;
6825 break;
6826 }
6827 }
6828
6829 if (!foundDuplicate)
6830 {
6831 deps.push_back(newDependency);
6832 }
6833
6834 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
6835
6836 VkImageAspectFlags aspect = 0u;
6837 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6838 {
6839 bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
6840 aspect = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
6841 }
6842 inputAttachmentReferences.push_back(
6843 AttachmentReference((uint32_t)subpassInputAttachments[inputAttachmentNdx],
6844 VK_IMAGE_LAYOUT_GENERAL, aspect));
6845 }
6846 }
6847
6848 if (depthStencilAttachment)
6849 {
6850 if (lastUseOfAttachment[*depthStencilAttachment])
6851 {
6852 bool foundDuplicate = false;
6853
6854 const uint32_t srcPass = *lastUseOfAttachment[*depthStencilAttachment];
6855 const uint32_t dstPass = subpassIndex;
6856 const VkDependencyFlags dependencyFlags =
6857 ((srcPass == subpassIndex) || rng.getBool()) ?
6858 (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT :
6859 0u;
6860
6861 const SubpassDependency newDependency(
6862 srcPass, dstPass,
6863 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6864 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6865 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6866 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6867
6868 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
6869 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
6870 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
6871 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6872
6873 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6874 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6875
6876 dependencyFlags);
6877 for (SubpassDependency &dependency : deps)
6878 {
6879 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6880 {
6881 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() |
6882 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6883 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() |
6884 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
6885 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6886 dependency.setDstAccessMask(newSrcFlags);
6887 dependency.setDstAccessMask(newDstFlags);
6888 foundDuplicate = true;
6889 break;
6890 }
6891 }
6892
6893 if (!foundDuplicate)
6894 {
6895 deps.push_back(newDependency);
6896 }
6897 }
6898
6899 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
6900
6901 depthStencilAttachmentReference =
6902 AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
6903 }
6904 else
6905 depthStencilAttachmentReference =
6906 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6907
6908 vector<uint32_t> preserveAttachments;
6909 for (uint32_t attachmentIndex = 0; attachmentIndex < (uint32_t)attachments.size();
6910 attachmentIndex++)
6911 {
6912 if (lastUseOfAttachment[attachmentIndex] &&
6913 (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
6914 preserveAttachments.push_back(attachmentIndex);
6915 }
6916
6917 // Use random image layout when possible
6918 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6919 {
6920 bool usedAsInput = false;
6921 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6922 if (colorAttachmentReferences[colorRefIdx].getAttachment() ==
6923 inputAttachmentReferences[inputRefIdx].getAttachment())
6924 usedAsInput = true;
6925
6926 if (!usedAsInput)
6927 colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(
6928 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
6929 }
6930 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6931 {
6932 bool usedAsDepthStencil = inputAttachmentReferences[inputRefIdx].getAttachment() ==
6933 depthStencilAttachmentReference.getAttachment();
6934 bool usedAsColor = false;
6935 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6936 if (inputAttachmentReferences[inputRefIdx].getAttachment() ==
6937 colorAttachmentReferences[colorRefIdx].getAttachment())
6938 usedAsColor = true;
6939
6940 if (!usedAsColor && !usedAsDepthStencil)
6941 inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(
6942 DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
6943 }
6944 {
6945 bool usedAsInput = false;
6946 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6947 if (depthStencilAttachmentReference.getAttachment() ==
6948 inputAttachmentReferences[inputRefIdx].getAttachment())
6949 usedAsInput = true;
6950
6951 if (!usedAsInput)
6952 depthStencilAttachmentReference.setImageLayout(
6953 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil),
6954 DE_ARRAY_END(subpassLayoutsDepthStencil)));
6955 }
6956
6957 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
6958 colorAttachmentReferences, vector<AttachmentReference>(),
6959 depthStencilAttachmentReference, preserveAttachments));
6960 }
6961 }
6962 {
6963 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(
6964 DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6965 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
6966 DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6967
6968 const string testCaseName = de::toString(testCaseNdx);
6969 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6970 const UVec2 renderPos =
6971 rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6972 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6973
6974 const RenderPass renderPass(attachments, subpasses, deps);
6975 const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
6976 renderSize, false, 80329, 0, testConfigExternal.allocationKind,
6977 testConfigExternal.groupParams);
6978
6979 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(),
6980 createTestShaders, renderPassTest, testConfig);
6981 }
6982 }
6983 else
6984 {
6985 const uint32_t attachmentCount =
6986 rng.choose<uint32_t>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
6987 vector<Attachment> attachments;
6988 vector<Subpass> subpasses;
6989
6990 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6991 {
6992 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6993 const VkFormat format =
6994 rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6995
6996 const VkAttachmentLoadOp loadOp =
6997 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6998 const VkAttachmentStoreOp storeOp =
6999 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
7000
7001 const VkImageLayout initialLayout =
7002 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
7003 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
7004 DE_ARRAY_END(initialAndFinalColorLayouts)) :
7005 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
7006 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
7007
7008 const VkImageLayout finalizeLayout =
7009 (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
7010 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
7011 DE_ARRAY_END(initialAndFinalColorLayouts)) :
7012 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
7013 DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
7014
7015 const VkAttachmentLoadOp stencilLoadOp =
7016 rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
7017 const VkAttachmentStoreOp stencilStoreOp =
7018 rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
7019
7020 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
7021 stencilStoreOp, initialLayout, finalizeLayout));
7022 }
7023
7024 if (allocationType == ALLOCATIONTYPE_GROW)
7025 {
7026 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
7027 {
7028 vector<AttachmentReference> colorAttachmentReferences;
7029
7030 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
7031 {
7032 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
7033 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
7034
7035 colorAttachmentReferences.push_back(
7036 AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
7037 }
7038
7039 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7040 colorAttachmentReferences, vector<AttachmentReference>(),
7041 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7042 vector<uint32_t>()));
7043 }
7044 }
7045 else if (allocationType == ALLOCATIONTYPE_SHRINK)
7046 {
7047 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
7048 {
7049 vector<AttachmentReference> colorAttachmentReferences;
7050
7051 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
7052 {
7053 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
7054 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
7055
7056 colorAttachmentReferences.push_back(
7057 AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
7058 }
7059
7060 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7061 colorAttachmentReferences, vector<AttachmentReference>(),
7062 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7063 vector<uint32_t>()));
7064 }
7065 }
7066 else if (allocationType == ALLOCATIONTYPE_ROLL)
7067 {
7068 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
7069 {
7070 vector<AttachmentReference> colorAttachmentReferences;
7071
7072 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
7073 {
7074 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
7075 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
7076
7077 colorAttachmentReferences.push_back(
7078 AttachmentReference((uint32_t)(subpassNdx + attachmentNdx), subpassLayout));
7079 }
7080
7081 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7082 colorAttachmentReferences, vector<AttachmentReference>(),
7083 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7084 vector<uint32_t>()));
7085 }
7086 }
7087 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
7088 {
7089 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
7090 {
7091 vector<AttachmentReference> colorAttachmentReferences;
7092
7093 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
7094 {
7095 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
7096 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
7097
7098 colorAttachmentReferences.push_back(
7099 AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
7100 }
7101
7102 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7103 colorAttachmentReferences, vector<AttachmentReference>(),
7104 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7105 vector<uint32_t>()));
7106 }
7107 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
7108 {
7109 vector<AttachmentReference> colorAttachmentReferences;
7110
7111 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
7112 {
7113 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
7114 DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
7115
7116 colorAttachmentReferences.push_back(
7117 AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
7118 }
7119
7120 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7121 colorAttachmentReferences, vector<AttachmentReference>(),
7122 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7123 vector<uint32_t>()));
7124 }
7125 }
7126 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
7127 {
7128 subpasses.push_back(Subpass(
7129 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7130 vector<AttachmentReference>(
7131 1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor),
7132 DE_ARRAY_END(subpassLayoutsColor)))),
7133 vector<AttachmentReference>(),
7134 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));
7135
7136 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
7137 {
7138 const VkImageAspectFlags inputAttachmentAspectMask =
7139 (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
7140 VK_IMAGE_ASPECT_COLOR_BIT :
7141 static_cast<VkImageAspectFlagBits>(0);
7142 subpasses.push_back(Subpass(
7143 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7144 vector<AttachmentReference>(1, AttachmentReference((uint32_t)(subpassNdx - 1),
7145 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
7146 inputAttachmentAspectMask)),
7147 vector<AttachmentReference>(
7148 1, AttachmentReference((uint32_t)(subpassNdx),
7149 rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor),
7150 DE_ARRAY_END(subpassLayoutsColor)))),
7151 vector<AttachmentReference>(),
7152 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));
7153 }
7154 }
7155 else
7156 DE_FATAL("Unknown allocation type");
7157
7158 {
7159 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(
7160 DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
7161 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
7162 DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
7163
7164 const string testCaseName = de::toString(testCaseNdx);
7165 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
7166 const UVec2 renderPos =
7167 rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
7168 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
7169
7170 vector<SubpassDependency> deps;
7171
7172 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
7173 {
7174 const bool byRegion = rng.getBool();
7175 deps.push_back(SubpassDependency(
7176 (uint32_t)subpassNdx, (uint32_t)subpassNdx + 1,
7177 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
7178 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7179
7180 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
7181 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7182
7183 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7184 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT),
7185
7186 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
7187 }
7188
7189 const RenderPass renderPass(attachments, subpasses, deps);
7190 const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
7191 renderSize, false, 80329, 0, testConfigExternal.allocationKind,
7192 testConfigExternal.groupParams);
7193
7194 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(),
7195 createTestShaders, renderPassTest, testConfig);
7196 }
7197 }
7198 }
7199 group->addChild(allocationTypeGroup.release());
7200 }
7201 }
7202
addSimpleTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)7203 void addSimpleTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
7204 {
7205 const UVec2 targetSize(64, 64);
7206 const UVec2 renderPos(0, 0);
7207 const UVec2 renderSize(64, 64);
7208
7209 // color
7210 {
7211 const RenderPass renderPass(
7212 vector<Attachment>(1,
7213 Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7214 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7215 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7216 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7217 vector<Subpass>(
7218 1, Subpass(
7219 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7220 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7221 vector<AttachmentReference>(),
7222 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>())),
7223 vector<SubpassDependency>());
7224 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7225 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7226 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7227
7228 addFunctionCaseWithPrograms<TestConfig>(group, "color", createTestShaders, renderPassTest, testConfig);
7229 }
7230
7231 // depth
7232 {
7233 const RenderPass renderPass(
7234 vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, VK_SAMPLE_COUNT_1_BIT,
7235 VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
7236 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7237 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7238 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7239 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7240 vector<AttachmentReference>(), vector<AttachmentReference>(),
7241 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7242 vector<uint32_t>())),
7243 vector<SubpassDependency>());
7244 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7245 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7246 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7247
7248 addFunctionCaseWithPrograms<TestConfig>(group, "depth", createTestShaders, renderPassTest, testConfig);
7249 }
7250
7251 // stencil
7252 {
7253 const RenderPass renderPass(
7254 vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7255 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_CLEAR,
7256 VK_ATTACHMENT_STORE_OP_STORE,
7257 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7258 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7259 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7260 vector<AttachmentReference>(), vector<AttachmentReference>(),
7261 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7262 vector<uint32_t>())),
7263 vector<SubpassDependency>());
7264 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7265 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7266 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7267
7268 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", createTestShaders, renderPassTest, testConfig);
7269 }
7270
7271 // depth_stencil
7272 {
7273 const RenderPass renderPass(
7274 vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT,
7275 VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
7276 VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
7277 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7278 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7279 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7280 vector<AttachmentReference>(), vector<AttachmentReference>(),
7281 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7282 vector<uint32_t>())),
7283 vector<SubpassDependency>());
7284 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7285 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7286 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7287
7288 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", createTestShaders, renderPassTest, testConfig);
7289 }
7290
7291 // color_depth
7292 {
7293 const Attachment attachments[] = {
7294 Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7295 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7296 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
7297 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7298 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7299 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7300 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7301 };
7302
7303 const RenderPass renderPass(
7304 vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
7305 vector<Subpass>(
7306 1, Subpass(
7307 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7308 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7309 vector<AttachmentReference>(),
7310 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
7311 vector<SubpassDependency>());
7312 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7313 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7314 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7315
7316 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", createTestShaders, renderPassTest, testConfig);
7317 }
7318
7319 // color_stencil
7320 {
7321 const Attachment attachments[] = {
7322 Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7323 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7324 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
7325 Attachment(VK_FORMAT_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7326 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
7327 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7328 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7329 };
7330
7331 const RenderPass renderPass(
7332 vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
7333 vector<Subpass>(
7334 1, Subpass(
7335 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7336 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7337 vector<AttachmentReference>(),
7338 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
7339 vector<SubpassDependency>());
7340 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7341 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7342 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7343
7344 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", createTestShaders, renderPassTest, testConfig);
7345 }
7346
7347 // color_depth_stencil
7348 {
7349 const Attachment attachments[] = {
7350 Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7351 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7352 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
7353 Attachment(VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7354 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
7355 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7356 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7357 };
7358
7359 const RenderPass renderPass(
7360 vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
7361 vector<Subpass>(
7362 1, Subpass(
7363 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7364 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7365 vector<AttachmentReference>(),
7366 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
7367 vector<SubpassDependency>());
7368 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7369 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7370 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7371
7372 // Color, depth and stencil attachment case.
7373 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", createTestShaders, renderPassTest,
7374 testConfig);
7375 }
7376
7377 // no attachments
7378 {
7379 const RenderPass renderPass(
7380 vector<Attachment>(),
7381 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7382 vector<AttachmentReference>(), vector<AttachmentReference>(),
7383 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7384 vector<uint32_t>())),
7385 vector<SubpassDependency>());
7386 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7387 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7388 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7389
7390 // No attachments case.
7391 addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", createTestShaders, renderPassTest, testConfig);
7392 }
7393
7394 // color_unused_omit_blend_state
7395 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7396 {
7397 vector<Subpass> subpasses;
7398
7399 // First subpass: use color attachment, create pipeline with color blend state
7400 subpasses.push_back(
7401 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7402 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7403 vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7404 vector<uint32_t>(), false));
7405
7406 // Second subpass: don't use color attachment, create pipeline without color blend state
7407 subpasses.push_back(
7408 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7409 vector<AttachmentReference>(
7410 1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7411 vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7412 vector<uint32_t>(), true));
7413
7414 const RenderPass renderPass(
7415 vector<Attachment>(1,
7416 Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
7417 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7418 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7419 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7420 subpasses, vector<SubpassDependency>());
7421
7422 const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
7423 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7424 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7425 // Two unused color attachment case without blend state
7426 addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state", createTestShaders,
7427 renderPassTest, testConfig);
7428 }
7429 }
7430
formatToName(VkFormat format)7431 std::string formatToName(VkFormat format)
7432 {
7433 const std::string formatStr = de::toString(format);
7434 const std::string prefix = "VK_FORMAT_";
7435
7436 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
7437
7438 return de::toLower(formatStr.substr(prefix.length()));
7439 }
7440
addFormatTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)7441 void addFormatTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
7442 {
7443 tcu::TestContext &testCtx = group->getTestContext();
7444
7445 const UVec2 targetSize(64, 64);
7446 const UVec2 renderPos(0, 0);
7447 const UVec2 renderSize(64, 64);
7448
7449 const struct
7450 {
7451 const char *const str;
7452 const VkAttachmentStoreOp op;
7453 } storeOps[] = {{"store", VK_ATTACHMENT_STORE_OP_STORE}, {"dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE}};
7454
7455 const struct
7456 {
7457 const char *const str;
7458 const VkAttachmentLoadOp op;
7459 } loadOps[] = {{"clear", VK_ATTACHMENT_LOAD_OP_CLEAR},
7460 {"load", VK_ATTACHMENT_LOAD_OP_LOAD},
7461 {"dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE}};
7462
7463 const struct
7464 {
7465 const char *const str;
7466 const TestConfig::RenderTypes types;
7467 } renderTypes[] = {{"clear", TestConfig::RENDERTYPES_CLEAR},
7468 {"draw", TestConfig::RENDERTYPES_DRAW},
7469 {"clear_draw", TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW}};
7470
7471 std::vector<VkFormat> colorFormatsToTest(s_coreColorFormats,
7472 s_coreColorFormats + de::arrayLength(s_coreColorFormats));
7473 #ifndef CTS_USES_VULKANSC
7474 colorFormatsToTest.push_back(VK_FORMAT_A8_UNORM_KHR);
7475 #endif // CTS_USES_VULKANSC
7476
7477 // Color formats
7478 for (const auto &format : colorFormatsToTest)
7479 {
7480 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatToName(format).c_str()));
7481
7482 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7483 {
7484 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7485 de::MovePtr<tcu::TestCaseGroup> loadOpGroup(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str));
7486
7487 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7488 {
7489 const RenderPass renderPass(
7490 vector<Attachment>(1,
7491 Attachment(format, VK_SAMPLE_COUNT_1_BIT, loadOp, VK_ATTACHMENT_STORE_OP_STORE,
7492 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7493 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7494 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7495 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7496 vector<AttachmentReference>(
7497 1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7498 vector<AttachmentReference>(),
7499 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7500 vector<uint32_t>())),
7501 vector<SubpassDependency>());
7502 const TestConfig testConfig(renderPass, renderTypes[renderTypeNdx].types,
7503 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7504 targetSize, renderPos, renderSize, false, 90239, 0,
7505 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7506
7507 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str,
7508 createTestShaders, renderPassTest, testConfig);
7509 }
7510
7511 formatGroup->addChild(loadOpGroup.release());
7512 }
7513
7514 {
7515 // Test attachment format as input
7516 de::MovePtr<tcu::TestCaseGroup> inputGroup(new tcu::TestCaseGroup(testCtx, "input"));
7517
7518 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7519 {
7520 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7521 de::MovePtr<tcu::TestCaseGroup> loadOpGroup(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str));
7522
7523 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7524 {
7525 const VkImageAspectFlags inputAttachmentAspectMask =
7526 (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
7527 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
7528 static_cast<VkImageAspectFlags>(0);
7529 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
7530 de::MovePtr<tcu::TestCaseGroup> storeOpGroup(
7531 new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str));
7532
7533 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7534 {
7535 const bool useInputAspect = useInputAspectNdx != 0;
7536
7537 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_RENDERPASS_LEGACY &&
7538 useInputAspect)
7539 continue;
7540
7541 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7542 {
7543 {
7544 vector<Attachment> attachments;
7545 vector<Subpass> subpasses;
7546 vector<SubpassDependency> deps;
7547 vector<VkInputAttachmentAspectReference> inputAspects;
7548
7549 attachments.push_back(Attachment(
7550 format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7551 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7552 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7553
7554 attachments.push_back(
7555 Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
7556 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
7557 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7558 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7559 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7560
7561 subpasses.push_back(
7562 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7563 vector<AttachmentReference>(
7564 1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7565 vector<AttachmentReference>(),
7566 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7567 vector<uint32_t>()));
7568 subpasses.push_back(
7569 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7570 vector<AttachmentReference>(
7571 1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
7572 inputAttachmentAspectMask)),
7573 vector<AttachmentReference>(
7574 1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7575 vector<AttachmentReference>(),
7576 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7577 vector<uint32_t>()));
7578
7579 deps.push_back(SubpassDependency(0, 1,
7580
7581 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7582 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7583
7584 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7585 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7586 vk::VK_DEPENDENCY_BY_REGION_BIT));
7587
7588 if (useInputAspect)
7589 {
7590 const VkInputAttachmentAspectReference inputAspect = {1u, 0u,
7591 VK_IMAGE_ASPECT_COLOR_BIT};
7592
7593 inputAspects.push_back(inputAspect);
7594 }
7595
7596 {
7597 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
7598 const TestConfig testConfig(
7599 renderPass, renderTypes[renderTypeNdx].types,
7600 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7601 targetSize, renderPos, renderSize, false, 89246, 0,
7602 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7603 const string testName(renderTypes[renderTypeNdx].str +
7604 string(useInputAspect ? "_use_input_aspect" : ""));
7605
7606 addFunctionCaseWithPrograms<TestConfig>(
7607 storeOpGroup.get(), testName, createTestShaders, renderPassTest, testConfig);
7608 }
7609 }
7610 {
7611 vector<Attachment> attachments;
7612 vector<Subpass> subpasses;
7613 vector<SubpassDependency> deps;
7614 vector<VkInputAttachmentAspectReference> inputAspects;
7615
7616 attachments.push_back(Attachment(
7617 format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7618 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7619 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7620
7621 subpasses.push_back(
7622 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7623 vector<AttachmentReference>(
7624 1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7625 vector<AttachmentReference>(),
7626 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7627 vector<uint32_t>()));
7628 subpasses.push_back(Subpass(
7629 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7630 vector<AttachmentReference>(
7631 1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7632 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
7633 vector<AttachmentReference>(),
7634 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7635 vector<uint32_t>()));
7636
7637 deps.push_back(SubpassDependency(
7638 0, 1, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7639 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7640
7641 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7642 vk::VK_DEPENDENCY_BY_REGION_BIT));
7643
7644 deps.push_back(SubpassDependency(
7645 1, 1, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7646 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7647
7648 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7649 vk::VK_DEPENDENCY_BY_REGION_BIT));
7650
7651 if (useInputAspect)
7652 {
7653 const VkInputAttachmentAspectReference inputAspect = {1u, 0u,
7654 VK_IMAGE_ASPECT_COLOR_BIT};
7655
7656 inputAspects.push_back(inputAspect);
7657 }
7658
7659 {
7660 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
7661 const TestConfig testConfig(
7662 renderPass, renderTypes[renderTypeNdx].types,
7663 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7664 targetSize, renderPos, renderSize, false, 89246, 0,
7665 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7666 const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
7667 (useInputAspect ? "_use_input_aspect" : ""));
7668
7669 addFunctionCaseWithPrograms<TestConfig>(
7670 storeOpGroup.get(), testName, createTestShaders, renderPassTest, testConfig);
7671 }
7672 }
7673 }
7674 }
7675
7676 loadOpGroup->addChild(storeOpGroup.release());
7677 }
7678
7679 inputGroup->addChild(loadOpGroup.release());
7680 }
7681
7682 formatGroup->addChild(inputGroup.release());
7683 }
7684
7685 group->addChild(formatGroup.release());
7686 }
7687
7688 // Depth stencil formats
7689 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
7690 {
7691 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
7692 const tcu::TextureFormat format = mapVkFormat(vkFormat);
7693 const bool isStencilAttachment = hasStencilComponent(format.order);
7694 const bool isDepthAttachment = hasDepthComponent(format.order);
7695 const VkImageAspectFlags formatAspectFlags =
7696 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
7697 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
7698 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str()));
7699
7700 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7701 {
7702 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7703 de::MovePtr<tcu::TestCaseGroup> loadOpGroup(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str));
7704
7705 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7706 {
7707 {
7708 const RenderPass renderPass(
7709 vector<Attachment>(1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
7710 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7711 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7712 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7713 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7714 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7715 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7716 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7717 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7718 vector<Subpass>(
7719 1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7720 vector<AttachmentReference>(), vector<AttachmentReference>(),
7721 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7722 vector<uint32_t>())),
7723 vector<SubpassDependency>());
7724 const TestConfig testConfig(renderPass, renderTypes[renderTypeNdx].types,
7725 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7726 targetSize, renderPos, renderSize, false, 90239, 0,
7727 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7728
7729 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str,
7730 createTestShaders, renderPassTest, testConfig);
7731 }
7732
7733 if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
7734 {
7735 {
7736 const RenderPass renderPass(
7737 vector<Attachment>(
7738 1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
7739 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7740 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7741 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7742 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7743 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7744 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7745 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7746 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7747 vector<Subpass>(1,
7748 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7749 vector<AttachmentReference>(), vector<AttachmentReference>(),
7750 AttachmentReference(
7751 0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7752 vector<uint32_t>())),
7753 vector<SubpassDependency>());
7754 const TestConfig testConfig(
7755 renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE,
7756 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7757 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7758 const string testName(string(renderTypes[renderTypeNdx].str) + "_depth_read_only");
7759
7760 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, createTestShaders,
7761 renderPassTest, testConfig);
7762 }
7763
7764 {
7765 const RenderPass renderPass(
7766 vector<Attachment>(
7767 1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
7768 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7769 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7770 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7771 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7772 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
7773 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7774 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7775 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7776 vector<Subpass>(1,
7777 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7778 vector<AttachmentReference>(), vector<AttachmentReference>(),
7779 AttachmentReference(
7780 0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7781 vector<uint32_t>())),
7782 vector<SubpassDependency>());
7783 const TestConfig testConfig(
7784 renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE,
7785 TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
7786 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7787 const string testName(string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");
7788
7789 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, createTestShaders,
7790 renderPassTest, testConfig);
7791 }
7792 }
7793 }
7794
7795 formatGroup->addChild(loadOpGroup.release());
7796 }
7797
7798 {
7799 de::MovePtr<tcu::TestCaseGroup> inputGroup(new tcu::TestCaseGroup(testCtx, "input"));
7800
7801 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7802 {
7803 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7804 de::MovePtr<tcu::TestCaseGroup> loadOpGroup(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str));
7805
7806 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7807 {
7808 const VkImageAspectFlags inputAttachmentAspectMask =
7809 (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
7810 formatAspectFlags :
7811 static_cast<VkImageAspectFlags>(0);
7812 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
7813 de::MovePtr<tcu::TestCaseGroup> storeOpGroup(
7814 new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str));
7815
7816 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7817 {
7818 const bool useInputAspect = useInputAspectNdx != 0;
7819
7820 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_RENDERPASS_LEGACY &&
7821 useInputAspect)
7822 continue;
7823
7824 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7825 {
7826 {
7827 vector<Attachment> attachments;
7828 vector<Subpass> subpasses;
7829 vector<SubpassDependency> deps;
7830 vector<VkInputAttachmentAspectReference> inputAspects;
7831
7832 attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
7833 loadOp, storeOp,
7834 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7835 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7836
7837 attachments.push_back(
7838 Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
7839 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
7840 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7841 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7842 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7843
7844 subpasses.push_back(
7845 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7846 vector<AttachmentReference>(), vector<AttachmentReference>(),
7847 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7848 vector<uint32_t>()));
7849 subpasses.push_back(
7850 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7851 vector<AttachmentReference>(
7852 1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
7853 inputAttachmentAspectMask)),
7854 vector<AttachmentReference>(
7855 1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7856 vector<AttachmentReference>(),
7857 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7858 vector<uint32_t>()));
7859
7860 deps.push_back(SubpassDependency(0, 1,
7861 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
7862 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7863 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7864
7865 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7866 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));
7867
7868 if (useInputAspect)
7869 {
7870 const VkInputAttachmentAspectReference inputAspect = {
7871 1u, 0u,
7872 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
7873 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
7874 0u)};
7875
7876 inputAspects.push_back(inputAspect);
7877 }
7878
7879 {
7880 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
7881 const TestConfig testConfig(
7882 renderPass, renderTypes[renderTypeNdx].types,
7883 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7884 targetSize, renderPos, renderSize, false, 89246, 0,
7885 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7886 const string testName(renderTypes[renderTypeNdx].str +
7887 string(useInputAspect ? "_use_input_aspect" : ""));
7888
7889 addFunctionCaseWithPrograms<TestConfig>(
7890 storeOpGroup.get(), testName, createTestShaders, renderPassTest, testConfig);
7891 }
7892 }
7893 {
7894 vector<Attachment> attachments;
7895 vector<Subpass> subpasses;
7896 vector<SubpassDependency> deps;
7897 vector<VkInputAttachmentAspectReference> inputAspects;
7898
7899 attachments.push_back(Attachment(
7900 vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7901 VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7902 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7903
7904 subpasses.push_back(
7905 Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7906 vector<AttachmentReference>(), vector<AttachmentReference>(),
7907 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7908 vector<uint32_t>()));
7909 subpasses.push_back(Subpass(
7910 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7911 vector<AttachmentReference>(
7912 1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7913 vector<AttachmentReference>(), vector<AttachmentReference>(),
7914 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));
7915
7916 deps.push_back(SubpassDependency(0, 1,
7917 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
7918 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7919 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7920
7921 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7922 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7923 vk::VK_DEPENDENCY_BY_REGION_BIT));
7924
7925 deps.push_back(SubpassDependency(1, 1,
7926 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
7927 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7928 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7929 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7930 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7931 vk::VK_DEPENDENCY_BY_REGION_BIT));
7932
7933 if (useInputAspect)
7934 {
7935 const VkInputAttachmentAspectReference inputAspect = {
7936 1u, 0u,
7937
7938 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
7939 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
7940 0u)};
7941
7942 inputAspects.push_back(inputAspect);
7943 }
7944
7945 {
7946 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
7947 const TestConfig testConfig(
7948 renderPass, renderTypes[renderTypeNdx].types,
7949 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
7950 targetSize, renderPos, renderSize, false, 89246, 0,
7951 testConfigExternal.allocationKind, testConfigExternal.groupParams);
7952 const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
7953 (useInputAspect ? "_use_input_aspect" : ""));
7954
7955 addFunctionCaseWithPrograms<TestConfig>(
7956 storeOpGroup.get(), testName, createTestShaders, renderPassTest, testConfig);
7957 }
7958 }
7959
7960 if (isStencilAttachment && isDepthAttachment)
7961 {
7962 // Depth read only
7963 {
7964 vector<Attachment> attachments;
7965 vector<Subpass> subpasses;
7966 vector<SubpassDependency> deps;
7967 vector<VkInputAttachmentAspectReference> inputAspects;
7968
7969 attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
7970 loadOp, storeOp,
7971 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7972 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7973
7974 attachments.push_back(
7975 Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
7976 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
7977 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7978 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7979 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7980
7981 subpasses.push_back(Subpass(
7982 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
7983 vector<AttachmentReference>(), vector<AttachmentReference>(),
7984 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7985 vector<uint32_t>()));
7986 subpasses.push_back(Subpass(
7987 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
7988 vector<AttachmentReference>(
7989 1, AttachmentReference(
7990 0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
7991 inputAttachmentAspectMask)),
7992 vector<AttachmentReference>(
7993 1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7994 vector<AttachmentReference>(),
7995 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7996 vector<uint32_t>()));
7997
7998 deps.push_back(SubpassDependency(0, 1,
7999 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8000 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
8001 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8002
8003 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8004 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));
8005
8006 if (useInputAspect)
8007 {
8008 const VkInputAttachmentAspectReference inputAspect = {
8009 1u, 0u,
8010
8011 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
8012 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
8013 0u)};
8014
8015 inputAspects.push_back(inputAspect);
8016 }
8017
8018 {
8019 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
8020 const TestConfig testConfig(
8021 renderPass, renderTypes[renderTypeNdx].types,
8022 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
8023 targetSize, renderPos, renderSize, false, 89246, 0,
8024 testConfigExternal.allocationKind, testConfigExternal.groupParams);
8025 const string testName(renderTypes[renderTypeNdx].str +
8026 string(useInputAspect ? "_use_input_aspect" : "") +
8027 "_depth_read_only");
8028
8029 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName,
8030 createTestShaders, renderPassTest,
8031 testConfig);
8032 }
8033 }
8034 {
8035 vector<Attachment> attachments;
8036 vector<Subpass> subpasses;
8037 vector<SubpassDependency> deps;
8038 vector<VkInputAttachmentAspectReference> inputAspects;
8039
8040 attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
8041 loadOp, storeOp,
8042 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
8043 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
8044
8045 subpasses.push_back(Subpass(
8046 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
8047 vector<AttachmentReference>(), vector<AttachmentReference>(),
8048 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
8049 vector<uint32_t>()));
8050 subpasses.push_back(Subpass(
8051 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
8052 vector<AttachmentReference>(
8053 1, AttachmentReference(
8054 0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
8055 inputAttachmentAspectMask)),
8056 vector<AttachmentReference>(), vector<AttachmentReference>(),
8057 AttachmentReference(0,
8058 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
8059 vector<uint32_t>()));
8060
8061 deps.push_back(SubpassDependency(0, 1,
8062 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8063 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
8064 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8065
8066 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8067 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
8068 vk::VK_DEPENDENCY_BY_REGION_BIT));
8069
8070 deps.push_back(SubpassDependency(1, 1,
8071 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8072 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
8073 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8074
8075 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8076 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
8077 vk::VK_DEPENDENCY_BY_REGION_BIT));
8078
8079 if (useInputAspect)
8080 {
8081 const VkInputAttachmentAspectReference inputAspect = {
8082 1u, 0u,
8083
8084 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
8085 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
8086 0u)};
8087
8088 inputAspects.push_back(inputAspect);
8089 }
8090
8091 {
8092 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
8093 const TestConfig testConfig(
8094 renderPass, renderTypes[renderTypeNdx].types,
8095 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
8096 targetSize, renderPos, renderSize, false, 89246, 0,
8097 testConfigExternal.allocationKind, testConfigExternal.groupParams);
8098 const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
8099 (useInputAspect ? "_use_input_aspect" : "") +
8100 "_depth_read_only");
8101
8102 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName,
8103 createTestShaders, renderPassTest,
8104 testConfig);
8105 }
8106 }
8107 // Stencil read only
8108 {
8109 vector<Attachment> attachments;
8110 vector<Subpass> subpasses;
8111 vector<SubpassDependency> deps;
8112 vector<VkInputAttachmentAspectReference> inputAspects;
8113
8114 attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
8115 loadOp, storeOp,
8116 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
8117 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
8118
8119 attachments.push_back(
8120 Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
8121 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
8122 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
8123 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
8124 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
8125
8126 subpasses.push_back(Subpass(
8127 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
8128 vector<AttachmentReference>(), vector<AttachmentReference>(),
8129 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
8130 vector<uint32_t>()));
8131 subpasses.push_back(Subpass(
8132 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
8133 vector<AttachmentReference>(
8134 1, AttachmentReference(
8135 0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
8136 inputAttachmentAspectMask)),
8137 vector<AttachmentReference>(
8138 1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
8139 vector<AttachmentReference>(),
8140 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
8141 vector<uint32_t>()));
8142
8143 deps.push_back(
8144 SubpassDependency(0, 1,
8145 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8146 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
8147 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
8148 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8149
8150 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
8151 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8152 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));
8153
8154 if (useInputAspect)
8155 {
8156 const VkInputAttachmentAspectReference inputAspect = {
8157 1u, 0u,
8158
8159 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
8160 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
8161 0u)};
8162
8163 inputAspects.push_back(inputAspect);
8164 }
8165
8166 {
8167 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
8168 const TestConfig testConfig(
8169 renderPass, renderTypes[renderTypeNdx].types,
8170 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
8171 targetSize, renderPos, renderSize, false, 89246, 0,
8172 testConfigExternal.allocationKind, testConfigExternal.groupParams);
8173 const string testName(renderTypes[renderTypeNdx].str +
8174 string(useInputAspect ? "_use_input_aspect" : "") +
8175 "_stencil_read_only");
8176
8177 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName,
8178 createTestShaders, renderPassTest,
8179 testConfig);
8180 }
8181 }
8182 {
8183 vector<Attachment> attachments;
8184 vector<Subpass> subpasses;
8185 vector<SubpassDependency> deps;
8186 vector<VkInputAttachmentAspectReference> inputAspects;
8187
8188 attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
8189 loadOp, storeOp,
8190 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
8191 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
8192
8193 subpasses.push_back(Subpass(
8194 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
8195 vector<AttachmentReference>(), vector<AttachmentReference>(),
8196 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
8197 vector<uint32_t>()));
8198 subpasses.push_back(Subpass(
8199 VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
8200 vector<AttachmentReference>(
8201 1, AttachmentReference(
8202 0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
8203 inputAttachmentAspectMask)),
8204 vector<AttachmentReference>(), vector<AttachmentReference>(),
8205 AttachmentReference(0,
8206 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
8207 vector<uint32_t>()));
8208
8209 deps.push_back(SubpassDependency(0, 1,
8210 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8211 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
8212 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8213
8214 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8215 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
8216 vk::VK_DEPENDENCY_BY_REGION_BIT));
8217
8218 deps.push_back(SubpassDependency(1, 1,
8219 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
8220 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
8221 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
8222
8223 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
8224 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
8225 vk::VK_DEPENDENCY_BY_REGION_BIT));
8226
8227 if (useInputAspect)
8228 {
8229 const VkInputAttachmentAspectReference inputAspect = {
8230 1u, 0u,
8231
8232 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
8233 (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
8234 0u)};
8235
8236 inputAspects.push_back(inputAspect);
8237 }
8238
8239 {
8240 const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
8241 const TestConfig testConfig(
8242 renderPass, renderTypes[renderTypeNdx].types,
8243 TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
8244 targetSize, renderPos, renderSize, false, 89246, 0,
8245 testConfigExternal.allocationKind, testConfigExternal.groupParams);
8246 const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
8247 (useInputAspect ? "_use_input_aspect" : "") +
8248 "_stencil_read_only");
8249
8250 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName,
8251 createTestShaders, renderPassTest,
8252 testConfig);
8253 }
8254 }
8255 }
8256 }
8257 }
8258
8259 loadOpGroup->addChild(storeOpGroup.release());
8260 }
8261
8262 inputGroup->addChild(loadOpGroup.release());
8263 }
8264
8265 formatGroup->addChild(inputGroup.release());
8266 }
8267
8268 group->addChild(formatGroup.release());
8269 }
8270 }
8271
addRenderPassTests(tcu::TestCaseGroup * group,const AllocationKind allocationKind,const SharedGroupParams groupParams)8272 void addRenderPassTests(tcu::TestCaseGroup *group, const AllocationKind allocationKind,
8273 const SharedGroupParams groupParams)
8274 {
8275 // tests added by this function have both primary and secondary cases and there is no need to repeat them for useSecondaryCmdBuffer flag;
8276 // but cases defined in other files that are later added to those groups in createRenderPassTestsInternal had to be adjusted and run
8277 // for useSecondaryCmdBuffer flag
8278 if (groupParams->useSecondaryCmdBuffer && !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
8279 return;
8280
8281 const TestConfigExternal testConfigExternal(allocationKind, groupParams);
8282
8283 // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
8284 if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
8285 {
8286 // Simple basic render pass tests
8287 addTestGroup(group, "simple", addSimpleTests, testConfigExternal);
8288 // Tests for different image formats.
8289 addTestGroup(group, "formats", addFormatTests, testConfigExternal);
8290 }
8291
8292 // Attachment format and count tests with load and store ops and image layouts
8293 addTestGroup(group, "attachment", addAttachmentTests, testConfigExternal);
8294
8295 // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
8296 if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
8297 // Attachment write mask tests
8298 addTestGroup(group, "attachment_write_mask", addAttachmentWriteMaskTests, testConfigExternal);
8299
8300 // this tests use many subpasses but when secondaries are tested then each subbpass is recorded to separate secondary command buffer;
8301 // we can't test dynamic_rendering_local_read and at the same time have begin/endRendering in each secondary command buffer
8302 if (!testConfigExternal.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
8303 addTestGroup(group, "attachment_allocation", addAttachmentAllocationTests, testConfigExternal);
8304 }
8305
createSuballocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)8306 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
8307 {
8308 // Suballocation RenderPass Tests
8309 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation"));
8310
8311 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, groupParams);
8312
8313 return suballocationTestsGroup;
8314 }
8315
createDedicatedAllocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)8316 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext &testCtx,
8317 const SharedGroupParams groupParams)
8318 {
8319 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(
8320 new tcu::TestCaseGroup(testCtx, "dedicated_allocation"));
8321
8322 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, groupParams);
8323
8324 return dedicatedAllocationTestsGroup;
8325 }
8326
createRenderPassTestsInternal(tcu::TestContext & testCtx,const char * groupName,const SharedGroupParams groupParams)8327 tcu::TestCaseGroup *createRenderPassTestsInternal(tcu::TestContext &testCtx, const char *groupName,
8328 const SharedGroupParams groupParams)
8329 {
8330 de::MovePtr<tcu::TestCaseGroup> renderingTests(new tcu::TestCaseGroup(testCtx, groupName));
8331 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx, groupParams);
8332 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx, groupParams);
8333 de::MovePtr<tcu::TestCaseGroup> noDrawGroup{new tcu::TestCaseGroup{testCtx, "no_draws"}};
8334 const RenderingType renderingType = groupParams->renderingType;
8335
8336 switch (renderingType)
8337 {
8338 case RENDERING_TYPE_RENDERPASS_LEGACY:
8339 #ifndef CTS_USES_VULKANSC
8340 renderingTests->addChild(createDepthStencilWriteConditionsTests(testCtx));
8341 #endif // CTS_USES_VULKANSC
8342 renderingTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));
8343 break;
8344
8345 case RENDERING_TYPE_RENDERPASS2:
8346 #ifndef CTS_USES_VULKANSC
8347 suballocationTestGroup->addChild(createRenderPassSubpassMergeFeedbackTests(testCtx, renderingType));
8348 #endif // CTS_USES_VULKANSC
8349 renderingTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
8350
8351 break;
8352
8353 #ifndef CTS_USES_VULKANSC
8354 case RENDERING_TYPE_DYNAMIC_RENDERING:
8355 // we are repeating only some multi-pass tests for pipeline libraries
8356 if (groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
8357 break;
8358
8359 renderingTests->addChild(createDynamicRenderingDepthStencilResolveTests(testCtx, groupParams));
8360
8361 // we are repeating some multi-pass tests for secondaries
8362 if (groupParams->useSecondaryCmdBuffer == false)
8363 {
8364 renderingTests->addChild(createDynamicRenderingRandomTests(testCtx));
8365 renderingTests->addChild(createDynamicRenderingBasicTests(testCtx));
8366 renderingTests->addChild(createDynamicRenderingUnusedAttachmentsTests(testCtx, false));
8367 renderingTests->addChild(createDynamicRenderingLocalReadTests(testCtx));
8368 }
8369 else if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
8370 {
8371 renderingTests->addChild(createDynamicRenderingUnusedAttachmentsTests(testCtx, true));
8372 }
8373 break;
8374 #endif // CTS_USES_VULKANSC
8375
8376 default:
8377 break;
8378 }
8379
8380 // attachment mapping from dynamic_rendering_local_read can't be used when
8381 // secondary command buffer doesn't compleately contain dynamic renderpass
8382 if ((renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) ||
8383 (groupParams->useSecondaryCmdBuffer == groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass))
8384 {
8385 suballocationTestGroup->addChild(createRenderPassSampleReadTests(testCtx, groupParams));
8386 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx, groupParams));
8387 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, groupParams));
8388 }
8389
8390 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, groupParams));
8391 suballocationTestGroup->addChild(createRenderPassSubpassDependencyTests(testCtx, groupParams));
8392 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx, groupParams));
8393 #ifndef CTS_USES_VULKANSC
8394 suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, groupParams));
8395 #endif // CTS_USES_VULKANSC
8396
8397 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
8398 {
8399 // repeat only dynamic_rendering_local_read tests for GPL
8400 suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, groupParams));
8401
8402 #ifndef CTS_USES_VULKANSC
8403 suballocationTestGroup->addChild(createRenderPassSparseRenderTargetTests(testCtx, groupParams));
8404
8405 renderingTests->addChild(createRenderPassDitheringTests(testCtx, groupParams));
8406 renderingTests->addChild(createFragmentDensityMapTests(testCtx, groupParams));
8407 #endif // CTS_USES_VULKANSC
8408
8409 if (groupParams->useSecondaryCmdBuffer == false)
8410 noDrawGroup->addChild(
8411 new RenderPassNoDrawLoadStoreTestCase(testCtx, "no_draw_clear_load_store", groupParams));
8412 }
8413
8414 renderingTests->addChild(suballocationTestGroup.release());
8415 renderingTests->addChild(dedicatedAllocationTestGroup.release());
8416 renderingTests->addChild(noDrawGroup.release());
8417
8418 return renderingTests.release();
8419 }
8420
8421 } // namespace
8422
createRenderPassTests(tcu::TestContext & testCtx,const std::string & name)8423 tcu::TestCaseGroup *createRenderPassTests(tcu::TestContext &testCtx, const std::string &name)
8424 {
8425 SharedGroupParams groupParams(new GroupParams{
8426 RENDERING_TYPE_RENDERPASS_LEGACY, // RenderingType renderingType;
8427 false, // bool useSecondaryCmdBuffer;
8428 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8429 PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // bool useGraphicsPipelineLibrary;
8430 });
8431 return createRenderPassTestsInternal(testCtx, name.c_str(), groupParams);
8432 }
8433
createRenderPass2Tests(tcu::TestContext & testCtx,const std::string & name)8434 tcu::TestCaseGroup *createRenderPass2Tests(tcu::TestContext &testCtx, const std::string &name)
8435 {
8436 SharedGroupParams groupParams(new GroupParams{
8437 RENDERING_TYPE_RENDERPASS2, // RenderingType renderingType;
8438 false, // bool useSecondaryCmdBuffer;
8439 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8440 PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // PipelineConstructionType pipelineConstructionType;
8441 });
8442 return createRenderPassTestsInternal(testCtx, name.c_str(), groupParams);
8443 }
8444
createDynamicRenderingTests(tcu::TestContext & testCtx,const std::string & name)8445 tcu::TestCaseGroup *createDynamicRenderingTests(tcu::TestContext &testCtx, const std::string &name)
8446 {
8447 // Draw using VK_KHR_dynamic_rendering
8448 de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup(new tcu::TestCaseGroup(testCtx, name.c_str()));
8449
8450 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(
8451 testCtx, "primary_cmd_buff",
8452 SharedGroupParams(new GroupParams{
8453 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8454 false, // bool useSecondaryCmdBuffer;
8455 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8456 PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // PipelineConstructionType pipelineConstructionType;
8457 })));
8458 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(
8459 testCtx, "partial_secondary_cmd_buff",
8460 SharedGroupParams(new GroupParams{
8461 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8462 true, // bool useSecondaryCmdBuffer;
8463 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8464 PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // PipelineConstructionType pipelineConstructionType;
8465 })));
8466 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(
8467 testCtx, "complete_secondary_cmd_buff",
8468 SharedGroupParams(new GroupParams{
8469 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8470 true, // bool useSecondaryCmdBuffer;
8471 true, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8472 PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // PipelineConstructionType pipelineConstructionType;
8473 })));
8474
8475 // on some implementations fast-link GPL generates fragment shader epilogs and we need to test this for dynamic_rendering_local_read
8476 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(
8477 testCtx, "graphics_pipeline_library",
8478 SharedGroupParams(new GroupParams{
8479 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8480 false, // bool useSecondaryCmdBuffer;
8481 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8482 PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY, // PipelineConstructionType pipelineConstructionType;
8483 })));
8484
8485 return dynamicRenderingGroup.release();
8486 }
8487
8488 } // namespace vkt
8489