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 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2809 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2810 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2811 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2813 const Vec4 resColor (result.getPixel(x, y));
2815 const Vec4 minRefColor = srgb ? tcu::linearToSRGB(valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs))
2816 : valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs) - threshold;
2817 const Vec4 maxRefColor = srgb ? tcu::linearToSRGB(valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs))
2818 : valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs) + threshold;
2820 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2821 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2822 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2823 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2825 if (tcu::anyNotEqual(tcu::logicalAnd(
2826 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2827 lessThanEqual(resColor, maxRefColor)),
2828 channelMask), channelMask))
2831 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2834 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2841 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2843 for (int y = posA.y(); y <= posB.y(); y++)
2844 for (int x = posA.x(); x <= posB.x(); x++)
2846 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2848 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2850 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2851 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2852 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2853 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2855 const UVec4 resColor (result.getPixelUint(x, y));
2857 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2858 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2860 const UVec4 minRefColor (minRefColorF.asUint());
2861 const UVec4 maxRefColor (maxRefColorF.asUint());
2863 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2864 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2865 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2866 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2868 if (tcu::anyNotEqual(tcu::logicalAnd(
2869 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2870 lessThanEqual(resColor, maxRefColor)),
2871 channelMask), channelMask))
2874 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2877 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2884 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2886 for (int y = posA.y(); y <= posB.y(); y++)
2887 for (int x = posA.x(); x <= posB.x(); x++)
2889 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2891 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2893 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2894 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2895 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2896 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2898 const IVec4 resColor (result.getPixelInt(x, y));
2900 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2901 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2903 const IVec4 minRefColor (minRefColorF.asInt());
2904 const IVec4 maxRefColor (maxRefColorF.asInt());
2906 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2907 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2908 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2909 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2911 if (tcu::anyNotEqual(tcu::logicalAnd(
2912 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2913 lessThanEqual(resColor, maxRefColor)),
2914 channelMask), channelMask))
2917 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2920 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2928 DE_FATAL("Invalid channel class");
2932 void checkColorClear (const ConstPixelBufferAccess& result,
2933 const UVec2& offset,
2935 vector<PixelStatus>& status,
2936 const VkClearColorValue& color)
2938 DE_ASSERT(offset.x() + size.x() <= (deUint32)result.getWidth());
2939 DE_ASSERT(offset.y() + size.y() <= (deUint32)result.getHeight());
2941 DE_ASSERT(result.getWidth() * result.getHeight() == (int)status.size());
2943 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2944 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2946 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2948 DE_ASSERT(x + y * result.getWidth() < (int)status.size());
2950 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2952 if (comparePixelToColorClearValue(result, x, y, color))
2953 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2955 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2960 void checkDepthClear (const ConstPixelBufferAccess& result,
2961 const UVec2& offset,
2963 vector<PixelStatus>& status,
2966 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2967 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2969 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2971 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2973 if (comparePixelToDepthClearValue(result, x, y, depth))
2974 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2976 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2981 void checkStencilClear (const ConstPixelBufferAccess& result,
2982 const UVec2& offset,
2984 vector<PixelStatus>& status,
2987 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2988 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2990 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2992 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2994 if (comparePixelToStencilClearValue(result, x, y, stencil))
2995 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2997 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
3002 bool verifyAttachment (const ConstPixelBufferAccess& result,
3003 const Maybe<ConstPixelBufferAccess>& secondaryResult,
3004 const RenderPass& renderPassInfo,
3005 const Maybe<VkClearValue>& renderPassClearValue,
3006 const Maybe<VkClearValue>& imageClearValue,
3007 const vector<Subpass>& subpasses,
3008 const vector<SubpassRenderInfo>& subpassRenderInfo,
3009 const PixelBufferAccess& errorImage,
3010 deUint32 attachmentIndex,
3011 const UVec2& renderPos,
3012 const UVec2& renderSize)
3014 const tcu::TextureFormat& format = result.getFormat();
3015 const bool hasDepth = tcu::hasDepthComponent(format.order);
3016 const bool hasStencil = tcu::hasStencilComponent(format.order);
3017 const bool isColorFormat = !hasDepth && !hasStencil;
3018 const PixelStatus initialStatus (isColorFormat ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3019 hasDepth ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3020 hasStencil ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK);
3022 bool attachmentIsUsed = false;
3023 vector<PixelStatus> status (result.getWidth() * result.getHeight(), initialStatus);
3024 tcu::clear(errorImage, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3026 // Check if attachment is used
3027 for (int subpassNdx = 0; subpassNdx < (int)subpasses.size(); subpassNdx++)
3029 const Subpass& subpass = subpasses[subpassNdx];
3030 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3032 if (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex)
3033 attachmentIsUsed = true;
3036 // Set all pixels that have undefined values to OK
3037 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3038 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)))
3040 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3041 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3043 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3045 if (isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3046 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3049 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3050 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3052 if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3053 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3058 // Check renderpass rendering results
3059 if (renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3060 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE))
3062 // Check subpass rendering results
3063 for (int subpassNdx = (int)subpasses.size() - 1; subpassNdx >= 0; subpassNdx--)
3065 const Subpass& subpass = subpasses[subpassNdx];
3066 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3067 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3069 // Check rendered quad
3070 if (renderInfo.getRenderQuad() && (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex))
3072 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3073 const Vec4 posA = renderQuad.getCornerA();
3074 const Vec4 posB = renderQuad.getCornerB();
3075 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3076 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3077 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
3078 (deInt32)(origin.y() + (p.y() * posA.y())));
3079 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
3080 (deInt32)(origin.y() + (p.y() * posB.y())));
3083 checkColorRenderQuad(result, posAI, posBI, status);
3087 checkDepthRenderQuad(result, posAI, posBI, status);
3089 if (hasDepth && hasStencil)
3090 checkStencilRenderQuad(*secondaryResult, posAI, posBI, status);
3091 else if (hasStencil)
3092 checkStencilRenderQuad(result, posAI, posBI, status);
3096 // Check color attachment clears
3097 if (attachmentNdx && !renderInfo.getColorClears().empty())
3099 const ColorClear& clear = renderInfo.getColorClears()[*attachmentNdx];
3101 checkColorClear(result, clear.getOffset(), clear.getSize(), status, clear.getColor());
3104 // Check depth/stencil attachment clears
3105 if (subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex && renderInfo.getDepthStencilClear())
3107 const DepthStencilClear clear = *renderInfo.getDepthStencilClear();
3110 checkDepthClear(result, clear.getOffset(), clear.getSize(), status, clear.getDepth());
3112 if (hasDepth && hasStencil)
3113 checkStencilClear(*secondaryResult, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3114 else if (hasStencil)
3115 checkStencilClear(result, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3119 // Check renderpas clear results
3120 if (attachmentIsUsed && renderPassClearValue)
3124 if (renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3125 checkColorClear(result, renderPos, renderSize, status, renderPassClearValue->color);
3129 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3130 checkDepthClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.depth);
3132 if (hasDepth && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3133 checkStencilClear(*secondaryResult, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3134 else if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3135 checkStencilClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3140 // Set all pixels that have undefined values fater renderpass to OK
3141 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3142 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)))
3144 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3145 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3147 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3149 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED
3150 && isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3151 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3154 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED
3155 && hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3156 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3158 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED
3159 && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3160 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3165 if (imageClearValue)
3168 checkColorClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->color);
3172 checkDepthClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.depth);
3174 if (hasDepth && hasStencil)
3175 checkStencilClear(*secondaryResult, UVec2(0, 0), UVec2(secondaryResult->getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3176 else if (hasStencil)
3177 checkStencilClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3184 for(int y = 0; y < result.getHeight(); y++)
3185 for(int x = 0; x < result.getWidth(); x++)
3187 const PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3191 if (pixelStatus.getColorStatus() != PixelStatus::STATUS_OK)
3193 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
3194 errorImage.setPixel(Vec4(1.0f, 1.0f, 0.0f, 1.0f), x, y);
3195 else if (pixelStatus.getColorStatus() == PixelStatus::STATUS_FAIL)
3196 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3203 if (hasDepth && pixelStatus.getDepthStatus() != PixelStatus::STATUS_OK)
3205 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3209 if (hasStencil && pixelStatus.getStencilStatus() != PixelStatus::STATUS_OK)
3211 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3221 bool logAndVerifyImages (TestLog& log,
3222 const DeviceInterface& vk,
3224 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3225 const vector<bool>& attachmentIsLazy,
3226 const RenderPass& renderPassInfo,
3227 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3228 const vector<Maybe<VkClearValue> >& imageClearValues,
3229 const vector<SubpassRenderInfo>& subpassRenderInfo,
3230 const UVec2& targetSize,
3231 const TestConfig& config)
3233 vector<tcu::TextureLevel> referenceAttachments;
3236 log << TestLog::Message << "Reference images fill undefined pixels with grid pattern." << TestLog::EndMessage;
3238 renderReferenceImages(referenceAttachments, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3240 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3242 if (!attachmentIsLazy[attachmentNdx])
3244 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3245 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3247 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3249 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3250 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3251 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3253 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3254 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3255 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3257 const VkMappedMemoryRange ranges[] =
3260 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3262 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3263 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3264 depthBufferSize // size;
3267 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3269 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3270 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3271 stencilBufferSize // size;
3274 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3277 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3278 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3279 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3281 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3282 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3284 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3286 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3287 && !verifyAttachment(depthAccess, tcu::just(stencilAccess), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3289 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3296 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3297 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3299 const VkMappedMemoryRange range =
3301 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3303 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3304 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3307 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3310 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3311 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3313 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3314 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3316 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3317 && !verifyAttachment(access, tcu::nothing<ConstPixelBufferAccess>(), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3319 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3330 std::string getAttachmentType (VkFormat vkFormat)
3332 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3333 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3335 switch (channelClass)
3337 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3340 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3343 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3344 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3345 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3349 DE_FATAL("Unknown channel class");
3354 void createTestShaders (SourceCollections& dst, TestConfig config)
3356 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3358 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3360 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3362 const Subpass& subpass = subpasses[subpassNdx];
3363 std::ostringstream vertexShader;
3364 std::ostringstream fragmentShader;
3366 vertexShader << "#version 310 es\n"
3367 << "layout(location = 0) in highp vec4 a_position;\n"
3368 << "layout(location = 0) out highp vec2 v_color;\n"
3369 << "void main (void) {\n"
3370 << "\thighp float a = 0.5 + a_position.x;\n"
3371 << "\thighp float b = 0.5 + a_position.y;\n"
3372 << "\tv_color = vec2(a, b);\n"
3373 << "\tgl_Position = a_position;\n"
3376 fragmentShader << "#version 310 es\n"
3377 << "layout(location = 0) in highp vec2 v_color;\n";
3379 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3381 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3382 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3385 fragmentShader << "void main (void) {\n"
3386 << "\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";
3388 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3390 const tcu::TextureFormat format = mapVkFormat(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3391 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
3392 const float clampMin = (float)(-MAX_INTEGER_VALUE);
3393 const float clampMax = (float)(MAX_INTEGER_VALUE);
3394 const Vec4 valueMax (de::clamp(formatInfo.valueMax[0], clampMin, clampMax),
3395 de::clamp(formatInfo.valueMax[1], clampMin, clampMax),
3396 de::clamp(formatInfo.valueMax[2], clampMin, clampMax),
3397 de::clamp(formatInfo.valueMax[3], clampMin, clampMax));
3399 const Vec4 valueMin (de::clamp(formatInfo.valueMin[0], clampMin, clampMax),
3400 de::clamp(formatInfo.valueMin[1], clampMin, clampMax),
3401 de::clamp(formatInfo.valueMin[2], clampMin, clampMax),
3402 de::clamp(formatInfo.valueMin[3], clampMin, clampMax));
3403 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3405 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4" << valueMin << " + vec4" << (valueMax - valueMin) << " * scale);\n";
3408 fragmentShader << "}\n";
3410 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3411 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3416 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3418 bool lastAttachmentWasLazy = false;
3420 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3422 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3423 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3424 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3425 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3427 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3429 attachmentIsLazy.push_back(true);
3430 lastAttachmentWasLazy = true;
3432 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3434 attachmentIsLazy.push_back(false);
3435 lastAttachmentWasLazy = false;
3438 DE_FATAL("Unknown imageMemory");
3441 attachmentIsLazy.push_back(false);
3445 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3447 bool lastSubpassWasSecondary = false;
3449 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3451 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3453 subpassIsSecondary.push_back(true);
3454 lastSubpassWasSecondary = true;
3456 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3458 subpassIsSecondary.push_back(false);
3459 lastSubpassWasSecondary = false;
3462 DE_FATAL("Unknown commandBuffer");
3466 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3468 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3470 if (!isLazy[attachmentNdx])
3471 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3473 clearValues.push_back(nothing<VkClearValue>());
3477 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3479 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3481 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3482 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3484 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3487 clearValues.push_back(nothing<VkClearValue>());
3491 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
3493 clearValues.resize(renderPass.getSubpasses().size());
3495 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3497 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
3498 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3500 clearValues[subpassNdx].resize(colorAttachments.size());
3502 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3504 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3505 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3507 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
3512 void logSubpassRenderInfo (TestLog& log,
3513 const SubpassRenderInfo& info)
3515 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
3517 if (info.isSecondary())
3518 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
3520 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
3522 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
3524 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
3526 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
3527 << ". Offset: " << colorClear.getOffset()
3528 << ", Size: " << colorClear.getSize()
3529 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
3532 if (info.getDepthStencilClear())
3534 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
3536 log << TestLog::Message << "Clearing depth stencil attachment"
3537 << ". Offset: " << depthStencilClear.getOffset()
3538 << ", Size: " << depthStencilClear.getSize()
3539 << ", Depth: " << depthStencilClear.getDepth()
3540 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
3543 if (info.getRenderQuad())
3545 const RenderQuad& renderQuad = *info.getRenderQuad();
3547 log << TestLog::Message << "Rendering gradient quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
3551 void logTestCaseInfo (TestLog& log,
3552 const TestConfig& config,
3553 const vector<bool>& attachmentIsLazy,
3554 const vector<Maybe<VkClearValue> >& imageClearValues,
3555 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3556 const vector<SubpassRenderInfo>& subpassRenderInfo)
3558 const RenderPass& renderPass = config.renderPass;
3560 logRenderPassInfo(log, renderPass);
3562 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
3563 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
3564 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
3566 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
3567 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
3569 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
3571 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
3573 if (attachmentIsLazy[attachmentNdx])
3574 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
3576 if (imageClearValues[attachmentNdx])
3577 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
3579 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
3580 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
3583 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3585 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
3587 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
3591 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
3593 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
3594 const vector<Subpass>& subpasses = renderPass.getSubpasses();
3595 bool lastSubpassWasSecondary = false;
3597 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
3599 const Subpass& subpass = subpasses[subpassNdx];
3600 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
3601 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
3602 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
3603 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
3604 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
3606 vector<ColorClear> colorClears;
3607 Maybe<DepthStencilClear> depthStencilClear;
3608 Maybe<RenderQuad> renderQuad;
3610 lastSubpassWasSecondary = subpassIsSecondary;
3612 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
3614 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3616 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3618 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3619 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3620 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3621 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
3622 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
3623 const VkClearColorValue color = randomColorClearValue(attachment, rng);
3625 colorClears.push_back(ColorClear(offset, size, color));
3628 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3630 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
3631 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3632 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
3633 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
3634 const VkClearValue value = randomClearValue(attachment, rng);
3636 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
3640 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3641 renderQuad = tcu::just(RenderQuad(tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f)));
3643 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
3647 void checkTextureFormatSupport (TestLog& log,
3648 const InstanceInterface& vk,
3649 VkPhysicalDevice device,
3650 const vector<Attachment>& attachments)
3652 bool supported = true;
3654 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3656 const Attachment& attachment = attachments[attachmentNdx];
3657 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3658 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
3659 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
3660 VkFormatProperties properties;
3662 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
3664 if ((properties.optimalTilingFeatures & flags) != flags)
3667 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
3672 TCU_THROW(NotSupportedError, "Format not supported");
3675 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
3677 const UVec2 targetSize = config.targetSize;
3678 const UVec2 renderPos = config.renderPos;
3679 const UVec2 renderSize = config.renderSize;
3680 const RenderPass& renderPassInfo = config.renderPass;
3682 TestLog& log = context.getTestContext().getLog();
3683 de::Random rng (config.seed);
3685 vector<bool> attachmentIsLazy;
3686 vector<Maybe<VkClearValue> > imageClearValues;
3687 vector<Maybe<VkClearValue> > renderPassClearValues;
3689 vector<bool> subpassIsSecondary;
3690 vector<SubpassRenderInfo> subpassRenderInfo;
3691 vector<vector<VkClearColorValue> > subpassColorClearValues;
3693 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
3694 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
3695 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
3697 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
3698 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
3699 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
3701 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
3703 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
3706 const VkDevice device = context.getDevice();
3707 const DeviceInterface& vk = context.getDeviceInterface();
3708 const VkQueue queue = context.getUniversalQueue();
3709 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
3710 Allocator& allocator = context.getDefaultAllocator();
3712 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
3713 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
3714 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3715 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3716 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3718 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
3719 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
3720 vector<VkImageView> attachmentViews;
3722 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3724 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
3726 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentIsLazy[attachmentNdx])));
3727 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
3730 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3731 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
3732 endCommandBuffer(vk, *initializeImagesCommandBuffer);
3735 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
3737 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3738 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, subpassRenderInfo[subpassNdx])));
3740 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3741 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
3742 endCommandBuffer(vk, *renderCommandBuffer);
3744 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3745 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
3746 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
3748 const VkCommandBuffer commandBuffers[] =
3750 *initializeImagesCommandBuffer,
3751 *renderCommandBuffer,
3752 *readImagesToBuffersCommandBuffer
3754 const Unique<VkFence> fence (createFence(vk, device, 0u));
3756 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
3757 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
3761 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
3762 return tcu::TestStatus::pass("Pass");
3764 return tcu::TestStatus::fail("Result verification failed");
3768 static const VkFormat s_coreColorFormats[] =
3770 VK_FORMAT_R5G6B5_UNORM_PACK16,
3775 VK_FORMAT_R8G8_UNORM,
3776 VK_FORMAT_R8G8_SNORM,
3777 VK_FORMAT_R8G8_UINT,
3778 VK_FORMAT_R8G8_SINT,
3779 VK_FORMAT_R8G8B8A8_UNORM,
3780 VK_FORMAT_R8G8B8A8_SNORM,
3781 VK_FORMAT_R8G8B8A8_UINT,
3782 VK_FORMAT_R8G8B8A8_SINT,
3783 VK_FORMAT_R8G8B8A8_SRGB,
3784 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3785 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3786 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3787 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3788 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3789 VK_FORMAT_B8G8R8A8_UNORM,
3790 VK_FORMAT_B8G8R8A8_SRGB,
3791 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3792 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3793 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3794 VK_FORMAT_R16_UNORM,
3795 VK_FORMAT_R16_SNORM,
3798 VK_FORMAT_R16_SFLOAT,
3799 VK_FORMAT_R16G16_UNORM,
3800 VK_FORMAT_R16G16_SNORM,
3801 VK_FORMAT_R16G16_UINT,
3802 VK_FORMAT_R16G16_SINT,
3803 VK_FORMAT_R16G16_SFLOAT,
3804 VK_FORMAT_R16G16B16A16_UNORM,
3805 VK_FORMAT_R16G16B16A16_SNORM,
3806 VK_FORMAT_R16G16B16A16_UINT,
3807 VK_FORMAT_R16G16B16A16_SINT,
3808 VK_FORMAT_R16G16B16A16_SFLOAT,
3811 VK_FORMAT_R32_SFLOAT,
3812 VK_FORMAT_R32G32_UINT,
3813 VK_FORMAT_R32G32_SINT,
3814 VK_FORMAT_R32G32_SFLOAT,
3815 VK_FORMAT_R32G32B32A32_UINT,
3816 VK_FORMAT_R32G32B32A32_SINT,
3817 VK_FORMAT_R32G32B32A32_SFLOAT
3820 static const VkFormat s_coreDepthStencilFormats[] =
3822 VK_FORMAT_D16_UNORM,
3824 VK_FORMAT_X8_D24_UNORM_PACK32,
3825 VK_FORMAT_D32_SFLOAT,
3827 VK_FORMAT_D24_UNORM_S8_UINT,
3828 VK_FORMAT_D32_SFLOAT_S8_UINT
3831 de::MovePtr<tcu::TestCaseGroup> createAttachmentTestCaseGroup (tcu::TestContext& testCtx)
3833 const deUint32 attachmentCounts[] = { 1, 3, 8 };
3834 const VkAttachmentLoadOp loadOps[] =
3836 VK_ATTACHMENT_LOAD_OP_LOAD,
3837 VK_ATTACHMENT_LOAD_OP_CLEAR,
3838 VK_ATTACHMENT_LOAD_OP_DONT_CARE
3841 const VkAttachmentStoreOp storeOps[] =
3843 VK_ATTACHMENT_STORE_OP_STORE,
3844 VK_ATTACHMENT_STORE_OP_DONT_CARE
3847 const VkImageLayout initialAndFinalColorLayouts[] =
3849 VK_IMAGE_LAYOUT_GENERAL,
3850 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3851 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3852 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3853 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3856 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
3858 VK_IMAGE_LAYOUT_GENERAL,
3859 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3860 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
3861 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3862 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3863 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3866 const VkImageLayout subpassLayouts[] =
3868 VK_IMAGE_LAYOUT_GENERAL,
3869 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
3872 const VkImageLayout depthStencilLayouts[] =
3874 VK_IMAGE_LAYOUT_GENERAL,
3875 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
3878 const TestConfig::RenderTypes renderCommands[] =
3880 TestConfig::RENDERTYPES_NONE,
3881 TestConfig::RENDERTYPES_CLEAR,
3882 TestConfig::RENDERTYPES_DRAW,
3883 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
3886 const TestConfig::CommandBufferTypes commandBuffers[] =
3888 TestConfig::COMMANDBUFFERTYPES_INLINE,
3889 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
3890 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
3893 const TestConfig::ImageMemory imageMemories[] =
3895 TestConfig::IMAGEMEMORY_STRICT,
3896 TestConfig::IMAGEMEMORY_LAZY,
3897 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
3900 const UVec2 targetSizes[] =
3906 const UVec2 renderPositions[] =
3912 const UVec2 renderSizes[] =
3918 de::Random rng (1433774382u);
3919 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment", "Attachment format and count tests with load and store ops and image layouts"));
3921 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
3923 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
3924 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
3925 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
3927 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
3929 const bool useDepthStencil = rng.getBool();
3930 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
3931 vector<Attachment> attachments;
3932 vector<AttachmentReference> colorAttachmentReferences;
3934 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
3936 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3937 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
3938 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3939 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3941 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3942 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3943 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
3945 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3946 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3948 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3949 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
3952 if (useDepthStencil)
3954 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3955 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
3956 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3957 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3959 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3960 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3962 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3963 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3965 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
3966 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3970 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
3971 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
3972 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
3973 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>()));
3974 const vector<SubpassDependency> deps;
3976 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
3977 const RenderPass renderPass (attachments, subpasses, deps);
3978 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
3979 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
3980 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
3982 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
3986 group->addChild(attachmentCountGroup.release());
3992 de::MovePtr<tcu::TestCaseGroup> createAttachmentAllocationTestGroup (tcu::TestContext& testCtx)
3994 const deUint32 attachmentCounts[] = { 4, 8 };
3995 const VkAttachmentLoadOp loadOps[] =
3997 VK_ATTACHMENT_LOAD_OP_LOAD,
3998 VK_ATTACHMENT_LOAD_OP_CLEAR,
3999 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4002 const VkAttachmentStoreOp storeOps[] =
4004 VK_ATTACHMENT_STORE_OP_STORE,
4005 VK_ATTACHMENT_STORE_OP_DONT_CARE
4008 const VkImageLayout initialAndFinalLayouts[] =
4010 VK_IMAGE_LAYOUT_GENERAL,
4011 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4012 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4013 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4014 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4015 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4016 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4019 const VkImageLayout subpassLayouts[] =
4021 VK_IMAGE_LAYOUT_GENERAL,
4022 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4027 // Each pass uses one more attachmen than previous one
4028 ALLOCATIONTYPE_GROW,
4029 // Each pass uses one less attachment than previous one
4030 ALLOCATIONTYPE_SHRINK,
4031 // Each pass drops one attachment and picks up new one
4032 ALLOCATIONTYPE_ROLL,
4033 // Start by growing and end by shrinking
4034 ALLOCATIONTYPE_GROW_SHRINK
4037 const AllocationType allocationTypes[] =
4039 ALLOCATIONTYPE_GROW,
4040 ALLOCATIONTYPE_SHRINK,
4041 ALLOCATIONTYPE_ROLL,
4042 ALLOCATIONTYPE_GROW_SHRINK
4045 const char* const allocationTypeStr[] =
4053 const TestConfig::RenderTypes renderCommands[] =
4055 TestConfig::RENDERTYPES_NONE,
4056 TestConfig::RENDERTYPES_CLEAR,
4057 TestConfig::RENDERTYPES_DRAW,
4058 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4061 const TestConfig::CommandBufferTypes commandBuffers[] =
4063 TestConfig::COMMANDBUFFERTYPES_INLINE,
4064 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4065 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4068 const TestConfig::ImageMemory imageMemories[] =
4070 TestConfig::IMAGEMEMORY_STRICT,
4071 TestConfig::IMAGEMEMORY_LAZY,
4072 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4075 const UVec2 targetSizes[] =
4081 const UVec2 renderPositions[] =
4087 const UVec2 renderSizes[] =
4093 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment_allocation", "Attachment allocation tests"));
4094 de::Random rng (3700649827u);
4096 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4098 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4099 const size_t testCaseCount = 100;
4100 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4102 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4104 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4105 vector<Attachment> attachments;
4106 vector<Subpass> subpasses;
4108 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4110 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4111 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4112 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4113 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4115 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4116 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4118 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4119 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4121 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4124 if (allocationType == ALLOCATIONTYPE_GROW)
4126 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4128 vector<AttachmentReference> colorAttachmentReferences;
4130 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4132 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4134 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4137 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>()));
4140 else if (allocationType == ALLOCATIONTYPE_SHRINK)
4142 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4144 vector<AttachmentReference> colorAttachmentReferences;
4146 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4148 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4150 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4153 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>()));
4156 else if (allocationType == ALLOCATIONTYPE_ROLL)
4158 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
4160 vector<AttachmentReference> colorAttachmentReferences;
4162 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
4164 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4166 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
4169 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>()));
4172 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
4174 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4176 vector<AttachmentReference> colorAttachmentReferences;
4178 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4180 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4182 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4185 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>()));
4188 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4190 vector<AttachmentReference> colorAttachmentReferences;
4192 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4194 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4196 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4199 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>()));
4203 DE_FATAL("Unknown allocation type");
4206 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4207 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4208 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4210 const string testCaseName = de::toString(testCaseNdx);
4211 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4212 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4213 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4215 vector<SubpassDependency> deps;
4217 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
4219 const bool byRegion = rng.getBool();
4220 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
4221 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4222 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4223 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4224 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4226 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4227 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4228 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4229 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4231 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4232 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, // \todo [pyry] Correct?
4234 byRegion ? (VkBool32)VK_TRUE : (VkBool32)VK_FALSE));
4237 const RenderPass renderPass (attachments, subpasses, deps);
4239 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4243 group->addChild(allocationTypeGroup.release());
4249 de::MovePtr<tcu::TestCaseGroup> createSimpleTestGroup (tcu::TestContext& testCtx)
4251 const UVec2 targetSize (64, 64);
4252 const UVec2 renderPos (0, 0);
4253 const UVec2 renderSize (64, 64);
4254 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "simple", "Simple basic render pass tests"));
4258 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4259 VK_SAMPLE_COUNT_1_BIT,
4260 VK_ATTACHMENT_LOAD_OP_CLEAR,
4261 VK_ATTACHMENT_STORE_OP_STORE,
4262 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4263 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4264 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4265 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4266 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4268 vector<AttachmentReference>(),
4269 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4270 vector<AttachmentReference>(),
4271 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4272 vector<AttachmentReference>())),
4273 vector<SubpassDependency>());
4275 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));
4280 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4281 VK_SAMPLE_COUNT_1_BIT,
4282 VK_ATTACHMENT_LOAD_OP_CLEAR,
4283 VK_ATTACHMENT_STORE_OP_STORE,
4284 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4285 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4286 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4287 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4288 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4290 vector<AttachmentReference>(),
4291 vector<AttachmentReference>(),
4292 vector<AttachmentReference>(),
4293 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4294 vector<AttachmentReference>())),
4295 vector<SubpassDependency>());
4297 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));
4302 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
4303 VK_SAMPLE_COUNT_1_BIT,
4304 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4305 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4306 VK_ATTACHMENT_LOAD_OP_CLEAR,
4307 VK_ATTACHMENT_STORE_OP_STORE,
4308 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4309 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4310 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4312 vector<AttachmentReference>(),
4313 vector<AttachmentReference>(),
4314 vector<AttachmentReference>(),
4315 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4316 vector<AttachmentReference>())),
4317 vector<SubpassDependency>());
4319 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));
4324 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4325 VK_SAMPLE_COUNT_1_BIT,
4326 VK_ATTACHMENT_LOAD_OP_CLEAR,
4327 VK_ATTACHMENT_STORE_OP_STORE,
4328 VK_ATTACHMENT_LOAD_OP_CLEAR,
4329 VK_ATTACHMENT_STORE_OP_STORE,
4330 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4331 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4332 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4334 vector<AttachmentReference>(),
4335 vector<AttachmentReference>(),
4336 vector<AttachmentReference>(),
4337 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4338 vector<AttachmentReference>())),
4339 vector<SubpassDependency>());
4341 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));
4346 const Attachment attachments[] =
4348 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4349 VK_SAMPLE_COUNT_1_BIT,
4350 VK_ATTACHMENT_LOAD_OP_CLEAR,
4351 VK_ATTACHMENT_STORE_OP_STORE,
4352 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4353 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4354 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4356 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4357 VK_SAMPLE_COUNT_1_BIT,
4358 VK_ATTACHMENT_LOAD_OP_CLEAR,
4359 VK_ATTACHMENT_STORE_OP_STORE,
4360 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4361 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4362 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4363 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4366 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4367 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4369 vector<AttachmentReference>(),
4370 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4371 vector<AttachmentReference>(),
4372 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4373 vector<AttachmentReference>())),
4374 vector<SubpassDependency>());
4376 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));
4381 const Attachment attachments[] =
4383 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4384 VK_SAMPLE_COUNT_1_BIT,
4385 VK_ATTACHMENT_LOAD_OP_CLEAR,
4386 VK_ATTACHMENT_STORE_OP_STORE,
4387 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4388 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4389 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4390 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4391 Attachment(VK_FORMAT_S8_UINT,
4392 VK_SAMPLE_COUNT_1_BIT,
4393 VK_ATTACHMENT_LOAD_OP_CLEAR,
4394 VK_ATTACHMENT_STORE_OP_STORE,
4395 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4396 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4397 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4398 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4401 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4402 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4404 vector<AttachmentReference>(),
4405 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4406 vector<AttachmentReference>(),
4407 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4408 vector<AttachmentReference>())),
4409 vector<SubpassDependency>());
4412 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));
4415 // color_depth_stencil
4417 const Attachment attachments[] =
4419 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4420 VK_SAMPLE_COUNT_1_BIT,
4421 VK_ATTACHMENT_LOAD_OP_CLEAR,
4422 VK_ATTACHMENT_STORE_OP_STORE,
4423 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4424 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4425 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4426 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4427 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4428 VK_SAMPLE_COUNT_1_BIT,
4429 VK_ATTACHMENT_LOAD_OP_CLEAR,
4430 VK_ATTACHMENT_STORE_OP_STORE,
4431 VK_ATTACHMENT_LOAD_OP_CLEAR,
4432 VK_ATTACHMENT_STORE_OP_STORE,
4433 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4434 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4437 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4438 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4440 vector<AttachmentReference>(),
4441 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4442 vector<AttachmentReference>(),
4443 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4444 vector<AttachmentReference>())),
4445 vector<SubpassDependency>());
4447 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));
4453 std::string formatToName (VkFormat format)
4455 const std::string formatStr = de::toString(format);
4456 const std::string prefix = "VK_FORMAT_";
4458 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4460 return de::toLower(formatStr.substr(prefix.length()));
4463 de::MovePtr<tcu::TestCaseGroup> createFormatTestGroup(tcu::TestContext& testCtx)
4465 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "formats", "Tests for different image formats."));
4467 const UVec2 targetSize (64, 64);
4468 const UVec2 renderPos (0, 0);
4469 const UVec2 renderSize (64, 64);
4473 const char* const str;
4474 const VkAttachmentLoadOp op;
4477 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
4478 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
4479 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
4484 const char* const str;
4485 const TestConfig::RenderTypes types;
4488 { "clear", TestConfig::RENDERTYPES_CLEAR },
4489 { "draw", TestConfig::RENDERTYPES_DRAW },
4490 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
4494 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
4496 const VkFormat format = s_coreColorFormats[formatNdx];
4497 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4499 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4501 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4502 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4504 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4506 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4507 VK_SAMPLE_COUNT_1_BIT,
4509 VK_ATTACHMENT_STORE_OP_STORE,
4510 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4511 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4512 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4513 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4514 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4516 vector<AttachmentReference>(),
4517 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4518 vector<AttachmentReference>(),
4519 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4520 vector<AttachmentReference>())),
4521 vector<SubpassDependency>());
4523 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));
4526 formatGroup->addChild(loadOpGroup.release());
4529 group->addChild(formatGroup.release());
4532 // Depth stencil formats
4533 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
4535 const VkFormat format = s_coreDepthStencilFormats[formatNdx];
4536 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4538 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4540 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4541 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4543 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4545 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4546 VK_SAMPLE_COUNT_1_BIT,
4547 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4548 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4550 VK_ATTACHMENT_STORE_OP_STORE,
4551 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4552 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4553 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4555 vector<AttachmentReference>(),
4556 vector<AttachmentReference>(),
4557 vector<AttachmentReference>(),
4558 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4559 vector<AttachmentReference>())),
4560 vector<SubpassDependency>());
4562 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));
4565 formatGroup->addChild(loadOpGroup.release());
4568 group->addChild(formatGroup.release());
4576 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
4578 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
4580 renderpassTests->addChild(createSimpleTestGroup(testCtx).release());
4581 renderpassTests->addChild(createFormatTestGroup(testCtx).release());
4582 renderpassTests->addChild(createAttachmentTestCaseGroup(testCtx).release());
4583 renderpassTests->addChild(createAttachmentAllocationTestGroup(testCtx).release());
4585 return renderpassTests.release();