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