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