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