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