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