1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief RenderPass tests
33 *//*--------------------------------------------------------------------*/
35 #include "vktRenderPassTests.hpp"
37 #include "vktTestCaseUtil.hpp"
40 #include "vkDeviceUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkPlatform.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkQueryUtil.hpp"
47 #include "vkRefUtil.hpp"
48 #include "vkStrUtil.hpp"
49 #include "vkTypeUtil.hpp"
51 #include "tcuTestLog.hpp"
52 #include "tcuResultCollector.hpp"
53 #include "tcuFormatUtil.hpp"
54 #include "tcuTextureUtil.hpp"
55 #include "tcuFloat.hpp"
56 #include "tcuMaybe.hpp"
57 #include "tcuVectorUtil.hpp"
59 #include "deUniquePtr.hpp"
60 #include "deSharedPtr.hpp"
61 #include "deStringUtil.hpp"
62 #include "deSTLUtil.hpp"
63 #include "deRandom.hpp"
80 using tcu::ConstPixelBufferAccess;
81 using tcu::PixelBufferAccess;
95 // Limit integer values that are representable as floats
96 MAX_INTEGER_VALUE = ((1u<<22u)-1u)
99 // Utility functions using flattened structs
100 Move<VkFence> createFence (const DeviceInterface& vk, VkDevice device, VkFenceCreateFlags flags)
102 const VkFenceCreateInfo pCreateInfo =
104 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
109 return createFence(vk, device, &pCreateInfo);
112 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
114 VkFramebufferCreateFlags pCreateInfo_flags,
115 VkRenderPass pCreateInfo_renderPass,
116 deUint32 pCreateInfo_attachmentCount,
117 const VkImageView* pCreateInfo_pAttachments,
118 deUint32 pCreateInfo_width,
119 deUint32 pCreateInfo_height,
120 deUint32 pCreateInfo_layers)
122 const VkFramebufferCreateInfo pCreateInfo =
124 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
127 pCreateInfo_renderPass,
128 pCreateInfo_attachmentCount,
129 pCreateInfo_pAttachments,
134 return createFramebuffer(vk, device, &pCreateInfo);
137 Move<VkImage> createImage (const DeviceInterface& vk,
139 VkImageCreateFlags pCreateInfo_flags,
140 VkImageType pCreateInfo_imageType,
141 VkFormat pCreateInfo_format,
142 VkExtent3D pCreateInfo_extent,
143 deUint32 pCreateInfo_mipLevels,
144 deUint32 pCreateInfo_arrayLayers,
145 VkSampleCountFlagBits pCreateInfo_samples,
146 VkImageTiling pCreateInfo_tiling,
147 VkImageUsageFlags pCreateInfo_usage,
148 VkSharingMode pCreateInfo_sharingMode,
149 deUint32 pCreateInfo_queueFamilyCount,
150 const deUint32* pCreateInfo_pQueueFamilyIndices,
151 VkImageLayout pCreateInfo_initialLayout)
153 const VkImageCreateInfo pCreateInfo =
155 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
158 pCreateInfo_imageType,
161 pCreateInfo_mipLevels,
162 pCreateInfo_arrayLayers,
166 pCreateInfo_sharingMode,
167 pCreateInfo_queueFamilyCount,
168 pCreateInfo_pQueueFamilyIndices,
169 pCreateInfo_initialLayout
171 return createImage(vk, device, &pCreateInfo);
174 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
176 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
179 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
181 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
184 Move<VkImageView> createImageView (const DeviceInterface& vk,
186 VkImageViewCreateFlags pCreateInfo_flags,
187 VkImage pCreateInfo_image,
188 VkImageViewType pCreateInfo_viewType,
189 VkFormat pCreateInfo_format,
190 VkComponentMapping pCreateInfo_components,
191 VkImageSubresourceRange pCreateInfo_subresourceRange)
193 const VkImageViewCreateInfo pCreateInfo =
195 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
199 pCreateInfo_viewType,
201 pCreateInfo_components,
202 pCreateInfo_subresourceRange,
204 return createImageView(vk, device, &pCreateInfo);
207 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
209 VkBufferCreateFlags pCreateInfo_flags,
210 VkDeviceSize pCreateInfo_size,
211 VkBufferUsageFlags pCreateInfo_usage,
212 VkSharingMode pCreateInfo_sharingMode,
213 deUint32 pCreateInfo_queueFamilyCount,
214 const deUint32* pCreateInfo_pQueueFamilyIndices)
216 const VkBufferCreateInfo pCreateInfo =
218 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
223 pCreateInfo_sharingMode,
224 pCreateInfo_queueFamilyCount,
225 pCreateInfo_pQueueFamilyIndices,
227 return createBuffer(vk, device, &pCreateInfo);
230 Move<VkCommandPool> createCommandPool (const DeviceInterface& vk,
232 VkCommandPoolCreateFlags pCreateInfo_flags,
233 deUint32 pCreateInfo_queueFamilyIndex)
235 const VkCommandPoolCreateInfo pCreateInfo =
237 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
240 pCreateInfo_queueFamilyIndex,
242 return createCommandPool(vk, device, &pCreateInfo);
245 void cmdBeginRenderPass (const DeviceInterface& vk,
246 VkCommandBuffer cmdBuffer,
247 VkRenderPass pRenderPassBegin_renderPass,
248 VkFramebuffer pRenderPassBegin_framebuffer,
249 VkRect2D pRenderPassBegin_renderArea,
250 deUint32 pRenderPassBegin_clearValueCount,
251 const VkClearValue* pRenderPassBegin_pAttachmentClearValues,
252 VkSubpassContents contents)
254 const VkRenderPassBeginInfo pRenderPassBegin =
256 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
258 pRenderPassBegin_renderPass,
259 pRenderPassBegin_framebuffer,
260 pRenderPassBegin_renderArea,
261 pRenderPassBegin_clearValueCount,
262 pRenderPassBegin_pAttachmentClearValues,
264 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
267 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface& vk,
269 VkCommandPool pCreateInfo_commandPool,
270 VkCommandBufferLevel pCreateInfo_level)
272 const VkCommandBufferAllocateInfo pAllocateInfo =
274 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
276 pCreateInfo_commandPool,
280 return allocateCommandBuffer(vk, device, &pAllocateInfo);
283 void beginCommandBuffer (const DeviceInterface& vk,
284 VkCommandBuffer cmdBuffer,
285 VkCommandBufferUsageFlags pBeginInfo_flags,
286 VkRenderPass pInheritanceInfo_renderPass,
287 deUint32 pInheritanceInfo_subpass,
288 VkFramebuffer pInheritanceInfo_framebuffer,
289 VkBool32 pInheritanceInfo_occlusionQueryEnable,
290 VkQueryControlFlags pInheritanceInfo_queryFlags,
291 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
293 const VkCommandBufferInheritanceInfo pInheritanceInfo =
295 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
297 pInheritanceInfo_renderPass,
298 pInheritanceInfo_subpass,
299 pInheritanceInfo_framebuffer,
300 pInheritanceInfo_occlusionQueryEnable,
301 pInheritanceInfo_queryFlags,
302 pInheritanceInfo_pipelineStatistics,
304 const VkCommandBufferBeginInfo pBeginInfo =
306 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
311 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
314 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
316 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
319 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
321 const VkSubmitInfo submitInfo =
323 VK_STRUCTURE_TYPE_SUBMIT_INFO,
325 0u, // waitSemaphoreCount
326 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
327 (const VkPipelineStageFlags*)DE_NULL,
328 cmdBufferCount, // commandBufferCount
330 0u, // signalSemaphoreCount
331 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
333 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
336 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
338 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
341 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
343 const tcu::TextureFormat format = mapVkFormat(vkFormat);
345 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
347 switch (format.order)
349 case tcu::TextureFormat::DS:
350 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
352 case tcu::TextureFormat::D:
353 return VK_IMAGE_ASPECT_DEPTH_BIT;
355 case tcu::TextureFormat::S:
356 return VK_IMAGE_ASPECT_STENCIL_BIT;
359 return VK_IMAGE_ASPECT_COLOR_BIT;
363 VkAccessFlags getAllMemoryReadFlags (void)
365 return VK_ACCESS_TRANSFER_READ_BIT
366 | VK_ACCESS_UNIFORM_READ_BIT
367 | VK_ACCESS_HOST_READ_BIT
368 | VK_ACCESS_INDEX_READ_BIT
369 | VK_ACCESS_SHADER_READ_BIT
370 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
371 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
372 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
373 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
374 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
377 VkAccessFlags getAllMemoryWriteFlags (void)
379 return VK_ACCESS_TRANSFER_WRITE_BIT
380 | VK_ACCESS_HOST_WRITE_BIT
381 | VK_ACCESS_SHADER_WRITE_BIT
382 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
383 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
386 VkPipelineStageFlags getAllPipelineStageFlags (void)
388 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
389 | VK_PIPELINE_STAGE_TRANSFER_BIT
390 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
391 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
392 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
393 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
394 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
395 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
396 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
397 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
398 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
399 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
400 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
403 class AttachmentReference
406 AttachmentReference (deUint32 attachment,
407 VkImageLayout layout)
408 : m_attachment (attachment)
413 deUint32 getAttachment (void) const { return m_attachment; }
414 VkImageLayout getImageLayout (void) const { return m_layout; }
417 deUint32 m_attachment;
418 VkImageLayout m_layout;
424 Subpass (VkPipelineBindPoint pipelineBindPoint,
425 VkSubpassDescriptionFlags flags,
426 const vector<AttachmentReference>& inputAttachments,
427 const vector<AttachmentReference>& colorAttachments,
428 const vector<AttachmentReference>& resolveAttachments,
429 AttachmentReference depthStencilAttachment,
430 const vector<AttachmentReference>& preserveAttachments)
431 : m_pipelineBindPoint (pipelineBindPoint)
433 , m_inputAttachments (inputAttachments)
434 , m_colorAttachments (colorAttachments)
435 , m_resolveAttachments (resolveAttachments)
436 , m_depthStencilAttachment (depthStencilAttachment)
437 , m_preserveAttachments (preserveAttachments)
441 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
442 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
443 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
444 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
445 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
446 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
447 const vector<AttachmentReference>& getPreserveAttachments (void) const { return m_preserveAttachments; }
450 VkPipelineBindPoint m_pipelineBindPoint;
451 VkSubpassDescriptionFlags m_flags;
453 vector<AttachmentReference> m_inputAttachments;
454 vector<AttachmentReference> m_colorAttachments;
455 vector<AttachmentReference> m_resolveAttachments;
456 AttachmentReference m_depthStencilAttachment;
458 vector<AttachmentReference> m_preserveAttachments;
461 class SubpassDependency
464 SubpassDependency (deUint32 srcPass,
467 VkPipelineStageFlags srcStageMask,
468 VkPipelineStageFlags dstStageMask,
470 VkAccessFlags outputMask,
471 VkAccessFlags inputMask,
473 VkDependencyFlags flags)
474 : m_srcPass (srcPass)
475 , m_dstPass (dstPass)
477 , m_srcStageMask (srcStageMask)
478 , m_dstStageMask (dstStageMask)
480 , m_outputMask (outputMask)
481 , m_inputMask (inputMask)
486 deUint32 getSrcPass (void) const { return m_srcPass; }
487 deUint32 getDstPass (void) const { return m_dstPass; }
489 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
490 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
492 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
493 VkAccessFlags getInputMask (void) const { return m_inputMask; }
495 VkDependencyFlags getFlags (void) const { return m_flags; }
501 VkPipelineStageFlags m_srcStageMask;
502 VkPipelineStageFlags m_dstStageMask;
504 VkAccessFlags m_outputMask;
505 VkAccessFlags m_inputMask;
506 VkDependencyFlags m_flags;
512 Attachment (VkFormat format,
513 VkSampleCountFlagBits samples,
515 VkAttachmentLoadOp loadOp,
516 VkAttachmentStoreOp storeOp,
518 VkAttachmentLoadOp stencilLoadOp,
519 VkAttachmentStoreOp stencilStoreOp,
521 VkImageLayout initialLayout,
522 VkImageLayout finalLayout)
524 , m_samples (samples)
527 , m_storeOp (storeOp)
529 , m_stencilLoadOp (stencilLoadOp)
530 , m_stencilStoreOp (stencilStoreOp)
532 , m_initialLayout (initialLayout)
533 , m_finalLayout (finalLayout)
537 VkFormat getFormat (void) const { return m_format; }
538 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
540 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
541 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
544 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
545 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
547 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
548 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
552 VkSampleCountFlagBits m_samples;
554 VkAttachmentLoadOp m_loadOp;
555 VkAttachmentStoreOp m_storeOp;
557 VkAttachmentLoadOp m_stencilLoadOp;
558 VkAttachmentStoreOp m_stencilStoreOp;
560 VkImageLayout m_initialLayout;
561 VkImageLayout m_finalLayout;
567 RenderPass (const vector<Attachment>& attachments,
568 const vector<Subpass>& subpasses,
569 const vector<SubpassDependency>& dependencies)
570 : m_attachments (attachments)
571 , m_subpasses (subpasses)
572 , m_dependencies (dependencies)
576 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
577 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
578 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
581 const vector<Attachment> m_attachments;
582 const vector<Subpass> m_subpasses;
583 const vector<SubpassDependency> m_dependencies;
590 RENDERTYPES_NONE = 0,
591 RENDERTYPES_CLEAR = (1<<1),
592 RENDERTYPES_DRAW = (1<<2)
595 enum CommandBufferTypes
597 COMMANDBUFFERTYPES_INLINE = (1<<0),
598 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
603 IMAGEMEMORY_STRICT = (1<<0),
604 IMAGEMEMORY_LAZY = (1<<1)
607 TestConfig (const RenderPass& renderPass_,
608 RenderTypes renderTypes_,
609 CommandBufferTypes commandBufferTypes_,
610 ImageMemory imageMemory_,
611 const UVec2& targetSize_,
612 const UVec2& renderPos_,
613 const UVec2& renderSize_,
615 : renderPass (renderPass_)
616 , renderTypes (renderTypes_)
617 , commandBufferTypes (commandBufferTypes_)
618 , imageMemory (imageMemory_)
619 , targetSize (targetSize_)
620 , renderPos (renderPos_)
621 , renderSize (renderSize_)
626 RenderPass renderPass;
627 RenderTypes renderTypes;
628 CommandBufferTypes commandBufferTypes;
629 ImageMemory imageMemory;
636 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
638 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
641 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
643 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
646 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
648 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
651 void logRenderPassInfo (TestLog& log,
652 const RenderPass& renderPass)
654 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
657 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
658 const vector<Attachment>& attachments = renderPass.getAttachments();
660 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
662 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
663 const Attachment& attachment = attachments[attachmentNdx];
665 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
666 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
668 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
669 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
671 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
672 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
674 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
675 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
680 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
681 const vector<Subpass>& subpasses = renderPass.getSubpasses();
683 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
685 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
686 const Subpass& subpass = subpasses[subpassNdx];
688 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
689 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
690 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
691 const vector<AttachmentReference>& preserveAttachments = subpass.getPreserveAttachments();
693 if (!inputAttachments.empty())
695 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
697 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
699 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
700 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
702 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
703 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
707 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
709 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
710 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
712 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
713 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
716 if (!colorAttachments.empty())
718 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
720 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
722 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
723 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
725 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
726 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
730 if (!resolveAttachments.empty())
732 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
734 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
736 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
737 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
739 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
740 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
744 if (!preserveAttachments.empty())
746 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
748 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
750 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
751 const AttachmentReference& preserveAttachment = preserveAttachments[preserveNdx];
753 log << TestLog::Message << "Attachment: " << preserveAttachment.getAttachment() << TestLog::EndMessage;
754 log << TestLog::Message << "Layout: " << preserveAttachment.getImageLayout() << TestLog::EndMessage;
761 if (!renderPass.getDependencies().empty())
763 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
765 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
767 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
768 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
770 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
771 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
773 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
774 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
776 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
777 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
778 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
783 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
785 const tcu::TextureFormat format = mapVkFormat(vkFormat);
786 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
787 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
789 std::ostringstream stream;
793 switch (channelClass)
795 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
796 for (int i = 0; i < 4; i++)
802 stream << value.int32[i];
808 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
809 for (int i = 0; i < 4; i++)
815 stream << value.uint32[i];
821 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
822 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
823 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
824 for (int i = 0; i < 4; i++)
830 stream << value.float32[i];
837 DE_FATAL("Unknown channel class");
845 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
847 const tcu::TextureFormat format = mapVkFormat(vkFormat);
849 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
851 std::ostringstream stream;
855 if (tcu::hasStencilComponent(format.order))
856 stream << "stencil: " << value.depthStencil.stencil;
858 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
861 if (tcu::hasDepthComponent(format.order))
862 stream << "depth: " << value.depthStencil.depth;
869 return clearColorToString(vkFormat, value.color);
872 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
874 const float clearNan = tcu::Float32::nan().asFloat();
875 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
876 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
877 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
878 VkClearColorValue clearColor;
880 switch (channelClass)
882 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
884 const tcu::IVec4 valueMin = tcu::getFormatMinIntValue(format);
885 const tcu::IVec4 valueMax = tcu::getFormatMaxIntValue(format);
887 for (int ndx = 0; ndx < 4; ndx++)
889 if (!channelMask[ndx])
890 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
892 clearColor.uint32[ndx] = rng.getInt(valueMin[ndx], valueMax[ndx]);
897 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
899 const UVec4 valueMax = tcu::getFormatMaxUintValue(format);
901 for (int ndx = 0; ndx < 4; ndx++)
903 if (!channelMask[ndx])
904 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
906 clearColor.uint32[ndx] = rng.getUint32() % valueMax[ndx];
911 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
912 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
913 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
915 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
917 for (int ndx = 0; ndx < 4; ndx++)
919 if (!channelMask[ndx])
920 clearColor.float32[ndx] = clearNan;
922 clearColor.float32[ndx] = formatInfo.valueMin[ndx] + rng.getFloat() * (formatInfo.valueMax[ndx] - formatInfo.valueMin[ndx]);
928 DE_FATAL("Unknown channel class");
934 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
936 const VkAttachmentDescription attachmentDescription =
940 attachment.getFormat(), // format
941 attachment.getSamples(), // samples
943 attachment.getLoadOp(), // loadOp
944 attachment.getStoreOp(), // storeOp
946 attachment.getStencilLoadOp(), // stencilLoadOp
947 attachment.getStencilStoreOp(), // stencilStoreOp
949 attachment.getInitialLayout(), // initialLayout
950 attachment.getFinalLayout(), // finalLayout
953 return attachmentDescription;
956 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
958 const VkAttachmentReference reference =
960 referenceInfo.getAttachment(), // attachment;
961 referenceInfo.getImageLayout() // layout;
967 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
968 vector<VkAttachmentReference>* attachmentReferenceLists,
969 vector<deUint32>* preserveAttachmentReferences)
971 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
972 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
973 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
974 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
976 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
977 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
979 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
980 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
982 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
983 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
985 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
987 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
988 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx].getAttachment());
990 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
993 const VkSubpassDescription subpassDescription =
995 subpass.getFlags(), // flags;
996 subpass.getPipelineBindPoint(), // pipelineBindPoint;
998 (deUint32)inputAttachmentReferences.size(), // inputCount;
999 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1001 (deUint32)colorAttachmentReferences.size(), // colorCount;
1002 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1003 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1005 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1006 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1007 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1010 return subpassDescription;
1014 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1016 const VkSubpassDependency dependency =
1018 dependencyInfo.getSrcPass(), // srcSubpass;
1019 dependencyInfo.getDstPass(), // destSubpass;
1021 dependencyInfo.getSrcStageMask(), // srcStageMask;
1022 dependencyInfo.getDstStageMask(), // destStageMask;
1024 dependencyInfo.getOutputMask(), // outputMask;
1025 dependencyInfo.getInputMask(), // inputMask;
1027 dependencyInfo.getFlags() // dependencyFlags;
1033 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1035 const RenderPass& renderPassInfo)
1037 const size_t perSubpassAttachmentReferenceLists = 4;
1038 vector<VkAttachmentDescription> attachments;
1039 vector<VkSubpassDescription> subpasses;
1040 vector<VkSubpassDependency> dependencies;
1041 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1042 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1044 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1045 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1047 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1048 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1050 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1051 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1054 const VkRenderPassCreateInfo createInfo =
1056 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1058 (VkRenderPassCreateFlags)0u,
1059 (deUint32)attachments.size(),
1060 (attachments.empty() ? DE_NULL : &attachments[0]),
1061 (deUint32)subpasses.size(),
1062 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1063 (deUint32)dependencies.size(),
1064 (dependencies.empty() ? DE_NULL : &dependencies[0])
1067 return createRenderPass(vk, device, &createInfo);
1071 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1073 VkRenderPass renderPass,
1075 const vector<VkImageView>& attachments)
1077 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1080 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1082 deUint32 queueIndex,
1085 VkSampleCountFlagBits samples,
1086 VkImageUsageFlags usageFlags,
1087 VkImageLayout layout)
1089 const VkExtent3D size_ = { size.x(), size.y(), 1u };
1090 VkImageUsageFlags targetUsageFlags = 0;
1091 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1093 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1095 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1099 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1102 return createImage(vk, device,
1103 (VkImageCreateFlags)0,
1110 VK_IMAGE_TILING_OPTIMAL,
1111 usageFlags | targetUsageFlags,
1112 VK_SHARING_MODE_EXCLUSIVE,
1118 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
1120 Allocator& allocator,
1124 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
1125 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1129 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1133 VkImageAspectFlags aspect)
1135 const VkImageSubresourceRange range =
1144 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1147 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1149 const float clearNan = tcu::Float32::nan().asFloat();
1150 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1152 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1154 VkClearValue clearValue;
1156 clearValue.depthStencil.depth = clearNan;
1157 clearValue.depthStencil.stencil = 255;
1159 if (tcu::hasStencilComponent(format.order))
1160 clearValue.depthStencil.stencil = rng.getInt(0, 255);
1162 if (tcu::hasDepthComponent(format.order))
1163 clearValue.depthStencil.depth = rng.getFloat();
1169 VkClearValue clearValue;
1171 clearValue.color = randomColorClearValue(attachment, rng);
1177 class AttachmentResources
1180 AttachmentResources (const DeviceInterface& vk,
1182 Allocator& allocator,
1183 deUint32 queueIndex,
1185 const Attachment& attachmentInfo,
1187 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), lazy ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : 0, VK_IMAGE_LAYOUT_UNDEFINED))
1188 , m_imageMemory (createImageMemory(vk, device, allocator, *m_image, lazy))
1189 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1193 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1195 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1197 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1198 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1200 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1201 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1203 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1204 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1206 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1208 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1209 m_secondaryBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
1211 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1215 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1217 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1218 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1220 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1225 ~AttachmentResources (void)
1229 VkImageView getAttachmentView (void) const
1231 return *m_attachmentView;
1234 VkImage getImage (void) const
1239 VkBuffer getBuffer (void) const
1241 DE_ASSERT(*m_buffer != DE_NULL);
1245 VkDeviceSize getBufferSize (void) const
1247 DE_ASSERT(*m_buffer != DE_NULL);
1248 return m_bufferSize;
1251 const Allocation& getResultMemory (void) const
1253 DE_ASSERT(m_bufferMemory);
1254 return *m_bufferMemory;
1257 VkBuffer getSecondaryBuffer (void) const
1259 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1260 return *m_secondaryBuffer;
1263 VkDeviceSize getSecondaryBufferSize (void) const
1265 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1266 return m_secondaryBufferSize;
1269 const Allocation& getSecondaryResultMemory (void) const
1271 DE_ASSERT(m_secondaryBufferMemory);
1272 return *m_secondaryBufferMemory;
1276 const Unique<VkImage> m_image;
1277 const UniquePtr<Allocation> m_imageMemory;
1278 const Unique<VkImageView> m_attachmentView;
1280 Move<VkBuffer> m_buffer;
1281 VkDeviceSize m_bufferSize;
1282 de::MovePtr<Allocation> m_bufferMemory;
1284 Move<VkBuffer> m_secondaryBuffer;
1285 VkDeviceSize m_secondaryBufferSize;
1286 de::MovePtr<Allocation> m_secondaryBufferMemory;
1289 void uploadBufferData (const DeviceInterface& vk,
1291 const Allocation& memory,
1295 const VkMappedMemoryRange range =
1297 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1299 memory.getMemory(), // mem;
1300 memory.getOffset(), // offset;
1301 (VkDeviceSize)size // size;
1303 void* const ptr = memory.getHostPtr();
1305 deMemcpy(ptr, data, size);
1306 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1309 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1311 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1315 case tcu::TextureFormat::D:
1316 case tcu::TextureFormat::DS:
1317 return VK_IMAGE_ASPECT_DEPTH_BIT;
1319 case tcu::TextureFormat::S:
1320 return VK_IMAGE_ASPECT_STENCIL_BIT;
1323 return VK_IMAGE_ASPECT_COLOR_BIT;
1330 RenderQuad (const Vec4& posA, const Vec4& posB)
1333 m_vertices[0] = posA;
1334 m_vertices[1] = Vec4(posA[0], posB[1], posA[2], posA[3]);
1335 m_vertices[2] = posB;
1337 m_vertices[3] = posB;
1338 m_vertices[4] = Vec4(posB[0], posA[1], posB[2], posA[3]);
1339 m_vertices[5] = posA;
1342 const Vec4& getCornerA (void) const
1344 return m_vertices[0];
1347 const Vec4& getCornerB (void) const
1349 return m_vertices[2];
1352 const void* getVertexPointer (void) const
1354 return &m_vertices[0];
1357 size_t getVertexDataSize (void) const
1359 return sizeof(Vec4) * m_vertices.size();
1363 vector<Vec4> m_vertices;
1369 ColorClear (const UVec2& offset,
1371 const VkClearColorValue& color)
1378 const UVec2& getOffset (void) const { return m_offset; }
1379 const UVec2& getSize (void) const { return m_size; }
1380 const VkClearColorValue& getColor (void) const { return m_color; }
1385 VkClearColorValue m_color;
1388 class DepthStencilClear
1391 DepthStencilClear (const UVec2& offset,
1398 , m_stencil (stencil)
1402 const UVec2& getOffset (void) const { return m_offset; }
1403 const UVec2& getSize (void) const { return m_size; }
1404 float getDepth (void) const { return m_depth; }
1405 deUint32 getStencil (void) const { return m_stencil; }
1415 class SubpassRenderInfo
1418 SubpassRenderInfo (const RenderPass& renderPass,
1419 deUint32 subpassIndex,
1423 const UVec2& viewportOffset,
1424 const UVec2& viewportSize,
1426 const Maybe<RenderQuad>& renderQuad,
1427 const vector<ColorClear>& colorClears,
1428 const Maybe<DepthStencilClear>& depthStencilClear)
1429 : m_viewportOffset (viewportOffset)
1430 , m_viewportSize (viewportSize)
1431 , m_subpassIndex (subpassIndex)
1432 , m_isSecondary (isSecondary_)
1433 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1434 , m_renderQuad (renderQuad)
1435 , m_colorClears (colorClears)
1436 , m_depthStencilClear (depthStencilClear)
1437 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1439 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1440 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1442 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1444 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1445 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1449 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1450 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1452 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1453 bool isSecondary (void) const { return m_isSecondary; }
1455 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1456 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1457 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1459 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1460 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1461 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1462 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1463 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1464 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1465 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1466 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1468 UVec2 m_viewportOffset;
1469 UVec2 m_viewportSize;
1471 deUint32 m_subpassIndex;
1473 VkSubpassDescriptionFlags m_flags;
1475 Maybe<RenderQuad> m_renderQuad;
1476 vector<ColorClear> m_colorClears;
1477 Maybe<DepthStencilClear> m_depthStencilClear;
1479 vector<AttachmentReference> m_colorAttachments;
1480 vector<Attachment> m_colorAttachmentInfo;
1482 Maybe<AttachmentReference> m_depthStencilAttachment;
1483 Maybe<Attachment> m_depthStencilAttachmentInfo;
1486 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1488 VkRenderPass renderPass,
1489 VkShaderModule vertexShaderModule,
1490 VkShaderModule fragmentShaderModule,
1491 VkPipelineLayout pipelineLayout,
1492 const SubpassRenderInfo& renderInfo)
1494 const VkSpecializationInfo emptyShaderSpecializations =
1496 0u, // mapEntryCount
1502 Maybe<VkSampleCountFlagBits> rasterSamples;
1503 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1505 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1507 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1509 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1511 rasterSamples = attachment.getSamples();
1514 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1516 VK_FALSE, // blendEnable
1517 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1518 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1519 VK_BLEND_OP_ADD, // blendOpColor
1520 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1521 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1522 VK_BLEND_OP_ADD, // blendOpAlpha
1523 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1526 attachmentBlendStates.push_back(attachmentBlendState);
1530 if (renderInfo.getDepthStencilAttachment())
1532 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1534 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1535 rasterSamples = attachment.getSamples();
1538 // If there are no attachment use single sample
1540 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1542 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1545 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1547 (VkPipelineShaderStageCreateFlags)0u,
1548 VK_SHADER_STAGE_VERTEX_BIT, // stage
1549 vertexShaderModule, // shader
1551 &emptyShaderSpecializations
1554 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1556 (VkPipelineShaderStageCreateFlags)0u,
1557 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1558 fragmentShaderModule, // shader
1560 &emptyShaderSpecializations
1563 const VkVertexInputBindingDescription vertexBinding =
1566 (deUint32)sizeof(tcu::Vec4), // strideInBytes
1567 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1569 const VkVertexInputAttributeDescription vertexAttrib =
1573 VK_FORMAT_R32G32B32A32_SFLOAT, // format
1574 0u, // offsetInBytes
1576 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1578 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1580 (VkPipelineVertexInputStateCreateFlags)0u,
1582 &vertexBinding, // pVertexBindingDescriptions
1583 1u, // attributeCount
1584 &vertexAttrib, // pVertexAttributeDescriptions
1586 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1588 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1590 (VkPipelineInputAssemblyStateCreateFlags)0u,
1591 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1592 VK_FALSE, // primitiveRestartEnable
1594 const VkViewport viewport =
1596 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1597 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1600 const VkRect2D scissor =
1602 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1603 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1605 const VkPipelineViewportStateCreateInfo viewportState =
1607 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1609 (VkPipelineViewportStateCreateFlags)0u,
1615 const VkPipelineRasterizationStateCreateInfo rasterState =
1617 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1619 (VkPipelineRasterizationStateCreateFlags)0u,
1620 VK_TRUE, // depthClipEnable
1621 VK_FALSE, // rasterizerDiscardEnable
1622 VK_POLYGON_MODE_FILL, // fillMode
1623 VK_CULL_MODE_NONE, // cullMode
1624 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1625 VK_FALSE, // depthBiasEnable
1627 0.0f, // depthBiasClamp
1628 0.0f, // slopeScaledDepthBias
1631 const VkPipelineMultisampleStateCreateInfo multisampleState =
1633 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1635 (VkPipelineMultisampleStateCreateFlags)0u,
1636 *rasterSamples, // rasterSamples
1637 VK_FALSE, // sampleShadingEnable
1638 0.0f, // minSampleShading
1639 DE_NULL, // pSampleMask
1640 VK_FALSE, // alphaToCoverageEnable
1641 VK_FALSE, // alphaToOneEnable
1643 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1645 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1647 (VkPipelineDepthStencilStateCreateFlags)0u,
1648 VK_TRUE, // depthTestEnable
1649 VK_TRUE, // depthWriteEnable
1650 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1651 VK_FALSE, // depthBoundsEnable
1652 VK_TRUE, // stencilTestEnable
1654 VK_STENCIL_OP_REPLACE, // stencilFailOp
1655 VK_STENCIL_OP_REPLACE, // stencilPassOp
1656 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1657 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1658 ~0u, // stencilCompareMask
1659 ~0u, // stencilWriteMask
1660 STENCIL_VALUE // stencilReference
1663 VK_STENCIL_OP_REPLACE, // stencilFailOp
1664 VK_STENCIL_OP_REPLACE, // stencilPassOp
1665 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1666 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1667 ~0u, // stencilCompareMask
1668 ~0u, // stencilWriteMask
1669 STENCIL_VALUE // stencilReference
1672 -1.0f, // minDepthBounds;
1673 1.0f // maxDepthBounds;
1675 const VkPipelineColorBlendStateCreateInfo blendState =
1677 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1679 (VkPipelineColorBlendStateCreateFlags)0u,
1680 VK_FALSE, // logicOpEnable
1681 VK_LOGIC_OP_COPY, // logicOp
1682 (deUint32)attachmentBlendStates.size(), // attachmentCount
1683 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1684 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1686 const VkPipelineDynamicStateCreateInfo dynamicState =
1688 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1690 (VkPipelineDynamicStateCreateFlags)0u,
1694 const VkGraphicsPipelineCreateInfo createInfo =
1696 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1698 (VkPipelineCreateFlags)0u,
1701 shaderStages, // pStages
1703 &vertexInputState, // pVertexInputState
1704 &inputAssemblyState, // pInputAssemblyState
1705 DE_NULL, // pTessellationState
1706 &viewportState, // pViewportState
1707 &rasterState, // pRasterState
1708 &multisampleState, // pMultisampleState
1709 &depthStencilState, // pDepthStencilState
1710 &blendState, // pColorBlendState
1711 &dynamicState, // pDynamicState
1712 pipelineLayout, // layout
1714 renderPass, // renderPass
1715 renderInfo.getSubpassIndex(), // subpass
1716 DE_NULL, // basePipelineHandle
1717 0u // basePipelineIndex
1720 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1723 class SubpassRenderer
1726 SubpassRenderer (Context& context,
1727 const DeviceInterface& vk,
1729 Allocator& allocator,
1730 VkRenderPass renderPass,
1731 VkFramebuffer framebuffer,
1732 VkCommandPool commandBufferPool,
1733 deUint32 queueFamilyIndex,
1734 const SubpassRenderInfo& renderInfo)
1735 : m_renderInfo (renderInfo)
1737 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1739 if (renderInfo.getRenderQuad())
1741 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1742 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1744 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1746 (vk::VkPipelineLayoutCreateFlags)0,
1747 0u, // descriptorSetCount;
1748 DE_NULL, // pSetLayouts;
1749 0u, // pushConstantRangeCount;
1750 DE_NULL, // pPushConstantRanges;
1753 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1754 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1755 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1756 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1758 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1759 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1761 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1762 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1765 if (renderInfo.isSecondary())
1767 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1769 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
1770 pushRenderCommands(vk, *m_commandBuffer);
1771 endCommandBuffer(vk, *m_commandBuffer);
1775 bool isSecondary (void) const
1777 return m_commandBuffer;
1780 VkCommandBuffer getCommandBuffer (void) const
1782 DE_ASSERT(isSecondary());
1783 return *m_commandBuffer;
1786 void pushRenderCommands (const DeviceInterface& vk,
1787 VkCommandBuffer commandBuffer)
1789 if (!m_renderInfo.getColorClears().empty())
1791 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
1793 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
1795 const ColorClear& colorClear = colorClears[attachmentNdx];
1796 const VkClearAttachment attachment =
1798 VK_IMAGE_ASPECT_COLOR_BIT,
1800 makeClearValue(colorClear.getColor()),
1802 const VkClearRect rect =
1805 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
1806 { colorClear.getSize().x(), colorClear.getSize().y() }
1808 0u, // baseArrayLayer
1812 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1816 if (m_renderInfo.getDepthStencilClear())
1818 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
1819 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
1820 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
1821 const VkClearAttachment attachment =
1823 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1824 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1826 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
1828 const VkClearRect rect =
1831 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
1832 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
1834 0u, // baseArrayLayer
1838 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1841 if (m_renderInfo.getRenderQuad())
1843 const VkDeviceSize offset = 0;
1844 const VkBuffer vertexBuffer = *m_vertexBuffer;
1846 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1847 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
1848 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
1853 const SubpassRenderInfo m_renderInfo;
1854 Move<VkCommandBuffer> m_commandBuffer;
1855 Move<VkPipeline> m_pipeline;
1856 Move<VkPipelineLayout> m_pipelineLayout;
1858 Move<VkShaderModule> m_vertexShaderModule;
1860 Move<VkShaderModule> m_fragmentShaderModule;
1862 Move<VkBuffer> m_vertexBuffer;
1863 de::MovePtr<Allocation> m_vertexBufferMemory;
1866 void pushImageInitializationCommands (const DeviceInterface& vk,
1867 VkCommandBuffer commandBuffer,
1868 const vector<Attachment>& attachmentInfo,
1869 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
1870 deUint32 queueIndex,
1871 const vector<Maybe<VkClearValue> >& clearValues)
1874 vector<VkImageMemoryBarrier> initializeLayouts;
1876 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1878 if (!clearValues[attachmentNdx])
1881 const VkImageMemoryBarrier barrier =
1883 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1886 getAllMemoryWriteFlags(), // srcAccessMask
1887 getAllMemoryReadFlags(), // dstAccessMask
1889 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
1890 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
1892 queueIndex, // srcQueueFamilyIndex;
1893 queueIndex, // destQueueFamilyIndex;
1895 attachmentResources[attachmentNdx]->getImage(), // image;
1896 { // subresourceRange;
1897 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1900 0, // baseArraySlice;
1905 initializeLayouts.push_back(barrier);
1908 if (!initializeLayouts.empty())
1909 vk.cmdPipelineBarrier(commandBuffer, (VkPipelineStageFlags)0, (VkPipelineStageFlags)0, (VkDependencyFlags)0,
1910 0, (const VkMemoryBarrier*)DE_NULL,
1911 0, (const VkBufferMemoryBarrier*)DE_NULL,
1912 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
1915 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1917 if (!clearValues[attachmentNdx])
1920 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
1922 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
1924 const float clearNan = tcu::Float32::nan().asFloat();
1925 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
1926 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : ~0u;
1927 const VkClearDepthStencilValue depthStencil =
1932 const VkImageSubresourceRange range =
1934 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1935 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1942 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
1946 const VkImageSubresourceRange range =
1948 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
1951 0, // baseArrayLayer;
1954 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
1956 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
1961 vector<VkImageMemoryBarrier> renderPassLayouts;
1963 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1965 const VkImageMemoryBarrier barrier =
1967 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1970 getAllMemoryWriteFlags(), // srcAccessMask
1971 getAllMemoryReadFlags(), // dstAccessMask
1973 clearValues[attachmentNdx] ?
1974 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
1975 : VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
1977 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
1979 queueIndex, // srcQueueFamilyIndex;
1980 queueIndex, // destQueueFamilyIndex;
1982 attachmentResources[attachmentNdx]->getImage(), // image;
1983 { // subresourceRange;
1984 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1987 0, // baseArraySlice;
1992 renderPassLayouts.push_back(barrier);
1995 if (!renderPassLayouts.empty())
1996 vk.cmdPipelineBarrier(commandBuffer, 0, 0, (VkDependencyFlags)0,
1997 0, (const VkMemoryBarrier*)DE_NULL,
1998 0, (const VkBufferMemoryBarrier*)DE_NULL,
1999 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2003 void pushRenderPassCommands (const DeviceInterface& vk,
2004 VkCommandBuffer commandBuffer,
2005 VkRenderPass renderPass,
2006 VkFramebuffer framebuffer,
2007 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2008 const UVec2& renderPos,
2009 const UVec2& renderSize,
2010 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2011 TestConfig::RenderTypes render)
2013 const float clearNan = tcu::Float32::nan().asFloat();
2014 vector<VkClearValue> attachmentClearValues;
2016 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2018 if (renderPassClearValues[attachmentNdx])
2019 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2021 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2025 const VkRect2D renderArea =
2027 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2028 { renderSize.x(), renderSize.y() }
2031 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2033 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2035 if (subpassNdx == 0)
2036 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2038 vk.cmdNextSubpass(commandBuffer, contents);
2042 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2044 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2046 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2048 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2049 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2052 DE_FATAL("Invalid contents");
2056 vk.cmdEndRenderPass(commandBuffer);
2060 void pushReadImagesToBuffers (const DeviceInterface& vk,
2061 VkCommandBuffer commandBuffer,
2062 deUint32 queueIndex,
2064 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2065 const vector<Attachment>& attachmentInfo,
2066 const vector<bool>& isLazy,
2068 const UVec2& targetSize)
2071 vector<VkImageMemoryBarrier> imageBarriers;
2073 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2075 if (isLazy[attachmentNdx])
2078 const VkImageMemoryBarrier barrier =
2080 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2083 getAllMemoryWriteFlags(), // srcAccessMask
2084 getAllMemoryReadFlags(), // dstAccessMask
2086 attachmentInfo[attachmentNdx].getFinalLayout(), // oldLayout
2087 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2089 queueIndex, // srcQueueFamilyIndex
2090 queueIndex, // destQueueFamilyIndex
2092 attachmentResources[attachmentNdx]->getImage(), // image
2093 { // subresourceRange
2094 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2097 0, // baseArraySlice
2102 imageBarriers.push_back(barrier);
2105 if (!imageBarriers.empty())
2106 vk.cmdPipelineBarrier(commandBuffer,
2107 getAllPipelineStageFlags(),
2108 getAllPipelineStageFlags(),
2109 (VkDependencyFlags)0,
2110 0, (const VkMemoryBarrier*)DE_NULL,
2111 0, (const VkBufferMemoryBarrier*)DE_NULL,
2112 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2115 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2117 if (isLazy[attachmentNdx])
2120 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2121 const VkBufferImageCopy rect =
2124 0, // bufferRowLength
2125 0, // bufferImageHeight
2126 { // imageSubresource
2127 getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2132 { 0, 0, 0 }, // imageOffset
2133 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2136 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2138 if (tcu::TextureFormat::DS == order)
2140 const VkBufferImageCopy stencilRect =
2143 0, // bufferRowLength
2144 0, // bufferImageHeight
2145 { // imageSubresource
2146 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2151 { 0, 0, 0 }, // imageOffset
2152 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2155 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2160 vector<VkBufferMemoryBarrier> bufferBarriers;
2162 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2164 if (isLazy[attachmentNdx])
2167 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2168 const VkBufferMemoryBarrier bufferBarrier =
2170 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2173 getAllMemoryWriteFlags(),
2174 getAllMemoryReadFlags(),
2179 attachmentResources[attachmentNdx]->getBuffer(),
2181 attachmentResources[attachmentNdx]->getBufferSize()
2184 bufferBarriers.push_back(bufferBarrier);
2186 if (tcu::TextureFormat::DS == order)
2188 const VkBufferMemoryBarrier secondaryBufferBarrier =
2190 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2193 getAllMemoryWriteFlags(),
2194 getAllMemoryReadFlags(),
2199 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2201 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2204 bufferBarriers.push_back(secondaryBufferBarrier);
2207 bufferBarriers.push_back(bufferBarrier);
2210 if (!bufferBarriers.empty())
2211 vk.cmdPipelineBarrier(commandBuffer,
2212 getAllPipelineStageFlags(),
2213 getAllPipelineStageFlags(),
2214 (VkDependencyFlags)0,
2215 0, (const VkMemoryBarrier*)DE_NULL,
2216 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2217 0, (const VkImageMemoryBarrier*)DE_NULL);
2221 void clear (const PixelBufferAccess& access, const VkClearValue& value)
2223 const tcu::TextureFormat& format = access.getFormat();
2225 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2227 if (tcu::hasDepthComponent(format.order))
2228 tcu::clearDepth(access, value.depthStencil.depth);
2230 if (tcu::hasStencilComponent(format.order))
2231 tcu::clearStencil(access, value.depthStencil.stencil);
2235 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT
2236 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
2237 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
2239 const tcu::Vec4 color (value.color.float32[0],
2240 value.color.float32[1],
2241 value.color.float32[2],
2242 value.color.float32[3]);
2244 if (tcu::isSRGB(format))
2245 tcu::clear(access, tcu::linearToSRGB(color));
2247 tcu::clear(access, color);
2249 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2251 const tcu::UVec4 color (value.color.uint32[0],
2252 value.color.uint32[1],
2253 value.color.uint32[2],
2254 value.color.uint32[3]);
2256 tcu::clear(access, color);
2258 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2260 const tcu::IVec4 color (value.color.int32[0],
2261 value.color.int32[1],
2262 value.color.int32[2],
2263 value.color.int32[3]);
2265 tcu::clear(access, color);
2268 DE_FATAL("Unknown channel class");
2272 Vec4 computeUvs (const IVec2& posA, const IVec2& posB, const IVec2& pos)
2274 const float u = de::clamp((float)(pos.x() - posA.x()) / (float)(posB.x() - posA.x()), 0.0f, 1.0f);
2275 const float v = de::clamp((float)(pos.y() - posA.y()) / (float)(posB.y() - posA.y()), 0.0f, 1.0f);
2277 return Vec4(u, v, u * v, (u + v) / 2.0f);
2280 void renderReferenceImages (vector<tcu::TextureLevel>& referenceAttachments,
2281 const RenderPass& renderPassInfo,
2282 const UVec2& targetSize,
2283 const vector<Maybe<VkClearValue> >& imageClearValues,
2284 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2285 const vector<SubpassRenderInfo>& subpassRenderInfo,
2286 const UVec2& renderPos,
2287 const UVec2& renderSize)
2289 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2290 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2292 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2294 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2296 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2297 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2298 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2299 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2300 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
2302 reference = tcu::TextureLevel(format, targetSize.x(), targetSize.y());
2304 if (imageClearValues[attachmentNdx])
2305 clear(reference.getAccess(), *imageClearValues[attachmentNdx]);
2308 // Fill with grid if image contentst are undefined before renderpass
2309 if (isDepthOrStencilAttachment)
2311 if (tcu::hasDepthComponent(format.order))
2312 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), 2, textureInfo.valueMin, textureInfo.valueMax);
2314 if (tcu::hasStencilComponent(format.order))
2315 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), 2, textureInfo.valueMin, textureInfo.valueMax);
2318 tcu::fillWithGrid(reference.getAccess(), 2, textureInfo.valueMin, textureInfo.valueMax);
2322 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2324 const Subpass& subpass = subpasses[subpassNdx];
2325 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2326 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2328 // Apply load op if attachment was used for the first time
2329 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2331 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2333 if (!attachmentUsed[attachmentIndex])
2335 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2336 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2338 DE_ASSERT(!tcu::hasDepthComponent(reference.getFormat().order));
2339 DE_ASSERT(!tcu::hasStencilComponent(reference.getFormat().order));
2341 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2342 clear(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2343 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2345 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2347 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2350 attachmentUsed[attachmentIndex] = true;
2354 // Apply load op to depth/stencil attachment if it was used for the first time
2355 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED && !attachmentUsed[subpass.getDepthStencilAttachment().getAttachment()])
2357 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2359 // Apply load op if attachment was used for the first time
2360 if (!attachmentUsed[attachmentIndex])
2362 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2363 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2365 if (tcu::hasDepthComponent(reference.getFormat().order))
2367 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2368 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2369 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2371 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2373 tcu::fillWithGrid(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2377 if (tcu::hasStencilComponent(reference.getFormat().order))
2379 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2380 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2381 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2383 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2385 tcu::fillWithGrid(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2390 attachmentUsed[attachmentIndex] = true;
2393 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2395 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2396 const UVec2 offset = colorClear.getOffset();
2397 const UVec2 size = colorClear.getSize();
2398 tcu::TextureLevel& reference = referenceAttachments[subpass.getColorAttachments()[colorClearNdx].getAttachment()];
2401 value.color = colorClear.getColor();
2403 clear(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), value);
2406 if (renderInfo.getDepthStencilClear())
2408 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
2409 const UVec2 offset = dsClear.getOffset();
2410 const UVec2 size = dsClear.getSize();
2411 tcu::TextureLevel& reference = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2413 if (tcu::hasDepthComponent(reference.getFormat().order))
2414 clearDepth(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getDepth());
2416 if (tcu::hasStencilComponent(reference.getFormat().order))
2417 clearStencil(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getStencil());
2420 if (renderInfo.getRenderQuad())
2422 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2423 const Vec4 posA = renderQuad.getCornerA();
2424 const Vec4 posB = renderQuad.getCornerB();
2425 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2426 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2427 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
2428 (deInt32)(origin.y() + (p.y() * posA.y())));
2429 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
2430 (deInt32)(origin.y() + (p.y() * posB.y())));
2432 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
2434 const Attachment attachment = renderPassInfo.getAttachments()[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2435 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(mapVkFormat(attachment.getFormat()));
2436 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2437 const bool srgb = tcu::isSRGB(referenceTexture.getFormat());
2438 const PixelBufferAccess reference = referenceTexture.getAccess();
2439 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2440 const float clampMax = (float)(MAX_INTEGER_VALUE);
2441 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2442 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2443 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2444 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2446 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2447 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2448 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2449 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2451 DE_ASSERT(posAI.x() < posBI.x());
2452 DE_ASSERT(posAI.y() < posBI.y());
2454 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2455 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2457 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2458 const Vec4 color = valueMax * uvs + valueMin * (Vec4(1.0f) - uvs);
2461 reference.setPixel(tcu::linearToSRGB(color), x, y);
2463 reference.setPixel(color, x, y);
2467 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2469 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2470 const PixelBufferAccess reference = referenceTexture.getAccess();
2472 DE_ASSERT(posAI.x() < posBI.x());
2473 DE_ASSERT(posAI.y() < posBI.y());
2475 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2476 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2478 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2480 if (tcu::hasDepthComponent(reference.getFormat().order))
2481 reference.setPixDepth(uvs.x(), x, y);
2483 if (tcu::hasStencilComponent(reference.getFormat().order))
2484 reference.setPixStencil(STENCIL_VALUE, x, y);
2490 // Mark all attachments that were used but not stored as undefined
2491 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2493 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2494 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2495 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2496 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2498 if (attachmentUsed[attachmentNdx] && renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
2499 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2503 Maybe<deUint32> findColorAttachment (const Subpass& subpass,
2504 deUint32 attachmentIndex)
2506 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpass.getColorAttachments().size(); colorAttachmentNdx++)
2508 if (subpass.getColorAttachments()[colorAttachmentNdx].getAttachment() == attachmentIndex)
2509 return tcu::just((deUint32)colorAttachmentNdx);
2512 return tcu::nothing<deUint32>();
2515 int calcFloatDiff (float a, float b)
2517 const deUint32 au = tcu::Float32(a).bits();
2518 const deUint32 bu = tcu::Float32(b).bits();
2520 const bool asign = (au & (0x1u << 31u)) != 0u;
2521 const bool bsign = (bu & (0x1u << 31u)) != 0u;
2523 const deUint32 avalue = (au & ((0x1u << 31u) - 1u));
2524 const deUint32 bvalue = (bu & ((0x1u << 31u) - 1u));
2527 return avalue + bvalue + 1u;
2528 else if (avalue < bvalue)
2529 return bvalue - avalue;
2531 return avalue - bvalue;
2534 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess& access,
2539 const tcu::TextureFormat format = tcu::getEffectiveDepthStencilTextureFormat(access.getFormat(), tcu::Sampler::MODE_DEPTH);
2540 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2542 switch (channelClass)
2544 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2545 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2547 const int bitDepth = tcu::getTextureFormatBitDepth(format).x();
2548 const float depth = access.getPixDepth(x, y);
2549 const float threshold = 2.0f / (float)((1 << bitDepth) - 1);
2551 return deFloatAbs(depth - ref) <= threshold;
2554 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2556 const float depth = access.getPixDepth(x, y);
2557 const int mantissaBits = tcu::getTextureFormatMantissaBitDepth(format).x();
2558 const int threshold = 10 * 1 << (23 - mantissaBits);
2560 DE_ASSERT(mantissaBits <= 23);
2562 return calcFloatDiff(depth, ref) <= threshold;
2566 DE_FATAL("Invalid channel class");
2571 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess& access,
2576 const deUint32 stencil = access.getPixStencil(x, y);
2578 return stencil == ref;
2581 bool comparePixelToColorClearValue (const ConstPixelBufferAccess& access,
2584 const VkClearColorValue& ref)
2586 const tcu::TextureFormat format = access.getFormat();
2587 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2588 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2590 switch (channelClass)
2592 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2593 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2595 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
2596 const Vec4 resColor (access.getPixel(x, y));
2597 const Vec4 refColor (ref.float32[0],
2601 const Vec4 threshold (bitDepth[0] > 0 ? 20.0f / (float)((1 << bitDepth[0]) - 1) : 1.0f,
2602 bitDepth[1] > 0 ? 20.0f / (float)((1 << bitDepth[1]) - 1) : 1.0f,
2603 bitDepth[2] > 0 ? 20.0f / (float)((1 << bitDepth[2]) - 1) : 1.0f,
2604 bitDepth[3] > 0 ? 20.0f / (float)((1 << bitDepth[3]) - 1) : 1.0f);
2606 if (tcu::isSRGB(access.getFormat()))
2607 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, tcu::linearToSRGB(refColor)), threshold), channelMask), channelMask));
2609 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2612 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2614 const UVec4 resColor (access.getPixelUint(x, y));
2615 const UVec4 refColor (ref.uint32[0],
2619 const UVec4 threshold (1);
2621 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2624 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2626 const IVec4 resColor (access.getPixelInt(x, y));
2627 const IVec4 refColor (ref.int32[0],
2631 const IVec4 threshold (1);
2633 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2636 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2638 const Vec4 resColor (access.getPixel(x, y));
2639 const Vec4 refColor (ref.float32[0],
2643 const IVec4 mantissaBits (tcu::getTextureFormatMantissaBitDepth(format));
2644 const IVec4 threshold (10 * IVec4(1) << (23 - mantissaBits));
2646 DE_ASSERT(tcu::allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true)));
2648 for (int ndx = 0; ndx < 4; ndx++)
2650 if (calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx])
2658 DE_FATAL("Invalid channel class");
2668 STATUS_UNDEFINED = 0,
2675 PixelStatus (Status color, Status depth, Status stencil)
2676 : m_status ((deUint8)(color << COLOR_OFFSET)
2677 | (deUint8)((deUint8)depth << DEPTH_OFFSET)
2678 | (deUint8)((deUint8)stencil << STENCIL_OFFSET))
2682 Status getColorStatus (void) const { return (Status)((m_status & COLOR_MASK) >> COLOR_OFFSET); }
2683 Status getDepthStatus (void) const { return (Status)((m_status & DEPTH_MASK) >> DEPTH_OFFSET); }
2684 Status getStencilStatus (void) const { return (Status)((m_status & STENCIL_MASK) >> STENCIL_OFFSET); }
2686 void setColorStatus (Status status)
2688 DE_ASSERT(getColorStatus() == STATUS_UNDEFINED);
2689 m_status |= (deUint8)(status << COLOR_OFFSET);
2692 void setDepthStatus (Status status)
2694 DE_ASSERT(getDepthStatus() == STATUS_UNDEFINED);
2695 m_status |= (deUint8)(status << DEPTH_OFFSET);
2698 void setStencilStatus (Status status)
2700 DE_ASSERT(getStencilStatus() == STATUS_UNDEFINED);
2701 m_status |= (deUint8)(status << STENCIL_OFFSET);
2711 COLOR_MASK = (3<<COLOR_OFFSET),
2712 DEPTH_MASK = (3<<DEPTH_OFFSET),
2713 STENCIL_MASK = (3<<STENCIL_OFFSET),
2718 void checkDepthRenderQuad (const ConstPixelBufferAccess& result,
2721 vector<PixelStatus>& status)
2723 for (int y = posA.y(); y <= posB.y(); y++)
2724 for (int x = posA.x(); x <= posB.x(); x++)
2726 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2728 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2730 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2731 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2732 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2733 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2734 const float resDepth = result.getPixDepth(x, y);
2736 if (resDepth >= minUvs.x() && resDepth <= maxUvs.x())
2737 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2738 else if (!softCheck)
2739 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2744 void checkStencilRenderQuad (const ConstPixelBufferAccess& result,
2747 vector<PixelStatus>& status)
2749 for (int y = posA.y(); y <= posB.y(); y++)
2750 for (int x = posA.x(); x <= posB.x(); x++)
2752 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2754 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2756 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2757 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2759 if (result.getPixStencil(x, y) == STENCIL_VALUE)
2760 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2761 else if (!softCheck)
2762 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
2767 void checkColorRenderQuad (const ConstPixelBufferAccess& result,
2770 vector<PixelStatus>& status)
2772 const tcu::TextureFormat& format = result.getFormat();
2773 const bool srgb = tcu::isSRGB(format);
2774 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2775 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2776 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2777 const float clampMax = (float)(MAX_INTEGER_VALUE);
2778 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2779 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2780 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2781 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2783 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2784 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2785 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2786 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2787 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2789 IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(format);
2790 Vec4 threshold = Vec4(1.0f) / Vec4((float)(1 << formatBitDepths.x()),
2791 (float)(1 << formatBitDepths.y()),
2792 (float)(1 << formatBitDepths.z()),
2793 (float)(1 << formatBitDepths.w()));
2795 switch (channelClass)
2797 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2798 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2799 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2801 for (int y = posA.y(); y <= posB.y(); y++)
2802 for (int x = posA.x(); x <= posB.x(); x++)
2804 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2806 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2808 const Vec4 minDiff = Vec4(1.0f) / (IVec4(1) << tcu::getTextureFormatMantissaBitDepth(format)).cast<float>();
2809 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2810 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2811 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2812 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2814 const Vec4 resColor (result.getPixel(x, y));
2816 Vec4 minRefColor = srgb ? tcu::linearToSRGB(valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs))
2817 : valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs) - threshold;
2818 Vec4 maxRefColor = srgb ? tcu::linearToSRGB(valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs))
2819 : valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs) + threshold;
2821 // Take into account rounding and quantization
2822 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
2824 minRefColor = tcu::min(minRefColor * (Vec4(1.0f) - minDiff), minRefColor * (Vec4(1.0f) + minDiff));
2825 maxRefColor = tcu::max(maxRefColor * (Vec4(1.0f) - minDiff), maxRefColor * (Vec4(1.0f) + minDiff));
2829 minRefColor = minRefColor - minDiff;
2830 maxRefColor = maxRefColor + minDiff;
2833 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2834 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2835 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2836 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2838 if (tcu::anyNotEqual(tcu::logicalAnd(
2839 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2840 lessThanEqual(resColor, maxRefColor)),
2841 channelMask), channelMask))
2844 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2847 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2854 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2856 for (int y = posA.y(); y <= posB.y(); y++)
2857 for (int x = posA.x(); x <= posB.x(); x++)
2859 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2861 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2863 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2864 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2865 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2866 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2868 const UVec4 resColor (result.getPixelUint(x, y));
2870 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2871 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2873 const UVec4 minRefColor (minRefColorF.asUint());
2874 const UVec4 maxRefColor (maxRefColorF.asUint());
2876 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2877 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2878 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2879 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2881 if (tcu::anyNotEqual(tcu::logicalAnd(
2882 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2883 lessThanEqual(resColor, maxRefColor)),
2884 channelMask), channelMask))
2887 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2890 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2897 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2899 for (int y = posA.y(); y <= posB.y(); y++)
2900 for (int x = posA.x(); x <= posB.x(); x++)
2902 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2904 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2906 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2907 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2908 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2909 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2911 const IVec4 resColor (result.getPixelInt(x, y));
2913 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2914 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2916 const IVec4 minRefColor (minRefColorF.asInt());
2917 const IVec4 maxRefColor (maxRefColorF.asInt());
2919 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2920 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2921 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2922 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2924 if (tcu::anyNotEqual(tcu::logicalAnd(
2925 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2926 lessThanEqual(resColor, maxRefColor)),
2927 channelMask), channelMask))
2930 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2933 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2941 DE_FATAL("Invalid channel class");
2945 void checkColorClear (const ConstPixelBufferAccess& result,
2946 const UVec2& offset,
2948 vector<PixelStatus>& status,
2949 const VkClearColorValue& color)
2951 DE_ASSERT(offset.x() + size.x() <= (deUint32)result.getWidth());
2952 DE_ASSERT(offset.y() + size.y() <= (deUint32)result.getHeight());
2954 DE_ASSERT(result.getWidth() * result.getHeight() == (int)status.size());
2956 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2957 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2959 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2961 DE_ASSERT(x + y * result.getWidth() < (int)status.size());
2963 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2965 if (comparePixelToColorClearValue(result, x, y, color))
2966 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2968 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2973 void checkDepthClear (const ConstPixelBufferAccess& result,
2974 const UVec2& offset,
2976 vector<PixelStatus>& status,
2979 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2980 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2982 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2984 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2986 if (comparePixelToDepthClearValue(result, x, y, depth))
2987 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2989 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2994 void checkStencilClear (const ConstPixelBufferAccess& result,
2995 const UVec2& offset,
2997 vector<PixelStatus>& status,
3000 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
3001 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
3003 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3005 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
3007 if (comparePixelToStencilClearValue(result, x, y, stencil))
3008 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3010 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
3015 bool verifyAttachment (const ConstPixelBufferAccess& result,
3016 const Maybe<ConstPixelBufferAccess>& secondaryResult,
3017 const RenderPass& renderPassInfo,
3018 const Maybe<VkClearValue>& renderPassClearValue,
3019 const Maybe<VkClearValue>& imageClearValue,
3020 const vector<Subpass>& subpasses,
3021 const vector<SubpassRenderInfo>& subpassRenderInfo,
3022 const PixelBufferAccess& errorImage,
3023 deUint32 attachmentIndex,
3024 const UVec2& renderPos,
3025 const UVec2& renderSize)
3027 const tcu::TextureFormat& format = result.getFormat();
3028 const bool hasDepth = tcu::hasDepthComponent(format.order);
3029 const bool hasStencil = tcu::hasStencilComponent(format.order);
3030 const bool isColorFormat = !hasDepth && !hasStencil;
3031 const PixelStatus initialStatus (isColorFormat ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3032 hasDepth ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3033 hasStencil ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK);
3035 bool attachmentIsUsed = false;
3036 vector<PixelStatus> status (result.getWidth() * result.getHeight(), initialStatus);
3037 tcu::clear(errorImage, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3039 // Check if attachment is used
3040 for (int subpassNdx = 0; subpassNdx < (int)subpasses.size(); subpassNdx++)
3042 const Subpass& subpass = subpasses[subpassNdx];
3043 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3045 if (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex)
3046 attachmentIsUsed = true;
3049 // Set all pixels that have undefined values to OK
3050 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3051 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)))
3053 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3054 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3056 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3058 if (isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3059 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3062 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3063 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3065 if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3066 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3071 // Check renderpass rendering results
3072 if (renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3073 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE))
3075 // Check subpass rendering results
3076 for (int subpassNdx = (int)subpasses.size() - 1; subpassNdx >= 0; subpassNdx--)
3078 const Subpass& subpass = subpasses[subpassNdx];
3079 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3080 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3082 // Check rendered quad
3083 if (renderInfo.getRenderQuad() && (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex))
3085 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3086 const Vec4 posA = renderQuad.getCornerA();
3087 const Vec4 posB = renderQuad.getCornerB();
3088 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3089 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3090 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
3091 (deInt32)(origin.y() + (p.y() * posA.y())));
3092 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
3093 (deInt32)(origin.y() + (p.y() * posB.y())));
3096 checkColorRenderQuad(result, posAI, posBI, status);
3100 checkDepthRenderQuad(result, posAI, posBI, status);
3102 if (hasDepth && hasStencil)
3103 checkStencilRenderQuad(*secondaryResult, posAI, posBI, status);
3104 else if (hasStencil)
3105 checkStencilRenderQuad(result, posAI, posBI, status);
3109 // Check color attachment clears
3110 if (attachmentNdx && !renderInfo.getColorClears().empty())
3112 const ColorClear& clear = renderInfo.getColorClears()[*attachmentNdx];
3114 checkColorClear(result, clear.getOffset(), clear.getSize(), status, clear.getColor());
3117 // Check depth/stencil attachment clears
3118 if (subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex && renderInfo.getDepthStencilClear())
3120 const DepthStencilClear clear = *renderInfo.getDepthStencilClear();
3123 checkDepthClear(result, clear.getOffset(), clear.getSize(), status, clear.getDepth());
3125 if (hasDepth && hasStencil)
3126 checkStencilClear(*secondaryResult, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3127 else if (hasStencil)
3128 checkStencilClear(result, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3132 // Check renderpas clear results
3133 if (attachmentIsUsed && renderPassClearValue)
3137 if (renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3138 checkColorClear(result, renderPos, renderSize, status, renderPassClearValue->color);
3142 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3143 checkDepthClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.depth);
3145 if (hasDepth && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3146 checkStencilClear(*secondaryResult, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3147 else if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3148 checkStencilClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3153 // Set all pixels that have undefined values fater renderpass to OK
3154 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3155 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)))
3157 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3158 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3160 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3162 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED
3163 && isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3164 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3167 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED
3168 && hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3169 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3171 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED
3172 && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3173 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3178 if (imageClearValue)
3181 checkColorClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->color);
3185 checkDepthClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.depth);
3187 if (hasDepth && hasStencil)
3188 checkStencilClear(*secondaryResult, UVec2(0, 0), UVec2(secondaryResult->getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3189 else if (hasStencil)
3190 checkStencilClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3197 for(int y = 0; y < result.getHeight(); y++)
3198 for(int x = 0; x < result.getWidth(); x++)
3200 const PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3204 if (pixelStatus.getColorStatus() != PixelStatus::STATUS_OK)
3206 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
3207 errorImage.setPixel(Vec4(1.0f, 1.0f, 0.0f, 1.0f), x, y);
3208 else if (pixelStatus.getColorStatus() == PixelStatus::STATUS_FAIL)
3209 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3216 if (hasDepth && pixelStatus.getDepthStatus() != PixelStatus::STATUS_OK)
3218 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3222 if (hasStencil && pixelStatus.getStencilStatus() != PixelStatus::STATUS_OK)
3224 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3234 bool logAndVerifyImages (TestLog& log,
3235 const DeviceInterface& vk,
3237 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3238 const vector<bool>& attachmentIsLazy,
3239 const RenderPass& renderPassInfo,
3240 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3241 const vector<Maybe<VkClearValue> >& imageClearValues,
3242 const vector<SubpassRenderInfo>& subpassRenderInfo,
3243 const UVec2& targetSize,
3244 const TestConfig& config)
3246 vector<tcu::TextureLevel> referenceAttachments;
3249 log << TestLog::Message << "Reference images fill undefined pixels with grid pattern." << TestLog::EndMessage;
3251 renderReferenceImages(referenceAttachments, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3253 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3255 if (!attachmentIsLazy[attachmentNdx])
3257 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3258 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3260 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3262 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3263 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3264 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3266 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3267 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3268 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3270 const VkMappedMemoryRange ranges[] =
3273 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3275 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3276 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3277 depthBufferSize // size;
3280 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3282 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3283 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3284 stencilBufferSize // size;
3287 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3290 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3291 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3292 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3294 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3295 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3297 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3299 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3300 && !verifyAttachment(depthAccess, tcu::just(stencilAccess), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3302 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3309 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3310 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3312 const VkMappedMemoryRange range =
3314 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3316 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3317 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3320 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3323 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3324 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3326 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3327 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3329 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3330 && !verifyAttachment(access, tcu::nothing<ConstPixelBufferAccess>(), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3332 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3343 std::string getAttachmentType (VkFormat vkFormat)
3345 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3346 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3348 switch (channelClass)
3350 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3353 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3356 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3357 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3358 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3362 DE_FATAL("Unknown channel class");
3367 void createTestShaders (SourceCollections& dst, TestConfig config)
3369 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3371 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3373 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3375 const Subpass& subpass = subpasses[subpassNdx];
3376 std::ostringstream vertexShader;
3377 std::ostringstream fragmentShader;
3379 vertexShader << "#version 310 es\n"
3380 << "layout(location = 0) in highp vec4 a_position;\n"
3381 << "layout(location = 0) out highp vec2 v_color;\n"
3382 << "void main (void) {\n"
3383 << "\thighp float a = 0.5 + a_position.x;\n"
3384 << "\thighp float b = 0.5 + a_position.y;\n"
3385 << "\tv_color = vec2(a, b);\n"
3386 << "\tgl_Position = a_position;\n"
3389 fragmentShader << "#version 310 es\n"
3390 << "layout(location = 0) in highp vec2 v_color;\n";
3392 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3394 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3395 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3398 fragmentShader << "void main (void) {\n"
3399 << "\thighp vec4 scale = vec4(v_color.x, v_color.y, v_color.x * v_color.y, (v_color.x + v_color.y) / 2.0);\n";
3401 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3403 const tcu::TextureFormat format = mapVkFormat(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3404 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
3405 const float clampMin = (float)(-MAX_INTEGER_VALUE);
3406 const float clampMax = (float)(MAX_INTEGER_VALUE);
3407 const Vec4 valueMax (de::clamp(formatInfo.valueMax[0], clampMin, clampMax),
3408 de::clamp(formatInfo.valueMax[1], clampMin, clampMax),
3409 de::clamp(formatInfo.valueMax[2], clampMin, clampMax),
3410 de::clamp(formatInfo.valueMax[3], clampMin, clampMax));
3412 const Vec4 valueMin (de::clamp(formatInfo.valueMin[0], clampMin, clampMax),
3413 de::clamp(formatInfo.valueMin[1], clampMin, clampMax),
3414 de::clamp(formatInfo.valueMin[2], clampMin, clampMax),
3415 de::clamp(formatInfo.valueMin[3], clampMin, clampMax));
3416 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3418 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4" << valueMin << " + vec4" << (valueMax - valueMin) << " * scale);\n";
3421 fragmentShader << "}\n";
3423 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3424 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3429 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3431 bool lastAttachmentWasLazy = false;
3433 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3435 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3436 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3437 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3438 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3440 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3442 attachmentIsLazy.push_back(true);
3443 lastAttachmentWasLazy = true;
3445 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3447 attachmentIsLazy.push_back(false);
3448 lastAttachmentWasLazy = false;
3451 DE_FATAL("Unknown imageMemory");
3454 attachmentIsLazy.push_back(false);
3458 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3460 bool lastSubpassWasSecondary = false;
3462 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3464 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3466 subpassIsSecondary.push_back(true);
3467 lastSubpassWasSecondary = true;
3469 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3471 subpassIsSecondary.push_back(false);
3472 lastSubpassWasSecondary = false;
3475 DE_FATAL("Unknown commandBuffer");
3479 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3481 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3483 if (!isLazy[attachmentNdx])
3484 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3486 clearValues.push_back(nothing<VkClearValue>());
3490 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3492 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3494 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3495 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3497 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3500 clearValues.push_back(nothing<VkClearValue>());
3504 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
3506 clearValues.resize(renderPass.getSubpasses().size());
3508 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3510 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
3511 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3513 clearValues[subpassNdx].resize(colorAttachments.size());
3515 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3517 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3518 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3520 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
3525 void logSubpassRenderInfo (TestLog& log,
3526 const SubpassRenderInfo& info)
3528 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
3530 if (info.isSecondary())
3531 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
3533 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
3535 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
3537 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
3539 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
3540 << ". Offset: " << colorClear.getOffset()
3541 << ", Size: " << colorClear.getSize()
3542 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
3545 if (info.getDepthStencilClear())
3547 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
3549 log << TestLog::Message << "Clearing depth stencil attachment"
3550 << ". Offset: " << depthStencilClear.getOffset()
3551 << ", Size: " << depthStencilClear.getSize()
3552 << ", Depth: " << depthStencilClear.getDepth()
3553 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
3556 if (info.getRenderQuad())
3558 const RenderQuad& renderQuad = *info.getRenderQuad();
3560 log << TestLog::Message << "Rendering gradient quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
3564 void logTestCaseInfo (TestLog& log,
3565 const TestConfig& config,
3566 const vector<bool>& attachmentIsLazy,
3567 const vector<Maybe<VkClearValue> >& imageClearValues,
3568 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3569 const vector<SubpassRenderInfo>& subpassRenderInfo)
3571 const RenderPass& renderPass = config.renderPass;
3573 logRenderPassInfo(log, renderPass);
3575 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
3576 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
3577 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
3579 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
3580 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
3582 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
3584 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
3586 if (attachmentIsLazy[attachmentNdx])
3587 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
3589 if (imageClearValues[attachmentNdx])
3590 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
3592 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
3593 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
3596 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3598 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
3600 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
3604 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
3606 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
3607 const vector<Subpass>& subpasses = renderPass.getSubpasses();
3608 bool lastSubpassWasSecondary = false;
3610 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
3612 const Subpass& subpass = subpasses[subpassNdx];
3613 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
3614 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
3615 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
3616 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
3617 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
3619 vector<ColorClear> colorClears;
3620 Maybe<DepthStencilClear> depthStencilClear;
3621 Maybe<RenderQuad> renderQuad;
3623 lastSubpassWasSecondary = subpassIsSecondary;
3625 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
3627 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3629 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3631 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3632 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3633 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3634 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
3635 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
3636 const VkClearColorValue color = randomColorClearValue(attachment, rng);
3638 colorClears.push_back(ColorClear(offset, size, color));
3641 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3643 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
3644 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3645 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
3646 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
3647 const VkClearValue value = randomClearValue(attachment, rng);
3649 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
3653 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3654 renderQuad = tcu::just(RenderQuad(tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f)));
3656 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
3660 void checkTextureFormatSupport (TestLog& log,
3661 const InstanceInterface& vk,
3662 VkPhysicalDevice device,
3663 const vector<Attachment>& attachments)
3665 bool supported = true;
3667 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3669 const Attachment& attachment = attachments[attachmentNdx];
3670 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3671 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
3672 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
3673 VkFormatProperties properties;
3675 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
3677 if ((properties.optimalTilingFeatures & flags) != flags)
3680 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
3685 TCU_THROW(NotSupportedError, "Format not supported");
3688 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
3690 const UVec2 targetSize = config.targetSize;
3691 const UVec2 renderPos = config.renderPos;
3692 const UVec2 renderSize = config.renderSize;
3693 const RenderPass& renderPassInfo = config.renderPass;
3695 TestLog& log = context.getTestContext().getLog();
3696 de::Random rng (config.seed);
3698 vector<bool> attachmentIsLazy;
3699 vector<Maybe<VkClearValue> > imageClearValues;
3700 vector<Maybe<VkClearValue> > renderPassClearValues;
3702 vector<bool> subpassIsSecondary;
3703 vector<SubpassRenderInfo> subpassRenderInfo;
3704 vector<vector<VkClearColorValue> > subpassColorClearValues;
3706 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
3707 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
3708 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
3710 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
3711 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
3712 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
3714 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
3716 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
3719 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3721 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
3723 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3725 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
3726 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
3731 const VkDevice device = context.getDevice();
3732 const DeviceInterface& vk = context.getDeviceInterface();
3733 const VkQueue queue = context.getUniversalQueue();
3734 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
3735 Allocator& allocator = context.getDefaultAllocator();
3737 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
3738 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
3739 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3740 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3741 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3743 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
3744 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
3745 vector<VkImageView> attachmentViews;
3747 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3749 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
3751 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentIsLazy[attachmentNdx])));
3752 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
3755 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3756 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
3757 endCommandBuffer(vk, *initializeImagesCommandBuffer);
3760 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
3762 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3763 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, subpassRenderInfo[subpassNdx])));
3765 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3766 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
3767 endCommandBuffer(vk, *renderCommandBuffer);
3769 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3770 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
3771 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
3773 const VkCommandBuffer commandBuffers[] =
3775 *initializeImagesCommandBuffer,
3776 *renderCommandBuffer,
3777 *readImagesToBuffersCommandBuffer
3779 const Unique<VkFence> fence (createFence(vk, device, 0u));
3781 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
3782 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
3786 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
3787 return tcu::TestStatus::pass("Pass");
3789 return tcu::TestStatus::fail("Result verification failed");
3793 static const VkFormat s_coreColorFormats[] =
3795 VK_FORMAT_R5G6B5_UNORM_PACK16,
3800 VK_FORMAT_R8G8_UNORM,
3801 VK_FORMAT_R8G8_SNORM,
3802 VK_FORMAT_R8G8_UINT,
3803 VK_FORMAT_R8G8_SINT,
3804 VK_FORMAT_R8G8B8A8_UNORM,
3805 VK_FORMAT_R8G8B8A8_SNORM,
3806 VK_FORMAT_R8G8B8A8_UINT,
3807 VK_FORMAT_R8G8B8A8_SINT,
3808 VK_FORMAT_R8G8B8A8_SRGB,
3809 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3810 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3811 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3812 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3813 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3814 VK_FORMAT_B8G8R8A8_UNORM,
3815 VK_FORMAT_B8G8R8A8_SRGB,
3816 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3817 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3818 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3819 VK_FORMAT_R16_UNORM,
3820 VK_FORMAT_R16_SNORM,
3823 VK_FORMAT_R16_SFLOAT,
3824 VK_FORMAT_R16G16_UNORM,
3825 VK_FORMAT_R16G16_SNORM,
3826 VK_FORMAT_R16G16_UINT,
3827 VK_FORMAT_R16G16_SINT,
3828 VK_FORMAT_R16G16_SFLOAT,
3829 VK_FORMAT_R16G16B16A16_UNORM,
3830 VK_FORMAT_R16G16B16A16_SNORM,
3831 VK_FORMAT_R16G16B16A16_UINT,
3832 VK_FORMAT_R16G16B16A16_SINT,
3833 VK_FORMAT_R16G16B16A16_SFLOAT,
3836 VK_FORMAT_R32_SFLOAT,
3837 VK_FORMAT_R32G32_UINT,
3838 VK_FORMAT_R32G32_SINT,
3839 VK_FORMAT_R32G32_SFLOAT,
3840 VK_FORMAT_R32G32B32A32_UINT,
3841 VK_FORMAT_R32G32B32A32_SINT,
3842 VK_FORMAT_R32G32B32A32_SFLOAT
3845 static const VkFormat s_coreDepthStencilFormats[] =
3847 VK_FORMAT_D16_UNORM,
3849 VK_FORMAT_X8_D24_UNORM_PACK32,
3850 VK_FORMAT_D32_SFLOAT,
3852 VK_FORMAT_D24_UNORM_S8_UINT,
3853 VK_FORMAT_D32_SFLOAT_S8_UINT
3856 de::MovePtr<tcu::TestCaseGroup> createAttachmentTestCaseGroup (tcu::TestContext& testCtx)
3858 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
3859 const VkAttachmentLoadOp loadOps[] =
3861 VK_ATTACHMENT_LOAD_OP_LOAD,
3862 VK_ATTACHMENT_LOAD_OP_CLEAR,
3863 VK_ATTACHMENT_LOAD_OP_DONT_CARE
3866 const VkAttachmentStoreOp storeOps[] =
3868 VK_ATTACHMENT_STORE_OP_STORE,
3869 VK_ATTACHMENT_STORE_OP_DONT_CARE
3872 const VkImageLayout initialAndFinalColorLayouts[] =
3874 VK_IMAGE_LAYOUT_GENERAL,
3875 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3876 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3877 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3878 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3881 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
3883 VK_IMAGE_LAYOUT_GENERAL,
3884 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3885 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
3886 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3887 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3888 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3891 const VkImageLayout subpassLayouts[] =
3893 VK_IMAGE_LAYOUT_GENERAL,
3894 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
3897 const VkImageLayout depthStencilLayouts[] =
3899 VK_IMAGE_LAYOUT_GENERAL,
3900 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
3903 const TestConfig::RenderTypes renderCommands[] =
3905 TestConfig::RENDERTYPES_NONE,
3906 TestConfig::RENDERTYPES_CLEAR,
3907 TestConfig::RENDERTYPES_DRAW,
3908 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
3911 const TestConfig::CommandBufferTypes commandBuffers[] =
3913 TestConfig::COMMANDBUFFERTYPES_INLINE,
3914 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
3915 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
3918 const TestConfig::ImageMemory imageMemories[] =
3920 TestConfig::IMAGEMEMORY_STRICT,
3921 TestConfig::IMAGEMEMORY_LAZY,
3922 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
3925 const UVec2 targetSizes[] =
3931 const UVec2 renderPositions[] =
3937 const UVec2 renderSizes[] =
3943 de::Random rng (1433774382u);
3944 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment", "Attachment format and count tests with load and store ops and image layouts"));
3946 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
3948 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
3949 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
3950 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
3952 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
3954 const bool useDepthStencil = rng.getBool();
3955 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
3956 vector<Attachment> attachments;
3957 vector<AttachmentReference> colorAttachmentReferences;
3959 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
3961 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3962 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
3963 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3964 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3966 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3967 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3968 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
3970 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3971 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3973 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3974 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
3977 if (useDepthStencil)
3979 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3980 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
3981 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3982 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3984 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3985 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3987 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3988 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3990 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
3991 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3995 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
3996 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
3997 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
3998 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<AttachmentReference>()));
3999 const vector<SubpassDependency> deps;
4001 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4002 const RenderPass renderPass (attachments, subpasses, deps);
4003 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4004 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4005 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4007 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
4011 group->addChild(attachmentCountGroup.release());
4017 de::MovePtr<tcu::TestCaseGroup> createAttachmentAllocationTestGroup (tcu::TestContext& testCtx)
4019 const deUint32 attachmentCounts[] = { 4, 8 };
4020 const VkAttachmentLoadOp loadOps[] =
4022 VK_ATTACHMENT_LOAD_OP_LOAD,
4023 VK_ATTACHMENT_LOAD_OP_CLEAR,
4024 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4027 const VkAttachmentStoreOp storeOps[] =
4029 VK_ATTACHMENT_STORE_OP_STORE,
4030 VK_ATTACHMENT_STORE_OP_DONT_CARE
4033 const VkImageLayout initialAndFinalLayouts[] =
4035 VK_IMAGE_LAYOUT_GENERAL,
4036 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4037 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4038 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4039 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4040 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4041 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4044 const VkImageLayout subpassLayouts[] =
4046 VK_IMAGE_LAYOUT_GENERAL,
4047 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4052 // Each pass uses one more attachmen than previous one
4053 ALLOCATIONTYPE_GROW,
4054 // Each pass uses one less attachment than previous one
4055 ALLOCATIONTYPE_SHRINK,
4056 // Each pass drops one attachment and picks up new one
4057 ALLOCATIONTYPE_ROLL,
4058 // Start by growing and end by shrinking
4059 ALLOCATIONTYPE_GROW_SHRINK
4062 const AllocationType allocationTypes[] =
4064 ALLOCATIONTYPE_GROW,
4065 ALLOCATIONTYPE_SHRINK,
4066 ALLOCATIONTYPE_ROLL,
4067 ALLOCATIONTYPE_GROW_SHRINK
4070 const char* const allocationTypeStr[] =
4078 const TestConfig::RenderTypes renderCommands[] =
4080 TestConfig::RENDERTYPES_NONE,
4081 TestConfig::RENDERTYPES_CLEAR,
4082 TestConfig::RENDERTYPES_DRAW,
4083 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4086 const TestConfig::CommandBufferTypes commandBuffers[] =
4088 TestConfig::COMMANDBUFFERTYPES_INLINE,
4089 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4090 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4093 const TestConfig::ImageMemory imageMemories[] =
4095 TestConfig::IMAGEMEMORY_STRICT,
4096 TestConfig::IMAGEMEMORY_LAZY,
4097 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4100 const UVec2 targetSizes[] =
4106 const UVec2 renderPositions[] =
4112 const UVec2 renderSizes[] =
4118 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment_allocation", "Attachment allocation tests"));
4119 de::Random rng (3700649827u);
4121 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4123 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4124 const size_t testCaseCount = 100;
4125 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4127 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4129 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4130 vector<Attachment> attachments;
4131 vector<Subpass> subpasses;
4133 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4135 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4136 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4137 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4138 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4140 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4141 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4143 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4144 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4146 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4149 if (allocationType == ALLOCATIONTYPE_GROW)
4151 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4153 vector<AttachmentReference> colorAttachmentReferences;
4155 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4157 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4159 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4162 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4165 else if (allocationType == ALLOCATIONTYPE_SHRINK)
4167 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4169 vector<AttachmentReference> colorAttachmentReferences;
4171 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4173 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4175 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4178 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4181 else if (allocationType == ALLOCATIONTYPE_ROLL)
4183 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
4185 vector<AttachmentReference> colorAttachmentReferences;
4187 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
4189 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4191 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
4194 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4197 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
4199 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4201 vector<AttachmentReference> colorAttachmentReferences;
4203 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4205 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4207 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4210 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4213 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4215 vector<AttachmentReference> colorAttachmentReferences;
4217 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4219 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4221 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4224 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4228 DE_FATAL("Unknown allocation type");
4231 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4232 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4233 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4235 const string testCaseName = de::toString(testCaseNdx);
4236 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4237 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4238 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4240 vector<SubpassDependency> deps;
4242 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
4244 const bool byRegion = rng.getBool();
4245 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
4246 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4247 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4248 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4249 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4251 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4252 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4253 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4254 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4256 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4257 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, // \todo [pyry] Correct?
4259 byRegion ? (VkBool32)VK_TRUE : (VkBool32)VK_FALSE));
4262 const RenderPass renderPass (attachments, subpasses, deps);
4264 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4268 group->addChild(allocationTypeGroup.release());
4274 de::MovePtr<tcu::TestCaseGroup> createSimpleTestGroup (tcu::TestContext& testCtx)
4276 const UVec2 targetSize (64, 64);
4277 const UVec2 renderPos (0, 0);
4278 const UVec2 renderSize (64, 64);
4279 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "simple", "Simple basic render pass tests"));
4283 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4284 VK_SAMPLE_COUNT_1_BIT,
4285 VK_ATTACHMENT_LOAD_OP_CLEAR,
4286 VK_ATTACHMENT_STORE_OP_STORE,
4287 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4288 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4289 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4290 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4291 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4293 vector<AttachmentReference>(),
4294 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4295 vector<AttachmentReference>(),
4296 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4297 vector<AttachmentReference>())),
4298 vector<SubpassDependency>());
4300 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4305 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4306 VK_SAMPLE_COUNT_1_BIT,
4307 VK_ATTACHMENT_LOAD_OP_CLEAR,
4308 VK_ATTACHMENT_STORE_OP_STORE,
4309 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4310 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4311 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4312 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4313 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4315 vector<AttachmentReference>(),
4316 vector<AttachmentReference>(),
4317 vector<AttachmentReference>(),
4318 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4319 vector<AttachmentReference>())),
4320 vector<SubpassDependency>());
4322 addFunctionCaseWithPrograms<TestConfig>(group.get(), "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4327 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
4328 VK_SAMPLE_COUNT_1_BIT,
4329 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4330 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4331 VK_ATTACHMENT_LOAD_OP_CLEAR,
4332 VK_ATTACHMENT_STORE_OP_STORE,
4333 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4334 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4335 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4337 vector<AttachmentReference>(),
4338 vector<AttachmentReference>(),
4339 vector<AttachmentReference>(),
4340 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4341 vector<AttachmentReference>())),
4342 vector<SubpassDependency>());
4344 addFunctionCaseWithPrograms<TestConfig>(group.get(), "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4349 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4350 VK_SAMPLE_COUNT_1_BIT,
4351 VK_ATTACHMENT_LOAD_OP_CLEAR,
4352 VK_ATTACHMENT_STORE_OP_STORE,
4353 VK_ATTACHMENT_LOAD_OP_CLEAR,
4354 VK_ATTACHMENT_STORE_OP_STORE,
4355 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4356 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4357 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4359 vector<AttachmentReference>(),
4360 vector<AttachmentReference>(),
4361 vector<AttachmentReference>(),
4362 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4363 vector<AttachmentReference>())),
4364 vector<SubpassDependency>());
4366 addFunctionCaseWithPrograms<TestConfig>(group.get(), "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4371 const Attachment attachments[] =
4373 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4374 VK_SAMPLE_COUNT_1_BIT,
4375 VK_ATTACHMENT_LOAD_OP_CLEAR,
4376 VK_ATTACHMENT_STORE_OP_STORE,
4377 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4378 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4379 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4380 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4381 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4382 VK_SAMPLE_COUNT_1_BIT,
4383 VK_ATTACHMENT_LOAD_OP_CLEAR,
4384 VK_ATTACHMENT_STORE_OP_STORE,
4385 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4386 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4387 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4388 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4391 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4392 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4394 vector<AttachmentReference>(),
4395 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4396 vector<AttachmentReference>(),
4397 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4398 vector<AttachmentReference>())),
4399 vector<SubpassDependency>());
4401 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4406 const Attachment attachments[] =
4408 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4409 VK_SAMPLE_COUNT_1_BIT,
4410 VK_ATTACHMENT_LOAD_OP_CLEAR,
4411 VK_ATTACHMENT_STORE_OP_STORE,
4412 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4413 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4414 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4415 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4416 Attachment(VK_FORMAT_S8_UINT,
4417 VK_SAMPLE_COUNT_1_BIT,
4418 VK_ATTACHMENT_LOAD_OP_CLEAR,
4419 VK_ATTACHMENT_STORE_OP_STORE,
4420 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4421 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4422 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4423 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4426 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4427 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4429 vector<AttachmentReference>(),
4430 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4431 vector<AttachmentReference>(),
4432 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4433 vector<AttachmentReference>())),
4434 vector<SubpassDependency>());
4437 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4440 // color_depth_stencil
4442 const Attachment attachments[] =
4444 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4445 VK_SAMPLE_COUNT_1_BIT,
4446 VK_ATTACHMENT_LOAD_OP_CLEAR,
4447 VK_ATTACHMENT_STORE_OP_STORE,
4448 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4449 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4450 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4451 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4452 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4453 VK_SAMPLE_COUNT_1_BIT,
4454 VK_ATTACHMENT_LOAD_OP_CLEAR,
4455 VK_ATTACHMENT_STORE_OP_STORE,
4456 VK_ATTACHMENT_LOAD_OP_CLEAR,
4457 VK_ATTACHMENT_STORE_OP_STORE,
4458 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4459 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4462 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4463 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4465 vector<AttachmentReference>(),
4466 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4467 vector<AttachmentReference>(),
4468 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4469 vector<AttachmentReference>())),
4470 vector<SubpassDependency>());
4472 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4478 std::string formatToName (VkFormat format)
4480 const std::string formatStr = de::toString(format);
4481 const std::string prefix = "VK_FORMAT_";
4483 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4485 return de::toLower(formatStr.substr(prefix.length()));
4488 de::MovePtr<tcu::TestCaseGroup> createFormatTestGroup(tcu::TestContext& testCtx)
4490 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "formats", "Tests for different image formats."));
4492 const UVec2 targetSize (64, 64);
4493 const UVec2 renderPos (0, 0);
4494 const UVec2 renderSize (64, 64);
4498 const char* const str;
4499 const VkAttachmentLoadOp op;
4502 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
4503 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
4504 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
4509 const char* const str;
4510 const TestConfig::RenderTypes types;
4513 { "clear", TestConfig::RENDERTYPES_CLEAR },
4514 { "draw", TestConfig::RENDERTYPES_DRAW },
4515 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
4519 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
4521 const VkFormat format = s_coreColorFormats[formatNdx];
4522 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4524 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4526 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4527 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4529 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4531 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4532 VK_SAMPLE_COUNT_1_BIT,
4534 VK_ATTACHMENT_STORE_OP_STORE,
4535 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4536 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4537 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4538 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4539 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4541 vector<AttachmentReference>(),
4542 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4543 vector<AttachmentReference>(),
4544 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4545 vector<AttachmentReference>())),
4546 vector<SubpassDependency>());
4548 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4551 formatGroup->addChild(loadOpGroup.release());
4554 group->addChild(formatGroup.release());
4557 // Depth stencil formats
4558 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
4560 const VkFormat format = s_coreDepthStencilFormats[formatNdx];
4561 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4563 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4565 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4566 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4568 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4570 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4571 VK_SAMPLE_COUNT_1_BIT,
4572 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4573 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4575 VK_ATTACHMENT_STORE_OP_STORE,
4576 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4577 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4578 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4580 vector<AttachmentReference>(),
4581 vector<AttachmentReference>(),
4582 vector<AttachmentReference>(),
4583 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4584 vector<AttachmentReference>())),
4585 vector<SubpassDependency>());
4587 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4590 formatGroup->addChild(loadOpGroup.release());
4593 group->addChild(formatGroup.release());
4601 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
4603 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
4605 renderpassTests->addChild(createSimpleTestGroup(testCtx).release());
4606 renderpassTests->addChild(createFormatTestGroup(testCtx).release());
4607 renderpassTests->addChild(createAttachmentTestCaseGroup(testCtx).release());
4608 renderpassTests->addChild(createAttachmentAllocationTestGroup(testCtx).release());
4610 return renderpassTests.release();