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