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