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::__anone08f04e90111::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::__anone08f04e90111::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 VkStencilOp stencilOp = writeStencil ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP;
2014
2015 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2016 {
2017 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
2018 DE_NULL, // pNext
2019 (VkPipelineDepthStencilStateCreateFlags)0u,
2020 writeDepth, // depthTestEnable
2021 writeDepth, // depthWriteEnable
2022 VK_COMPARE_OP_ALWAYS, // depthCompareOp
2023 VK_FALSE, // depthBoundsEnable
2024 writeStencil, // stencilTestEnable
2025 {
2026 stencilOp, // stencilFailOp
2027 stencilOp, // stencilPassOp
2028 stencilOp, // stencilDepthFailOp
2029 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
2030 ~0u, // stencilCompareMask
2031 ~0u, // stencilWriteMask
2032 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
2033 }, // front
2034 {
2035 stencilOp, // stencilFailOp
2036 stencilOp, // stencilPassOp
2037 stencilOp, // stencilDepthFailOp
2038 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
2039 ~0u, // stencilCompareMask
2040 ~0u, // stencilWriteMask
2041 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
2042 }, // back
2043
2044 0.0f, // minDepthBounds;
2045 1.0f // maxDepthBounds;
2046 };
2047
2048 const VkPipelineColorBlendStateCreateInfo blendState =
2049 {
2050 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
2051 DE_NULL, // pNext
2052 (VkPipelineColorBlendStateCreateFlags)0u,
2053 VK_FALSE, // logicOpEnable
2054 VK_LOGIC_OP_COPY, // logicOp
2055 (deUint32)attachmentBlendStates.size(), // attachmentCount
2056 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
2057 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
2058 };
2059
2060 #ifndef CTS_USES_VULKANSC
2061 std::vector<vk::VkFormat> colorAttachmentFormats;
2062 for (deUint32 i = 0; i < renderInfo.getColorAttachmentCount(); ++i)
2063 colorAttachmentFormats.push_back(renderInfo.getColorAttachment(i).getFormat());
2064
2065 vk::VkFormat depthFormat = VK_FORMAT_UNDEFINED;
2066 vk::VkFormat stencilFormat = VK_FORMAT_UNDEFINED;
2067 if (renderInfo.getDepthStencilAttachment())
2068 {
2069 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
2070 vk::VkFormat depthStencilFormat = attachment.getFormat();
2071 if (depthStencilFormat != VK_FORMAT_UNDEFINED)
2072 {
2073 if (tcu::hasDepthComponent(mapVkFormat(depthStencilFormat).order))
2074 {
2075 depthFormat = depthStencilFormat;
2076 }
2077 if (tcu::hasStencilComponent(mapVkFormat(depthStencilFormat).order))
2078 {
2079 stencilFormat = depthStencilFormat;
2080 }
2081 }
2082 }
2083
2084
2085 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
2086 {
2087 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2088 DE_NULL,
2089 0u,
2090 static_cast<deUint32>(colorAttachmentFormats.size()),
2091 colorAttachmentFormats.data(),
2092 depthFormat,
2093 stencilFormat
2094 };
2095 #endif // CTS_USES_VULKANSC
2096
2097 return makeGraphicsPipeline(vk, // const DeviceInterface& vk
2098 device, // const VkDevice device
2099 pipelineLayout, // const VkPipelineLayout pipelineLayout
2100 vertexShaderModule, // const VkShaderModule vertexShaderModule
2101 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2102 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2103 DE_NULL, // const VkShaderModule geometryShaderModule
2104 fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2105 renderPass, // const VkRenderPass renderPass
2106 renderInfo.getSubpassIndex(), // const deUint32 subpass
2107 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2108 &inputAssemblyState, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2109 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2110 &viewportState, // const VkPipelineViewportStateCreateInfo* pViewportStat;
2111 &rasterizationState, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState
2112 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2113 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
2114 renderInfo.getOmitBlendState()
2115 ? DE_NULL : &blendState, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
2116 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
2117 #ifndef CTS_USES_VULKANSC
2118 (renderPass == DE_NULL)
2119 ? &renderingCreateInfo : DE_NULL); // const void* pNext)
2120 #else
2121 DE_NULL); // const void* pNext)
2122 #endif // CTS_USES_VULKANSC
2123 }
2124
2125 #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)2126 void beginDynamicRendering(const DeviceInterface& vk,
2127 VkCommandBuffer commandBuffer,
2128 const RenderPass& renderPassInfo,
2129 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2130 const VkRect2D& renderArea,
2131 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2132 const VkRenderingFlagsKHR renderingFlags = 0u)
2133 {
2134 const float clearNan = tcu::Float32::nan().asFloat();
2135 const VkClearValue clearValueNan = makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan);
2136
2137 // translate structures that were prepared to construct renderpass to structures needed for dynamic rendering
2138
2139 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachmentVect;
2140 const Subpass& subpassInfo = renderPassInfo.getSubpasses()[0];
2141 const vector<AttachmentReference>& colorAttachmentsInfo = subpassInfo.getColorAttachments();
2142 const vector<AttachmentReference>& resolveAttachmentsInfo = subpassInfo.getResolveAttachments();
2143
2144 for (deUint32 i = 0; i < colorAttachmentsInfo.size(); ++i)
2145 {
2146 const AttachmentReference& colorAttachmentReference = colorAttachmentsInfo[i];
2147 const deUint32 colorAttachmentIndex = colorAttachmentReference.getAttachment();
2148 const Attachment& colorAttachmentInfo = renderPassInfo.getAttachments()[colorAttachmentIndex];
2149
2150 VkResolveModeFlagBits resolveMode = VK_RESOLVE_MODE_NONE;
2151 VkImageView resolveImageView = DE_NULL;
2152 VkImageLayout resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2153
2154 // handle resolve attachments if they were specified
2155 if (!resolveAttachmentsInfo.empty())
2156 {
2157 const AttachmentReference& resolveAttachmentReference = resolveAttachmentsInfo[i];
2158 const deUint32 resolveAttachmentIndex = resolveAttachmentReference.getAttachment();
2159 const Attachment& resolveAttachmentInfo = renderPassInfo.getAttachments()[resolveAttachmentIndex];
2160
2161 resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
2162 resolveImageView = attachmentResources[resolveAttachmentIndex]->getAttachmentView();
2163 resolveImageLayout = resolveAttachmentInfo.getInitialLayout();
2164 }
2165
2166 colorAttachmentVect.push_back({
2167 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType
2168 DE_NULL, // const void* pNext
2169 attachmentResources[colorAttachmentIndex]->getAttachmentView(), // VkImageView imageView
2170 colorAttachmentReference.getImageLayout(), // VkImageLayout imageLayout
2171 resolveMode, // VkResolveModeFlagBits resolveMode
2172 resolveImageView, // VkImageView resolveImageView
2173 resolveImageLayout, // VkImageLayout resolveImageLayout
2174 colorAttachmentInfo.getLoadOp(), // VkAttachmentLoadOp loadOp
2175 colorAttachmentInfo.getStoreOp(), // VkAttachmentStoreOp storeOp
2176 (renderPassClearValues[colorAttachmentIndex] ?
2177 *renderPassClearValues[colorAttachmentIndex] :
2178 clearValueNan) // VkClearValue clearValue
2179 });
2180 }
2181
2182 VkRenderingAttachmentInfoKHR* pDepthAttachment = DE_NULL;
2183 VkRenderingAttachmentInfoKHR* pStencilAttachment = DE_NULL;
2184 VkRenderingAttachmentInfoKHR depthAttachment
2185 {
2186 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2187 DE_NULL, // const void* pNext;
2188 DE_NULL, // VkImageView imageView;
2189 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2190 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2191 DE_NULL, // VkImageView resolveImageView;
2192 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2193 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2194 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2195 clearValueNan // VkClearValue clearValue;
2196 };
2197 VkRenderingAttachmentInfoKHR stencilAttachment = depthAttachment;
2198 const AttachmentReference& depthStencilAttachmentReference = subpassInfo.getDepthStencilAttachment();
2199 const deUint32 dsAttachmentIndex = depthStencilAttachmentReference.getAttachment();
2200
2201 if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
2202 {
2203 const Attachment& dsAttachmentInfo = renderPassInfo.getAttachments()[dsAttachmentIndex];
2204 const tcu::TextureFormat format = mapVkFormat(dsAttachmentInfo.getFormat());
2205
2206 if (tcu::hasDepthComponent(format.order))
2207 {
2208 depthAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2209 depthAttachment.imageLayout = depthStencilAttachmentReference.getImageLayout();
2210 depthAttachment.loadOp = dsAttachmentInfo.getLoadOp();
2211 depthAttachment.storeOp = dsAttachmentInfo.getStoreOp();
2212
2213 if (renderPassClearValues[dsAttachmentIndex])
2214 depthAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2215
2216 pDepthAttachment = &depthAttachment;
2217 }
2218
2219 if (tcu::hasStencilComponent(format.order))
2220 {
2221 stencilAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2222 stencilAttachment.imageLayout = depthStencilAttachmentReference.getImageLayout();
2223 stencilAttachment.loadOp = dsAttachmentInfo.getStencilLoadOp();
2224 stencilAttachment.storeOp = dsAttachmentInfo.getStencilStoreOp();
2225
2226 if (renderPassClearValues[dsAttachmentIndex])
2227 stencilAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2228
2229 pStencilAttachment = &stencilAttachment;
2230 }
2231 }
2232
2233 vk::VkRenderingInfoKHR renderingInfo
2234 {
2235 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2236 DE_NULL,
2237 renderingFlags, // VkRenderingFlagsKHR flags;
2238 renderArea, // VkRect2D renderArea;
2239 1u, // deUint32 layerCount;
2240 0u, // deUint32 viewMask;
2241 static_cast<deUint32>(colorAttachmentVect.size()), // deUint32 colorAttachmentCount;
2242 colorAttachmentVect.empty() ? DE_NULL : &colorAttachmentVect[0], // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2243 pDepthAttachment, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2244 pStencilAttachment // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2245 };
2246
2247 vk.cmdBeginRendering(commandBuffer, &renderingInfo);
2248 }
2249
endDynamicRendering(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2250 void endDynamicRendering(const DeviceInterface& vk, VkCommandBuffer commandBuffer)
2251 {
2252 vk.cmdEndRendering(commandBuffer);
2253 }
2254 #endif // CTS_USES_VULKANSC
2255
2256 class SubpassRenderer
2257 {
2258 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)2259 SubpassRenderer (Context& context,
2260 const DeviceInterface& vk,
2261 VkDevice device,
2262 Allocator& allocator,
2263 const RenderPass& renderPassInfo,
2264 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2265 const VkRect2D& renderArea,
2266 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2267 VkRenderPass renderPass,
2268 VkFramebuffer framebuffer,
2269 VkCommandPool commandBufferPool,
2270 deUint32 queueFamilyIndex,
2271 const vector<VkImage>& attachmentImages,
2272 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
2273 const SubpassRenderInfo& renderInfo,
2274 const AllocationKind allocationKind,
2275 const bool dynamicRendering,
2276 const bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2277 : m_renderInfo (renderInfo)
2278 {
2279 // unreference values not used by Vulkan SC, no need to pu this under ifdef
2280 DE_UNREF(attachmentResources);
2281 DE_UNREF(renderArea);
2282 DE_UNREF(renderPassClearValues);
2283
2284 const InstanceInterface& vki = context.getInstanceInterface();
2285 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
2286 const vector<Attachment>& attachmentInfos = renderPassInfo.getAttachments();
2287 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
2288 vector<VkDescriptorSetLayoutBinding> bindings;
2289
2290 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2291 {
2292 const deUint32 attachmentNdx = (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ? colorAttachmentNdx
2293 : renderInfo.getColorAttachmentIndex(colorAttachmentNdx);
2294
2295 m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
2296 }
2297
2298 if (renderInfo.getDepthStencilAttachmentIndex())
2299 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
2300
2301 if (renderInfo.getRenderQuad())
2302 {
2303 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2304
2305 if (renderInfo.getInputAttachmentCount() > 0)
2306 {
2307 deUint32 bindingIndex = 0;
2308
2309 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2310 {
2311 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2312 const VkImageLayout layout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2313 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2314 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2315 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2316 const deUint32 bindingCount = (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2317 && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2318 ? 2u
2319 : 1u;
2320
2321 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
2322 {
2323 const VkDescriptorSetLayoutBinding binding =
2324 {
2325 bindingIndex,
2326 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2327 1u,
2328 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
2329 DE_NULL
2330 };
2331
2332 bindings.push_back(binding);
2333 bindingIndex++;
2334 }
2335 }
2336
2337 const VkDescriptorSetLayoutCreateInfo createInfo =
2338 {
2339 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2340 DE_NULL,
2341
2342 0u,
2343 (deUint32)bindings.size(),
2344 &bindings[0]
2345 };
2346
2347 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
2348 }
2349
2350 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
2351 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2352 {
2353 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
2354 DE_NULL, // pNext;
2355 (vk::VkPipelineLayoutCreateFlags)0,
2356 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
2357 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
2358 0u, // pushConstantRangeCount;
2359 DE_NULL, // pPushConstantRanges;
2360 };
2361
2362 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
2363 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
2364 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
2365 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
2366
2367 // Round up the vertex buffer size to honor nonCoherentAtomSize.
2368 const auto properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2369 const auto vertexBufferSize = de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()), properties.limits.nonCoherentAtomSize);
2370
2371 m_vertexBuffer = createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2372 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
2373
2374 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
2375
2376 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);
2377
2378 if (renderInfo.getInputAttachmentCount() > 0)
2379 {
2380 {
2381 const VkDescriptorPoolSize poolSize =
2382 {
2383 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2384 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2385 renderInfo.getInputAttachmentCount() * 2u
2386 };
2387 const VkDescriptorPoolCreateInfo createInfo =
2388 {
2389 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2390 DE_NULL,
2391 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2392
2393 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2394 renderInfo.getInputAttachmentCount() * 2u,
2395 1u,
2396 &poolSize
2397 };
2398
2399 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2400 }
2401 {
2402 const VkDescriptorSetAllocateInfo allocateInfo =
2403 {
2404 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2405 DE_NULL,
2406
2407 *m_descriptorPool,
2408 1u,
2409 &descriptorSetLayout
2410 };
2411
2412 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2413 }
2414 {
2415 vector<VkWriteDescriptorSet> writes (bindings.size());
2416 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
2417 deUint32 bindingIndex = 0;
2418
2419 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2420 {
2421 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2422 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2423 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2424 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2425 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2426
2427
2428 if (isDepthFormat && isStencilFormat)
2429 {
2430 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2431 {
2432 const VkDescriptorImageInfo imageInfo =
2433 {
2434 (VkSampler)0,
2435 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2436 inputAttachmentLayout
2437 };
2438 imageInfos[bindingIndex] = imageInfo;
2439
2440 {
2441 const VkWriteDescriptorSet write =
2442 {
2443 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2444 DE_NULL,
2445
2446 *m_descriptorSet,
2447 bindingIndex,
2448 0u,
2449 1u,
2450 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2451 &imageInfos[bindingIndex],
2452 DE_NULL,
2453 DE_NULL
2454 };
2455 writes[bindingIndex] = write;
2456
2457 bindingIndex++;
2458 }
2459 }
2460
2461 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2462 {
2463 const VkDescriptorImageInfo imageInfo =
2464 {
2465 (VkSampler)0,
2466 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2467 inputAttachmentLayout
2468 };
2469 imageInfos[bindingIndex] = imageInfo;
2470
2471 {
2472 const VkWriteDescriptorSet write =
2473 {
2474 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2475 DE_NULL,
2476
2477 *m_descriptorSet,
2478 bindingIndex,
2479 0u,
2480 1u,
2481 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2482 &imageInfos[bindingIndex],
2483 DE_NULL,
2484 DE_NULL
2485 };
2486 writes[bindingIndex] = write;
2487
2488 bindingIndex++;
2489 }
2490 }
2491 }
2492 else
2493 {
2494 const VkDescriptorImageInfo imageInfo =
2495 {
2496 (VkSampler)0,
2497 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2498 inputAttachmentLayout
2499 };
2500 imageInfos[bindingIndex] = imageInfo;
2501
2502 {
2503 const VkWriteDescriptorSet write =
2504 {
2505 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2506 DE_NULL,
2507
2508 *m_descriptorSet,
2509 bindingIndex,
2510 0u,
2511 1u,
2512 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2513 &imageInfos[bindingIndex],
2514 DE_NULL,
2515 DE_NULL
2516 };
2517 writes[bindingIndex] = write;
2518
2519 bindingIndex++;
2520 }
2521 }
2522 }
2523
2524 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2525 }
2526 }
2527 }
2528
2529 if (renderInfo.isSecondary())
2530 {
2531 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2532
2533 beginCommandBuffer(vk, *m_commandBuffer, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0,
2534 (VkQueryPipelineStatisticFlags)0, &renderInfo, dynamicRendering, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
2535
2536 if (dynamicRendering && secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2537 {
2538 #ifndef CTS_USES_VULKANSC
2539 beginDynamicRendering(vk, *m_commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues);
2540 pushRenderCommands(vk, *m_commandBuffer);
2541 endDynamicRendering(vk, *m_commandBuffer);
2542 #endif // CTS_USES_VULKANSC
2543 }
2544 else
2545 pushRenderCommands(vk, *m_commandBuffer);
2546
2547 endCommandBuffer(vk, *m_commandBuffer);
2548 }
2549 }
2550
isSecondary(void) const2551 bool isSecondary (void) const
2552 {
2553 return !!m_commandBuffer;
2554 }
2555
getCommandBuffer(void) const2556 VkCommandBuffer getCommandBuffer (void) const
2557 {
2558 DE_ASSERT(isSecondary());
2559 return *m_commandBuffer;
2560 }
2561
pushRenderCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2562 void pushRenderCommands (const DeviceInterface& vk,
2563 VkCommandBuffer commandBuffer)
2564 {
2565 if (!m_renderInfo.getColorClears().empty())
2566 {
2567 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2568
2569 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2570 {
2571 const ColorClear& colorClear = colorClears[attachmentNdx];
2572 const VkClearAttachment attachment =
2573 {
2574 VK_IMAGE_ASPECT_COLOR_BIT,
2575 attachmentNdx,
2576 makeClearValue(colorClear.getColor()),
2577 };
2578 const VkClearRect rect =
2579 {
2580 {
2581 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2582 { colorClear.getSize().x(), colorClear.getSize().y() }
2583 }, // rect
2584 0u, // baseArrayLayer
2585 1u, // layerCount
2586 };
2587
2588 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2589 }
2590 }
2591
2592 if (m_renderInfo.getDepthStencilClear())
2593 {
2594 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2595 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2596 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2597 const VkImageLayout layout = *m_renderInfo.getDepthStencilAttachmentLayout();
2598 const VkClearAttachment attachment =
2599 {
2600 (VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2601 | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2602 attachmentNdx,
2603 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2604 };
2605 const VkClearRect rect =
2606 {
2607 {
2608 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2609 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2610 }, // rect
2611 0u, // baseArrayLayer
2612 1u, // layerCount
2613 };
2614
2615 if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2616 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
2617 {
2618 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2619 }
2620 }
2621
2622 vector<VkImageMemoryBarrier> selfDeps;
2623 VkPipelineStageFlags srcStages = 0;
2624 VkPipelineStageFlags dstStages = 0;
2625
2626 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2627 {
2628 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2629 {
2630 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2631 {
2632 const VkImageMemoryBarrier barrier =
2633 {
2634 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2635 DE_NULL, // pNext
2636
2637 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2638 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2639
2640 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2641 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2642
2643 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2644 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2645
2646 m_colorAttachmentImages[colorAttachmentNdx], // image
2647 { // subresourceRange
2648 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2649 0, // baseMipLevel
2650 1, // mipLevels
2651 0, // baseArraySlice
2652 1 // arraySize
2653 }
2654 };
2655
2656 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2657 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2658
2659 selfDeps.push_back(barrier);
2660 }
2661 }
2662
2663 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2664 {
2665 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2666 const bool hasDepth = hasDepthComponent(format.order);
2667 const bool hasStencil = hasStencilComponent(format.order);
2668 const VkImageMemoryBarrier barrier =
2669 {
2670 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2671 DE_NULL, // pNext;
2672
2673 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2674 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2675
2676 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // oldLayout
2677 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // newLayout;
2678
2679 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2680 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2681
2682 m_depthStencilAttachmentImage, // image;
2683 { // subresourceRange;
2684 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2685 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2686 0, // baseMipLevel;
2687 1, // mipLevels;
2688 0, // baseArraySlice;
2689 1 // arraySize;
2690 }
2691 };
2692
2693 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2694 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2695
2696 selfDeps.push_back(barrier);
2697 }
2698 }
2699
2700 if (!selfDeps.empty())
2701 {
2702 DE_ASSERT(srcStages != 0);
2703 DE_ASSERT(dstStages != 0);
2704 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2705 }
2706
2707 if (m_renderInfo.getRenderQuad())
2708 {
2709 const VkDeviceSize offset = 0;
2710 const VkBuffer vertexBuffer = *m_vertexBuffer;
2711
2712 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2713
2714 if (m_descriptorSet)
2715 {
2716 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2717 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2718 }
2719
2720 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2721 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2722 }
2723 }
2724
2725 private:
2726 const SubpassRenderInfo m_renderInfo;
2727 Move<VkCommandBuffer> m_commandBuffer;
2728 Move<VkPipeline> m_pipeline;
2729 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2730 Move<VkPipelineLayout> m_pipelineLayout;
2731
2732 Move<VkShaderModule> m_vertexShaderModule;
2733 Move<VkShaderModule> m_fragmentShaderModule;
2734
2735 Move<VkDescriptorPool> m_descriptorPool;
2736 Move<VkDescriptorSet> m_descriptorSet;
2737 Move<VkBuffer> m_vertexBuffer;
2738 de::MovePtr<Allocation> m_vertexBufferMemory;
2739 vector<VkImage> m_colorAttachmentImages;
2740 VkImage m_depthStencilAttachmentImage;
2741 };
2742
pushImageInitializationCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const vector<Attachment> & attachmentInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,deUint32 queueIndex,const vector<Maybe<VkClearValue>> & clearValues)2743 void pushImageInitializationCommands (const DeviceInterface& vk,
2744 VkCommandBuffer commandBuffer,
2745 const vector<Attachment>& attachmentInfo,
2746 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2747 deUint32 queueIndex,
2748 const vector<Maybe<VkClearValue> >& clearValues)
2749 {
2750 {
2751 vector<VkImageMemoryBarrier> initializeLayouts;
2752
2753 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2754 {
2755 if (!clearValues[attachmentNdx])
2756 continue;
2757
2758 const VkImageMemoryBarrier barrier =
2759 {
2760 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2761 DE_NULL, // pNext;
2762
2763 (VkAccessFlags)0, // srcAccessMask
2764 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2765
2766 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2767 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2768
2769 queueIndex, // srcQueueFamilyIndex;
2770 queueIndex, // destQueueFamilyIndex;
2771
2772 attachmentResources[attachmentNdx]->getImage(), // image;
2773 { // subresourceRange;
2774 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2775 0, // baseMipLevel;
2776 1, // mipLevels;
2777 0, // baseArraySlice;
2778 1 // arraySize;
2779 }
2780 };
2781
2782 initializeLayouts.push_back(barrier);
2783 }
2784
2785 if (!initializeLayouts.empty())
2786 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2787 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2788 0, (const VkMemoryBarrier*)DE_NULL,
2789 0, (const VkBufferMemoryBarrier*)DE_NULL,
2790 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2791 }
2792
2793 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2794 {
2795 if (!clearValues[attachmentNdx])
2796 continue;
2797
2798 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2799
2800 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2801 {
2802 const float clearNan = tcu::Float32::nan().asFloat();
2803 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2804 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2805 const VkClearDepthStencilValue depthStencil =
2806 {
2807 clearDepth,
2808 clearStencil
2809 };
2810 const VkImageSubresourceRange range =
2811 {
2812 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2813 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2814 0,
2815 1,
2816 0,
2817 1
2818 };
2819
2820 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2821 }
2822 else
2823 {
2824 const VkImageSubresourceRange range =
2825 {
2826 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2827 0, // baseMipLevel;
2828 1, // mipLevels;
2829 0, // baseArrayLayer;
2830 1 // layerCount;
2831 };
2832 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2833
2834 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2835 }
2836 }
2837
2838 {
2839 vector<VkImageMemoryBarrier> renderPassLayouts;
2840
2841 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2842 {
2843 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2844 const VkImageMemoryBarrier barrier =
2845 {
2846 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2847 DE_NULL, // pNext;
2848
2849 getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2850 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2851
2852 oldLayout, // oldLayout
2853 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2854
2855 queueIndex, // srcQueueFamilyIndex;
2856 queueIndex, // destQueueFamilyIndex;
2857
2858 attachmentResources[attachmentNdx]->getImage(), // image;
2859 { // subresourceRange;
2860 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2861 0, // baseMipLevel;
2862 1, // mipLevels;
2863 0, // baseArraySlice;
2864 1 // arraySize;
2865 }
2866 };
2867
2868 renderPassLayouts.push_back(barrier);
2869 }
2870
2871 if (!renderPassLayouts.empty())
2872 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2873 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2874 0, (const VkMemoryBarrier*)DE_NULL,
2875 0, (const VkBufferMemoryBarrier*)DE_NULL,
2876 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2877 }
2878 }
2879
2880 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)2881 void pushRenderPassCommands (const DeviceInterface& vk,
2882 VkCommandBuffer commandBuffer,
2883 VkRenderPass renderPass,
2884 VkFramebuffer framebuffer,
2885 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2886 const VkRect2D& renderArea,
2887 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2888 TestConfig::RenderTypes render)
2889 {
2890 const float clearNan = tcu::Float32::nan().asFloat();
2891 vector<VkClearValue> attachmentClearValues;
2892 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
2893
2894 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2895 {
2896 if (renderPassClearValues[attachmentNdx])
2897 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2898 else
2899 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2900 }
2901
2902 {
2903 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2904 {
2905 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2906 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents);
2907 const VkRenderPassBeginInfo renderPassBeginInfo = createRenderPassBeginInfo(renderPass,
2908 framebuffer,
2909 renderArea,
2910 (deUint32)attachmentClearValues.size(),
2911 attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);
2912
2913 if (subpassNdx == 0)
2914 RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
2915 else
2916 RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2917
2918 if (render)
2919 {
2920 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2921 {
2922 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2923 }
2924 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2925 {
2926 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2927 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2928 }
2929 else
2930 DE_FATAL("Invalid contents");
2931 }
2932 }
2933
2934 RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
2935 }
2936 }
2937
2938 #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)2939 void pushDynamicRenderingCommands (const DeviceInterface& vk,
2940 VkCommandBuffer commandBuffer,
2941 const RenderPass& renderPassInfo,
2942 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2943 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2944 const VkRect2D& renderArea,
2945 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2946 deUint32 queueIndex,
2947 TestConfig::RenderTypes renderType,
2948 bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2949 {
2950 DE_ASSERT(subpassRenderers.size() == 1);
2951
2952 vector<VkImageMemoryBarrier> imageBarriersBeforeRendering;
2953 vector<VkImageMemoryBarrier> imageBarriersAfterRendering;
2954
2955 const Subpass& subpassInfo = renderPassInfo.getSubpasses()[0];
2956 const vector<AttachmentReference>& colorAttachmentsInfo = subpassInfo.getColorAttachments();
2957
2958 for (deUint32 i = 0 ; i < colorAttachmentsInfo.size() ; ++i)
2959 {
2960 const AttachmentReference& colorAttachmentReference = colorAttachmentsInfo[i];
2961 const deUint32 colorAttachmentIndex = colorAttachmentReference.getAttachment();
2962 const Attachment& colorAttachmentInfo = renderPassInfo.getAttachments()[colorAttachmentIndex];
2963
2964 const VkImageLayout initialLayout = colorAttachmentInfo.getInitialLayout();
2965 const VkImageLayout renderingLayout = colorAttachmentReference.getImageLayout();
2966 const VkImageLayout finalLayout = colorAttachmentInfo.getFinalLayout();
2967
2968 const VkImageMemoryBarrier barrierBeforeRendering
2969 {
2970 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2971 DE_NULL, // pNext
2972
2973 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout), // srcAccessMask
2974 getMemoryFlagsForLayout(renderingLayout), // dstAccessMask
2975
2976 initialLayout, // oldLayout
2977 renderingLayout, // newLayout
2978
2979 queueIndex, // srcQueueFamilyIndex
2980 queueIndex, // destQueueFamilyIndex
2981
2982 attachmentResources[colorAttachmentIndex]->getImage(), // image
2983 { // subresourceRange
2984 getImageAspectFlags(colorAttachmentInfo.getFormat()), // aspect;
2985 0, // baseMipLevel
2986 1, // mipLevels
2987 0, // baseArraySlice
2988 1 // arraySize
2989 }
2990 };
2991 imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
2992
2993 const VkImageMemoryBarrier barrierAfterRendering
2994 {
2995 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2996 DE_NULL, // pNext
2997
2998 getMemoryFlagsForLayout(renderingLayout), // srcAccessMask
2999 getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout), // dstAccessMask
3000
3001 renderingLayout, // oldLayout
3002 finalLayout, // newLayout
3003
3004 queueIndex, // srcQueueFamilyIndex
3005 queueIndex, // destQueueFamilyIndex
3006
3007 attachmentResources[colorAttachmentIndex]->getImage(), // image
3008 { // subresourceRange
3009 getImageAspectFlags(colorAttachmentInfo.getFormat()), // aspect;
3010 0, // baseMipLevel
3011 1, // mipLevels
3012 0, // baseArraySlice
3013 1 // arraySize
3014 }
3015 };
3016 imageBarriersAfterRendering.push_back(barrierAfterRendering);
3017 }
3018
3019 const AttachmentReference& depthStencilAttachmentReference = subpassInfo.getDepthStencilAttachment();
3020 const deUint32 dsAttachmentIndex = depthStencilAttachmentReference.getAttachment();
3021
3022 if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
3023 {
3024 const Attachment& dsAttachmentInfo = renderPassInfo.getAttachments()[dsAttachmentIndex];
3025
3026 const VkImageLayout initialLayout = dsAttachmentInfo.getInitialLayout();
3027 const VkImageLayout renderingLayout = depthStencilAttachmentReference.getImageLayout();
3028 const VkImageLayout finalLayout = dsAttachmentInfo.getFinalLayout();
3029
3030 const VkImageMemoryBarrier barrierBeforeRendering
3031 {
3032 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
3033 DE_NULL, // pNext
3034
3035 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout), // srcAccessMask
3036 getMemoryFlagsForLayout(renderingLayout), // dstAccessMask
3037
3038 initialLayout, // oldLayout
3039 renderingLayout, // newLayout
3040
3041 queueIndex, // srcQueueFamilyIndex
3042 queueIndex, // destQueueFamilyIndex
3043
3044 attachmentResources[dsAttachmentIndex]->getImage(), // image
3045 { // subresourceRange
3046 getImageAspectFlags(dsAttachmentInfo.getFormat()), // aspect;
3047 0, // baseMipLevel
3048 1, // mipLevels
3049 0, // baseArraySlice
3050 1 // arraySize
3051 }
3052 };
3053 imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
3054
3055 const VkImageMemoryBarrier barrierAfterRendering
3056 {
3057 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
3058 DE_NULL, // pNext
3059
3060 getMemoryFlagsForLayout(renderingLayout), // srcAccessMask
3061 getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout), // dstAccessMask
3062
3063 renderingLayout, // oldLayout
3064 finalLayout, // newLayout
3065
3066 queueIndex, // srcQueueFamilyIndex
3067 queueIndex, // destQueueFamilyIndex
3068
3069 attachmentResources[dsAttachmentIndex]->getImage(), // image
3070 { // subresourceRange
3071 getImageAspectFlags(dsAttachmentInfo.getFormat()), // aspect;
3072 0, // baseMipLevel
3073 1, // mipLevels
3074 0, // baseArraySlice
3075 1 // arraySize
3076 }
3077 };
3078 imageBarriersAfterRendering.push_back(barrierAfterRendering);
3079 }
3080
3081 if (!imageBarriersBeforeRendering.empty())
3082 vk.cmdPipelineBarrier(commandBuffer,
3083 getAllPipelineStageFlags(),
3084 getAllPipelineStageFlags(),
3085 (VkDependencyFlags)0,
3086 0, (const VkMemoryBarrier*)DE_NULL,
3087 0, (const VkBufferMemoryBarrier*)DE_NULL,
3088 (deUint32)imageBarriersBeforeRendering.size(),
3089 &imageBarriersBeforeRendering[0]);
3090
3091 bool executeRenderCommands = (renderType != TestConfig::RENDERTYPES_NONE);
3092
3093 if (secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3094 {
3095 // when secondary command buffer completely contains dynamic renderpass
3096 // then we need to execute it even when render type is none
3097 executeRenderCommands = true;
3098 }
3099 else
3100 {
3101 VkRenderingFlagsKHR renderingFlags = 0u;
3102 if (subpassRenderers[0]->isSecondary())
3103 renderingFlags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR;
3104
3105 beginDynamicRendering(vk, commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues, renderingFlags);
3106 }
3107
3108 if (executeRenderCommands)
3109 {
3110 if (subpassRenderers[0]->isSecondary())
3111 {
3112 const VkCommandBuffer cmd = subpassRenderers[0]->getCommandBuffer();
3113 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
3114 }
3115 else
3116 subpassRenderers[0]->pushRenderCommands(vk, commandBuffer);
3117 }
3118
3119 if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3120 endDynamicRendering(vk, commandBuffer);
3121
3122 if (!imageBarriersAfterRendering.empty())
3123 vk.cmdPipelineBarrier(commandBuffer,
3124 getAllPipelineStageFlags(),
3125 getAllPipelineStageFlags(),
3126 (VkDependencyFlags)0,
3127 0, (const VkMemoryBarrier*)DE_NULL,
3128 0, (const VkBufferMemoryBarrier*)DE_NULL,
3129 (deUint32)imageBarriersAfterRendering.size(),
3130 &imageBarriersAfterRendering[0]);
3131 }
3132 #endif // CTS_USES_VULKANSC
3133
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)3134 void pushRenderPassCommands (const DeviceInterface& vk,
3135 VkCommandBuffer commandBuffer,
3136 VkRenderPass renderPass,
3137 const RenderPass& renderPassInfo,
3138 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3139 VkFramebuffer framebuffer,
3140 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
3141 const VkRect2D& renderArea,
3142 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3143 deUint32 queueIndex,
3144 TestConfig::RenderTypes render,
3145 RenderingType renderingType,
3146 bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3147 {
3148 // unreference arguments not used by Vulkan SC, no need to put them under ifdef
3149 DE_UNREF(renderPassInfo);
3150 DE_UNREF(attachmentResources);
3151 DE_UNREF(queueIndex);
3152 DE_UNREF(secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3153
3154 switch (renderingType)
3155 {
3156 case RENDERING_TYPE_RENDERPASS_LEGACY:
3157 return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3158 case RENDERING_TYPE_RENDERPASS2:
3159 return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3160
3161 #ifndef CTS_USES_VULKANSC
3162 case RENDERING_TYPE_DYNAMIC_RENDERING:
3163 return pushDynamicRenderingCommands(vk, commandBuffer, renderPassInfo, attachmentResources, subpassRenderers, renderArea, renderPassClearValues, queueIndex, render, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3164 #endif // CTS_USES_VULKANSC
3165
3166 default:
3167 TCU_THROW(InternalError, "Impossible");
3168 }
3169 }
3170
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)3171 void pushReadImagesToBuffers (const DeviceInterface& vk,
3172 VkCommandBuffer commandBuffer,
3173 deUint32 queueIndex,
3174
3175 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3176 const vector<Attachment>& attachmentInfo,
3177 const vector<bool>& isLazy,
3178
3179 const UVec2& targetSize)
3180 {
3181 {
3182 vector<VkImageMemoryBarrier> imageBarriers;
3183
3184 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3185 {
3186 if (isLazy[attachmentNdx])
3187 continue;
3188
3189 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
3190 const VkImageMemoryBarrier barrier =
3191 {
3192 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
3193 DE_NULL, // pNext
3194
3195 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
3196 getAllMemoryReadFlags(), // dstAccessMask
3197
3198 oldLayout, // oldLayout
3199 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
3200
3201 queueIndex, // srcQueueFamilyIndex
3202 queueIndex, // destQueueFamilyIndex
3203
3204 attachmentResources[attachmentNdx]->getImage(), // image
3205 { // subresourceRange
3206 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
3207 0, // baseMipLevel
3208 1, // mipLevels
3209 0, // baseArraySlice
3210 1 // arraySize
3211 }
3212 };
3213
3214 imageBarriers.push_back(barrier);
3215 }
3216
3217 if (!imageBarriers.empty())
3218 vk.cmdPipelineBarrier(commandBuffer,
3219 getAllPipelineStageFlags(),
3220 getAllPipelineStageFlags(),
3221 (VkDependencyFlags)0,
3222 0, (const VkMemoryBarrier*)DE_NULL,
3223 0, (const VkBufferMemoryBarrier*)DE_NULL,
3224 (deUint32)imageBarriers.size(), &imageBarriers[0]);
3225 }
3226
3227 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3228 {
3229 if (isLazy[attachmentNdx])
3230 continue;
3231
3232 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3233 const VkBufferImageCopy rect =
3234 {
3235 0, // bufferOffset
3236 0, // bufferRowLength
3237 0, // bufferImageHeight
3238 { // imageSubresource
3239 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
3240 0, // mipLevel
3241 0, // arraySlice
3242 1 // arraySize
3243 },
3244 { 0, 0, 0 }, // imageOffset
3245 { targetSize.x(), targetSize.y(), 1u } // imageExtent
3246 };
3247
3248 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
3249
3250 if (tcu::TextureFormat::DS == order)
3251 {
3252 const VkBufferImageCopy stencilRect =
3253 {
3254 0, // bufferOffset
3255 0, // bufferRowLength
3256 0, // bufferImageHeight
3257 { // imageSubresource
3258 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
3259 0, // mipLevel
3260 0, // arraySlice
3261 1 // arraySize
3262 },
3263 { 0, 0, 0 }, // imageOffset
3264 { targetSize.x(), targetSize.y(), 1u } // imageExtent
3265 };
3266
3267 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
3268 }
3269 }
3270
3271 {
3272 vector<VkBufferMemoryBarrier> bufferBarriers;
3273
3274 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3275 {
3276 if (isLazy[attachmentNdx])
3277 continue;
3278
3279 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3280 const VkBufferMemoryBarrier bufferBarrier =
3281 {
3282 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3283 DE_NULL,
3284
3285 getAllMemoryWriteFlags(),
3286 getAllMemoryReadFlags(),
3287
3288 queueIndex,
3289 queueIndex,
3290
3291 attachmentResources[attachmentNdx]->getBuffer(),
3292 0,
3293 attachmentResources[attachmentNdx]->getBufferSize()
3294 };
3295
3296 bufferBarriers.push_back(bufferBarrier);
3297
3298 if (tcu::TextureFormat::DS == order)
3299 {
3300 const VkBufferMemoryBarrier secondaryBufferBarrier =
3301 {
3302 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3303 DE_NULL,
3304
3305 getAllMemoryWriteFlags(),
3306 getAllMemoryReadFlags(),
3307
3308 queueIndex,
3309 queueIndex,
3310
3311 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
3312 0,
3313 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
3314 };
3315
3316 bufferBarriers.push_back(secondaryBufferBarrier);
3317 }
3318 }
3319
3320 if (!bufferBarriers.empty())
3321 vk.cmdPipelineBarrier(commandBuffer,
3322 getAllPipelineStageFlags(),
3323 getAllPipelineStageFlags(),
3324 (VkDependencyFlags)0,
3325 0, (const VkMemoryBarrier*)DE_NULL,
3326 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
3327 0, (const VkImageMemoryBarrier*)DE_NULL);
3328 }
3329 }
3330
3331 class PixelValue
3332 {
3333 public:
3334 PixelValue (const Maybe<bool>& x = tcu::Nothing,
3335 const Maybe<bool>& y = tcu::Nothing,
3336 const Maybe<bool>& z = tcu::Nothing,
3337 const Maybe<bool>& w = tcu::Nothing);
3338
3339 void setUndefined (size_t ndx);
3340 void setValue (size_t ndx, bool value);
3341 Maybe<bool> getValue (size_t ndx) const;
3342
3343 private:
3344 deUint16 m_status;
3345 };
3346
PixelValue(const Maybe<bool> & x,const Maybe<bool> & y,const Maybe<bool> & z,const Maybe<bool> & w)3347 PixelValue::PixelValue (const Maybe<bool>& x,
3348 const Maybe<bool>& y,
3349 const Maybe<bool>& z,
3350 const Maybe<bool>& w)
3351 : m_status (0)
3352 {
3353 const Maybe<bool> values[] =
3354 {
3355 x, y, z, w
3356 };
3357
3358 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
3359 {
3360 if (values[ndx])
3361 setValue(ndx, *values[ndx]);
3362 else
3363 setUndefined(ndx);
3364 }
3365
3366 DE_ASSERT(m_status <= 0xFFu);
3367 }
3368
setUndefined(size_t ndx)3369 void PixelValue::setUndefined (size_t ndx)
3370 {
3371 DE_ASSERT(ndx < 4);
3372 DE_ASSERT(m_status <= 0xFFu);
3373
3374 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
3375 DE_ASSERT(m_status <= 0xFFu);
3376 }
3377
setValue(size_t ndx,bool value)3378 void PixelValue::setValue (size_t ndx, bool value)
3379 {
3380 DE_ASSERT(ndx < 4);
3381 DE_ASSERT(m_status <= 0xFFu);
3382
3383 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
3384
3385 if (value)
3386 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
3387 else
3388 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
3389
3390 DE_ASSERT(m_status <= 0xFFu);
3391 }
3392
getValue(size_t ndx) const3393 Maybe<bool> PixelValue::getValue (size_t ndx) const
3394 {
3395 DE_ASSERT(ndx < 4);
3396 DE_ASSERT(m_status <= 0xFFu);
3397
3398 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
3399 {
3400 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
3401 }
3402 else
3403 return tcu::Nothing;
3404 }
3405
clearReferenceValues(vector<PixelValue> & values,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size,const BVec4 & mask,const PixelValue & value)3406 void clearReferenceValues (vector<PixelValue>& values,
3407 const UVec2& targetSize,
3408 const UVec2& offset,
3409 const UVec2& size,
3410 const BVec4& mask,
3411 const PixelValue& value)
3412 {
3413 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3414 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
3415 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
3416
3417 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3418 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3419 {
3420 for (int compNdx = 0; compNdx < 4; compNdx++)
3421 {
3422 if (mask[compNdx])
3423 {
3424 if (value.getValue(compNdx))
3425 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
3426 else
3427 values[x + y * targetSize.x()].setUndefined(compNdx);
3428 }
3429 }
3430 }
3431 }
3432
markUndefined(vector<PixelValue> & values,const BVec4 & mask,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size)3433 void markUndefined (vector<PixelValue>& values,
3434 const BVec4& mask,
3435 const UVec2& targetSize,
3436 const UVec2& offset,
3437 const UVec2& size)
3438 {
3439 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3440
3441 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3442 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3443 {
3444 for (int compNdx = 0; compNdx < 4; compNdx++)
3445 {
3446 if (mask[compNdx])
3447 values[x + y * targetSize.x()].setUndefined(compNdx);
3448 }
3449 }
3450 }
3451
clearValueToPixelValue(const VkClearValue & value,const tcu::TextureFormat & format,const DepthValuesArray & depthValues)3452 PixelValue clearValueToPixelValue (const VkClearValue& value,
3453 const tcu::TextureFormat& format,
3454 const DepthValuesArray& depthValues)
3455 {
3456 const bool isDepthAttachment = hasDepthComponent(format.order);
3457 const bool isStencilAttachment = hasStencilComponent(format.order);
3458 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
3459 PixelValue pixelValue;
3460
3461 if (isDepthOrStencilAttachment)
3462 {
3463 if (isDepthAttachment)
3464 {
3465 if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
3466 pixelValue.setValue(0, true);
3467 else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
3468 pixelValue.setValue(0, false);
3469 else
3470 DE_FATAL("Unknown depth value");
3471 }
3472
3473 if (isStencilAttachment)
3474 {
3475 if (value.depthStencil.stencil == 0xFFu)
3476 pixelValue.setValue(1, true);
3477 else if (value.depthStencil.stencil == 0x0u)
3478 pixelValue.setValue(1, false);
3479 else
3480 DE_FATAL("Unknown stencil value");
3481 }
3482 }
3483 else
3484 {
3485 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3486 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3487
3488 switch (channelClass)
3489 {
3490 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3491 for (int i = 0; i < 4; i++)
3492 {
3493 if (channelMask[i])
3494 {
3495 if (value.color.int32[i] == 1)
3496 pixelValue.setValue(i, true);
3497 else if (value.color.int32[i] == 0)
3498 pixelValue.setValue(i, false);
3499 else
3500 DE_FATAL("Unknown clear color value");
3501 }
3502 }
3503 break;
3504
3505 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3506 for (int i = 0; i < 4; i++)
3507 {
3508 if (channelMask[i])
3509 {
3510 if (value.color.uint32[i] == 1u)
3511 pixelValue.setValue(i, true);
3512 else if (value.color.uint32[i] == 0u)
3513 pixelValue.setValue(i, false);
3514 else
3515 DE_FATAL("Unknown clear color value");
3516 }
3517 }
3518 break;
3519
3520 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3521 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3522 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3523 for (int i = 0; i < 4; i++)
3524 {
3525 if (channelMask[i])
3526 {
3527 if (value.color.float32[i] == 1.0f)
3528 pixelValue.setValue(i, true);
3529 else if (value.color.float32[i] == 0.0f)
3530 pixelValue.setValue(i, false);
3531 else
3532 DE_FATAL("Unknown clear color value");
3533 }
3534 }
3535 break;
3536
3537 default:
3538 DE_FATAL("Unknown channel class");
3539 }
3540 }
3541
3542 return pixelValue;
3543 }
3544
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)3545 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
3546 const RenderPass& renderPassInfo,
3547 const UVec2& targetSize,
3548 const vector<Maybe<VkClearValue> >& imageClearValues,
3549 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3550 const vector<SubpassRenderInfo>& subpassRenderInfo,
3551 const UVec2& renderPos,
3552 const UVec2& renderSize,
3553 const deUint32 drawStartNdx,
3554 const DepthValuesArray& depthValues)
3555 {
3556 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
3557 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
3558
3559 referenceAttachments.resize(renderPassInfo.getAttachments().size());
3560
3561 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3562 {
3563 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3564 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3565 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
3566
3567 reference.resize(targetSize.x() * targetSize.y());
3568
3569 if (imageClearValues[attachmentNdx])
3570 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
3571 }
3572
3573 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3574 {
3575 const Subpass& subpass = subpasses[subpassNdx];
3576 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3577 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3578
3579 // Apply load op if attachment was used for the first time
3580 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
3581 {
3582 const deUint32 attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);
3583
3584 if (!attachmentUsed[attachmentIndex] && colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
3585 {
3586 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3587 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3588 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3589
3590 DE_ASSERT(!tcu::hasDepthComponent(format.order));
3591 DE_ASSERT(!tcu::hasStencilComponent(format.order));
3592
3593 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3594 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3595 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3596 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3597
3598 attachmentUsed[attachmentIndex] = true;
3599 }
3600 }
3601
3602 // Apply load op to depth/stencil attachment if it was used for the first time
3603 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3604 {
3605 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3606
3607 // Apply load op if attachment was used for the first time
3608 if (!attachmentUsed[attachmentIndex])
3609 {
3610 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3611 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3612 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3613
3614 if (tcu::hasDepthComponent(format.order))
3615 {
3616 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3617 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3618 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3619 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3620 }
3621
3622 if (tcu::hasStencilComponent(format.order))
3623 {
3624 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3625 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3626 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3627 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3628 }
3629
3630 attachmentUsed[attachmentIndex] = true;
3631 }
3632 }
3633
3634 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
3635 {
3636 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
3637 const UVec2 offset = colorClear.getOffset();
3638 const UVec2 size = colorClear.getSize();
3639 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
3640 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3641 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3642 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3643 VkClearValue value;
3644
3645 value.color = colorClear.getColor();
3646
3647 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format, depthValues));
3648 }
3649
3650 if (renderInfo.getDepthStencilClear())
3651 {
3652 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
3653 const UVec2 offset = dsClear.getOffset();
3654 const UVec2 size = dsClear.getSize();
3655 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3656 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3657 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3658 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3659 const bool hasStencil = tcu::hasStencilComponent(format.order)
3660 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
3661 const bool hasDepth = tcu::hasDepthComponent(format.order)
3662 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
3663 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3664 VkClearValue value;
3665
3666 value.depthStencil.depth = dsClear.getDepth();
3667 value.depthStencil.stencil = dsClear.getStencil();
3668
3669 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format, depthValues));
3670 }
3671
3672 if (renderInfo.getRenderQuad())
3673 {
3674 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3675 const Vec2 posA = renderQuad.getCornerA();
3676 const Vec2 posB = renderQuad.getCornerB();
3677 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3678 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3679 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3680 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3681 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3682 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3683
3684 DE_ASSERT(posAI.x() < posBI.x());
3685 DE_ASSERT(posAI.y() < posBI.y());
3686
3687 if (subpass.getInputAttachments().empty())
3688 {
3689 for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3690 {
3691 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3692
3693 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
3694 continue;
3695
3696 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3697 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3698 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3699 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3700
3701 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3702 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3703 {
3704 for (int compNdx = 0; compNdx < 4; compNdx++)
3705 {
3706 const size_t index = subpassNdx + attachmentIndex + compNdx;
3707 const BoolOp op = boolOpFromIndex(index);
3708 const bool boolX = x % 2 == (int)(index % 2);
3709 const bool boolY = y % 2 == (int)((index / 2) % 2);
3710
3711 if (channelMask[compNdx])
3712 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3713 }
3714 }
3715 }
3716
3717 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3718 {
3719 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3720 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3721 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3722 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3723 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3724
3725 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3726 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3727 {
3728 if (tcu::hasDepthComponent(format.order)
3729 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3730 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3731 {
3732 const size_t index = subpassNdx + 1;
3733 const BoolOp op = boolOpFromIndex(index);
3734 const bool boolX = x % 2 == (int)(index % 2);
3735 const bool boolY = y % 2 == (int)((index / 2) % 2);
3736
3737 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3738 }
3739
3740 if (tcu::hasStencilComponent(format.order)
3741 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3742 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3743 {
3744 const size_t index = subpassNdx;
3745 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3746 }
3747 }
3748 }
3749 }
3750 else
3751 {
3752 size_t outputComponentCount = 0;
3753 vector<Maybe<bool> > inputs;
3754
3755 DE_ASSERT(posAI.x() < posBI.x());
3756 DE_ASSERT(posAI.y() < posBI.y());
3757
3758 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3759 {
3760 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3761 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3762 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3763 const int componentCount = tcu::getNumUsedChannels(format.order);
3764
3765 outputComponentCount += (size_t)componentCount;
3766 }
3767
3768 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3769 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3770 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3771 {
3772 const Attachment& attachment (renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
3773 const tcu::TextureFormat format (mapVkFormat(attachment.getFormat()));
3774
3775 if (tcu::hasDepthComponent(format.order))
3776 outputComponentCount++;
3777 }
3778
3779 if (outputComponentCount > 0)
3780 {
3781 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3782 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3783 {
3784 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3785 {
3786 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3787 const VkImageLayout layout = subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
3788 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3789 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3790 const int componentCount = tcu::getNumUsedChannels(format.order);
3791
3792 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3793 {
3794 if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3795 && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
3796 {
3797 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3798 }
3799 }
3800 }
3801
3802 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3803 ? ((inputs.size() / outputComponentCount)
3804 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3805 : 1;
3806
3807 size_t outputValueNdx = 0;
3808
3809 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3810 {
3811 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3812 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3813 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3814 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3815 const int componentCount = tcu::getNumUsedChannels(format.order);
3816
3817 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3818 {
3819 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3820 const BoolOp op = boolOpFromIndex(index);
3821 const bool boolX = x % 2 == (int)(index % 2);
3822 const bool boolY = y % 2 == (int)((index / 2) % 2);
3823 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3824
3825 for (size_t i = 0; i < inputsPerOutput; i++)
3826 {
3827 if (!output)
3828 break;
3829 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3830 output = tcu::Nothing;
3831 else
3832 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3833 }
3834
3835 if (output)
3836 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3837 else
3838 reference[x + y * targetSize.x()].setUndefined(compNdx);
3839 }
3840
3841 outputValueNdx += componentCount;
3842 }
3843
3844 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3845 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3846 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3847 {
3848 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3849 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3850 const size_t index = subpassNdx + attachmentIndex;
3851 const BoolOp op = boolOpFromIndex(index);
3852 const bool boolX = x % 2 == (int)(index % 2);
3853 const bool boolY = y % 2 == (int)((index / 2) % 2);
3854 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3855
3856 for (size_t i = 0; i < inputsPerOutput; i++)
3857 {
3858 if (!output)
3859 break;
3860 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3861 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3862 else
3863 output = tcu::Nothing;
3864 }
3865
3866 if (output)
3867 reference[x + y * targetSize.x()].setValue(0, *output);
3868 else
3869 reference[x + y * targetSize.x()].setUndefined(0);
3870 }
3871
3872 inputs.clear();
3873 }
3874 }
3875
3876 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3877 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3878 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3879 {
3880 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3881 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3882 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3883 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3884
3885 if (tcu::hasStencilComponent(format.order))
3886 {
3887 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3888 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3889 {
3890 const size_t index = subpassNdx;
3891 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3892 }
3893 }
3894 }
3895 }
3896 }
3897 }
3898
3899 // Mark all attachments that were used but not stored as undefined
3900 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3901 {
3902 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3903 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3904 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3905 const bool isStencilAttachment = hasStencilComponent(format.order);
3906 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3907
3908 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3909 {
3910 if (isDepthOrStencilAttachment)
3911 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3912 else
3913 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3914 }
3915
3916 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3917 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3918 }
3919 }
3920
renderReferenceImagesFromValues(vector<tcu::TextureLevel> & referenceImages,const vector<vector<PixelValue>> & referenceValues,const UVec2 & targetSize,const RenderPass & renderPassInfo,const DepthValuesArray & depthValues)3921 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3922 const vector<vector<PixelValue> >& referenceValues,
3923 const UVec2& targetSize,
3924 const RenderPass& renderPassInfo,
3925 const DepthValuesArray& depthValues)
3926 {
3927 referenceImages.resize(referenceValues.size());
3928
3929 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3930 {
3931 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3932 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3933 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3934 const bool hasDepth = tcu::hasDepthComponent(format.order);
3935 const bool hasStencil = tcu::hasStencilComponent(format.order);
3936 const bool hasDepthOrStencil = hasDepth || hasStencil;
3937 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3938
3939 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3940
3941 if (hasDepthOrStencil)
3942 {
3943 if (hasDepth)
3944 {
3945 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3946
3947 for (deUint32 y = 0; y < targetSize.y(); y++)
3948 for (deUint32 x = 0; x < targetSize.x(); x++)
3949 {
3950 if (reference[x + y * targetSize.x()].getValue(0))
3951 {
3952 if (*reference[x + y * targetSize.x()].getValue(0))
3953 depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
3954 else
3955 depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
3956 }
3957 else // Fill with 3x3 grid
3958 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3959 }
3960 }
3961
3962 if (hasStencil)
3963 {
3964 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3965
3966 for (deUint32 y = 0; y < targetSize.y(); y++)
3967 for (deUint32 x = 0; x < targetSize.x(); x++)
3968 {
3969 if (reference[x + y * targetSize.x()].getValue(1))
3970 {
3971 if (*reference[x + y * targetSize.x()].getValue(1))
3972 stencilAccess.setPixStencil(0xFFu, x, y);
3973 else
3974 stencilAccess.setPixStencil(0x0u, x, y);
3975 }
3976 else // Fill with 3x3 grid
3977 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3978 }
3979 }
3980 }
3981 else
3982 {
3983 for (deUint32 y = 0; y < targetSize.y(); y++)
3984 for (deUint32 x = 0; x < targetSize.x(); x++)
3985 {
3986 tcu::Vec4 color;
3987
3988 for (int compNdx = 0; compNdx < 4; compNdx++)
3989 {
3990 if (reference[x + y * targetSize.x()].getValue(compNdx))
3991 {
3992 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3993 color[compNdx] = 1.0f;
3994 else
3995 color[compNdx] = 0.0f;
3996 }
3997 else // Fill with 3x3 grid
3998 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3999 }
4000
4001 referenceImage.getAccess().setPixel(color, x, y);
4002 }
4003 }
4004 }
4005 }
4006
verifyColorAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const deBool useFormatCompCount)4007 bool verifyColorAttachment (const vector<PixelValue>& reference,
4008 const ConstPixelBufferAccess& result,
4009 const PixelBufferAccess& errorImage,
4010 const deBool useFormatCompCount)
4011 {
4012 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
4013 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4014 bool ok = true;
4015
4016 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4017 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4018 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4019
4020 for (int y = 0; y < result.getHeight(); y++)
4021 for (int x = 0; x < result.getWidth(); x++)
4022 {
4023 const Vec4 resultColor = result.getPixel(x, y);
4024 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
4025 bool pixelOk = true;
4026 const deUint32 componentCount = useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(result.getFormat().order) : 4;
4027
4028 for (deUint32 compNdx = 0; compNdx < componentCount; compNdx++)
4029 {
4030 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
4031
4032 if (maybeValue)
4033 {
4034 const bool value = *maybeValue;
4035
4036 if ((value && (resultColor[compNdx] != 1.0f))
4037 || (!value && resultColor[compNdx] != 0.0f))
4038 pixelOk = false;
4039 }
4040 }
4041
4042 if (!pixelOk)
4043 {
4044 errorImage.setPixel(red, x, y);
4045 ok = false;
4046 }
4047 else
4048 errorImage.setPixel(green, x, y);
4049 }
4050
4051 return ok;
4052 }
4053
4054 // Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
4055 const tcu::Vec4 kDefaultColorForLog {0.0f, 0.0f, 0.0f, 1.0f};
4056 const float kTrueComponent = 1.0f;
4057 const float kFalseComponent = 0.5f;
4058 const float kUnsetComponentLow = 0.0f;
4059 const float kUnsetComponentHigh = 0.25f;
4060
renderColorImageForLog(const ConstPixelBufferAccess & image,int numChannels)4061 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const ConstPixelBufferAccess& image, int numChannels)
4062 {
4063 // Same channel order, but using UNORM_INT8 for the color format.
4064 const auto order = image.getFormat().order;
4065 const tcu::TextureFormat loggableFormat {order, tcu::TextureFormat::UNORM_INT8};
4066 const int width = image.getWidth();
4067 const int height = image.getHeight();
4068 std::unique_ptr<tcu::TextureLevel> result {new tcu::TextureLevel{loggableFormat, width, height}};
4069 auto access = result->getAccess();
4070 tcu::Vec4 outColor = kDefaultColorForLog;
4071
4072 for (int x = 0; x < width; ++x)
4073 for (int y = 0; y < height; ++y)
4074 {
4075 const auto value = image.getPixel(x, y);
4076 for (int c = 0; c < numChannels; ++c)
4077 {
4078 if (value[c] == 0.0f)
4079 outColor[c] = kFalseComponent;
4080 else if (value[c] == 1.0f)
4081 outColor[c] = kTrueComponent;
4082 else
4083 DE_ASSERT(false);
4084 }
4085 access.setPixel(outColor, x, y);
4086 }
4087
4088 return result;
4089 }
4090
renderColorImageForLog(const vector<PixelValue> & reference,const UVec2 & targetSize,int numChannels)4091 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const vector<PixelValue>& reference, const UVec2& targetSize, int numChannels)
4092 {
4093 const tcu::TextureFormat loggableFormat {tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
4094 const int width = static_cast<int>(targetSize.x());
4095 const int height = static_cast<int>(targetSize.y());
4096 std::unique_ptr<tcu::TextureLevel> result {new tcu::TextureLevel{loggableFormat, width, height}};
4097 auto access = result->getAccess();
4098 tcu::Vec4 outColor = kDefaultColorForLog;
4099
4100 for (int x = 0; x < width; ++x)
4101 for (int y = 0; y < height; ++y)
4102 {
4103 const int index = x + y * width;
4104 for (int c = 0; c < numChannels; ++c)
4105 {
4106 const auto maybeValue = reference[index].getValue(c);
4107 if (maybeValue)
4108 outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
4109 else
4110 outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
4111 }
4112 access.setPixel(outColor, x, y);
4113 }
4114
4115 return result;
4116 }
4117
verifyDepthAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const DepthValuesArray & depthValues,float epsilon)4118 bool verifyDepthAttachment (const vector<PixelValue>& reference,
4119 const ConstPixelBufferAccess& result,
4120 const PixelBufferAccess& errorImage,
4121 const DepthValuesArray& depthValues,
4122 float epsilon)
4123 {
4124 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
4125 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4126 bool ok = true;
4127
4128 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4129 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4130 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4131
4132 for (int y = 0; y < result.getHeight(); y++)
4133 for (int x = 0; x < result.getWidth(); x++)
4134 {
4135 bool pixelOk = true;
4136
4137 const float resultDepth = result.getPixDepth(x, y);
4138 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
4139 const Maybe<bool> maybeValue = referenceValue.getValue(0);
4140
4141 if (maybeValue)
4142 {
4143 const bool value = *maybeValue;
4144
4145 if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon))
4146 || (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
4147 pixelOk = false;
4148 }
4149
4150 if (!pixelOk)
4151 {
4152 errorImage.setPixel(red, x, y);
4153 ok = false;
4154 }
4155 else
4156 errorImage.setPixel(green, x, y);
4157 }
4158
4159 return ok;
4160 }
4161
verifyStencilAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)4162 bool verifyStencilAttachment (const vector<PixelValue>& reference,
4163 const ConstPixelBufferAccess& result,
4164 const PixelBufferAccess& errorImage)
4165 {
4166 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
4167 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4168 bool ok = true;
4169
4170 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4171 DE_ASSERT(result.getWidth() == errorImage.getWidth());
4172 DE_ASSERT(result.getHeight() == errorImage.getHeight());
4173
4174 for (int y = 0; y < result.getHeight(); y++)
4175 for (int x = 0; x < result.getWidth(); x++)
4176 {
4177 bool pixelOk = true;
4178
4179 const deUint32 resultStencil = result.getPixStencil(x, y);
4180 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
4181 const Maybe<bool> maybeValue = referenceValue.getValue(1);
4182
4183 if (maybeValue)
4184 {
4185 const bool value = *maybeValue;
4186
4187 if ((value && (resultStencil != 0xFFu))
4188 || (!value && resultStencil != 0x0u))
4189 pixelOk = false;
4190 }
4191
4192 if (!pixelOk)
4193 {
4194 errorImage.setPixel(red, x, y);
4195 ok = false;
4196 }
4197 else
4198 errorImage.setPixel(green, x, y);
4199 }
4200
4201 return ok;
4202 }
4203
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)4204 bool logAndVerifyImages (TestLog& log,
4205 const DeviceInterface& vk,
4206 VkDevice device,
4207 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
4208 const vector<bool>& attachmentIsLazy,
4209 const RenderPass& renderPassInfo,
4210 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4211 const vector<Maybe<VkClearValue> >& imageClearValues,
4212 const vector<SubpassRenderInfo>& subpassRenderInfo,
4213 const UVec2& targetSize,
4214 const TestConfig& config)
4215 {
4216 vector<vector<PixelValue> > referenceValues;
4217 vector<tcu::TextureLevel> referenceAttachments;
4218 bool isOk = true;
4219
4220 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
4221
4222 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx, config.depthValues);
4223 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo, config.depthValues);
4224
4225 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4226 {
4227 if (!attachmentIsLazy[attachmentNdx])
4228 {
4229 bool attachmentOK = true;
4230 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
4231 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4232
4233 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
4234 {
4235 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
4236 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4237
4238 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
4239 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
4240
4241 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4242 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());
4243
4244 {
4245 bool depthOK = true;
4246 bool stencilOK = true;
4247 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
4248 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
4249 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4250 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4251
4252 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4253 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4254 {
4255 depthOK = false;
4256 }
4257
4258 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4259 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
4260 {
4261 stencilOK = false;
4262 }
4263
4264 if (!depthOK || !stencilOK)
4265 {
4266 const auto attachmentNdxStr = de::toString(attachmentNdx);
4267
4268 // Output images.
4269 log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr, "Output depth and stencil attachments " + attachmentNdxStr);
4270 log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth", "Attachment " + attachmentNdxStr + " Depth", depthAccess);
4271 log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil", "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
4272 log << TestLog::EndImageSet;
4273
4274 // Reference images. These will be logged as image sets due to having depth and stencil aspects.
4275 log << TestLog::Image("AttachmentReferences" + attachmentNdxStr, "Reference images " + attachmentNdxStr, referenceAttachments[attachmentNdx].getAccess());
4276
4277 // Error masks.
4278 log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
4279 if (!depthOK)
4280 log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr, "Depth Attachment Error " + attachmentNdxStr, depthErrorImage.getAccess());
4281 if (!stencilOK)
4282 log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr, "Stencil Attachment Error " + attachmentNdxStr, stencilErrorImage.getAccess());
4283 log << TestLog::EndImageSet;
4284
4285 attachmentOK = false;
4286 }
4287 }
4288 }
4289 else
4290 {
4291 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4292
4293 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4294
4295 bool depthOK = true;
4296 bool stencilOK = true;
4297 bool colorOK = true;
4298 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
4299 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4300
4301 if (tcu::hasDepthComponent(format.order))
4302 {
4303 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4304 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4305 {
4306 depthOK = false;
4307 }
4308 }
4309 else if (tcu::hasStencilComponent(format.order))
4310 {
4311 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4312 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
4313 {
4314 stencilOK = false;
4315 }
4316 }
4317 else
4318 {
4319 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4320 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.useFormatCompCount))
4321 {
4322 colorOK = false;
4323 }
4324 }
4325
4326 if (!depthOK || !stencilOK || !colorOK)
4327 {
4328 log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
4329 if (!depthOK || !stencilOK)
4330 {
4331 // Log without conversions.
4332 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
4333 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
4334 }
4335 else
4336 {
4337 // Convert color images to better reflect test status and output in any format.
4338 const auto numChannels = tcu::getNumUsedChannels(access.getFormat().order);
4339 const auto attachmentForLog = renderColorImageForLog(access, numChannels);
4340 const auto referenceForLog = renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);
4341
4342 log << TestLog::Message << "Check the attachment formats and test data to verify which components affect the test result." << TestLog::EndMessage;
4343 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;
4344 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;
4345
4346 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), attachmentForLog->getAccess());
4347 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceForLog->getAccess());
4348 }
4349 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
4350 log << TestLog::EndImageSet;
4351
4352 attachmentOK = false;
4353 }
4354 }
4355
4356 if (!attachmentOK)
4357 isOk = false;
4358 }
4359 }
4360
4361 return isOk;
4362 }
4363
getInputAttachmentType(VkFormat vkFormat)4364 std::string getInputAttachmentType (VkFormat vkFormat)
4365 {
4366 const tcu::TextureFormat format = mapVkFormat(vkFormat);
4367 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4368
4369 switch (channelClass)
4370 {
4371 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4372 return "isubpassInput";
4373
4374 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4375 return "usubpassInput";
4376
4377 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4378 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4379 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4380 return "subpassInput";
4381
4382 default:
4383 DE_FATAL("Unknown channel class");
4384 return "";
4385 }
4386 }
4387
getAttachmentType(VkFormat vkFormat,deBool useFormatCompCount)4388 std::string getAttachmentType (VkFormat vkFormat, deBool useFormatCompCount)
4389 {
4390 const tcu::TextureFormat format = mapVkFormat(vkFormat);
4391 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4392 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4393
4394 switch (channelClass)
4395 {
4396 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4397 if (useFormatCompCount)
4398 return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
4399 else
4400 return "ivec4";
4401
4402 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4403 if (useFormatCompCount)
4404 return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
4405 else
4406 return "uvec4";
4407
4408 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4409 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4410 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4411 if (useFormatCompCount)
4412 return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
4413 else
4414 return "vec4";
4415
4416 default:
4417 DE_FATAL("Unknown channel class");
4418 return "";
4419 }
4420 }
4421
createTestShaders(SourceCollections & dst,TestConfig config)4422 void createTestShaders (SourceCollections& dst, TestConfig config)
4423 {
4424 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4425 {
4426 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
4427
4428 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4429 {
4430 const Subpass& subpass = subpasses[subpassNdx];
4431 deUint32 inputAttachmentBinding = 0;
4432 std::ostringstream vertexShader;
4433 std::ostringstream fragmentShader;
4434
4435 vertexShader << "#version 310 es\n"
4436 << "layout(location = 0) in highp vec2 a_position;\n"
4437 << "void main (void) {\n"
4438 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
4439 << "}\n";
4440
4441 fragmentShader << "#version 310 es\n"
4442 << "precision highp float;\n";
4443
4444 bool hasAnyDepthFormats = false;
4445
4446 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4447 {
4448 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4449 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4450 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4451 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4452 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
4453 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
4454
4455 if (isDepthFormat || isStencilFormat)
4456 {
4457 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4458 {
4459 hasAnyDepthFormats = true;
4460 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
4461 inputAttachmentBinding++;
4462 }
4463
4464 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4465 {
4466 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
4467 inputAttachmentBinding++;
4468 }
4469 }
4470 else
4471 {
4472 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
4473
4474 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
4475 inputAttachmentBinding++;
4476 }
4477 }
4478
4479 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4480 {
4481 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)].getFormat(), config.useFormatCompCount);
4482 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
4483 }
4484
4485 if (hasAnyDepthFormats)
4486 fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
4487 << "\treturn abs(a - b) <= epsilon;\n}\n\n";
4488
4489 fragmentShader << "void main (void) {\n";
4490
4491 if (subpass.getInputAttachments().empty())
4492 {
4493 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4494 {
4495 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4496
4497 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4498 continue;
4499
4500 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4501 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4502 const size_t componentCount = config.useFormatCompCount ? (size_t)tcu::getNumUsedChannels(format.order) : 4;
4503 const std::string attachmentType = getAttachmentType(attachment.getFormat(), config.useFormatCompCount);
4504
4505 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(" << attachmentType + "(";
4506
4507 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4508 {
4509 const size_t index = subpassNdx + attachmentIndex + compNdx;
4510 const BoolOp op = boolOpFromIndex(index);
4511
4512 if (compNdx > 0)
4513 fragmentShader << ",\n\t\t";
4514
4515 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
4516 << ") " << boolOpToString(op) << " ("
4517 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4518 << ") ? 1.0 : 0.0)";
4519 }
4520
4521 fragmentShader << "));\n";
4522 }
4523
4524 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4525 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4526 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4527 {
4528 const size_t index = subpassNdx + 1;
4529 const BoolOp op = boolOpFromIndex(index);
4530
4531 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
4532 << ") " << boolOpToString(op) << " ("
4533 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4534 << ") ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f);\n";
4535 }
4536 }
4537 else
4538 {
4539 size_t inputComponentCount = 0;
4540 size_t outputComponentCount = 0;
4541
4542 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4543 {
4544 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4545 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4546 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4547 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4548 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4549
4550 if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4551 inputComponentCount += 1;
4552 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4553 inputComponentCount += 1;
4554 else
4555 inputComponentCount += componentCount;
4556 }
4557
4558 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4559 {
4560 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4561 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4562 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4563 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4564
4565 outputComponentCount += componentCount;
4566 }
4567
4568 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4569 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4570 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4571 {
4572 outputComponentCount++;
4573 }
4574
4575 if (outputComponentCount > 0)
4576 {
4577 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
4578 ? ((inputComponentCount / outputComponentCount)
4579 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
4580 : 1;
4581
4582 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
4583
4584 if (outputComponentCount > 0)
4585 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
4586
4587 size_t inputValueNdx = 0;
4588
4589 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4590 {
4591 const char* const components[] =
4592 {
4593 "x", "y", "z", "w"
4594 };
4595 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4596 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4597 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4598 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4599 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4600 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
4601 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
4602
4603 if (isDepthFormat || isStencilFormat)
4604 {
4605 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4606 {
4607 fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual(" << deUint32(config.depthValues[1]) <<
4608 ".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), " <<
4609 std::fixed << std::setprecision(12) << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
4610 inputValueNdx++;
4611 }
4612
4613 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4614 {
4615 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
4616 inputValueNdx++;
4617 }
4618 }
4619 else
4620 {
4621 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4622 {
4623 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
4624 inputValueNdx++;
4625 }
4626 }
4627 }
4628
4629 size_t outputValueNdx = 0;
4630
4631 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4632 {
4633 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4634 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4635 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
4636 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4637 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4638
4639 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4640 {
4641 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
4642 const BoolOp op = boolOpFromIndex(index);
4643
4644 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
4645 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4646 << ") " << boolOpToString(op) << " ("
4647 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4648 << ");\n";
4649
4650 for (size_t i = 0; i < inputsPerOutput; i++)
4651 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
4652 }
4653
4654 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
4655
4656 for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
4657 {
4658 if (compNdx > 0)
4659 fragmentShader << ", ";
4660
4661 if (compNdx < componentCount)
4662 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
4663 else
4664 fragmentShader << "0";
4665 }
4666
4667 outputValueNdx += componentCount;
4668
4669 fragmentShader << ");\n";
4670 }
4671
4672 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4673 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4674 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4675 {
4676 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4677 const size_t index = subpassNdx + attachmentIndex;
4678 const BoolOp op = boolOpFromIndex(index);
4679
4680 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
4681 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4682 << ") " << boolOpToString(op) << " ("
4683 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4684 << ");\n";
4685
4686 for (size_t i = 0; i < inputsPerOutput; i++)
4687 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
4688
4689 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f;\n";
4690 }
4691 }
4692 }
4693
4694 fragmentShader << "}\n";
4695
4696 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
4697 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
4698 }
4699 }
4700 }
4701
initializeAttachmentIsLazy(vector<bool> & attachmentIsLazy,const vector<Attachment> & attachments,TestConfig::ImageMemory imageMemory)4702 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
4703 {
4704 bool lastAttachmentWasLazy = false;
4705
4706 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4707 {
4708 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4709 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
4710 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4711 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
4712 {
4713 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
4714 {
4715 attachmentIsLazy.push_back(true);
4716
4717 lastAttachmentWasLazy = true;
4718 }
4719 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
4720 {
4721 attachmentIsLazy.push_back(false);
4722 lastAttachmentWasLazy = false;
4723 }
4724 else
4725 DE_FATAL("Unknown imageMemory");
4726 }
4727 else
4728 attachmentIsLazy.push_back(false);
4729 }
4730 }
4731
4732 enum AttachmentRefType
4733 {
4734 ATTACHMENTREFTYPE_COLOR,
4735 ATTACHMENTREFTYPE_DEPTH_STENCIL,
4736 ATTACHMENTREFTYPE_INPUT,
4737 ATTACHMENTREFTYPE_RESOLVE,
4738 };
4739
getImageUsageFromLayout(VkImageLayout layout)4740 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
4741 {
4742 switch (layout)
4743 {
4744 case VK_IMAGE_LAYOUT_GENERAL:
4745 case VK_IMAGE_LAYOUT_PREINITIALIZED:
4746 return 0;
4747
4748 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
4749 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4750
4751 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
4752 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
4753 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4754
4755 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
4756 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4757
4758 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4759 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4760
4761 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4762 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4763
4764 default:
4765 DE_FATAL("Unexpected image layout");
4766 return 0;
4767 }
4768 }
4769
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,size_t count,const AttachmentReference * references)4770 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
4771 {
4772 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
4773 {
4774 const deUint32 attachment = references[referenceNdx].getAttachment();
4775
4776 if (attachment != VK_ATTACHMENT_UNUSED)
4777 {
4778 VkImageUsageFlags usage;
4779
4780 switch (refType)
4781 {
4782 case ATTACHMENTREFTYPE_COLOR:
4783 case ATTACHMENTREFTYPE_RESOLVE:
4784 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4785 break;
4786
4787 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
4788 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4789 break;
4790
4791 case ATTACHMENTREFTYPE_INPUT:
4792 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4793 break;
4794
4795 default:
4796 DE_FATAL("Unexpected attachment reference type");
4797 usage = 0;
4798 break;
4799 }
4800
4801 attachmentImageUsage[attachment] |= usage;
4802 }
4803 }
4804 }
4805
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,const vector<AttachmentReference> & references)4806 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4807 {
4808 if (!references.empty())
4809 {
4810 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4811 }
4812 }
4813
initializeAttachmentImageUsage(Context & context,vector<VkImageUsageFlags> & attachmentImageUsage,const RenderPass & renderPassInfo,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & clearValues)4814 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4815 {
4816 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4817
4818 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4819 {
4820 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4821
4822 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4823 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4824 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4825 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4826 }
4827
4828 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4829 {
4830 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4831 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4832 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
4833
4834 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4835 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4836
4837 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4838 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4839
4840 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4841 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4842
4843 if (!attachmentIsLazy[attachmentNdx])
4844 {
4845 if (clearValues[attachmentNdx])
4846 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4847
4848 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4849 }
4850 else
4851 {
4852 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);
4853
4854 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4855 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4856 }
4857 }
4858 }
4859
initializeSubpassIsSecondary(vector<bool> & subpassIsSecondary,const vector<Subpass> & subpasses,TestConfig::CommandBufferTypes commandBuffer)4860 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4861 {
4862 bool lastSubpassWasSecondary = false;
4863
4864 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4865 {
4866 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4867 {
4868 subpassIsSecondary.push_back(true);
4869 lastSubpassWasSecondary = true;
4870 }
4871 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4872 {
4873 subpassIsSecondary.push_back(false);
4874 lastSubpassWasSecondary = false;
4875 }
4876 else
4877 DE_FATAL("Unknown commandBuffer");
4878 }
4879 }
4880
initializeImageClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,const vector<bool> & isLazy,deBool useFormatCompCount,const DepthValuesArray & depthValues)4881 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4882 {
4883 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4884 {
4885 if (!isLazy[attachmentNdx])
4886 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4887 else
4888 clearValues.push_back(tcu::Nothing);
4889 }
4890 }
4891
initializeRenderPassClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,deBool useFormatCompCount,const DepthValuesArray & depthValues)4892 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4893 {
4894 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4895 {
4896 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4897 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4898 {
4899 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4900 }
4901 else
4902 clearValues.push_back(tcu::Nothing);
4903 }
4904 }
4905
logSubpassRenderInfo(TestLog & log,const SubpassRenderInfo & info,TestConfig config)4906 void logSubpassRenderInfo (TestLog& log, const SubpassRenderInfo& info, TestConfig config)
4907 {
4908 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4909
4910 if (info.isSecondary())
4911 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4912 else
4913 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4914
4915 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4916 {
4917 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4918
4919 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4920 << ". Offset: " << colorClear.getOffset()
4921 << ", Size: " << colorClear.getSize()
4922 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(), config.useFormatCompCount) << TestLog::EndMessage;
4923 }
4924
4925 if (info.getDepthStencilClear())
4926 {
4927 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4928
4929 log << TestLog::Message << "Clearing depth stencil attachment"
4930 << ". Offset: " << depthStencilClear.getOffset()
4931 << ", Size: " << depthStencilClear.getSize()
4932 << ", Depth: " << depthStencilClear.getDepth()
4933 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4934 }
4935
4936 if (info.getRenderQuad())
4937 {
4938 const RenderQuad& renderQuad = *info.getRenderQuad();
4939
4940 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4941 }
4942 }
4943
logTestCaseInfo(TestLog & log,const TestConfig & config,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo)4944 void logTestCaseInfo (TestLog& log,
4945 const TestConfig& config,
4946 const vector<bool>& attachmentIsLazy,
4947 const vector<Maybe<VkClearValue> >& imageClearValues,
4948 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4949 const vector<SubpassRenderInfo>& subpassRenderInfo)
4950 {
4951 const RenderPass& renderPass = config.renderPass;
4952
4953 logRenderPassInfo(log, renderPass);
4954
4955 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4956 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4957 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4958
4959 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4960 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4961
4962 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4963 {
4964 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4965
4966 if (attachmentIsLazy[attachmentNdx])
4967 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4968
4969 if (imageClearValues[attachmentNdx])
4970 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4971 *imageClearValues[attachmentNdx], config.useFormatCompCount) << " before rendering." << TestLog::EndMessage;
4972
4973 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4974 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4975 *renderPassClearValues[attachmentNdx], config.useFormatCompCount) << " in the beginning of the render pass." << TestLog::EndMessage;
4976 }
4977
4978 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4979 {
4980 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4981
4982 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
4983 }
4984 }
4985
roundToViewport(float x,deUint32 offset,deUint32 size)4986 float roundToViewport (float x, deUint32 offset, deUint32 size)
4987 {
4988 const float origin = (float)(offset) + ((float(size) / 2.0f));
4989 const float p = (float)(size) / 2.0f;
4990 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4991
4992 return (((float)xi) - origin) / p;
4993 }
4994
initializeSubpassRenderInfo(vector<SubpassRenderInfo> & renderInfos,de::Random & rng,const RenderPass & renderPass,const TestConfig & config)4995 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4996 {
4997 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4998 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4999 bool lastSubpassWasSecondary = false;
5000
5001 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
5002 {
5003 const Subpass& subpass = subpasses[subpassNdx];
5004 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
5005 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
5006 const bool omitBlendState = subpass.getOmitBlendState();
5007 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
5008 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
5009 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
5010
5011 vector<ColorClear> colorClears;
5012 Maybe<DepthStencilClear> depthStencilClear;
5013 Maybe<RenderQuad> renderQuad;
5014
5015 lastSubpassWasSecondary = subpassIsSecondary;
5016
5017 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
5018 {
5019 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
5020
5021 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
5022 {
5023 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
5024 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
5025 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
5026 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
5027 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
5028 const VkClearColorValue color = randomColorClearValue(attachment, rng, config.useFormatCompCount);
5029
5030 colorClears.push_back(ColorClear(offset, size, color));
5031 }
5032
5033 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
5034 {
5035 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
5036 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
5037 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
5038 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
5039 const VkClearValue value = randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);
5040
5041 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
5042 }
5043 }
5044
5045 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
5046 {
5047 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
5048 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
5049
5050 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
5051 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
5052
5053 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
5054 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
5055
5056 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
5057 }
5058
5059 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary, omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
5060 }
5061 }
5062
checkTextureFormatSupport(TestLog & log,const InstanceInterface & vk,VkPhysicalDevice device,const vector<Attachment> & attachments)5063 void checkTextureFormatSupport (TestLog& log,
5064 const InstanceInterface& vk,
5065 VkPhysicalDevice device,
5066 const vector<Attachment>& attachments)
5067 {
5068 bool supported = true;
5069
5070 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5071 {
5072 const Attachment& attachment = attachments[attachmentNdx];
5073 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
5074 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
5075 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
5076 VkFormatProperties properties;
5077
5078 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
5079
5080 if ((properties.optimalTilingFeatures & flags) != flags)
5081 {
5082 supported = false;
5083 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
5084 }
5085 }
5086
5087 if (!supported)
5088 TCU_THROW(NotSupportedError, "Format not supported");
5089 }
5090
renderPassTest(Context & context,TestConfig config)5091 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
5092 {
5093 const UVec2 targetSize = config.targetSize;
5094 const UVec2 renderPos = config.renderPos;
5095 const UVec2 renderSize = config.renderSize;
5096 const RenderPass& renderPassInfo = config.renderPass;
5097
5098 TestLog& log = context.getTestContext().getLog();
5099 de::Random rng (config.seed);
5100
5101 vector<bool> attachmentIsLazy;
5102 vector<VkImageUsageFlags> attachmentImageUsage;
5103 vector<Maybe<VkClearValue> > imageClearValues;
5104 vector<Maybe<VkClearValue> > renderPassClearValues;
5105
5106 vector<bool> subpassIsSecondary;
5107 vector<SubpassRenderInfo> subpassRenderInfo;
5108
5109 if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
5110 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
5111
5112 if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5113 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
5114
5115 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
5116 {
5117 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
5118 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
5119 }
5120
5121 if (!renderPassInfo.getInputAspects().empty())
5122 {
5123 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5124 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
5125 }
5126
5127 {
5128 bool requireDepthStencilLayout = false;
5129
5130 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5131 {
5132 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5133 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
5134 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5135 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5136 {
5137 requireDepthStencilLayout = true;
5138 break;
5139 }
5140 }
5141
5142 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
5143 {
5144 const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
5145
5146 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
5147 {
5148 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5149 || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5150 {
5151 requireDepthStencilLayout = true;
5152 break;
5153 }
5154 }
5155
5156 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
5157 {
5158 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5159 || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5160 {
5161 requireDepthStencilLayout = true;
5162 break;
5163 }
5164 }
5165
5166 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
5167 {
5168 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5169 || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5170 {
5171 requireDepthStencilLayout = true;
5172 break;
5173 }
5174 }
5175
5176 if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5177 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5178 {
5179 requireDepthStencilLayout = true;
5180 break;
5181 }
5182 }
5183
5184 if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5185 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
5186 }
5187
5188 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
5189 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy, config.useFormatCompCount, config.depthValues);
5190 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
5191 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(), config.useFormatCompCount, config.depthValues);
5192
5193 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
5194 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
5195
5196 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
5197
5198 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
5199
5200 {
5201 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5202
5203 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
5204
5205 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5206 {
5207 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
5208 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
5209 }
5210 }
5211
5212 {
5213 const InstanceInterface& vki = context.getInstanceInterface();
5214 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
5215 const VkDevice device = context.getDevice();
5216 const DeviceInterface& vk = context.getDeviceInterface();
5217 const VkQueue queue = context.getUniversalQueue();
5218 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
5219 Allocator& allocator = context.getDefaultAllocator();
5220
5221 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, 0, queueIndex));
5222 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5223 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5224 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5225
5226 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
5227 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
5228 vector<VkImage> attachmentImages;
5229 vector<VkImageView> attachmentViews;
5230 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
5231
5232 Move<VkRenderPass> renderPass;
5233 if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5234 renderPass = createRenderPass(vk, device, renderPassInfo, config.groupParams->renderingType);
5235
5236 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5237 {
5238 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
5239
5240 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
5241 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
5242 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
5243
5244 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
5245 }
5246
5247 beginCommandBuffer(vk, *initializeImagesCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5248 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
5249 endCommandBuffer(vk, *initializeImagesCommandBuffer);
5250
5251 {
5252 Move<VkFramebuffer> framebuffer;
5253 if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5254 framebuffer = createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews);
5255
5256 const VkRect2D renderArea
5257 {
5258 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
5259 { renderSize.x(), renderSize.y() }
5260 };
5261 const bool dynamicRendering = (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5262 const bool secondaryCmdBufferCompletelyContainsDynamicRenderpass = (config.commandBufferTypes == TestConfig::COMMANDBUFFERTYPES_SECONDARY) &&
5263 config.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass;
5264
5265 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5266 {
5267 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, renderPassInfo, attachmentResources,
5268 renderArea, renderPassClearValues, *renderPass, *framebuffer,
5269 *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews,
5270 subpassRenderInfo[subpassNdx], config.allocationKind, dynamicRendering,
5271 secondaryCmdBufferCompletelyContainsDynamicRenderpass)));
5272 }
5273
5274 beginCommandBuffer(vk, *renderCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5275 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, renderPassInfo, attachmentResources, *framebuffer, subpassRenderers, renderArea,
5276 renderPassClearValues, queueIndex, config.renderTypes, config.groupParams->renderingType, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
5277 endCommandBuffer(vk, *renderCommandBuffer);
5278
5279 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5280 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
5281 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
5282 {
5283 const VkCommandBuffer commandBuffers[] =
5284 {
5285 *initializeImagesCommandBuffer,
5286 *renderCommandBuffer,
5287 *readImagesToBuffersCommandBuffer
5288 };
5289 const Unique<VkFence> fence (createFence(vk, device, 0u));
5290
5291 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
5292 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
5293 }
5294 }
5295 #ifdef CTS_USES_VULKANSC
5296 if (!context.getTestContext().getCommandLine().isSubProcess())
5297 return tcu::TestStatus::pass("Pass");
5298 #endif
5299 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
5300 return tcu::TestStatus::pass("Pass");
5301 else
5302 return tcu::TestStatus::fail("Result verification failed");
5303 }
5304 }
5305
5306 class RenderPassNoDrawLoadStoreTestCase : public vkt::TestCase
5307 {
5308 public:
5309 RenderPassNoDrawLoadStoreTestCase(tcu::TestContext& context, const std::string& name, const std::string& description, bool useRenderPass2);
5310 TestInstance* createInstance (Context& context) const override;
5311 private:
5312 bool m_renderPass2;
5313 };
5314
5315 class RenderPassNoDrawLoadStoreTestInstance : public vkt::TestInstance
5316 {
5317 public:
5318 RenderPassNoDrawLoadStoreTestInstance(Context& context, bool useRenderPass2);
5319
5320 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
5321 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk, VkDevice vkDevice, RenderingType type);
5322 virtual tcu::TestStatus iterate(void);
5323 private:
5324 bool m_renderPass2;
5325 };
5326
RenderPassNoDrawLoadStoreTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool useRenderPass2)5327 RenderPassNoDrawLoadStoreTestCase::RenderPassNoDrawLoadStoreTestCase(tcu::TestContext& context, const std::string& name, const std::string& description, bool useRenderPass2)
5328 : vkt::TestCase(context, name, description), m_renderPass2(useRenderPass2) {}
5329
RenderPassNoDrawLoadStoreTestInstance(Context & context,bool useRenderPass2)5330 RenderPassNoDrawLoadStoreTestInstance::RenderPassNoDrawLoadStoreTestInstance(Context& context, bool useRenderPass2) : vkt::TestInstance(context), m_renderPass2(useRenderPass2) { }
5331
createInstance(Context & context) const5332 TestInstance* RenderPassNoDrawLoadStoreTestCase::createInstance(Context& context) const {
5333 return new RenderPassNoDrawLoadStoreTestInstance(context, m_renderPass2);
5334 }
5335
5336 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,RenderingType type)5337 Move<VkRenderPass> RenderPassNoDrawLoadStoreTestInstance::createRenderPass (const DeviceInterface& vk,
5338 VkDevice vkDevice,
5339 RenderingType type)
5340 {
5341 const VkImageAspectFlags aspectMask = type == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
5342
5343 const AttachmentDesc attachmentDescription =
5344 // Result attachment
5345 AttachmentDesc (
5346 nullptr, // const void* pNext
5347 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
5348 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
5349 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
5350 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
5351 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
5352 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
5353 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
5354 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
5355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
5356 );
5357
5358 const AttachmentRef resultAttachmentRefSubpass0 (
5359 nullptr, // const void* pNext
5360 0u, // deUint32 attachment
5361 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
5362 aspectMask // VkImageAspectFlags aspectMask
5363 );
5364
5365 const SubpassDesc subpassDescription =
5366 SubpassDesc (
5367 nullptr,
5368 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
5369 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
5370 0u, // deUint32 viewMask
5371 0u, // deUint32 inputAttachmentCount
5372 nullptr, // const VkAttachmentReference* pInputAttachments
5373 1u, // deUint32 colorAttachmentCount
5374 &resultAttachmentRefSubpass0, // const VkAttachmentReference* pColorAttachments
5375 nullptr, // const VkAttachmentReference* pResolveAttachments
5376 nullptr, // const VkAttachmentReference* pDepthStencilAttachment
5377 0u, // deUint32 preserveAttachmentCount
5378 nullptr // const deUint32* pPreserveAttachments
5379 );
5380
5381 const RenderPassCreateInfo renderPassInfo (
5382 nullptr, // const void* pNext
5383 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
5384 1u, // deUint32 attachmentCount
5385 &attachmentDescription, // const VkAttachmentDescription* pAttachments
5386 1u, // deUint32 subpassCount
5387 &subpassDescription, // const VkSubpassDescription* pSubpasses
5388 0u, // deUint32 dependencyCount
5389 nullptr, // const VkSubpassDependency* pDependencies
5390 0u, // deUint32 correlatedViewMaskCount
5391 nullptr // const deUint32* pCorrelatedViewMasks
5392 );
5393 return renderPassInfo.createRenderPass(vk, vkDevice);
5394 }
5395
iterate()5396 tcu::TestStatus RenderPassNoDrawLoadStoreTestInstance::iterate() {
5397 const auto& vkd = m_context.getDeviceInterface();
5398 const auto device = m_context.getDevice();
5399 auto& alloc = m_context.getDefaultAllocator();
5400
5401 auto imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
5402 auto imageExtent = makeExtent3D(1, 1, 1u);
5403
5404 const tcu::IVec3 imageDim (static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), static_cast<int>(imageExtent.depth));
5405 const tcu::IVec2 imageSize (imageDim.x(), imageDim.y());
5406
5407 const std::vector<VkViewport> viewports { makeViewport(imageExtent) };
5408 const std::vector<VkRect2D> scissors { makeRect2D(imageExtent) };
5409
5410 de::MovePtr<ImageWithMemory> colorAttachment;
5411
5412 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
5413
5414 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
5415 const auto imageUsage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
5416 const VkImageCreateInfo imageCreateInfo =
5417 {
5418 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5419 nullptr, // const void* pNext;
5420 0u, // VkImageCreateFlags flags;
5421 VK_IMAGE_TYPE_2D, // VkImageType imageType;
5422 imageFormat, // VkFormat format;
5423 imageExtent, // VkExtent3D extent;
5424 1u, // deUint32 mipLevels;
5425 1u, // deUint32 arrayLayers;
5426 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
5427 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5428 imageUsage, // VkImageUsageFlags usage;
5429 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5430 0u, // deUint32 queueFamilyIndexCount;
5431 nullptr, // const deUint32* pQueueFamilyIndices;
5432 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5433 };
5434
5435 colorAttachment = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
5436 auto colorAttachmentView = makeImageView(vkd, device, colorAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
5437
5438 const auto tcuFormat = mapVkFormat(imageFormat);
5439 const auto outBufferSize = static_cast<VkDeviceSize>(static_cast<uint32_t>(tcu::getPixelSize(tcuFormat)) * imageExtent.width * imageExtent.height);
5440
5441 BufferWithMemory outBuffer (vkd, device, alloc, makeBufferCreateInfo(outBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
5442 auto& outBufferAlloc = outBuffer.getAllocation();
5443 void* outBufferData = outBufferAlloc.getHostPtr();
5444
5445 Move<VkRenderPass> renderPass;
5446 if (m_renderPass2) {
5447 renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>
5448 (vkd, device, RENDERING_TYPE_RENDERPASS_LEGACY);
5449 } else {
5450 renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>
5451 (vkd, device, RENDERING_TYPE_RENDERPASS2);
5452 }
5453
5454 // Framebuffer.
5455 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), imageExtent.width, imageExtent.height);
5456
5457 const auto clearValueColor = makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
5458
5459 auto graphicsPipelineLayout = makePipelineLayout(vkd, device);
5460 auto commandPool = createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, qIndex);
5461 auto commandBuffer = allocateCommandBuffer(vkd, device, commandPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5462
5463 beginCommandBuffer(vkd, commandBuffer.get());
5464
5465 const VkRenderPassBeginInfo renderPassBeginInfo =
5466 {
5467 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
5468 nullptr, // const void* pNext;
5469 *renderPass, // VkRenderPass renderPass;
5470 *framebuffer, // VkFramebuffer framebuffer;
5471 scissors.at(0), // VkRect2D renderArea;
5472 1, // uint32_t clearValueCount;
5473 &clearValueColor, // const VkClearValue* pClearValues;
5474 };
5475 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
5476 vkd.cmdEndRenderPass(*commandBuffer);
5477 auto barrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
5478 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorAttachment->get(), subresourceRange);
5479 cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &barrier);
5480 copyImageToBuffer(vkd, commandBuffer.get(), colorAttachment.get()->get(), outBuffer.get(), imageSize);
5481 endCommandBuffer(vkd, commandBuffer.get());
5482 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), commandBuffer.get());
5483 invalidateAlloc(vkd, device, outBufferAlloc);
5484
5485 tcu::ConstPixelBufferAccess outPixels(tcuFormat, imageDim, outBufferData);
5486 auto pixel = outPixels.getPixel(0, 0);
5487 auto expected = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
5488
5489 if (pixel != expected) {
5490 std::stringstream output("Pixel isn't equal to clear color: ");
5491 output << pixel << " instead of " << expected;
5492 return tcu::TestStatus::fail(output.str());
5493 }
5494
5495 return tcu::TestStatus::pass("Pass");
5496 }
5497
5498 static const VkFormat s_coreColorFormats[] =
5499 {
5500 VK_FORMAT_R5G6B5_UNORM_PACK16,
5501 VK_FORMAT_R8_UNORM,
5502 VK_FORMAT_R8_SNORM,
5503 VK_FORMAT_R8_UINT,
5504 VK_FORMAT_R8_SINT,
5505 VK_FORMAT_R8G8_UNORM,
5506 VK_FORMAT_R8G8_SNORM,
5507 VK_FORMAT_R8G8_UINT,
5508 VK_FORMAT_R8G8_SINT,
5509 VK_FORMAT_R8G8B8A8_UNORM,
5510 VK_FORMAT_R8G8B8A8_SNORM,
5511 VK_FORMAT_R8G8B8A8_UINT,
5512 VK_FORMAT_R8G8B8A8_SINT,
5513 VK_FORMAT_R8G8B8A8_SRGB,
5514 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
5515 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
5516 VK_FORMAT_A8B8G8R8_UINT_PACK32,
5517 VK_FORMAT_A8B8G8R8_SINT_PACK32,
5518 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5519 VK_FORMAT_B8G8R8A8_UNORM,
5520 VK_FORMAT_B8G8R8A8_SRGB,
5521 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
5522 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
5523 VK_FORMAT_A2B10G10R10_UINT_PACK32,
5524 VK_FORMAT_R16_UNORM,
5525 VK_FORMAT_R16_SNORM,
5526 VK_FORMAT_R16_UINT,
5527 VK_FORMAT_R16_SINT,
5528 VK_FORMAT_R16_SFLOAT,
5529 VK_FORMAT_R16G16_UNORM,
5530 VK_FORMAT_R16G16_SNORM,
5531 VK_FORMAT_R16G16_UINT,
5532 VK_FORMAT_R16G16_SINT,
5533 VK_FORMAT_R16G16_SFLOAT,
5534 VK_FORMAT_R16G16B16A16_UNORM,
5535 VK_FORMAT_R16G16B16A16_SNORM,
5536 VK_FORMAT_R16G16B16A16_UINT,
5537 VK_FORMAT_R16G16B16A16_SINT,
5538 VK_FORMAT_R16G16B16A16_SFLOAT,
5539 VK_FORMAT_R32_UINT,
5540 VK_FORMAT_R32_SINT,
5541 VK_FORMAT_R32_SFLOAT,
5542 VK_FORMAT_R32G32_UINT,
5543 VK_FORMAT_R32G32_SINT,
5544 VK_FORMAT_R32G32_SFLOAT,
5545 VK_FORMAT_R32G32B32A32_UINT,
5546 VK_FORMAT_R32G32B32A32_SINT,
5547 VK_FORMAT_R32G32B32A32_SFLOAT
5548 };
5549
5550 static const VkFormat s_coreDepthStencilFormats[] =
5551 {
5552 VK_FORMAT_D16_UNORM,
5553
5554 VK_FORMAT_X8_D24_UNORM_PACK32,
5555 VK_FORMAT_D32_SFLOAT,
5556
5557 VK_FORMAT_D24_UNORM_S8_UINT,
5558 VK_FORMAT_D32_SFLOAT_S8_UINT
5559 };
5560
addAttachmentTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5561 void addAttachmentTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5562 {
5563 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
5564 const VkAttachmentLoadOp loadOps[] =
5565 {
5566 VK_ATTACHMENT_LOAD_OP_LOAD,
5567 VK_ATTACHMENT_LOAD_OP_CLEAR,
5568 VK_ATTACHMENT_LOAD_OP_DONT_CARE
5569 };
5570
5571 const VkAttachmentStoreOp storeOps[] =
5572 {
5573 VK_ATTACHMENT_STORE_OP_STORE,
5574 VK_ATTACHMENT_STORE_OP_DONT_CARE
5575 };
5576
5577 const VkImageLayout initialAndFinalColorLayouts[] =
5578 {
5579 VK_IMAGE_LAYOUT_GENERAL,
5580 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5581 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5582 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5583 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5584 };
5585
5586 const VkImageLayout initialAndFinalColorLayoutsLazy[] =
5587 {
5588 VK_IMAGE_LAYOUT_GENERAL,
5589 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5590 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5591 };
5592
5593 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5594 {
5595 VK_IMAGE_LAYOUT_GENERAL,
5596 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5597 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5598 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5599 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5600 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5601 };
5602
5603 const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] =
5604 {
5605 VK_IMAGE_LAYOUT_GENERAL,
5606 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5607 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5608 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5609 };
5610
5611 const VkImageLayout subpassLayouts[] =
5612 {
5613 VK_IMAGE_LAYOUT_GENERAL,
5614 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5615 };
5616
5617 const VkImageLayout depthStencilLayouts[] =
5618 {
5619 VK_IMAGE_LAYOUT_GENERAL,
5620 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5621 };
5622
5623 const TestConfig::RenderTypes renderCommands[] =
5624 {
5625 TestConfig::RENDERTYPES_NONE,
5626 TestConfig::RENDERTYPES_CLEAR,
5627 TestConfig::RENDERTYPES_DRAW,
5628 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5629 };
5630
5631 const TestConfig::CommandBufferTypes commandBuffers[] =
5632 {
5633 TestConfig::COMMANDBUFFERTYPES_INLINE,
5634 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5635 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5636 };
5637
5638 const TestConfig::ImageMemory imageMemories[] =
5639 {
5640 TestConfig::IMAGEMEMORY_STRICT,
5641 TestConfig::IMAGEMEMORY_LAZY,
5642 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
5643 };
5644
5645 const UVec2 targetSizes[] =
5646 {
5647 UVec2(64, 64),
5648 UVec2(63, 65)
5649 };
5650
5651 const UVec2 renderPositions[] =
5652 {
5653 UVec2(0, 0),
5654 UVec2(3, 17)
5655 };
5656
5657 const UVec2 renderSizes[] =
5658 {
5659 UVec2(32, 32),
5660 UVec2(60, 47)
5661 };
5662
5663 tcu::TestContext& testCtx (group->getTestContext());
5664 bool useDynamicRendering (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5665 de::Random rng (1433774382u);
5666
5667 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5668 {
5669 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
5670 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
5671 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
5672
5673 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
5674 {
5675 const bool useDepthStencil = rng.getBool();
5676 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5677 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
5678 vector<Attachment> attachments;
5679 vector<AttachmentReference> colorAttachmentReferences;
5680
5681 // we want to make sure that dynamic rendering test cases have corresponding renderpass
5682 // cases as this will allow drivers to easily compare GPU batches; since configurations
5683 // for those tests are generated we need to generate configurations for all cases
5684 // even when we know earlier that for dynamic rendering we will skip it
5685 bool executeForDynamicRendering = true;
5686
5687 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5688 {
5689 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5690 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5691 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5692 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5693
5694 const VkImageLayout initialLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5695 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5696 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5697 VkImageLayout finalizeLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5698 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5699 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5700 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5701
5702 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5703 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5704
5705 if (useDynamicRendering)
5706 {
5707 // with renderpass we can have automatic layout transitions; to do the same with dynamic rendering cases
5708 // we would need to add addtional barries but since those tests won't add coverage we are skipping them
5709 if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5710 (initialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL))
5711 finalizeLayout = initialLayout;
5712 else
5713 executeForDynamicRendering = false;
5714 }
5715
5716 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5717 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5718 }
5719
5720 if (useDepthStencil)
5721 {
5722 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5723 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5724 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5725 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5726
5727 const VkImageLayout initialLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5728 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5729 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5730 VkImageLayout finalizeLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5731 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5732 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5733
5734 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5735 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5736
5737 if (useDynamicRendering)
5738 {
5739 if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5740 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) ||
5741 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
5742 finalizeLayout = initialLayout;
5743 else
5744 executeForDynamicRendering = false;
5745 }
5746
5747 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
5748 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5749 }
5750
5751 {
5752 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5753 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5754 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>()));
5755 const vector<SubpassDependency> deps;
5756 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
5757 const RenderPass renderPass (attachments, subpasses, deps);
5758 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5759 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5760 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5761
5762 if (useDynamicRendering)
5763 {
5764 // skip dynamic rendering cases (that don't add coverage) this can be done not earlier than after grabbing all
5765 // random numbers as we need to make sure that those tests that will be created for dynamic rendering have
5766 // corresponding renderpass tests with the same name
5767 if (!executeForDynamicRendering)
5768 continue;
5769
5770 // dont repeat non secondary buffer cases when testing secondaryCmdBufferCompletelyContainsDynamicRenderpass flag
5771 if (testConfigExternal.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass &&
5772 (commandBuffer != TestConfig::COMMANDBUFFERTYPES_SECONDARY))
5773 {
5774 continue;
5775 }
5776 }
5777
5778 const TestConfig testConfig (renderPass,
5779 render,
5780 commandBuffer,
5781 imageMemory,
5782 targetSize,
5783 renderPos,
5784 renderSize,
5785 DE_FALSE,
5786 1293809,
5787 0,
5788 testConfigExternal.allocationKind,
5789 testConfigExternal.groupParams);
5790
5791 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5792 }
5793 }
5794
5795 group->addChild(attachmentCountGroup.release());
5796 }
5797 }
5798
addAttachmentWriteMaskTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5799 void addAttachmentWriteMaskTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5800 {
5801 const deUint32 attachmentCounts[] = { 1, 2, 3, 4, 8 };
5802
5803 const VkFormat attachmentFormats[] =
5804 {
5805 VK_FORMAT_R8G8B8A8_UINT,
5806 VK_FORMAT_R8G8B8A8_UNORM,
5807 VK_FORMAT_R5G6B5_UNORM_PACK16,
5808 VK_FORMAT_R8G8_UNORM
5809 };
5810
5811 tcu::TestContext& testCtx = group->getTestContext();
5812
5813 for (deUint32 attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5814 {
5815 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
5816 const string groupName = "attachment_count_" + de::toString(attachmentCount);
5817
5818 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), de::toString(attachmentCount).c_str()));
5819
5820 for (deUint32 drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
5821 {
5822 deUint32 formatNdx = 0;
5823 vector<Attachment> attachments;
5824 vector<AttachmentReference> colorAttachmentReferences;
5825
5826 for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5827 {
5828 const VkFormat format = attachmentFormats[formatNdx];
5829 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5830 const VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
5831 const VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE;
5832 const VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
5833 const VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
5834 const VkImageLayout initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5835 const VkImageLayout finalizeLayout = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5836 ? initialLayout : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5837 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
5838
5839 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5840 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5841
5842 if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
5843 formatNdx = 0;
5844 }
5845
5846 {
5847 const VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
5848 const vector<Subpass> subpass (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
5849 const vector<SubpassDependency> deps;
5850
5851 const string testCaseName = "start_index_" + de::toString(drawStartNdx);
5852 const RenderPass renderPass (attachments, subpass, deps);
5853
5854 const TestConfig::RenderTypes render = TestConfig::RENDERTYPES_DRAW;
5855 const TestConfig::CommandBufferTypes commandBuffer = TestConfig::COMMANDBUFFERTYPES_INLINE;
5856 const TestConfig::ImageMemory imageMemory = TestConfig::IMAGEMEMORY_LAZY;
5857 const UVec2 targetSize = UVec2(64, 64);
5858 const UVec2 renderPos = UVec2(0, 0);
5859 const UVec2 renderSize = UVec2(64, 64);
5860 const deBool useFormatCompCount = DE_TRUE;
5861 const vector<DeviceCoreFeature> requiredFeatures = {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
5862 const TestConfig testConfig (renderPass,
5863 render,
5864 commandBuffer,
5865 imageMemory,
5866 targetSize,
5867 renderPos,
5868 renderSize,
5869 useFormatCompCount,
5870 1293809,
5871 drawStartNdx,
5872 testConfigExternal.allocationKind,
5873 testConfigExternal.groupParams,
5874 requiredFeatures);
5875
5876 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), checkSupport, createTestShaders, renderPassTest, testConfig);
5877 }
5878 }
5879
5880 group->addChild(attachmentCountGroup.release());
5881 }
5882 }
5883
5884 template<typename T>
chooseRandom(de::Random & rng,const set<T> & values)5885 T chooseRandom (de::Random& rng, const set<T>& values)
5886 {
5887 size_t ndx = ((size_t)rng.getUint32()) % values.size();
5888 typename set<T>::const_iterator iter = values.begin();
5889
5890 for (; ndx > 0; ndx--)
5891 iter++;
5892
5893 return *iter;
5894 }
5895
addAttachmentAllocationTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5896 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5897 {
5898 const deUint32 attachmentCounts[] = { 4, 8 };
5899 const VkAttachmentLoadOp loadOps[] =
5900 {
5901 VK_ATTACHMENT_LOAD_OP_LOAD,
5902 VK_ATTACHMENT_LOAD_OP_CLEAR,
5903 VK_ATTACHMENT_LOAD_OP_DONT_CARE
5904 };
5905
5906 const VkAttachmentStoreOp storeOps[] =
5907 {
5908 VK_ATTACHMENT_STORE_OP_STORE,
5909 VK_ATTACHMENT_STORE_OP_DONT_CARE
5910 };
5911
5912 const VkImageLayout initialAndFinalColorLayouts[] =
5913 {
5914 VK_IMAGE_LAYOUT_GENERAL,
5915 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5916 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5917 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5918 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5919 };
5920
5921 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5922 {
5923 VK_IMAGE_LAYOUT_GENERAL,
5924 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5925 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5926 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5927 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5928 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5929 };
5930
5931 const VkImageLayout subpassLayoutsColor[] =
5932 {
5933 VK_IMAGE_LAYOUT_GENERAL,
5934 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5935 };
5936
5937 const VkImageLayout subpassLayoutsDepthStencil[] =
5938 {
5939 VK_IMAGE_LAYOUT_GENERAL,
5940 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5941 };
5942
5943 const VkImageLayout subpassLayoutsInput[] =
5944 {
5945 VK_IMAGE_LAYOUT_GENERAL,
5946 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5947 };
5948
5949 enum AllocationType
5950 {
5951 // Each pass uses one more attachmen than previous one
5952 ALLOCATIONTYPE_GROW,
5953 // Each pass uses one less attachment than previous one
5954 ALLOCATIONTYPE_SHRINK,
5955 // Each pass drops one attachment and picks up new one
5956 ALLOCATIONTYPE_ROLL,
5957 // Start by growing and end by shrinking
5958 ALLOCATIONTYPE_GROW_SHRINK,
5959 // Each subpass has single input and single output attachment
5960 ALLOCATIONTYPE_IO_CHAIN,
5961 // Each subpass has multiple inputs and multiple outputs attachment
5962 ALLOCATIONTYPE_IO_GENERIC
5963 };
5964
5965 const AllocationType allocationTypes[] =
5966 {
5967 ALLOCATIONTYPE_GROW,
5968 ALLOCATIONTYPE_SHRINK,
5969 ALLOCATIONTYPE_ROLL,
5970 ALLOCATIONTYPE_GROW_SHRINK,
5971 ALLOCATIONTYPE_IO_CHAIN,
5972 ALLOCATIONTYPE_IO_GENERIC
5973 };
5974
5975 const char* const allocationTypeStr[] =
5976 {
5977 "grow",
5978 "shrink",
5979 "roll",
5980 "grow_shrink",
5981 "input_output_chain",
5982 "input_output",
5983 };
5984
5985 const TestConfig::RenderTypes renderCommands[] =
5986 {
5987 TestConfig::RENDERTYPES_NONE,
5988 TestConfig::RENDERTYPES_CLEAR,
5989 TestConfig::RENDERTYPES_DRAW,
5990 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5991 };
5992
5993 const TestConfig::CommandBufferTypes commandBuffers[] =
5994 {
5995 TestConfig::COMMANDBUFFERTYPES_INLINE,
5996 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5997 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5998 };
5999
6000 const TestConfig::ImageMemory imageMemories[] =
6001 {
6002 TestConfig::IMAGEMEMORY_STRICT,
6003 TestConfig::IMAGEMEMORY_LAZY,
6004 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
6005 };
6006
6007 const UVec2 targetSizes[] =
6008 {
6009 UVec2(64, 64),
6010 UVec2(63, 65)
6011 };
6012
6013 const UVec2 renderPositions[] =
6014 {
6015 UVec2(0, 0),
6016 UVec2(3, 17)
6017 };
6018
6019 const UVec2 renderSizes[] =
6020 {
6021 UVec2(32, 32),
6022 UVec2(60, 47)
6023 };
6024
6025 tcu::TestContext& testCtx = group->getTestContext();
6026 de::Random rng (3700649827u);
6027
6028 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
6029 {
6030 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
6031 const size_t testCaseCount = 100;
6032 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
6033
6034 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
6035 {
6036 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
6037 {
6038 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
6039 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
6040 vector<Attachment> attachments;
6041
6042 set<deUint32> definedAttachments;
6043
6044 vector<Subpass> subpasses;
6045 set<deUint32> colorAttachments;
6046 set<deUint32> depthStencilAttachments;
6047
6048 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
6049 {
6050 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
6051 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6052 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6053 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6054
6055 const VkImageLayout initialLayout = isDepthStencilAttachment
6056 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
6057 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6058 const VkImageLayout finalizeLayout = isDepthStencilAttachment
6059 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
6060 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6061
6062 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6063 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6064
6065 if (isDepthStencilAttachment)
6066 {
6067 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
6068
6069 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
6070 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6071 definedAttachments.insert(attachmentIndex);
6072
6073 depthStencilAttachments.insert(attachmentIndex);
6074
6075 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6076 }
6077 else
6078 {
6079 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6080
6081 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6082 definedAttachments.insert(attachmentIndex);
6083
6084 colorAttachments.insert(attachmentIndex);
6085
6086 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6087 }
6088 }
6089 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), tcu::Nothing);
6090 vector<SubpassDependency> deps;
6091
6092 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
6093 {
6094 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
6095 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
6096 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
6097 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
6098 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
6099 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
6100 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
6101 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
6102 ? just(chooseRandom(rng, depthStencilAttachments))
6103 : tcu::Nothing);
6104 std::vector<deUint32> subpassPreserveAttachments;
6105
6106 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
6107 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
6108
6109 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
6110 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
6111
6112 if (depthStencilAttachment)
6113 definedAttachments.insert(*depthStencilAttachment);
6114
6115 {
6116 std::vector<AttachmentReference> inputAttachmentReferences;
6117 std::vector<AttachmentReference> colorAttachmentReferences;
6118 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6119
6120 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
6121 {
6122 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
6123
6124 if (lastUseOfAttachment[colorAttachmentIndex])
6125 {
6126 deBool foundDuplicate = false;
6127
6128 const deUint32 srcPass = *lastUseOfAttachment[colorAttachmentIndex];
6129 const deUint32 dstPass = subpassIndex;
6130 const VkDependencyFlags dependencyFlags = rng.getBool() ? (VkDependencyFlags) VK_DEPENDENCY_BY_REGION_BIT : 0u;
6131
6132 const SubpassDependency newDependency(srcPass, dstPass,
6133 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6134 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6135 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6136 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6137
6138 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6139 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6140 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6141 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6142
6143 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6144 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
6145
6146 dependencyFlags);
6147
6148 for (SubpassDependency& dependency : deps)
6149 {
6150 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6151 {
6152 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
6153 dependency.setDstAccessMask(newDstFlags);
6154 foundDuplicate = true;
6155 break;
6156 }
6157 }
6158
6159 if (!foundDuplicate)
6160 {
6161 deps.push_back(newDependency);
6162 }
6163 }
6164
6165 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
6166
6167 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
6168 }
6169
6170 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
6171 {
6172 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
6173
6174 if(lastUseOfAttachment[inputAttachmentIndex])
6175 {
6176 deBool foundDuplicate = false;
6177
6178 const deUint32 srcPass = *lastUseOfAttachment[inputAttachmentIndex];
6179 const deUint32 dstPass = subpassIndex;
6180 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6181
6182 const SubpassDependency newDependency(srcPass, dstPass,
6183 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6184 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6185 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6186 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6187
6188 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6189 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6190 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6191 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6192
6193 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6194 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6195
6196 dependencyFlags);
6197 for (SubpassDependency& dependency : deps)
6198 {
6199 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6200 {
6201 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6202 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6203 dependency.setDstAccessMask(newSrcFlags);
6204 dependency.setDstAccessMask(newDstFlags);
6205 foundDuplicate = true;
6206 break;
6207 }
6208 }
6209
6210 if (!foundDuplicate)
6211 {
6212 deps.push_back(newDependency);
6213 }
6214
6215 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
6216
6217 VkImageAspectFlags aspect = 0u;
6218 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6219 {
6220 bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
6221 aspect = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
6222 }
6223 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL, aspect));
6224 }
6225 }
6226
6227 if (depthStencilAttachment)
6228 {
6229 if (lastUseOfAttachment[*depthStencilAttachment])
6230 {
6231 deBool foundDuplicate = false;
6232
6233 const deUint32 srcPass = *lastUseOfAttachment[*depthStencilAttachment];
6234 const deUint32 dstPass = subpassIndex;
6235 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6236
6237 const SubpassDependency newDependency(srcPass, dstPass,
6238 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6239 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6240 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6241 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6242
6243 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6244 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6245 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6246 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6247
6248 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6249 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
6250 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6251
6252 dependencyFlags);
6253 for (SubpassDependency& dependency : deps)
6254 {
6255 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6256 {
6257 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6258 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6259 dependency.setDstAccessMask(newSrcFlags);
6260 dependency.setDstAccessMask(newDstFlags);
6261 foundDuplicate = true;
6262 break;
6263 }
6264 }
6265
6266 if (!foundDuplicate)
6267 {
6268 deps.push_back(newDependency);
6269 }
6270 }
6271
6272 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
6273
6274 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
6275 }
6276 else
6277 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6278
6279 vector<deUint32> preserveAttachments;
6280 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
6281 {
6282 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
6283 preserveAttachments.push_back(attachmentIndex);
6284 }
6285
6286 // Use random image layout when possible
6287 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6288 {
6289 bool usedAsInput = false;
6290 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6291 if (colorAttachmentReferences[colorRefIdx].getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6292 usedAsInput = true;
6293
6294 if (!usedAsInput)
6295 colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
6296 }
6297 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6298 {
6299 bool usedAsDepthStencil = inputAttachmentReferences[inputRefIdx].getAttachment() == depthStencilAttachmentReference.getAttachment();
6300 bool usedAsColor = false;
6301 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6302 if (inputAttachmentReferences[inputRefIdx].getAttachment() == colorAttachmentReferences[colorRefIdx].getAttachment())
6303 usedAsColor = true;
6304
6305 if (!usedAsColor && !usedAsDepthStencil)
6306 inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
6307 }
6308 {
6309 bool usedAsInput = false;
6310 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6311 if (depthStencilAttachmentReference.getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6312 usedAsInput = true;
6313
6314 if (!usedAsInput)
6315 depthStencilAttachmentReference.setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil), DE_ARRAY_END(subpassLayoutsDepthStencil)));
6316 }
6317
6318 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6319 inputAttachmentReferences,
6320 colorAttachmentReferences,
6321 vector<AttachmentReference>(),
6322 depthStencilAttachmentReference,
6323 preserveAttachments));
6324 }
6325 }
6326 {
6327 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6328 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6329 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6330
6331 const string testCaseName = de::toString(testCaseNdx);
6332 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6333 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6334 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6335
6336 const RenderPass renderPass (attachments, subpasses, deps);
6337 const TestConfig testConfig (renderPass,
6338 render,
6339 commandBuffer,
6340 imageMemory,
6341 targetSize,
6342 renderPos,
6343 renderSize,
6344 DE_FALSE,
6345 80329,
6346 0,
6347 testConfigExternal.allocationKind,
6348 testConfigExternal.groupParams);
6349
6350 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6351 }
6352 }
6353 else
6354 {
6355 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
6356 vector<Attachment> attachments;
6357 vector<Subpass> subpasses;
6358
6359 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6360 {
6361 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
6362 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6363 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6364 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6365
6366 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6367 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6368
6369 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6370 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6371
6372 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6373 }
6374
6375 if (allocationType == ALLOCATIONTYPE_GROW)
6376 {
6377 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6378 {
6379 vector<AttachmentReference> colorAttachmentReferences;
6380
6381 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6382 {
6383 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6384
6385 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6386 }
6387
6388 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6389 vector<AttachmentReference>(),
6390 colorAttachmentReferences,
6391 vector<AttachmentReference>(),
6392 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6393 vector<deUint32>()));
6394 }
6395 }
6396 else if (allocationType == ALLOCATIONTYPE_SHRINK)
6397 {
6398 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6399 {
6400 vector<AttachmentReference> colorAttachmentReferences;
6401
6402 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6403 {
6404 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6405
6406 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6407 }
6408
6409 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6410 vector<AttachmentReference>(),
6411 colorAttachmentReferences,
6412 vector<AttachmentReference>(),
6413 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6414 vector<deUint32>()));
6415 }
6416 }
6417 else if (allocationType == ALLOCATIONTYPE_ROLL)
6418 {
6419 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
6420 {
6421 vector<AttachmentReference> colorAttachmentReferences;
6422
6423 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
6424 {
6425 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6426
6427 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
6428 }
6429
6430 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6431 vector<AttachmentReference>(),
6432 colorAttachmentReferences,
6433 vector<AttachmentReference>(),
6434 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6435 vector<deUint32>()));
6436 }
6437 }
6438 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
6439 {
6440 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6441 {
6442 vector<AttachmentReference> colorAttachmentReferences;
6443
6444 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6445 {
6446 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6447
6448 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6449 }
6450
6451 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6452 vector<AttachmentReference>(),
6453 colorAttachmentReferences,
6454 vector<AttachmentReference>(),
6455 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6456 vector<deUint32>()));
6457 }
6458 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6459 {
6460 vector<AttachmentReference> colorAttachmentReferences;
6461
6462 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6463 {
6464 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6465
6466 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6467 }
6468
6469 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6470 vector<AttachmentReference>(),
6471 colorAttachmentReferences,
6472 vector<AttachmentReference>(),
6473 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6474 vector<deUint32>()));
6475 }
6476 }
6477 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
6478 {
6479 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6480 vector<AttachmentReference>(),
6481 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6482 vector<AttachmentReference>(),
6483 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6484 vector<deUint32>()));
6485
6486 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
6487 {
6488 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ? VK_IMAGE_ASPECT_COLOR_BIT : static_cast<VkImageAspectFlagBits>(0);
6489 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6490 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6491 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6492 vector<AttachmentReference>(),
6493 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6494 vector<deUint32>()));
6495 }
6496 }
6497 else
6498 DE_FATAL("Unknown allocation type");
6499
6500 {
6501 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6502 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6503 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6504
6505 const string testCaseName = de::toString(testCaseNdx);
6506 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6507 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6508 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6509
6510 vector<SubpassDependency> deps;
6511
6512 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
6513 {
6514 const bool byRegion = rng.getBool();
6515 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
6516 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6517 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6518 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6519 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6520
6521 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6522 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6523 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6524 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6525
6526 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6527 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT),
6528
6529 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
6530 }
6531
6532 const RenderPass renderPass (attachments, subpasses, deps);
6533 const TestConfig testConfig (renderPass,
6534 render,
6535 commandBuffer,
6536 imageMemory,
6537 targetSize,
6538 renderPos,
6539 renderSize,
6540 DE_FALSE,
6541 80329,
6542 0,
6543 testConfigExternal.allocationKind,
6544 testConfigExternal.groupParams);
6545
6546 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6547 }
6548 }
6549 }
6550 group->addChild(allocationTypeGroup.release());
6551 }
6552 }
6553
addSimpleTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6554 void addSimpleTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6555 {
6556 const UVec2 targetSize (64, 64);
6557 const UVec2 renderPos (0, 0);
6558 const UVec2 renderSize (64, 64);
6559
6560 // color
6561 {
6562 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6563 VK_SAMPLE_COUNT_1_BIT,
6564 VK_ATTACHMENT_LOAD_OP_CLEAR,
6565 VK_ATTACHMENT_STORE_OP_STORE,
6566 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6567 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6568 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6569 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6570 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6571 0u,
6572 vector<AttachmentReference>(),
6573 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6574 vector<AttachmentReference>(),
6575 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6576 vector<deUint32>())),
6577 vector<SubpassDependency>());
6578 const TestConfig testConfig (renderPass,
6579 TestConfig::RENDERTYPES_DRAW,
6580 TestConfig::COMMANDBUFFERTYPES_INLINE,
6581 TestConfig::IMAGEMEMORY_STRICT,
6582 targetSize,
6583 renderPos,
6584 renderSize,
6585 DE_FALSE,
6586 90239,
6587 0,
6588 testConfigExternal.allocationKind,
6589 testConfigExternal.groupParams);
6590
6591 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, testConfig);
6592 }
6593
6594 // depth
6595 {
6596 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6597 VK_SAMPLE_COUNT_1_BIT,
6598 VK_ATTACHMENT_LOAD_OP_CLEAR,
6599 VK_ATTACHMENT_STORE_OP_STORE,
6600 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6601 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6602 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6603 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6604 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6605 0u,
6606 vector<AttachmentReference>(),
6607 vector<AttachmentReference>(),
6608 vector<AttachmentReference>(),
6609 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6610 vector<deUint32>())),
6611 vector<SubpassDependency>());
6612 const TestConfig testConfig (renderPass,
6613 TestConfig::RENDERTYPES_DRAW,
6614 TestConfig::COMMANDBUFFERTYPES_INLINE,
6615 TestConfig::IMAGEMEMORY_STRICT,
6616 targetSize,
6617 renderPos,
6618 renderSize,
6619 DE_FALSE,
6620 90239,
6621 0,
6622 testConfigExternal.allocationKind,
6623 testConfigExternal.groupParams);
6624
6625 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, testConfig);
6626 }
6627
6628 // stencil
6629 {
6630 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
6631 VK_SAMPLE_COUNT_1_BIT,
6632 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6633 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6634 VK_ATTACHMENT_LOAD_OP_CLEAR,
6635 VK_ATTACHMENT_STORE_OP_STORE,
6636 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6637 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6638 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6639 0u,
6640 vector<AttachmentReference>(),
6641 vector<AttachmentReference>(),
6642 vector<AttachmentReference>(),
6643 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6644 vector<deUint32>())),
6645 vector<SubpassDependency>());
6646 const TestConfig testConfig (renderPass,
6647 TestConfig::RENDERTYPES_DRAW,
6648 TestConfig::COMMANDBUFFERTYPES_INLINE,
6649 TestConfig::IMAGEMEMORY_STRICT,
6650 targetSize,
6651 renderPos,
6652 renderSize,
6653 DE_FALSE,
6654 90239,
6655 0,
6656 testConfigExternal.allocationKind,
6657 testConfigExternal.groupParams);
6658
6659 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6660 }
6661
6662 // depth_stencil
6663 {
6664 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6665 VK_SAMPLE_COUNT_1_BIT,
6666 VK_ATTACHMENT_LOAD_OP_CLEAR,
6667 VK_ATTACHMENT_STORE_OP_STORE,
6668 VK_ATTACHMENT_LOAD_OP_CLEAR,
6669 VK_ATTACHMENT_STORE_OP_STORE,
6670 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6671 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6672 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6673 0u,
6674 vector<AttachmentReference>(),
6675 vector<AttachmentReference>(),
6676 vector<AttachmentReference>(),
6677 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6678 vector<deUint32>())),
6679 vector<SubpassDependency>());
6680 const TestConfig testConfig (renderPass,
6681 TestConfig::RENDERTYPES_DRAW,
6682 TestConfig::COMMANDBUFFERTYPES_INLINE,
6683 TestConfig::IMAGEMEMORY_STRICT,
6684 targetSize,
6685 renderPos,
6686 renderSize,
6687 DE_FALSE,
6688 90239,
6689 0,
6690 testConfigExternal.allocationKind,
6691 testConfigExternal.groupParams);
6692
6693 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6694 }
6695
6696 // color_depth
6697 {
6698 const Attachment attachments[] =
6699 {
6700 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6701 VK_SAMPLE_COUNT_1_BIT,
6702 VK_ATTACHMENT_LOAD_OP_CLEAR,
6703 VK_ATTACHMENT_STORE_OP_STORE,
6704 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6705 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6706 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6707 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6708 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6709 VK_SAMPLE_COUNT_1_BIT,
6710 VK_ATTACHMENT_LOAD_OP_CLEAR,
6711 VK_ATTACHMENT_STORE_OP_STORE,
6712 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6713 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6714 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6715 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6716 };
6717
6718 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6719 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6720 0u,
6721 vector<AttachmentReference>(),
6722 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6723 vector<AttachmentReference>(),
6724 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6725 vector<deUint32>())),
6726 vector<SubpassDependency>());
6727 const TestConfig testConfig (renderPass,
6728 TestConfig::RENDERTYPES_DRAW,
6729 TestConfig::COMMANDBUFFERTYPES_INLINE,
6730 TestConfig::IMAGEMEMORY_STRICT,
6731 targetSize,
6732 renderPos,
6733 renderSize,
6734 DE_FALSE,
6735 90239,
6736 0,
6737 testConfigExternal.allocationKind,
6738 testConfigExternal.groupParams);
6739
6740 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, testConfig);
6741 }
6742
6743 // color_stencil
6744 {
6745 const Attachment attachments[] =
6746 {
6747 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6748 VK_SAMPLE_COUNT_1_BIT,
6749 VK_ATTACHMENT_LOAD_OP_CLEAR,
6750 VK_ATTACHMENT_STORE_OP_STORE,
6751 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6752 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6753 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6754 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6755 Attachment(VK_FORMAT_S8_UINT,
6756 VK_SAMPLE_COUNT_1_BIT,
6757 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6758 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6759 VK_ATTACHMENT_LOAD_OP_CLEAR,
6760 VK_ATTACHMENT_STORE_OP_STORE,
6761 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6762 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6763 };
6764
6765 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6766 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6767 0u,
6768 vector<AttachmentReference>(),
6769 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6770 vector<AttachmentReference>(),
6771 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6772 vector<deUint32>())),
6773 vector<SubpassDependency>());
6774 const TestConfig testConfig (renderPass,
6775 TestConfig::RENDERTYPES_DRAW,
6776 TestConfig::COMMANDBUFFERTYPES_INLINE,
6777 TestConfig::IMAGEMEMORY_STRICT,
6778 targetSize,
6779 renderPos,
6780 renderSize,
6781 DE_FALSE,
6782 90239,
6783 0,
6784 testConfigExternal.allocationKind,
6785 testConfigExternal.groupParams);
6786
6787 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6788 }
6789
6790 // color_depth_stencil
6791 {
6792 const Attachment attachments[] =
6793 {
6794 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6795 VK_SAMPLE_COUNT_1_BIT,
6796 VK_ATTACHMENT_LOAD_OP_CLEAR,
6797 VK_ATTACHMENT_STORE_OP_STORE,
6798 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6799 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6800 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6801 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6802 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6803 VK_SAMPLE_COUNT_1_BIT,
6804 VK_ATTACHMENT_LOAD_OP_CLEAR,
6805 VK_ATTACHMENT_STORE_OP_STORE,
6806 VK_ATTACHMENT_LOAD_OP_CLEAR,
6807 VK_ATTACHMENT_STORE_OP_STORE,
6808 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6809 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6810 };
6811
6812 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6813 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6814 0u,
6815 vector<AttachmentReference>(),
6816 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6817 vector<AttachmentReference>(),
6818 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6819 vector<deUint32>())),
6820 vector<SubpassDependency>());
6821 const TestConfig testConfig (renderPass,
6822 TestConfig::RENDERTYPES_DRAW,
6823 TestConfig::COMMANDBUFFERTYPES_INLINE,
6824 TestConfig::IMAGEMEMORY_STRICT,
6825 targetSize,
6826 renderPos,
6827 renderSize,
6828 DE_FALSE,
6829 90239,
6830 0,
6831 testConfigExternal.allocationKind,
6832 testConfigExternal.groupParams);
6833
6834 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6835 }
6836
6837 // no attachments
6838 {
6839 const RenderPass renderPass (vector<Attachment>(),
6840 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6841 0u,
6842 vector<AttachmentReference>(),
6843 vector<AttachmentReference>(),
6844 vector<AttachmentReference>(),
6845 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6846 vector<deUint32>())),
6847 vector<SubpassDependency>());
6848 const TestConfig testConfig (renderPass,
6849 TestConfig::RENDERTYPES_DRAW,
6850 TestConfig::COMMANDBUFFERTYPES_INLINE,
6851 TestConfig::IMAGEMEMORY_STRICT,
6852 targetSize,
6853 renderPos,
6854 renderSize,
6855 DE_FALSE,
6856 90239,
6857 0,
6858 testConfigExternal.allocationKind,
6859 testConfigExternal.groupParams);
6860
6861 addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", "No attachments case.", createTestShaders, renderPassTest, testConfig);
6862 }
6863
6864 // color_unused_omit_blend_state
6865 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
6866 {
6867 vector<Subpass> subpasses;
6868
6869 // First subpass: use color attachment, create pipeline with color blend state
6870 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6871 0u,
6872 vector<AttachmentReference>(),
6873 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6874 vector<AttachmentReference>(),
6875 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6876 vector<deUint32>(),
6877 false));
6878
6879 // Second subpass: don't use color attachment, create pipeline without color blend state
6880 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6881 0u,
6882 vector<AttachmentReference>(),
6883 vector<AttachmentReference>(1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6884 vector<AttachmentReference>(),
6885 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6886 vector<deUint32>(),
6887 true));
6888
6889 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6890 VK_SAMPLE_COUNT_1_BIT,
6891 VK_ATTACHMENT_LOAD_OP_CLEAR,
6892 VK_ATTACHMENT_STORE_OP_STORE,
6893 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6894 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6895 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6896 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6897 subpasses,
6898 vector<SubpassDependency>());
6899
6900 const TestConfig testConfig (renderPass,
6901 TestConfig::RENDERTYPES_DRAW,
6902 TestConfig::COMMANDBUFFERTYPES_INLINE,
6903 TestConfig::IMAGEMEMORY_STRICT,
6904 targetSize,
6905 renderPos,
6906 renderSize,
6907 DE_FALSE,
6908 90239,
6909 0,
6910 testConfigExternal.allocationKind,
6911 testConfigExternal.groupParams);
6912 addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state", "Two unused color attachment case without blend state", createTestShaders, renderPassTest, testConfig);
6913 }
6914 }
6915
formatToName(VkFormat format)6916 std::string formatToName (VkFormat format)
6917 {
6918 const std::string formatStr = de::toString(format);
6919 const std::string prefix = "VK_FORMAT_";
6920
6921 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
6922
6923 return de::toLower(formatStr.substr(prefix.length()));
6924 }
6925
addFormatTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6926 void addFormatTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6927 {
6928 tcu::TestContext& testCtx = group->getTestContext();
6929
6930 const UVec2 targetSize (64, 64);
6931 const UVec2 renderPos (0, 0);
6932 const UVec2 renderSize (64, 64);
6933
6934 const struct
6935 {
6936 const char* const str;
6937 const VkAttachmentStoreOp op;
6938 } storeOps[] =
6939 {
6940 { "store", VK_ATTACHMENT_STORE_OP_STORE },
6941 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
6942 };
6943
6944 const struct
6945 {
6946 const char* const str;
6947 const VkAttachmentLoadOp op;
6948 } loadOps[] =
6949 {
6950 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
6951 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
6952 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
6953 };
6954
6955 const struct
6956 {
6957 const char* const str;
6958 const TestConfig::RenderTypes types;
6959 } renderTypes[] =
6960 {
6961 { "clear", TestConfig::RENDERTYPES_CLEAR },
6962 { "draw", TestConfig::RENDERTYPES_DRAW },
6963 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
6964 };
6965
6966 // Color formats
6967 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
6968 {
6969 const VkFormat format = s_coreColorFormats[formatNdx];
6970 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
6971
6972 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6973 {
6974 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
6975 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6976
6977 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6978 {
6979 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
6980 VK_SAMPLE_COUNT_1_BIT,
6981 loadOp,
6982 VK_ATTACHMENT_STORE_OP_STORE,
6983 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6984 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6985 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6986 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6987 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6988 0u,
6989 vector<AttachmentReference>(),
6990 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6991 vector<AttachmentReference>(),
6992 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6993 vector<deUint32>())),
6994 vector<SubpassDependency>());
6995 const TestConfig testConfig (renderPass,
6996 renderTypes[renderTypeNdx].types,
6997 TestConfig::COMMANDBUFFERTYPES_INLINE,
6998 TestConfig::IMAGEMEMORY_STRICT,
6999 targetSize,
7000 renderPos,
7001 renderSize,
7002 DE_FALSE,
7003 90239,
7004 0,
7005 testConfigExternal.allocationKind,
7006 testConfigExternal.groupParams);
7007
7008 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7009 }
7010
7011 formatGroup->addChild(loadOpGroup.release());
7012 }
7013
7014 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7015 {
7016 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
7017
7018 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7019 {
7020 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7021 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7022
7023 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7024 {
7025 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
7026 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
7027 : static_cast<VkImageAspectFlags>(0);
7028 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
7029 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
7030
7031 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7032 {
7033 const bool useInputAspect = useInputAspectNdx != 0;
7034
7035 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
7036 continue;
7037
7038 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7039 {
7040 {
7041 vector<Attachment> attachments;
7042 vector<Subpass> subpasses;
7043 vector<SubpassDependency> deps;
7044 vector<VkInputAttachmentAspectReference> inputAspects;
7045
7046 attachments.push_back(Attachment(format,
7047 VK_SAMPLE_COUNT_1_BIT,
7048 loadOp,
7049 storeOp,
7050 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7051 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7052 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7053 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7054
7055 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7056 VK_SAMPLE_COUNT_1_BIT,
7057 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7058 VK_ATTACHMENT_STORE_OP_STORE,
7059 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7060 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7061 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7062 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7063
7064 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7065 0u,
7066 vector<AttachmentReference>(),
7067 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7068 vector<AttachmentReference>(),
7069 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7070 vector<deUint32>()));
7071 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7072 0u,
7073 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7074 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7075 vector<AttachmentReference>(),
7076 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7077 vector<deUint32>()));
7078
7079 deps.push_back(SubpassDependency(0, 1,
7080
7081 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7082 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7083
7084 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7085 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7086 vk::VK_DEPENDENCY_BY_REGION_BIT));
7087
7088 if (useInputAspect)
7089 {
7090 const VkInputAttachmentAspectReference inputAspect =
7091 {
7092 1u,
7093 0u,
7094 VK_IMAGE_ASPECT_COLOR_BIT
7095 };
7096
7097 inputAspects.push_back(inputAspect);
7098 }
7099
7100 {
7101 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7102 const TestConfig testConfig (renderPass,
7103 renderTypes[renderTypeNdx].types,
7104 TestConfig::COMMANDBUFFERTYPES_INLINE,
7105 TestConfig::IMAGEMEMORY_STRICT,
7106 targetSize,
7107 renderPos,
7108 renderSize,
7109 DE_FALSE,
7110 89246,
7111 0,
7112 testConfigExternal.allocationKind,
7113 testConfigExternal.groupParams);
7114 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
7115
7116 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7117 }
7118 }
7119 {
7120 vector<Attachment> attachments;
7121 vector<Subpass> subpasses;
7122 vector<SubpassDependency> deps;
7123 vector<VkInputAttachmentAspectReference> inputAspects;
7124
7125 attachments.push_back(Attachment(format,
7126 VK_SAMPLE_COUNT_1_BIT,
7127 loadOp,
7128 storeOp,
7129 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7130 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7131 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7132 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7133
7134 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7135 0u,
7136 vector<AttachmentReference>(),
7137 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7138 vector<AttachmentReference>(),
7139 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7140 vector<deUint32>()));
7141 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7142 0u,
7143 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7144 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
7145 vector<AttachmentReference>(),
7146 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7147 vector<deUint32>()));
7148
7149 deps.push_back(SubpassDependency(0, 1,
7150 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7151 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7152
7153 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7154 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7155 vk::VK_DEPENDENCY_BY_REGION_BIT));
7156
7157 deps.push_back(SubpassDependency(1, 1,
7158 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7159 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7160
7161 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7162 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7163 vk::VK_DEPENDENCY_BY_REGION_BIT));
7164
7165 if (useInputAspect)
7166 {
7167 const VkInputAttachmentAspectReference inputAspect =
7168 {
7169 1u,
7170 0u,
7171 VK_IMAGE_ASPECT_COLOR_BIT
7172 };
7173
7174 inputAspects.push_back(inputAspect);
7175 }
7176
7177 {
7178 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7179 const TestConfig testConfig (renderPass,
7180 renderTypes[renderTypeNdx].types,
7181 TestConfig::COMMANDBUFFERTYPES_INLINE,
7182 TestConfig::IMAGEMEMORY_STRICT,
7183 targetSize,
7184 renderPos,
7185 renderSize,
7186 DE_FALSE,
7187 89246,
7188 0,
7189 testConfigExternal.allocationKind,
7190 testConfigExternal.groupParams);
7191 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
7192
7193 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7194 }
7195 }
7196 }
7197 }
7198
7199 loadOpGroup->addChild(storeOpGroup.release());
7200 }
7201
7202 inputGroup->addChild(loadOpGroup.release());
7203 }
7204
7205 formatGroup->addChild(inputGroup.release());
7206 }
7207
7208 group->addChild(formatGroup.release());
7209 }
7210
7211 // Depth stencil formats
7212 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
7213 {
7214 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
7215 const tcu::TextureFormat format = mapVkFormat(vkFormat);
7216 const bool isStencilAttachment = hasStencilComponent(format.order);
7217 const bool isDepthAttachment = hasDepthComponent(format.order);
7218 const VkImageAspectFlags formatAspectFlags = (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7219 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
7220 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
7221
7222 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7223 {
7224 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7225 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7226
7227 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7228 {
7229 {
7230 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
7231 VK_SAMPLE_COUNT_1_BIT,
7232 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7233 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7234 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7235 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7236 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7237 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7238 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7239 0u,
7240 vector<AttachmentReference>(),
7241 vector<AttachmentReference>(),
7242 vector<AttachmentReference>(),
7243 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7244 vector<deUint32>())),
7245 vector<SubpassDependency>());
7246 const TestConfig testConfig (renderPass,
7247 renderTypes[renderTypeNdx].types,
7248 TestConfig::COMMANDBUFFERTYPES_INLINE,
7249 TestConfig::IMAGEMEMORY_STRICT,
7250 targetSize,
7251 renderPos,
7252 renderSize,
7253 DE_FALSE,
7254 90239,
7255 0,
7256 testConfigExternal.allocationKind,
7257 testConfigExternal.groupParams);
7258
7259 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7260 }
7261
7262 if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
7263 {
7264 {
7265 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
7266 VK_SAMPLE_COUNT_1_BIT,
7267 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7268 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7269 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7270 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7271 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7272 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7273 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7274 0u,
7275 vector<AttachmentReference>(),
7276 vector<AttachmentReference>(),
7277 vector<AttachmentReference>(),
7278 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7279 vector<deUint32>())),
7280 vector<SubpassDependency>());
7281 const TestConfig testConfig (renderPass,
7282 renderTypes[renderTypeNdx].types,
7283 TestConfig::COMMANDBUFFERTYPES_INLINE,
7284 TestConfig::IMAGEMEMORY_STRICT,
7285 targetSize,
7286 renderPos,
7287 renderSize,
7288 DE_FALSE,
7289 90239,
7290 0,
7291 testConfigExternal.allocationKind,
7292 testConfigExternal.groupParams);
7293 const string testName (string(renderTypes[renderTypeNdx].str) + "_depth_read_only");
7294
7295 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7296 }
7297
7298 {
7299 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
7300 VK_SAMPLE_COUNT_1_BIT,
7301 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7302 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7303 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7304 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7305 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7306 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7307 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7308 0u,
7309 vector<AttachmentReference>(),
7310 vector<AttachmentReference>(),
7311 vector<AttachmentReference>(),
7312 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7313 vector<deUint32>())),
7314 vector<SubpassDependency>());
7315 const TestConfig testConfig (renderPass,
7316 renderTypes[renderTypeNdx].types,
7317 TestConfig::COMMANDBUFFERTYPES_INLINE,
7318 TestConfig::IMAGEMEMORY_STRICT,
7319 targetSize,
7320 renderPos,
7321 renderSize,
7322 DE_FALSE,
7323 90239,
7324 0,
7325 testConfigExternal.allocationKind,
7326 testConfigExternal.groupParams);
7327 const string testName (string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");
7328
7329 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7330 }
7331 }
7332 }
7333
7334 formatGroup->addChild(loadOpGroup.release());
7335 }
7336
7337 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7338 {
7339 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
7340
7341 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7342 {
7343 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
7344 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7345
7346 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7347 {
7348 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
7349 ? formatAspectFlags
7350 : static_cast<VkImageAspectFlags>(0);
7351 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
7352 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
7353
7354 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7355 {
7356 const bool useInputAspect = useInputAspectNdx != 0;
7357
7358 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
7359 continue;
7360
7361 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7362 {
7363 {
7364 vector<Attachment> attachments;
7365 vector<Subpass> subpasses;
7366 vector<SubpassDependency> deps;
7367 vector<VkInputAttachmentAspectReference> inputAspects;
7368
7369 attachments.push_back(Attachment(vkFormat,
7370 VK_SAMPLE_COUNT_1_BIT,
7371 loadOp,
7372 storeOp,
7373 loadOp,
7374 storeOp,
7375 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7376 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7377
7378 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7379 VK_SAMPLE_COUNT_1_BIT,
7380 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7381 VK_ATTACHMENT_STORE_OP_STORE,
7382 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7383 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7384 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7385 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7386
7387 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7388 0u,
7389 vector<AttachmentReference>(),
7390 vector<AttachmentReference>(),
7391 vector<AttachmentReference>(),
7392 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7393 vector<deUint32>()));
7394 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7395 0u,
7396 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7397 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7398 vector<AttachmentReference>(),
7399 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7400 vector<deUint32>()));
7401
7402 deps.push_back(SubpassDependency(0, 1,
7403 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7404 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7405
7406 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7407 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7408 0u));
7409
7410 if (useInputAspect)
7411 {
7412 const VkInputAttachmentAspectReference inputAspect =
7413 {
7414 1u,
7415 0u,
7416 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7417 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7418 };
7419
7420 inputAspects.push_back(inputAspect);
7421 }
7422
7423 {
7424 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7425 const TestConfig testConfig (renderPass,
7426 renderTypes[renderTypeNdx].types,
7427 TestConfig::COMMANDBUFFERTYPES_INLINE,
7428 TestConfig::IMAGEMEMORY_STRICT,
7429 targetSize,
7430 renderPos,
7431 renderSize,
7432 DE_FALSE,
7433 89246,
7434 0,
7435 testConfigExternal.allocationKind,
7436 testConfigExternal.groupParams);
7437 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
7438
7439 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7440 }
7441 }
7442 {
7443 vector<Attachment> attachments;
7444 vector<Subpass> subpasses;
7445 vector<SubpassDependency> deps;
7446 vector<VkInputAttachmentAspectReference> inputAspects;
7447
7448 attachments.push_back(Attachment(vkFormat,
7449 VK_SAMPLE_COUNT_1_BIT,
7450 loadOp,
7451 storeOp,
7452 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7453 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7454 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7455 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7456
7457 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7458 0u,
7459 vector<AttachmentReference>(),
7460 vector<AttachmentReference>(),
7461 vector<AttachmentReference>(),
7462 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7463 vector<deUint32>()));
7464 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7465 0u,
7466 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7467 vector<AttachmentReference>(),
7468 vector<AttachmentReference>(),
7469 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
7470 vector<deUint32>()));
7471
7472 deps.push_back(SubpassDependency(0, 1,
7473 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7474 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7475
7476 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7477 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7478 vk::VK_DEPENDENCY_BY_REGION_BIT));
7479
7480 deps.push_back(SubpassDependency(1, 1,
7481 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7482 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7483 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7484 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7485 vk::VK_DEPENDENCY_BY_REGION_BIT));
7486
7487
7488 if (useInputAspect)
7489 {
7490 const VkInputAttachmentAspectReference inputAspect =
7491 {
7492 1u,
7493 0u,
7494
7495 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7496 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7497 };
7498
7499 inputAspects.push_back(inputAspect);
7500 }
7501
7502 {
7503 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7504 const TestConfig testConfig (renderPass,
7505 renderTypes[renderTypeNdx].types,
7506 TestConfig::COMMANDBUFFERTYPES_INLINE,
7507 TestConfig::IMAGEMEMORY_STRICT,
7508 targetSize,
7509 renderPos,
7510 renderSize,
7511 DE_FALSE,
7512 89246,
7513 0,
7514 testConfigExternal.allocationKind,
7515 testConfigExternal.groupParams);
7516 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
7517
7518 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7519 }
7520 }
7521
7522 if (isStencilAttachment && isDepthAttachment)
7523 {
7524 // Depth read only
7525 {
7526 vector<Attachment> attachments;
7527 vector<Subpass> subpasses;
7528 vector<SubpassDependency> deps;
7529 vector<VkInputAttachmentAspectReference> inputAspects;
7530
7531 attachments.push_back(Attachment(vkFormat,
7532 VK_SAMPLE_COUNT_1_BIT,
7533 loadOp,
7534 storeOp,
7535 loadOp,
7536 storeOp,
7537 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7538 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7539
7540 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7541 VK_SAMPLE_COUNT_1_BIT,
7542 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7543 VK_ATTACHMENT_STORE_OP_STORE,
7544 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7545 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7546 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7547 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7548
7549 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7550 0u,
7551 vector<AttachmentReference>(),
7552 vector<AttachmentReference>(),
7553 vector<AttachmentReference>(),
7554 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7555 vector<deUint32>()));
7556 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7557 0u,
7558 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7559 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7560 vector<AttachmentReference>(),
7561 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7562 vector<deUint32>()));
7563
7564 deps.push_back(SubpassDependency(0, 1,
7565 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7566 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7567
7568 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7569 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7570 0u));
7571
7572 if (useInputAspect)
7573 {
7574 const VkInputAttachmentAspectReference inputAspect =
7575 {
7576 1u,
7577 0u,
7578
7579 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7580 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7581 };
7582
7583 inputAspects.push_back(inputAspect);
7584 }
7585
7586 {
7587 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7588 const TestConfig testConfig (renderPass,
7589 renderTypes[renderTypeNdx].types,
7590 TestConfig::COMMANDBUFFERTYPES_INLINE,
7591 TestConfig::IMAGEMEMORY_STRICT,
7592 targetSize,
7593 renderPos,
7594 renderSize,
7595 DE_FALSE,
7596 89246,
7597 0,
7598 testConfigExternal.allocationKind,
7599 testConfigExternal.groupParams);
7600 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7601
7602 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7603 }
7604 }
7605 {
7606 vector<Attachment> attachments;
7607 vector<Subpass> subpasses;
7608 vector<SubpassDependency> deps;
7609 vector<VkInputAttachmentAspectReference> inputAspects;
7610
7611 attachments.push_back(Attachment(vkFormat,
7612 VK_SAMPLE_COUNT_1_BIT,
7613 loadOp,
7614 storeOp,
7615 loadOp,
7616 storeOp,
7617 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7618 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7619
7620 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7621 0u,
7622 vector<AttachmentReference>(),
7623 vector<AttachmentReference>(),
7624 vector<AttachmentReference>(),
7625 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7626 vector<deUint32>()));
7627 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7628 0u,
7629 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7630 vector<AttachmentReference>(),
7631 vector<AttachmentReference>(),
7632 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7633 vector<deUint32>()));
7634
7635 deps.push_back(SubpassDependency(0, 1,
7636 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7637 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7638
7639 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7640 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7641 vk::VK_DEPENDENCY_BY_REGION_BIT));
7642
7643 deps.push_back(SubpassDependency(1, 1,
7644 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7645 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7646
7647 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7648 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7649 vk::VK_DEPENDENCY_BY_REGION_BIT));
7650
7651 if (useInputAspect)
7652 {
7653 const VkInputAttachmentAspectReference inputAspect =
7654 {
7655 1u,
7656 0u,
7657
7658 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7659 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7660 };
7661
7662 inputAspects.push_back(inputAspect);
7663 }
7664
7665 {
7666 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7667 const TestConfig testConfig (renderPass,
7668 renderTypes[renderTypeNdx].types,
7669 TestConfig::COMMANDBUFFERTYPES_INLINE,
7670 TestConfig::IMAGEMEMORY_STRICT,
7671 targetSize,
7672 renderPos,
7673 renderSize,
7674 DE_FALSE,
7675 89246,
7676 0,
7677 testConfigExternal.allocationKind,
7678 testConfigExternal.groupParams);
7679 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7680
7681 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7682 }
7683 }
7684 // Stencil read only
7685 {
7686 vector<Attachment> attachments;
7687 vector<Subpass> subpasses;
7688 vector<SubpassDependency> deps;
7689 vector<VkInputAttachmentAspectReference> inputAspects;
7690
7691 attachments.push_back(Attachment(vkFormat,
7692 VK_SAMPLE_COUNT_1_BIT,
7693 loadOp,
7694 storeOp,
7695 loadOp,
7696 storeOp,
7697 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7698 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7699
7700 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7701 VK_SAMPLE_COUNT_1_BIT,
7702 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7703 VK_ATTACHMENT_STORE_OP_STORE,
7704 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7705 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7706 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7707 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7708
7709 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7710 0u,
7711 vector<AttachmentReference>(),
7712 vector<AttachmentReference>(),
7713 vector<AttachmentReference>(),
7714 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7715 vector<deUint32>()));
7716 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7717 0u,
7718 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7719 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7720 vector<AttachmentReference>(),
7721 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7722 vector<deUint32>()));
7723
7724 deps.push_back(SubpassDependency(0, 1,
7725 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7726 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7727
7728 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7729 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7730 0u));
7731
7732 if (useInputAspect)
7733 {
7734 const VkInputAttachmentAspectReference inputAspect =
7735 {
7736 1u,
7737 0u,
7738
7739 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7740 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7741 };
7742
7743 inputAspects.push_back(inputAspect);
7744 }
7745
7746 {
7747 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7748 const TestConfig testConfig (renderPass,
7749 renderTypes[renderTypeNdx].types,
7750 TestConfig::COMMANDBUFFERTYPES_INLINE,
7751 TestConfig::IMAGEMEMORY_STRICT,
7752 targetSize,
7753 renderPos,
7754 renderSize,
7755 DE_FALSE,
7756 89246,
7757 0,
7758 testConfigExternal.allocationKind,
7759 testConfigExternal.groupParams);
7760 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7761
7762 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7763 }
7764 }
7765 {
7766 vector<Attachment> attachments;
7767 vector<Subpass> subpasses;
7768 vector<SubpassDependency> deps;
7769 vector<VkInputAttachmentAspectReference> inputAspects;
7770
7771 attachments.push_back(Attachment(vkFormat,
7772 VK_SAMPLE_COUNT_1_BIT,
7773 loadOp,
7774 storeOp,
7775 loadOp,
7776 storeOp,
7777 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7778 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7779
7780 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7781 0u,
7782 vector<AttachmentReference>(),
7783 vector<AttachmentReference>(),
7784 vector<AttachmentReference>(),
7785 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7786 vector<deUint32>()));
7787 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7788 0u,
7789 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7790 vector<AttachmentReference>(),
7791 vector<AttachmentReference>(),
7792 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7793 vector<deUint32>()));
7794
7795 deps.push_back(SubpassDependency(0, 1,
7796 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7797 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7798
7799 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7800 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7801 vk::VK_DEPENDENCY_BY_REGION_BIT));
7802
7803 deps.push_back(SubpassDependency(1, 1,
7804 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7805 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7806
7807 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7808 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7809 vk::VK_DEPENDENCY_BY_REGION_BIT));
7810
7811
7812 if (useInputAspect)
7813 {
7814 const VkInputAttachmentAspectReference inputAspect =
7815 {
7816 1u,
7817 0u,
7818
7819 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7820 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7821 };
7822
7823 inputAspects.push_back(inputAspect);
7824 }
7825
7826 {
7827 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7828 const TestConfig testConfig (renderPass,
7829 renderTypes[renderTypeNdx].types,
7830 TestConfig::COMMANDBUFFERTYPES_INLINE,
7831 TestConfig::IMAGEMEMORY_STRICT,
7832 targetSize,
7833 renderPos,
7834 renderSize,
7835 DE_FALSE,
7836 89246,
7837 0,
7838 testConfigExternal.allocationKind,
7839 testConfigExternal.groupParams);
7840 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7841
7842 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7843 }
7844 }
7845 }
7846 }
7847 }
7848
7849 loadOpGroup->addChild(storeOpGroup.release());
7850 }
7851
7852 inputGroup->addChild(loadOpGroup.release());
7853 }
7854
7855 formatGroup->addChild(inputGroup.release());
7856 }
7857
7858 group->addChild(formatGroup.release());
7859 }
7860 }
7861
addRenderPassTests(tcu::TestCaseGroup * group,const AllocationKind allocationKind,const SharedGroupParams groupParams)7862 void addRenderPassTests (tcu::TestCaseGroup* group, const AllocationKind allocationKind, const SharedGroupParams groupParams)
7863 {
7864 // tests added by this function have both primary and secondary cases and there is no need to repeat them for useSecondaryCmdBuffer flag;
7865 // but cases defined in other files that are later added to those groups in createRenderPassTestsInternal had to be adjusted and run
7866 // for useSecondaryCmdBuffer flag
7867 if (groupParams->useSecondaryCmdBuffer && !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7868 return;
7869
7870 const TestConfigExternal testConfigExternal (allocationKind, groupParams);
7871
7872 // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7873 if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7874 {
7875 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, testConfigExternal);
7876 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, testConfigExternal);
7877 }
7878
7879 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, testConfigExternal);
7880
7881 // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7882 if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7883 addTestGroup(group, "attachment_write_mask", "Attachment write mask tests", addAttachmentWriteMaskTests, testConfigExternal);
7884
7885 if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7886 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, testConfigExternal);
7887 }
7888
createSuballocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)7889 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7890 {
7891 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
7892
7893 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, groupParams);
7894
7895 return suballocationTestsGroup;
7896 }
7897
createDedicatedAllocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)7898 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7899 {
7900 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
7901
7902 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, groupParams);
7903
7904 return dedicatedAllocationTestsGroup;
7905 }
7906
createRenderPassTestsInternal(tcu::TestContext & testCtx,const char * groupName,const SharedGroupParams groupParams)7907 tcu::TestCaseGroup* createRenderPassTestsInternal (tcu::TestContext& testCtx, const char* groupName, const SharedGroupParams groupParams)
7908 {
7909 de::MovePtr<tcu::TestCaseGroup> renderingTests (new tcu::TestCaseGroup(testCtx, groupName, ""));
7910 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx, groupParams);
7911 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx, groupParams);
7912 de::MovePtr<tcu::TestCaseGroup> noDrawGroup {new tcu::TestCaseGroup{testCtx, "no_draws", ""}};
7913
7914 const RenderingType renderingType = groupParams->renderingType;
7915
7916 switch (renderingType)
7917 {
7918 case RENDERING_TYPE_RENDERPASS_LEGACY:
7919 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
7920 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx, groupParams));
7921 suballocationTestGroup->addChild(createRenderPassSubpassDependencyTests(testCtx));
7922 suballocationTestGroup->addChild(createRenderPassSampleReadTests(testCtx));
7923 noDrawGroup->addChild(new RenderPassNoDrawLoadStoreTestCase(testCtx, "render_pass_no_draw_clear_load_store", "Test clears in a renderpass with no drawing commands", false));
7924
7925 #ifndef CTS_USES_VULKANSC
7926 suballocationTestGroup->addChild(createRenderPassSparseRenderTargetTests(testCtx, groupParams));
7927 renderingTests->addChild(createDepthStencilWriteConditionsTests(testCtx));
7928 #endif // CTS_USES_VULKANSC
7929
7930 renderingTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));
7931
7932 break;
7933
7934 case RENDERING_TYPE_RENDERPASS2:
7935 suballocationTestGroup->addChild(createRenderPass2MultisampleTests(testCtx));
7936 suballocationTestGroup->addChild(createRenderPass2MultisampleResolveTests(testCtx, groupParams));
7937 suballocationTestGroup->addChild(createRenderPass2SubpassDependencyTests(testCtx));
7938 suballocationTestGroup->addChild(createRenderPass2SampleReadTests(testCtx));
7939 noDrawGroup->addChild(new RenderPassNoDrawLoadStoreTestCase(testCtx, "render_pass2_no_draw_clear_load_store", "Test clears in a renderpass with no drawing commands", true));
7940
7941 #ifndef CTS_USES_VULKANSC
7942 suballocationTestGroup->addChild(createRenderPass2SparseRenderTargetTests(testCtx, groupParams));
7943 #endif // CTS_USES_VULKANSC
7944
7945 renderingTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
7946 break;
7947
7948 #ifndef CTS_USES_VULKANSC
7949 case RENDERING_TYPE_DYNAMIC_RENDERING:
7950 suballocationTestGroup->addChild(createDynamicRenderingMultisampleResolveTests(testCtx, groupParams));
7951 suballocationTestGroup->addChild(createDynamicRenderingSparseRenderTargetTests(testCtx, groupParams));
7952
7953 if (groupParams->useSecondaryCmdBuffer == false)
7954 {
7955 renderingTests->addChild(createDynamicRenderingRandomTests(testCtx));
7956 renderingTests->addChild(createDynamicRenderingBasicTests(testCtx));
7957 }
7958 break;
7959 #endif // CTS_USES_VULKANSC
7960
7961 default:
7962 break;
7963 }
7964
7965 if (renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7966 {
7967 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderingType));
7968 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderingType));
7969 }
7970
7971 suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, groupParams));
7972
7973 #ifndef CTS_USES_VULKANSC
7974 suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, groupParams));
7975
7976 if (renderingType == RENDERING_TYPE_RENDERPASS2)
7977 {
7978 suballocationTestGroup->addChild(createRenderPassSubpassMergeFeedbackTests(testCtx, renderingType));
7979 }
7980
7981 renderingTests->addChild(createFragmentDensityMapTests(testCtx, groupParams));
7982 renderingTests->addChild(createRenderPassDitheringTests(testCtx, renderingType));
7983 #endif // CTS_USES_VULKANSC
7984
7985 renderingTests->addChild(suballocationTestGroup.release());
7986 renderingTests->addChild(dedicatedAllocationTestGroup.release());
7987 renderingTests->addChild(noDrawGroup.release());
7988
7989 return renderingTests.release();
7990 }
7991
7992 } // anonymous
7993
createRenderPassTests(tcu::TestContext & testCtx)7994 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
7995 {
7996 SharedGroupParams groupParams(
7997 new GroupParams
7998 {
7999 RENDERING_TYPE_RENDERPASS_LEGACY, // RenderingType renderingType;
8000 false, // bool useSecondaryCmdBuffer;
8001 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8002 });
8003 return createRenderPassTestsInternal(testCtx, "renderpass", groupParams);
8004 }
8005
createRenderPass2Tests(tcu::TestContext & testCtx)8006 tcu::TestCaseGroup* createRenderPass2Tests (tcu::TestContext& testCtx)
8007 {
8008 SharedGroupParams groupParams(
8009 new GroupParams
8010 {
8011 RENDERING_TYPE_RENDERPASS2, // RenderingType renderingType;
8012 false, // bool useSecondaryCmdBuffer;
8013 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8014 });
8015 return createRenderPassTestsInternal(testCtx, "renderpass2", groupParams);
8016 }
8017
createDynamicRenderingTests(tcu::TestContext & testCtx)8018 tcu::TestCaseGroup* createDynamicRenderingTests(tcu::TestContext& testCtx)
8019 {
8020 de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup(new tcu::TestCaseGroup(testCtx, "dynamic_rendering", "Draw using VK_KHR_dynamic_rendering"));
8021
8022 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "primary_cmd_buff", SharedGroupParams(
8023 new GroupParams
8024 {
8025 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8026 false, // bool useSecondaryCmdBuffer;
8027 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8028 })));
8029 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "partial_secondary_cmd_buff", SharedGroupParams(
8030 new GroupParams
8031 {
8032 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8033 true, // bool useSecondaryCmdBuffer;
8034 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8035 })));
8036 dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "complete_secondary_cmd_buff", SharedGroupParams(
8037 new GroupParams
8038 {
8039 RENDERING_TYPE_DYNAMIC_RENDERING, // RenderingType renderingType;
8040 true, // bool useSecondaryCmdBuffer;
8041 true, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8042 })));
8043
8044 return dynamicRenderingGroup.release();
8045 }
8046
8047 } // vkt
8048