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