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 pBeginInfo_renderPass,
287 deUint32 pBeginInfo_subpass,
288 VkFramebuffer pBeginInfo_framebuffer,
289 VkBool32 pBeginInfo_occlusionQueryEnable,
290 VkQueryControlFlags pBeginInfo_queryFlags,
291 VkQueryPipelineStatisticFlags pBeginInfo_pipelineStatistics)
293 const VkCommandBufferBeginInfo pBeginInfo =
295 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
298 pBeginInfo_renderPass,
300 pBeginInfo_framebuffer,
301 pBeginInfo_occlusionQueryEnable,
302 pBeginInfo_queryFlags,
303 pBeginInfo_pipelineStatistics,
305 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
308 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
310 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
313 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
315 const VkSubmitInfo submitInfo =
317 VK_STRUCTURE_TYPE_SUBMIT_INFO,
319 0u, // waitSemaphoreCount
320 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
321 cmdBufferCount, // commandBufferCount
323 0u, // signalSemaphoreCount
324 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
326 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
329 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
331 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
334 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
336 const tcu::TextureFormat format = mapVkFormat(vkFormat);
338 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
340 switch (format.order)
342 case tcu::TextureFormat::DS:
343 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
345 case tcu::TextureFormat::D:
346 return VK_IMAGE_ASPECT_DEPTH_BIT;
348 case tcu::TextureFormat::S:
349 return VK_IMAGE_ASPECT_STENCIL_BIT;
352 return VK_IMAGE_ASPECT_COLOR_BIT;
356 VkAccessFlags getAllMemoryReadFlags (void)
358 return VK_ACCESS_TRANSFER_READ_BIT
359 | VK_ACCESS_UNIFORM_READ_BIT
360 | VK_ACCESS_HOST_READ_BIT
361 | VK_ACCESS_INDEX_READ_BIT
362 | VK_ACCESS_SHADER_READ_BIT
363 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
364 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
365 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
366 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
367 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
370 VkAccessFlags getAllMemoryWriteFlags (void)
372 return VK_ACCESS_TRANSFER_WRITE_BIT
373 | VK_ACCESS_HOST_WRITE_BIT
374 | VK_ACCESS_SHADER_WRITE_BIT
375 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
376 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
379 VkPipelineStageFlags getAllPipelineStageFlags (void)
381 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
382 | VK_PIPELINE_STAGE_TRANSFER_BIT
383 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
384 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
385 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
386 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
387 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
388 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
389 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
390 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
391 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
392 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
393 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
396 class AttachmentReference
399 AttachmentReference (deUint32 attachment,
400 VkImageLayout layout)
401 : m_attachment (attachment)
406 deUint32 getAttachment (void) const { return m_attachment; }
407 VkImageLayout getImageLayout (void) const { return m_layout; }
410 deUint32 m_attachment;
411 VkImageLayout m_layout;
417 Subpass (VkPipelineBindPoint pipelineBindPoint,
418 VkSubpassDescriptionFlags flags,
419 const vector<AttachmentReference>& inputAttachments,
420 const vector<AttachmentReference>& colorAttachments,
421 const vector<AttachmentReference>& resolveAttachments,
422 AttachmentReference depthStencilAttachment,
423 const vector<AttachmentReference>& preserveAttachments)
424 : m_pipelineBindPoint (pipelineBindPoint)
426 , m_inputAttachments (inputAttachments)
427 , m_colorAttachments (colorAttachments)
428 , m_resolveAttachments (resolveAttachments)
429 , m_depthStencilAttachment (depthStencilAttachment)
430 , m_preserveAttachments (preserveAttachments)
434 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
435 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
436 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
437 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
438 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
439 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
440 const vector<AttachmentReference>& getPreserveAttachments (void) const { return m_preserveAttachments; }
443 VkPipelineBindPoint m_pipelineBindPoint;
444 VkSubpassDescriptionFlags m_flags;
446 vector<AttachmentReference> m_inputAttachments;
447 vector<AttachmentReference> m_colorAttachments;
448 vector<AttachmentReference> m_resolveAttachments;
449 AttachmentReference m_depthStencilAttachment;
451 vector<AttachmentReference> m_preserveAttachments;
454 class SubpassDependency
457 SubpassDependency (deUint32 srcPass,
460 VkPipelineStageFlags srcStageMask,
461 VkPipelineStageFlags dstStageMask,
463 VkAccessFlags outputMask,
464 VkAccessFlags inputMask,
466 VkDependencyFlags flags)
467 : m_srcPass (srcPass)
468 , m_dstPass (dstPass)
470 , m_srcStageMask (srcStageMask)
471 , m_dstStageMask (dstStageMask)
473 , m_outputMask (outputMask)
474 , m_inputMask (inputMask)
479 deUint32 getSrcPass (void) const { return m_srcPass; }
480 deUint32 getDstPass (void) const { return m_dstPass; }
482 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
483 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
485 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
486 VkAccessFlags getInputMask (void) const { return m_inputMask; }
488 VkDependencyFlags getFlags (void) const { return m_flags; }
494 VkPipelineStageFlags m_srcStageMask;
495 VkPipelineStageFlags m_dstStageMask;
497 VkAccessFlags m_outputMask;
498 VkAccessFlags m_inputMask;
499 VkDependencyFlags m_flags;
505 Attachment (VkFormat format,
506 VkSampleCountFlagBits samples,
508 VkAttachmentLoadOp loadOp,
509 VkAttachmentStoreOp storeOp,
511 VkAttachmentLoadOp stencilLoadOp,
512 VkAttachmentStoreOp stencilStoreOp,
514 VkImageLayout initialLayout,
515 VkImageLayout finalLayout)
517 , m_samples (samples)
520 , m_storeOp (storeOp)
522 , m_stencilLoadOp (stencilLoadOp)
523 , m_stencilStoreOp (stencilStoreOp)
525 , m_initialLayout (initialLayout)
526 , m_finalLayout (finalLayout)
530 VkFormat getFormat (void) const { return m_format; }
531 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
533 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
534 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
537 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
538 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
540 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
541 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
545 VkSampleCountFlagBits m_samples;
547 VkAttachmentLoadOp m_loadOp;
548 VkAttachmentStoreOp m_storeOp;
550 VkAttachmentLoadOp m_stencilLoadOp;
551 VkAttachmentStoreOp m_stencilStoreOp;
553 VkImageLayout m_initialLayout;
554 VkImageLayout m_finalLayout;
560 RenderPass (const vector<Attachment>& attachments,
561 const vector<Subpass>& subpasses,
562 const vector<SubpassDependency>& dependencies)
563 : m_attachments (attachments)
564 , m_subpasses (subpasses)
565 , m_dependencies (dependencies)
569 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
570 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
571 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
574 const vector<Attachment> m_attachments;
575 const vector<Subpass> m_subpasses;
576 const vector<SubpassDependency> m_dependencies;
583 RENDERTYPES_NONE = 0,
584 RENDERTYPES_CLEAR = (1<<1),
585 RENDERTYPES_DRAW = (1<<2)
588 enum CommandBufferTypes
590 COMMANDBUFFERTYPES_INLINE = (1<<0),
591 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
596 IMAGEMEMORY_STRICT = (1<<0),
597 IMAGEMEMORY_LAZY = (1<<1)
600 TestConfig (const RenderPass& renderPass_,
601 RenderTypes renderTypes_,
602 CommandBufferTypes commandBufferTypes_,
603 ImageMemory imageMemory_,
604 const UVec2& targetSize_,
605 const UVec2& renderPos_,
606 const UVec2& renderSize_,
608 : renderPass (renderPass_)
609 , renderTypes (renderTypes_)
610 , commandBufferTypes (commandBufferTypes_)
611 , imageMemory (imageMemory_)
612 , targetSize (targetSize_)
613 , renderPos (renderPos_)
614 , renderSize (renderSize_)
619 RenderPass renderPass;
620 RenderTypes renderTypes;
621 CommandBufferTypes commandBufferTypes;
622 ImageMemory imageMemory;
629 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
631 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
634 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
636 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
639 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
641 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
644 void logRenderPassInfo (TestLog& log,
645 const RenderPass& renderPass)
647 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
650 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
651 const vector<Attachment>& attachments = renderPass.getAttachments();
653 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
655 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
656 const Attachment& attachment = attachments[attachmentNdx];
658 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
659 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
661 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
662 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
664 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
665 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
667 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
668 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
673 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
674 const vector<Subpass>& subpasses = renderPass.getSubpasses();
676 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
678 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
679 const Subpass& subpass = subpasses[subpassNdx];
681 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
682 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
683 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
684 const vector<AttachmentReference>& preserveAttachments = subpass.getPreserveAttachments();
686 if (!inputAttachments.empty())
688 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
690 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
692 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
693 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
695 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
696 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
700 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
702 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
703 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
705 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
706 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
709 if (!colorAttachments.empty())
711 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
713 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
715 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
716 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
718 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
719 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
723 if (!resolveAttachments.empty())
725 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
727 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
729 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
730 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
732 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
733 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
737 if (!preserveAttachments.empty())
739 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
741 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
743 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
744 const AttachmentReference& preserveAttachment = preserveAttachments[preserveNdx];
746 log << TestLog::Message << "Attachment: " << preserveAttachment.getAttachment() << TestLog::EndMessage;
747 log << TestLog::Message << "Layout: " << preserveAttachment.getImageLayout() << TestLog::EndMessage;
754 if (!renderPass.getDependencies().empty())
756 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
758 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
760 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
761 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
763 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
764 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
766 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
767 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
769 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
770 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
771 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
776 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
778 const tcu::TextureFormat format = mapVkFormat(vkFormat);
779 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
780 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
782 std::ostringstream stream;
786 switch (channelClass)
788 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
789 for (int i = 0; i < 4; i++)
795 stream << value.int32[i];
801 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
802 for (int i = 0; i < 4; i++)
808 stream << value.uint32[i];
814 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
815 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
816 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
817 for (int i = 0; i < 4; i++)
823 stream << value.float32[i];
830 DE_FATAL("Unknown channel class");
838 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
840 const tcu::TextureFormat format = mapVkFormat(vkFormat);
842 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
844 std::ostringstream stream;
848 if (tcu::hasStencilComponent(format.order))
849 stream << "stencil: " << value.depthStencil.stencil;
851 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
854 if (tcu::hasDepthComponent(format.order))
855 stream << "depth: " << value.depthStencil.depth;
862 return clearColorToString(vkFormat, value.color);
865 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
867 const float clearNan = tcu::Float32::nan().asFloat();
868 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
869 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
870 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
871 VkClearColorValue clearColor;
873 switch (channelClass)
875 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
877 const tcu::IVec4 valueMin = tcu::getFormatMinIntValue(format);
878 const tcu::IVec4 valueMax = tcu::getFormatMaxIntValue(format);
880 for (int ndx = 0; ndx < 4; ndx++)
882 if (!channelMask[ndx])
883 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
885 clearColor.uint32[ndx] = rng.getInt(valueMin[ndx], valueMax[ndx]);
890 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
892 const UVec4 valueMax = tcu::getFormatMaxUintValue(format);
894 for (int ndx = 0; ndx < 4; ndx++)
896 if (!channelMask[ndx])
897 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
899 clearColor.uint32[ndx] = rng.getUint32() % valueMax[ndx];
904 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
905 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
906 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
908 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
910 for (int ndx = 0; ndx < 4; ndx++)
912 if (!channelMask[ndx])
913 clearColor.float32[ndx] = clearNan;
915 clearColor.float32[ndx] = formatInfo.valueMin[ndx] + rng.getFloat() * (formatInfo.valueMax[ndx] - formatInfo.valueMin[ndx]);
921 DE_FATAL("Unknown channel class");
927 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
929 const VkAttachmentDescription attachmentDescription =
933 attachment.getFormat(), // format
934 attachment.getSamples(), // samples
936 attachment.getLoadOp(), // loadOp
937 attachment.getStoreOp(), // storeOp
939 attachment.getStencilLoadOp(), // stencilLoadOp
940 attachment.getStencilStoreOp(), // stencilStoreOp
942 attachment.getInitialLayout(), // initialLayout
943 attachment.getFinalLayout(), // finalLayout
946 return attachmentDescription;
949 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
951 const VkAttachmentReference reference =
953 referenceInfo.getAttachment(), // attachment;
954 referenceInfo.getImageLayout() // layout;
960 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
961 vector<VkAttachmentReference>* attachmentReferenceLists)
963 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
964 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
965 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
966 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
967 vector<VkAttachmentReference>& preserveAttachmentReferences = attachmentReferenceLists[4];
969 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
970 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
972 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
973 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
975 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
976 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
978 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
980 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
981 preserveAttachmentReferences.push_back(createAttachmentReference(subpass.getPreserveAttachments()[attachmentNdx]));
983 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
986 const VkSubpassDescription subpassDescription =
988 subpass.getFlags(), // flags;
989 subpass.getPipelineBindPoint(), // pipelineBindPoint;
991 (deUint32)inputAttachmentReferences.size(), // inputCount;
992 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
994 (deUint32)colorAttachmentReferences.size(), // colorCount;
995 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
996 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
998 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
999 (deUint32)preserveAttachmentReferences.size(), // preserveCount;
1000 preserveAttachmentReferences.empty() ? DE_NULL : &preserveAttachmentReferences[0] // preserveAttachments;
1003 return subpassDescription;
1007 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1009 const VkSubpassDependency dependency =
1011 dependencyInfo.getSrcPass(), // srcSubpass;
1012 dependencyInfo.getDstPass(), // destSubpass;
1014 dependencyInfo.getSrcStageMask(), // srcStageMask;
1015 dependencyInfo.getDstStageMask(), // destStageMask;
1017 dependencyInfo.getOutputMask(), // outputMask;
1018 dependencyInfo.getInputMask(), // inputMask;
1020 dependencyInfo.getFlags() // dependencyFlags;
1026 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1028 const RenderPass& renderPassInfo)
1030 const size_t perSubpassAttachmentReferenceLists = 5;
1031 vector<VkAttachmentDescription> attachments;
1032 vector<VkSubpassDescription> subpasses;
1033 vector<VkSubpassDependency> dependencies;
1034 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1036 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1037 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1039 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1040 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists])));
1042 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1043 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1046 const VkRenderPassCreateInfo createInfo =
1048 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1050 (VkRenderPassCreateFlags)0u,
1051 (deUint32)attachments.size(),
1052 (attachments.empty() ? DE_NULL : &attachments[0]),
1053 (deUint32)subpasses.size(),
1054 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1055 (deUint32)dependencies.size(),
1056 (dependencies.empty() ? DE_NULL : &dependencies[0])
1059 return createRenderPass(vk, device, &createInfo);
1063 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1065 VkRenderPass renderPass,
1067 const vector<VkImageView>& attachments)
1069 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1072 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1074 deUint32 queueIndex,
1077 VkSampleCountFlagBits samples,
1078 VkImageUsageFlags usageFlags,
1079 VkImageLayout layout)
1081 const VkExtent3D size_ = { (deInt32)size.x(), (deInt32)size.y(), 1 };
1082 VkImageUsageFlags targetUsageFlags = 0;
1083 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1085 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1087 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1091 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1094 return createImage(vk, device,
1095 (VkImageCreateFlags)0,
1102 VK_IMAGE_TILING_OPTIMAL,
1103 usageFlags | targetUsageFlags,
1104 VK_SHARING_MODE_EXCLUSIVE,
1110 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
1112 Allocator& allocator,
1116 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
1117 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1121 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1125 VkImageAspectFlags aspect)
1127 const VkImageSubresourceRange range =
1136 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1139 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1141 const float clearNan = tcu::Float32::nan().asFloat();
1142 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1144 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1146 VkClearValue clearValue;
1148 clearValue.depthStencil.depth = clearNan;
1149 clearValue.depthStencil.stencil = 255;
1151 if (tcu::hasStencilComponent(format.order))
1152 clearValue.depthStencil.stencil = rng.getInt(0, 255);
1154 if (tcu::hasDepthComponent(format.order))
1155 clearValue.depthStencil.depth = rng.getFloat();
1161 VkClearValue clearValue;
1163 clearValue.color = randomColorClearValue(attachment, rng);
1169 class AttachmentResources
1172 AttachmentResources (const DeviceInterface& vk,
1174 Allocator& allocator,
1175 deUint32 queueIndex,
1177 const Attachment& attachmentInfo,
1179 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), lazy ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : 0, VK_IMAGE_LAYOUT_UNDEFINED))
1180 , m_imageMemory (createImageMemory(vk, device, allocator, *m_image, lazy))
1181 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1185 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1187 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1189 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1190 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1192 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1193 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1195 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1196 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1198 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1200 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1201 m_secondaryBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
1203 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1207 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1209 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1210 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1212 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1217 ~AttachmentResources (void)
1221 VkImageView getAttachmentView (void) const
1223 return *m_attachmentView;
1226 VkImage getImage (void) const
1231 VkBuffer getBuffer (void) const
1233 DE_ASSERT(*m_buffer != DE_NULL);
1237 VkDeviceSize getBufferSize (void) const
1239 DE_ASSERT(*m_buffer != DE_NULL);
1240 return m_bufferSize;
1243 const Allocation& getResultMemory (void) const
1245 DE_ASSERT(m_bufferMemory);
1246 return *m_bufferMemory;
1249 VkBuffer getSecondaryBuffer (void) const
1251 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1252 return *m_secondaryBuffer;
1255 VkDeviceSize getSecondaryBufferSize (void) const
1257 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1258 return m_secondaryBufferSize;
1261 const Allocation& getSecondaryResultMemory (void) const
1263 DE_ASSERT(m_secondaryBufferMemory);
1264 return *m_secondaryBufferMemory;
1268 const Unique<VkImage> m_image;
1269 const UniquePtr<Allocation> m_imageMemory;
1270 const Unique<VkImageView> m_attachmentView;
1272 Move<VkBuffer> m_buffer;
1273 VkDeviceSize m_bufferSize;
1274 de::MovePtr<Allocation> m_bufferMemory;
1276 Move<VkBuffer> m_secondaryBuffer;
1277 VkDeviceSize m_secondaryBufferSize;
1278 de::MovePtr<Allocation> m_secondaryBufferMemory;
1281 void uploadBufferData (const DeviceInterface& vk,
1283 const Allocation& memory,
1287 const VkMappedMemoryRange range =
1289 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1291 memory.getMemory(), // mem;
1292 memory.getOffset(), // offset;
1293 (VkDeviceSize)size // size;
1295 void* const ptr = memory.getHostPtr();
1297 deMemcpy(ptr, data, size);
1298 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1301 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1303 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1307 case tcu::TextureFormat::D:
1308 case tcu::TextureFormat::DS:
1309 return VK_IMAGE_ASPECT_DEPTH_BIT;
1311 case tcu::TextureFormat::S:
1312 return VK_IMAGE_ASPECT_STENCIL_BIT;
1315 return VK_IMAGE_ASPECT_COLOR_BIT;
1322 RenderQuad (const Vec4& posA, const Vec4& posB)
1325 m_vertices[0] = posA;
1326 m_vertices[1] = Vec4(posA[0], posB[1], posA[2], posA[3]);
1327 m_vertices[2] = posB;
1329 m_vertices[3] = posB;
1330 m_vertices[4] = Vec4(posB[0], posA[1], posB[2], posA[3]);
1331 m_vertices[5] = posA;
1334 const Vec4& getCornerA (void) const
1336 return m_vertices[0];
1339 const Vec4& getCornerB (void) const
1341 return m_vertices[2];
1344 const void* getVertexPointer (void) const
1346 return &m_vertices[0];
1349 size_t getVertexDataSize (void) const
1351 return sizeof(Vec4) * m_vertices.size();
1355 vector<Vec4> m_vertices;
1361 ColorClear (const UVec2& offset,
1363 const VkClearColorValue& color)
1370 const UVec2& getOffset (void) const { return m_offset; }
1371 const UVec2& getSize (void) const { return m_size; }
1372 const VkClearColorValue& getColor (void) const { return m_color; }
1377 VkClearColorValue m_color;
1380 class DepthStencilClear
1383 DepthStencilClear (const UVec2& offset,
1390 , m_stencil (stencil)
1394 const UVec2& getOffset (void) const { return m_offset; }
1395 const UVec2& getSize (void) const { return m_size; }
1396 float getDepth (void) const { return m_depth; }
1397 deUint32 getStencil (void) const { return m_stencil; }
1407 class SubpassRenderInfo
1410 SubpassRenderInfo (const RenderPass& renderPass,
1411 deUint32 subpassIndex,
1415 const UVec2& viewportOffset,
1416 const UVec2& viewportSize,
1418 const Maybe<RenderQuad>& renderQuad,
1419 const vector<ColorClear>& colorClears,
1420 const Maybe<DepthStencilClear>& depthStencilClear)
1421 : m_viewportOffset (viewportOffset)
1422 , m_viewportSize (viewportSize)
1423 , m_subpassIndex (subpassIndex)
1424 , m_isSecondary (isSecondary_)
1425 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1426 , m_renderQuad (renderQuad)
1427 , m_colorClears (colorClears)
1428 , m_depthStencilClear (depthStencilClear)
1429 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1431 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1432 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1434 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1436 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1437 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1441 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1442 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1444 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1445 bool isSecondary (void) const { return m_isSecondary; }
1447 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1448 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1449 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1451 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1452 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1453 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1454 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1455 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1456 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1457 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1458 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1460 UVec2 m_viewportOffset;
1461 UVec2 m_viewportSize;
1463 deUint32 m_subpassIndex;
1465 VkSubpassDescriptionFlags m_flags;
1467 Maybe<RenderQuad> m_renderQuad;
1468 vector<ColorClear> m_colorClears;
1469 Maybe<DepthStencilClear> m_depthStencilClear;
1471 vector<AttachmentReference> m_colorAttachments;
1472 vector<Attachment> m_colorAttachmentInfo;
1474 Maybe<AttachmentReference> m_depthStencilAttachment;
1475 Maybe<Attachment> m_depthStencilAttachmentInfo;
1478 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1480 VkRenderPass renderPass,
1481 VkShaderModule vertexShaderModule,
1482 VkShaderModule fragmentShaderModule,
1483 VkPipelineLayout pipelineLayout,
1484 const SubpassRenderInfo& renderInfo)
1486 const VkSpecializationInfo emptyShaderSpecializations =
1488 0u, // mapEntryCount
1494 Maybe<VkSampleCountFlagBits> rasterSamples;
1495 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1497 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1499 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1501 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1503 rasterSamples = attachment.getSamples();
1506 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1508 VK_FALSE, // blendEnable
1509 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1510 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1511 VK_BLEND_OP_ADD, // blendOpColor
1512 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1513 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1514 VK_BLEND_OP_ADD, // blendOpAlpha
1515 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1518 attachmentBlendStates.push_back(attachmentBlendState);
1522 if (renderInfo.getDepthStencilAttachment())
1524 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1526 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1527 rasterSamples = attachment.getSamples();
1530 // If there are no attachment use single sample
1532 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1534 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1537 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1539 (VkPipelineShaderStageCreateFlags)0u,
1540 VK_SHADER_STAGE_VERTEX_BIT, // stage
1541 vertexShaderModule, // shader
1543 &emptyShaderSpecializations
1546 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1548 (VkPipelineShaderStageCreateFlags)0u,
1549 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1550 fragmentShaderModule, // shader
1552 &emptyShaderSpecializations
1555 const VkVertexInputBindingDescription vertexBinding =
1558 (deUint32)sizeof(tcu::Vec4), // strideInBytes
1559 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1561 const VkVertexInputAttributeDescription vertexAttrib =
1565 VK_FORMAT_R32G32B32A32_SFLOAT, // format
1566 0u, // offsetInBytes
1568 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1570 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1572 (VkPipelineVertexInputStateCreateFlags)0u,
1574 &vertexBinding, // pVertexBindingDescriptions
1575 1u, // attributeCount
1576 &vertexAttrib, // pVertexAttributeDescriptions
1578 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1580 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1582 (VkPipelineInputAssemblyStateCreateFlags)0u,
1583 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1584 VK_FALSE, // primitiveRestartEnable
1586 const VkViewport viewport =
1588 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1589 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1592 const VkRect2D scissor =
1594 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1595 { (deInt32)renderInfo.getViewportSize().x(), (deInt32)renderInfo.getViewportSize().y() }
1597 const VkPipelineViewportStateCreateInfo viewportState =
1599 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1601 (VkPipelineViewportStateCreateFlags)0u,
1607 const VkPipelineRasterizationStateCreateInfo rasterState =
1609 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1611 (VkPipelineRasterizationStateCreateFlags)0u,
1612 VK_TRUE, // depthClipEnable
1613 VK_FALSE, // rasterizerDiscardEnable
1614 VK_POLYGON_MODE_FILL, // fillMode
1615 VK_CULL_MODE_NONE, // cullMode
1616 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1617 VK_FALSE, // depthBiasEnable
1619 0.0f, // depthBiasClamp
1620 0.0f, // slopeScaledDepthBias
1623 const VkPipelineMultisampleStateCreateInfo multisampleState =
1625 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1627 (VkPipelineMultisampleStateCreateFlags)0u,
1628 *rasterSamples, // rasterSamples
1629 VK_FALSE, // sampleShadingEnable
1630 0.0f, // minSampleShading
1631 DE_NULL, // pSampleMask
1632 VK_FALSE, // alphaToCoverageEnable
1633 VK_FALSE, // alphaToOneEnable
1635 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1637 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1639 (VkPipelineDepthStencilStateCreateFlags)0u,
1640 VK_TRUE, // depthTestEnable
1641 VK_TRUE, // depthWriteEnable
1642 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1643 VK_FALSE, // depthBoundsEnable
1644 VK_TRUE, // stencilTestEnable
1646 VK_STENCIL_OP_REPLACE, // stencilFailOp
1647 VK_STENCIL_OP_REPLACE, // stencilPassOp
1648 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1649 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1650 ~0u, // stencilCompareMask
1651 ~0u, // stencilWriteMask
1652 STENCIL_VALUE // stencilReference
1655 VK_STENCIL_OP_REPLACE, // stencilFailOp
1656 VK_STENCIL_OP_REPLACE, // stencilPassOp
1657 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1658 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1659 ~0u, // stencilCompareMask
1660 ~0u, // stencilWriteMask
1661 STENCIL_VALUE // stencilReference
1664 -1.0f, // minDepthBounds;
1665 1.0f // maxDepthBounds;
1667 const VkPipelineColorBlendStateCreateInfo blendState =
1669 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1671 (VkPipelineColorBlendStateCreateFlags)0u,
1672 VK_FALSE, // logicOpEnable
1673 VK_LOGIC_OP_COPY, // logicOp
1674 (deUint32)attachmentBlendStates.size(), // attachmentCount
1675 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1676 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1678 const VkPipelineDynamicStateCreateInfo dynamicState =
1680 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1682 (VkPipelineDynamicStateCreateFlags)0u,
1686 const VkGraphicsPipelineCreateInfo createInfo =
1688 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1690 (VkPipelineCreateFlags)0u,
1693 shaderStages, // pStages
1695 &vertexInputState, // pVertexInputState
1696 &inputAssemblyState, // pInputAssemblyState
1697 DE_NULL, // pTessellationState
1698 &viewportState, // pViewportState
1699 &rasterState, // pRasterState
1700 &multisampleState, // pMultisampleState
1701 &depthStencilState, // pDepthStencilState
1702 &blendState, // pColorBlendState
1703 &dynamicState, // pDynamicState
1704 pipelineLayout, // layout
1706 renderPass, // renderPass
1707 renderInfo.getSubpassIndex(), // subpass
1708 DE_NULL, // basePipelineHandle
1709 0u // basePipelineIndex
1712 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1715 class SubpassRenderer
1718 SubpassRenderer (Context& context,
1719 const DeviceInterface& vk,
1721 Allocator& allocator,
1722 VkRenderPass renderPass,
1723 VkFramebuffer framebuffer,
1724 VkCommandPool commandBufferPool,
1725 deUint32 queueFamilyIndex,
1726 const SubpassRenderInfo& renderInfo)
1727 : m_renderInfo (renderInfo)
1729 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1731 if (renderInfo.getRenderQuad())
1733 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1734 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1736 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1738 (vk::VkPipelineLayoutCreateFlags)0,
1739 0u, // descriptorSetCount;
1740 DE_NULL, // pSetLayouts;
1741 0u, // pushConstantRangeCount;
1742 DE_NULL, // pPushConstantRanges;
1745 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1746 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1747 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1748 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1750 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1751 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1753 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1754 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1757 if (renderInfo.isSecondary())
1759 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1761 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
1762 pushRenderCommands(vk, *m_commandBuffer);
1763 endCommandBuffer(vk, *m_commandBuffer);
1767 bool isSecondary (void) const
1769 return m_commandBuffer;
1772 VkCommandBuffer getCommandBuffer (void) const
1774 DE_ASSERT(isSecondary());
1775 return *m_commandBuffer;
1778 void pushRenderCommands (const DeviceInterface& vk,
1779 VkCommandBuffer commandBuffer)
1781 if (!m_renderInfo.getColorClears().empty())
1783 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
1785 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
1787 const ColorClear& colorClear = colorClears[attachmentNdx];
1788 const VkClearAttachment attachment =
1790 VK_IMAGE_ASPECT_COLOR_BIT,
1792 makeClearValue(colorClear.getColor()),
1794 const VkClearRect rect =
1797 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
1798 { (deInt32)colorClear.getSize().x(), (deInt32)colorClear.getSize().y() }
1800 0u, // baseArrayLayer
1804 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1808 if (m_renderInfo.getDepthStencilClear())
1810 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
1811 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
1812 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
1813 const VkClearAttachment attachment =
1815 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1816 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1818 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
1820 const VkClearRect rect =
1823 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
1824 { (deInt32)depthStencilClear.getSize().x(), (deInt32)depthStencilClear.getSize().y() }
1826 0u, // baseArrayLayer
1830 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1833 if (m_renderInfo.getRenderQuad())
1835 const VkDeviceSize offset = 0;
1836 const VkBuffer vertexBuffer = *m_vertexBuffer;
1838 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1839 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
1840 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
1845 const SubpassRenderInfo m_renderInfo;
1846 Move<VkCommandBuffer> m_commandBuffer;
1847 Move<VkPipeline> m_pipeline;
1848 Move<VkPipelineLayout> m_pipelineLayout;
1850 Move<VkShaderModule> m_vertexShaderModule;
1852 Move<VkShaderModule> m_fragmentShaderModule;
1854 Move<VkBuffer> m_vertexBuffer;
1855 de::MovePtr<Allocation> m_vertexBufferMemory;
1858 void pushImageInitializationCommands (const DeviceInterface& vk,
1859 VkCommandBuffer commandBuffer,
1860 const vector<Attachment>& attachmentInfo,
1861 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
1862 deUint32 queueIndex,
1863 const vector<Maybe<VkClearValue> >& clearValues)
1866 vector<VkImageMemoryBarrier> initializeLayouts;
1868 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1870 if (!clearValues[attachmentNdx])
1873 const VkImageMemoryBarrier barrier =
1875 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1878 getAllMemoryWriteFlags(), // srcAccessMask
1879 getAllMemoryReadFlags(), // dstAccessMask
1881 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
1882 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
1884 queueIndex, // srcQueueFamilyIndex;
1885 queueIndex, // destQueueFamilyIndex;
1887 attachmentResources[attachmentNdx]->getImage(), // image;
1888 { // subresourceRange;
1889 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1892 0, // baseArraySlice;
1897 initializeLayouts.push_back(barrier);
1900 if (!initializeLayouts.empty())
1902 vector<VkImageMemoryBarrier*> initializeLayoutPtrs;
1904 for (size_t ndx = 0; ndx < initializeLayouts.size(); ndx++)
1905 initializeLayoutPtrs.push_back(&initializeLayouts[ndx]);
1907 vk.cmdPipelineBarrier(commandBuffer, 0, 0, VK_FALSE, (deUint32)initializeLayouts.size(), (const void* const*)&initializeLayoutPtrs[0]);
1911 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1913 if (!clearValues[attachmentNdx])
1916 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
1918 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
1920 const float clearNan = tcu::Float32::nan().asFloat();
1921 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
1922 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : ~0u;
1923 const VkClearDepthStencilValue depthStencil =
1928 const VkImageSubresourceRange range =
1930 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1931 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1938 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
1942 const VkImageSubresourceRange range =
1944 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
1947 0, // baseArrayLayer;
1950 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
1952 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
1957 vector<VkImageMemoryBarrier> renderPassLayouts;
1959 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1961 const VkImageMemoryBarrier barrier =
1963 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1966 getAllMemoryWriteFlags(), // srcAccessMask
1967 getAllMemoryReadFlags(), // dstAccessMask
1969 clearValues[attachmentNdx] ?
1970 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
1971 : VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
1973 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
1975 queueIndex, // srcQueueFamilyIndex;
1976 queueIndex, // destQueueFamilyIndex;
1978 attachmentResources[attachmentNdx]->getImage(), // image;
1979 { // subresourceRange;
1980 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1983 0, // baseArraySlice;
1988 renderPassLayouts.push_back(barrier);
1991 if (!renderPassLayouts.empty())
1993 vector<VkImageMemoryBarrier*> renderPassLayoutPtrs;
1995 for (size_t ndx = 0; ndx < renderPassLayouts.size(); ndx++)
1996 renderPassLayoutPtrs.push_back(&renderPassLayouts[ndx]);
1998 vk.cmdPipelineBarrier(commandBuffer, 0, 0, VK_FALSE, (deUint32)renderPassLayouts.size(), (const void* const*)&renderPassLayoutPtrs[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 { (deInt32)renderSize.x(), (deInt32)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())
2107 vector<VkImageMemoryBarrier*> clearLayoutPtrs;
2109 for (size_t ndx = 0; ndx < imageBarriers.size(); ndx++)
2110 clearLayoutPtrs.push_back(&imageBarriers[ndx]);
2112 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(),
2113 getAllPipelineStageFlags(),
2114 VK_FALSE, (deUint32)imageBarriers.size(), (const void* const*)&clearLayoutPtrs[0]);
2118 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2120 if (isLazy[attachmentNdx])
2123 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2124 const VkBufferImageCopy rect =
2127 0, // bufferRowLength
2128 0, // bufferImageHeight
2129 { // imageSubresource
2130 getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2135 { 0, 0, 0 }, // imageOffset
2136 { (deInt32)targetSize.x(), (deInt32)targetSize.y(), 1 } // imageExtent
2139 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2141 if (tcu::TextureFormat::DS == order)
2143 const VkBufferImageCopy stencilRect =
2146 0, // bufferRowLength
2147 0, // bufferImageHeight
2148 { // imageSubresource
2149 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2154 { 0, 0, 0 }, // imageOffset
2155 { (deInt32)targetSize.x(), (deInt32)targetSize.y(), 1 } // imageExtent
2158 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2163 vector<VkBufferMemoryBarrier> bufferBarriers;
2165 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2167 if (isLazy[attachmentNdx])
2170 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2171 const VkBufferMemoryBarrier bufferBarrier =
2173 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2176 getAllMemoryWriteFlags(),
2177 getAllMemoryReadFlags(),
2182 attachmentResources[attachmentNdx]->getBuffer(),
2184 attachmentResources[attachmentNdx]->getBufferSize()
2187 bufferBarriers.push_back(bufferBarrier);
2189 if (tcu::TextureFormat::DS == order)
2191 const VkBufferMemoryBarrier secondaryBufferBarrier =
2193 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2196 getAllMemoryWriteFlags(),
2197 getAllMemoryReadFlags(),
2202 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2204 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2207 bufferBarriers.push_back(secondaryBufferBarrier);
2210 bufferBarriers.push_back(bufferBarrier);
2213 if (!bufferBarriers.empty())
2215 vector<VkBufferMemoryBarrier*> clearLayoutPtrs;
2217 for (size_t ndx = 0; ndx < bufferBarriers.size(); ndx++)
2218 clearLayoutPtrs.push_back(&bufferBarriers[ndx]);
2220 vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(),
2221 getAllPipelineStageFlags(),
2222 VK_FALSE, (deUint32)bufferBarriers.size(), (const void* const*)&clearLayoutPtrs[0]);
2227 void clear (const PixelBufferAccess& access, const VkClearValue& value)
2229 const tcu::TextureFormat& format = access.getFormat();
2231 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2233 if (tcu::hasDepthComponent(format.order))
2234 tcu::clearDepth(access, value.depthStencil.depth);
2236 if (tcu::hasStencilComponent(format.order))
2237 tcu::clearStencil(access, value.depthStencil.stencil);
2241 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT
2242 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
2243 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
2245 const tcu::Vec4 color (value.color.float32[0],
2246 value.color.float32[1],
2247 value.color.float32[2],
2248 value.color.float32[3]);
2250 if (tcu::isSRGB(format))
2251 tcu::clear(access, tcu::linearToSRGB(color));
2253 tcu::clear(access, color);
2255 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2257 const tcu::UVec4 color (value.color.uint32[0],
2258 value.color.uint32[1],
2259 value.color.uint32[2],
2260 value.color.uint32[3]);
2262 tcu::clear(access, color);
2264 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2266 const tcu::IVec4 color (value.color.int32[0],
2267 value.color.int32[1],
2268 value.color.int32[2],
2269 value.color.int32[3]);
2271 tcu::clear(access, color);
2274 DE_FATAL("Unknown channel class");
2278 Vec4 computeUvs (const IVec2& posA, const IVec2& posB, const IVec2& pos)
2280 const float u = de::clamp((float)(pos.x() - posA.x()) / (float)(posB.x() - posA.x()), 0.0f, 1.0f);
2281 const float v = de::clamp((float)(pos.y() - posA.y()) / (float)(posB.y() - posA.y()), 0.0f, 1.0f);
2283 return Vec4(u, v, u * v, (u + v) / 2.0f);
2286 void renderReferenceImages (vector<tcu::TextureLevel>& referenceAttachments,
2287 const RenderPass& renderPassInfo,
2288 const UVec2& targetSize,
2289 const vector<Maybe<VkClearValue> >& imageClearValues,
2290 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2291 const vector<SubpassRenderInfo>& subpassRenderInfo,
2292 const UVec2& renderPos,
2293 const UVec2& renderSize)
2295 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2296 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2298 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2300 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2302 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2303 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2304 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2305 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2306 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
2308 reference = tcu::TextureLevel(format, targetSize.x(), targetSize.y());
2310 if (imageClearValues[attachmentNdx])
2311 clear(reference.getAccess(), *imageClearValues[attachmentNdx]);
2314 // Fill with grid if image contentst are undefined before renderpass
2315 if (isDepthOrStencilAttachment)
2317 if (tcu::hasDepthComponent(format.order))
2318 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), 2, textureInfo.valueMin, textureInfo.valueMax);
2320 if (tcu::hasStencilComponent(format.order))
2321 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), 2, textureInfo.valueMin, textureInfo.valueMax);
2324 tcu::fillWithGrid(reference.getAccess(), 2, textureInfo.valueMin, textureInfo.valueMax);
2328 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2330 const Subpass& subpass = subpasses[subpassNdx];
2331 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2332 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2334 // Apply load op if attachment was used for the first time
2335 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2337 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2339 if (!attachmentUsed[attachmentIndex])
2341 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2342 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2344 DE_ASSERT(!tcu::hasDepthComponent(reference.getFormat().order));
2345 DE_ASSERT(!tcu::hasStencilComponent(reference.getFormat().order));
2347 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2348 clear(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2349 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2351 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2353 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2356 attachmentUsed[attachmentIndex] = true;
2360 // Apply load op to depth/stencil attachment if it was used for the first time
2361 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED && !attachmentUsed[subpass.getDepthStencilAttachment().getAttachment()])
2363 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2365 // Apply load op if attachment was used for the first time
2366 if (!attachmentUsed[attachmentIndex])
2368 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2369 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2371 if (tcu::hasDepthComponent(reference.getFormat().order))
2373 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2374 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2375 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2377 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2379 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);
2383 if (tcu::hasStencilComponent(reference.getFormat().order))
2385 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2386 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2387 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2389 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2391 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);
2396 attachmentUsed[attachmentIndex] = true;
2399 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2401 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2402 const UVec2 offset = colorClear.getOffset();
2403 const UVec2 size = colorClear.getSize();
2404 tcu::TextureLevel& reference = referenceAttachments[subpass.getColorAttachments()[colorClearNdx].getAttachment()];
2407 value.color = colorClear.getColor();
2409 clear(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), value);
2412 if (renderInfo.getDepthStencilClear())
2414 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
2415 const UVec2 offset = dsClear.getOffset();
2416 const UVec2 size = dsClear.getSize();
2417 tcu::TextureLevel& reference = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2419 if (tcu::hasDepthComponent(reference.getFormat().order))
2420 clearDepth(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getDepth());
2422 if (tcu::hasStencilComponent(reference.getFormat().order))
2423 clearStencil(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getStencil());
2426 if (renderInfo.getRenderQuad())
2428 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2429 const Vec4 posA = renderQuad.getCornerA();
2430 const Vec4 posB = renderQuad.getCornerB();
2431 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2432 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2433 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
2434 (deInt32)(origin.y() + (p.y() * posA.y())));
2435 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
2436 (deInt32)(origin.y() + (p.y() * posB.y())));
2438 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
2440 const Attachment attachment = renderPassInfo.getAttachments()[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2441 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(mapVkFormat(attachment.getFormat()));
2442 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2443 const bool srgb = tcu::isSRGB(referenceTexture.getFormat());
2444 const PixelBufferAccess reference = referenceTexture.getAccess();
2445 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2446 const float clampMax = (float)(MAX_INTEGER_VALUE);
2447 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2448 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2449 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2450 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2452 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2453 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2454 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2455 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2457 DE_ASSERT(posAI.x() < posBI.x());
2458 DE_ASSERT(posAI.y() < posBI.y());
2460 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2461 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2463 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2464 const Vec4 color = valueMax * uvs + valueMin * (Vec4(1.0f) - uvs);
2467 reference.setPixel(tcu::linearToSRGB(color), x, y);
2469 reference.setPixel(color, x, y);
2473 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2475 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2476 const PixelBufferAccess reference = referenceTexture.getAccess();
2478 DE_ASSERT(posAI.x() < posBI.x());
2479 DE_ASSERT(posAI.y() < posBI.y());
2481 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2482 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2484 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2486 if (tcu::hasDepthComponent(reference.getFormat().order))
2487 reference.setPixDepth(uvs.x(), x, y);
2489 if (tcu::hasStencilComponent(reference.getFormat().order))
2490 reference.setPixStencil(STENCIL_VALUE, x, y);
2496 // Mark all attachments that were used but not stored as undefined
2497 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2499 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2500 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2501 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2502 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2504 if (attachmentUsed[attachmentNdx] && renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
2505 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2509 Maybe<deUint32> findColorAttachment (const Subpass& subpass,
2510 deUint32 attachmentIndex)
2512 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpass.getColorAttachments().size(); colorAttachmentNdx++)
2514 if (subpass.getColorAttachments()[colorAttachmentNdx].getAttachment() == attachmentIndex)
2515 return tcu::just((deUint32)colorAttachmentNdx);
2518 return tcu::nothing<deUint32>();
2521 int calcFloatDiff (float a, float b)
2523 const deUint32 au = tcu::Float32(a).bits();
2524 const deUint32 bu = tcu::Float32(b).bits();
2526 const bool asign = (au & (0x1u << 31u)) != 0u;
2527 const bool bsign = (bu & (0x1u << 31u)) != 0u;
2529 const deUint32 avalue = (au & ((0x1u << 31u) - 1u));
2530 const deUint32 bvalue = (bu & ((0x1u << 31u) - 1u));
2533 return avalue + bvalue + 1u;
2534 else if (avalue < bvalue)
2535 return bvalue - avalue;
2537 return avalue - bvalue;
2540 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess& access,
2545 const tcu::TextureFormat format = tcu::getEffectiveDepthStencilTextureFormat(access.getFormat(), tcu::Sampler::MODE_DEPTH);
2546 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2548 switch (channelClass)
2550 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2551 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2553 const int bitDepth = tcu::getTextureFormatBitDepth(format).x();
2554 const float depth = access.getPixDepth(x, y);
2555 const float threshold = 2.0f / (float)((1 << bitDepth) - 1);
2557 return deFloatAbs(depth - ref) <= threshold;
2560 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2562 const float depth = access.getPixDepth(x, y);
2563 const int mantissaBits = tcu::getTextureFormatMantissaBitDepth(format).x();
2564 const int threshold = 10 * 1 << (23 - mantissaBits);
2566 DE_ASSERT(mantissaBits <= 23);
2568 return calcFloatDiff(depth, ref) <= threshold;
2572 DE_FATAL("Invalid channel class");
2577 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess& access,
2582 const deUint32 stencil = access.getPixStencil(x, y);
2584 return stencil == ref;
2587 bool comparePixelToColorClearValue (const ConstPixelBufferAccess& access,
2590 const VkClearColorValue& ref)
2592 const tcu::TextureFormat format = access.getFormat();
2593 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2594 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2596 switch (channelClass)
2598 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2599 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2601 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
2602 const Vec4 resColor (access.getPixel(x, y));
2603 const Vec4 refColor (ref.float32[0],
2607 const Vec4 threshold (bitDepth[0] > 0 ? 20.0f / (float)((1 << bitDepth[0]) - 1) : 1.0f,
2608 bitDepth[1] > 0 ? 20.0f / (float)((1 << bitDepth[1]) - 1) : 1.0f,
2609 bitDepth[2] > 0 ? 20.0f / (float)((1 << bitDepth[2]) - 1) : 1.0f,
2610 bitDepth[3] > 0 ? 20.0f / (float)((1 << bitDepth[3]) - 1) : 1.0f);
2612 if (tcu::isSRGB(access.getFormat()))
2613 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, tcu::linearToSRGB(refColor)), threshold), channelMask), channelMask));
2615 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2618 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2620 const UVec4 resColor (access.getPixelUint(x, y));
2621 const UVec4 refColor (ref.uint32[0],
2625 const UVec4 threshold (1);
2627 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2630 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2632 const IVec4 resColor (access.getPixelInt(x, y));
2633 const IVec4 refColor (ref.int32[0],
2637 const IVec4 threshold (1);
2639 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2642 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2644 const Vec4 resColor (access.getPixel(x, y));
2645 const Vec4 refColor (ref.float32[0],
2649 const IVec4 mantissaBits (tcu::getTextureFormatMantissaBitDepth(format));
2650 const IVec4 threshold (10 * IVec4(1) << (23 - mantissaBits));
2652 DE_ASSERT(tcu::allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true)));
2654 for (int ndx = 0; ndx < 4; ndx++)
2656 if (calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx])
2664 DE_FATAL("Invalid channel class");
2674 STATUS_UNDEFINED = 0,
2681 PixelStatus (Status color, Status depth, Status stencil)
2682 : m_status ((deUint8)(color << COLOR_OFFSET)
2683 | (deUint8)((deUint8)depth << DEPTH_OFFSET)
2684 | (deUint8)((deUint8)stencil << STENCIL_OFFSET))
2688 Status getColorStatus (void) const { return (Status)((m_status & COLOR_MASK) >> COLOR_OFFSET); }
2689 Status getDepthStatus (void) const { return (Status)((m_status & DEPTH_MASK) >> DEPTH_OFFSET); }
2690 Status getStencilStatus (void) const { return (Status)((m_status & STENCIL_MASK) >> STENCIL_OFFSET); }
2692 void setColorStatus (Status status)
2694 DE_ASSERT(getColorStatus() == STATUS_UNDEFINED);
2695 m_status |= (deUint8)(status << COLOR_OFFSET);
2698 void setDepthStatus (Status status)
2700 DE_ASSERT(getDepthStatus() == STATUS_UNDEFINED);
2701 m_status |= (deUint8)(status << DEPTH_OFFSET);
2704 void setStencilStatus (Status status)
2706 DE_ASSERT(getStencilStatus() == STATUS_UNDEFINED);
2707 m_status |= (deUint8)(status << STENCIL_OFFSET);
2717 COLOR_MASK = (3<<COLOR_OFFSET),
2718 DEPTH_MASK = (3<<DEPTH_OFFSET),
2719 STENCIL_MASK = (3<<STENCIL_OFFSET),
2724 void checkDepthRenderQuad (const ConstPixelBufferAccess& result,
2727 vector<PixelStatus>& status)
2729 for (int y = posA.y(); y <= posB.y(); y++)
2730 for (int x = posA.x(); x <= posB.x(); x++)
2732 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2734 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2736 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2737 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2738 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2739 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2740 const float resDepth = result.getPixDepth(x, y);
2742 if (resDepth >= minUvs.x() && resDepth <= maxUvs.x())
2743 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2744 else if (!softCheck)
2745 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2750 void checkStencilRenderQuad (const ConstPixelBufferAccess& result,
2753 vector<PixelStatus>& status)
2755 for (int y = posA.y(); y <= posB.y(); y++)
2756 for (int x = posA.x(); x <= posB.x(); x++)
2758 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2760 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2762 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2763 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2765 if (result.getPixStencil(x, y) == STENCIL_VALUE)
2766 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2767 else if (!softCheck)
2768 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
2773 void checkColorRenderQuad (const ConstPixelBufferAccess& result,
2776 vector<PixelStatus>& status)
2778 const tcu::TextureFormat& format = result.getFormat();
2779 const bool srgb = tcu::isSRGB(format);
2780 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2781 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2782 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2783 const float clampMax = (float)(MAX_INTEGER_VALUE);
2784 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2785 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2786 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2787 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2789 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2790 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2791 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2792 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2793 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2795 IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(format);
2796 Vec4 threshold = Vec4(1.0f) / Vec4((float)(1 << formatBitDepths.x()),
2797 (float)(1 << formatBitDepths.y()),
2798 (float)(1 << formatBitDepths.z()),
2799 (float)(1 << formatBitDepths.w()));
2801 switch (channelClass)
2803 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2804 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2805 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2807 for (int y = posA.y(); y <= posB.y(); y++)
2808 for (int x = posA.x(); x <= posB.x(); x++)
2810 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2812 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2814 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2815 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2816 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2817 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2819 const Vec4 resColor (result.getPixel(x, y));
2821 const Vec4 minRefColor = srgb ? tcu::linearToSRGB(valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs))
2822 : valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs) - threshold;
2823 const Vec4 maxRefColor = srgb ? tcu::linearToSRGB(valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs))
2824 : valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs) + threshold;
2826 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2827 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2828 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2829 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2831 if (tcu::anyNotEqual(tcu::logicalAnd(
2832 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2833 lessThanEqual(resColor, maxRefColor)),
2834 channelMask), channelMask))
2837 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2840 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2847 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2849 for (int y = posA.y(); y <= posB.y(); y++)
2850 for (int x = posA.x(); x <= posB.x(); x++)
2852 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2854 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2856 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2857 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2858 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2859 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2861 const UVec4 resColor (result.getPixelUint(x, y));
2863 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2864 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2866 const UVec4 minRefColor (minRefColorF.asUint());
2867 const UVec4 maxRefColor (maxRefColorF.asUint());
2869 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2870 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2871 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2872 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2874 if (tcu::anyNotEqual(tcu::logicalAnd(
2875 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2876 lessThanEqual(resColor, maxRefColor)),
2877 channelMask), channelMask))
2880 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2883 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2890 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2892 for (int y = posA.y(); y <= posB.y(); y++)
2893 for (int x = posA.x(); x <= posB.x(); x++)
2895 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2897 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2899 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2900 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2901 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2902 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2904 const IVec4 resColor (result.getPixelInt(x, y));
2906 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2907 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2909 const IVec4 minRefColor (minRefColorF.asInt());
2910 const IVec4 maxRefColor (maxRefColorF.asInt());
2912 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2913 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2914 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2915 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2917 if (tcu::anyNotEqual(tcu::logicalAnd(
2918 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2919 lessThanEqual(resColor, maxRefColor)),
2920 channelMask), channelMask))
2923 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2926 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2934 DE_FATAL("Invalid channel class");
2938 void checkColorClear (const ConstPixelBufferAccess& result,
2939 const UVec2& offset,
2941 vector<PixelStatus>& status,
2942 const VkClearColorValue& color)
2944 DE_ASSERT(offset.x() + size.x() <= (deUint32)result.getWidth());
2945 DE_ASSERT(offset.y() + size.y() <= (deUint32)result.getHeight());
2947 DE_ASSERT(result.getWidth() * result.getHeight() == (int)status.size());
2949 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2950 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2952 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2954 DE_ASSERT(x + y * result.getWidth() < (int)status.size());
2956 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2958 if (comparePixelToColorClearValue(result, x, y, color))
2959 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2961 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2966 void checkDepthClear (const ConstPixelBufferAccess& result,
2967 const UVec2& offset,
2969 vector<PixelStatus>& status,
2972 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2973 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2975 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2977 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2979 if (comparePixelToDepthClearValue(result, x, y, depth))
2980 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2982 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2987 void checkStencilClear (const ConstPixelBufferAccess& result,
2988 const UVec2& offset,
2990 vector<PixelStatus>& status,
2993 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2994 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2996 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2998 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
3000 if (comparePixelToStencilClearValue(result, x, y, stencil))
3001 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3003 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
3008 bool verifyAttachment (const ConstPixelBufferAccess& result,
3009 const Maybe<ConstPixelBufferAccess>& secondaryResult,
3010 const RenderPass& renderPassInfo,
3011 const Maybe<VkClearValue>& renderPassClearValue,
3012 const Maybe<VkClearValue>& imageClearValue,
3013 const vector<Subpass>& subpasses,
3014 const vector<SubpassRenderInfo>& subpassRenderInfo,
3015 const PixelBufferAccess& errorImage,
3016 deUint32 attachmentIndex,
3017 const UVec2& renderPos,
3018 const UVec2& renderSize)
3020 const tcu::TextureFormat& format = result.getFormat();
3021 const bool hasDepth = tcu::hasDepthComponent(format.order);
3022 const bool hasStencil = tcu::hasStencilComponent(format.order);
3023 const bool isColorFormat = !hasDepth && !hasStencil;
3024 const PixelStatus initialStatus (isColorFormat ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3025 hasDepth ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3026 hasStencil ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK);
3028 bool attachmentIsUsed = false;
3029 vector<PixelStatus> status (result.getWidth() * result.getHeight(), initialStatus);
3030 tcu::clear(errorImage, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3032 // Check if attachment is used
3033 for (int subpassNdx = 0; subpassNdx < (int)subpasses.size(); subpassNdx++)
3035 const Subpass& subpass = subpasses[subpassNdx];
3036 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3038 if (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex)
3039 attachmentIsUsed = true;
3042 // Set all pixels that have undefined values to OK
3043 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3044 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)))
3046 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3047 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3049 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3051 if (isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3052 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3055 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3056 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3058 if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3059 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3064 // Check renderpass rendering results
3065 if (renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3066 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE))
3068 // Check subpass rendering results
3069 for (int subpassNdx = (int)subpasses.size() - 1; subpassNdx >= 0; subpassNdx--)
3071 const Subpass& subpass = subpasses[subpassNdx];
3072 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3073 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3075 // Check rendered quad
3076 if (renderInfo.getRenderQuad() && (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex))
3078 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3079 const Vec4 posA = renderQuad.getCornerA();
3080 const Vec4 posB = renderQuad.getCornerB();
3081 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3082 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3083 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
3084 (deInt32)(origin.y() + (p.y() * posA.y())));
3085 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
3086 (deInt32)(origin.y() + (p.y() * posB.y())));
3089 checkColorRenderQuad(result, posAI, posBI, status);
3093 checkDepthRenderQuad(result, posAI, posBI, status);
3095 if (hasDepth && hasStencil)
3096 checkStencilRenderQuad(*secondaryResult, posAI, posBI, status);
3097 else if (hasStencil)
3098 checkStencilRenderQuad(result, posAI, posBI, status);
3102 // Check color attachment clears
3103 if (attachmentNdx && !renderInfo.getColorClears().empty())
3105 const ColorClear& clear = renderInfo.getColorClears()[*attachmentNdx];
3107 checkColorClear(result, clear.getOffset(), clear.getSize(), status, clear.getColor());
3110 // Check depth/stencil attachment clears
3111 if (subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex && renderInfo.getDepthStencilClear())
3113 const DepthStencilClear clear = *renderInfo.getDepthStencilClear();
3116 checkDepthClear(result, clear.getOffset(), clear.getSize(), status, clear.getDepth());
3118 if (hasDepth && hasStencil)
3119 checkStencilClear(*secondaryResult, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3120 else if (hasStencil)
3121 checkStencilClear(result, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3125 // Check renderpas clear results
3126 if (attachmentIsUsed && renderPassClearValue)
3130 if (renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3131 checkColorClear(result, renderPos, renderSize, status, renderPassClearValue->color);
3135 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3136 checkDepthClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.depth);
3138 if (hasDepth && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3139 checkStencilClear(*secondaryResult, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3140 else if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3141 checkStencilClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3146 // Set all pixels that have undefined values fater renderpass to OK
3147 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3148 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)))
3150 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3151 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3153 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3155 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED
3156 && isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3157 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3160 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED
3161 && hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3162 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3164 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED
3165 && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3166 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3171 if (imageClearValue)
3174 checkColorClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->color);
3178 checkDepthClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.depth);
3180 if (hasDepth && hasStencil)
3181 checkStencilClear(*secondaryResult, UVec2(0, 0), UVec2(secondaryResult->getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3182 else if (hasStencil)
3183 checkStencilClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3190 for(int y = 0; y < result.getHeight(); y++)
3191 for(int x = 0; x < result.getWidth(); x++)
3193 const PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3197 if (pixelStatus.getColorStatus() != PixelStatus::STATUS_OK)
3199 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
3200 errorImage.setPixel(Vec4(1.0f, 1.0f, 0.0f, 1.0f), x, y);
3201 else if (pixelStatus.getColorStatus() == PixelStatus::STATUS_FAIL)
3202 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3209 if (hasDepth && pixelStatus.getDepthStatus() != PixelStatus::STATUS_OK)
3211 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3215 if (hasStencil && pixelStatus.getStencilStatus() != PixelStatus::STATUS_OK)
3217 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3227 bool logAndVerifyImages (TestLog& log,
3228 const DeviceInterface& vk,
3230 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3231 const vector<bool>& attachmentIsLazy,
3232 const RenderPass& renderPassInfo,
3233 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3234 const vector<Maybe<VkClearValue> >& imageClearValues,
3235 const vector<SubpassRenderInfo>& subpassRenderInfo,
3236 const UVec2& targetSize,
3237 const TestConfig& config)
3239 vector<tcu::TextureLevel> referenceAttachments;
3242 log << TestLog::Message << "Reference images fill undefined pixels with grid pattern." << TestLog::EndMessage;
3244 renderReferenceImages(referenceAttachments, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3246 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3248 if (!attachmentIsLazy[attachmentNdx])
3250 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3251 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3253 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3255 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3256 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3257 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3259 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3260 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3261 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3263 const VkMappedMemoryRange ranges[] =
3266 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3268 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3269 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3270 depthBufferSize // size;
3273 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3275 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3276 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3277 stencilBufferSize // size;
3280 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3283 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3284 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3285 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3287 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3288 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3290 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3292 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3293 && !verifyAttachment(depthAccess, tcu::just(stencilAccess), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3295 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3302 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3303 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3305 const VkMappedMemoryRange range =
3307 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3309 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3310 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3313 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3316 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3317 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3319 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3320 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3322 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3323 && !verifyAttachment(access, tcu::nothing<ConstPixelBufferAccess>(), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3325 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3336 std::string getAttachmentType (VkFormat vkFormat)
3338 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3339 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3341 switch (channelClass)
3343 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3346 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3349 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3350 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3351 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3355 DE_FATAL("Unknown channel class");
3360 void createTestShaders (SourceCollections& dst, TestConfig config)
3362 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3364 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3366 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3368 const Subpass& subpass = subpasses[subpassNdx];
3369 std::ostringstream vertexShader;
3370 std::ostringstream fragmentShader;
3372 vertexShader << "#version 310 es\n"
3373 << "layout(location = 0) in highp vec4 a_position;\n"
3374 << "layout(location = 0) out highp vec2 v_color;\n"
3375 << "void main (void) {\n"
3376 << "\thighp float a = 0.5 + a_position.x;\n"
3377 << "\thighp float b = 0.5 + a_position.y;\n"
3378 << "\tv_color = vec2(a, b);\n"
3379 << "\tgl_Position = a_position;\n"
3382 fragmentShader << "#version 310 es\n"
3383 << "layout(location = 0) in highp vec2 v_color;\n";
3385 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3387 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3388 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3391 fragmentShader << "void main (void) {\n"
3392 << "\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";
3394 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3396 const tcu::TextureFormat format = mapVkFormat(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3397 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
3398 const float clampMin = (float)(-MAX_INTEGER_VALUE);
3399 const float clampMax = (float)(MAX_INTEGER_VALUE);
3400 const Vec4 valueMax (de::clamp(formatInfo.valueMax[0], clampMin, clampMax),
3401 de::clamp(formatInfo.valueMax[1], clampMin, clampMax),
3402 de::clamp(formatInfo.valueMax[2], clampMin, clampMax),
3403 de::clamp(formatInfo.valueMax[3], clampMin, clampMax));
3405 const Vec4 valueMin (de::clamp(formatInfo.valueMin[0], clampMin, clampMax),
3406 de::clamp(formatInfo.valueMin[1], clampMin, clampMax),
3407 de::clamp(formatInfo.valueMin[2], clampMin, clampMax),
3408 de::clamp(formatInfo.valueMin[3], clampMin, clampMax));
3409 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3411 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4" << valueMin << " + vec4" << (valueMax - valueMin) << " * scale);\n";
3414 fragmentShader << "}\n";
3416 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3417 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3422 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3424 bool lastAttachmentWasLazy = false;
3426 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3428 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3429 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3430 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3431 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3433 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3435 attachmentIsLazy.push_back(true);
3436 lastAttachmentWasLazy = true;
3438 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3440 attachmentIsLazy.push_back(false);
3441 lastAttachmentWasLazy = false;
3444 DE_FATAL("Unknown imageMemory");
3447 attachmentIsLazy.push_back(false);
3451 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3453 bool lastSubpassWasSecondary = false;
3455 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3457 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3459 subpassIsSecondary.push_back(true);
3460 lastSubpassWasSecondary = true;
3462 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3464 subpassIsSecondary.push_back(false);
3465 lastSubpassWasSecondary = false;
3468 DE_FATAL("Unknown commandBuffer");
3472 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3474 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3476 if (!isLazy[attachmentNdx])
3477 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3479 clearValues.push_back(nothing<VkClearValue>());
3483 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3485 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3487 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3488 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3490 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3493 clearValues.push_back(nothing<VkClearValue>());
3497 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
3499 clearValues.resize(renderPass.getSubpasses().size());
3501 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3503 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
3504 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3506 clearValues[subpassNdx].resize(colorAttachments.size());
3508 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3510 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3511 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3513 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
3518 void logSubpassRenderInfo (TestLog& log,
3519 const SubpassRenderInfo& info)
3521 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
3523 if (info.isSecondary())
3524 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
3526 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
3528 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
3530 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
3532 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
3533 << ". Offset: " << colorClear.getOffset()
3534 << ", Size: " << colorClear.getSize()
3535 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
3538 if (info.getDepthStencilClear())
3540 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
3542 log << TestLog::Message << "Clearing depth stencil attachment"
3543 << ". Offset: " << depthStencilClear.getOffset()
3544 << ", Size: " << depthStencilClear.getSize()
3545 << ", Depth: " << depthStencilClear.getDepth()
3546 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
3549 if (info.getRenderQuad())
3551 const RenderQuad& renderQuad = *info.getRenderQuad();
3553 log << TestLog::Message << "Rendering gradient quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
3557 void logTestCaseInfo (TestLog& log,
3558 const TestConfig& config,
3559 const vector<bool>& attachmentIsLazy,
3560 const vector<Maybe<VkClearValue> >& imageClearValues,
3561 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3562 const vector<SubpassRenderInfo>& subpassRenderInfo)
3564 const RenderPass& renderPass = config.renderPass;
3566 logRenderPassInfo(log, renderPass);
3568 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
3569 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
3570 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
3572 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
3573 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
3575 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
3577 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
3579 if (attachmentIsLazy[attachmentNdx])
3580 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
3582 if (imageClearValues[attachmentNdx])
3583 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
3585 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
3586 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
3589 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3591 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
3593 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
3597 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
3599 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
3600 const vector<Subpass>& subpasses = renderPass.getSubpasses();
3601 bool lastSubpassWasSecondary = false;
3603 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
3605 const Subpass& subpass = subpasses[subpassNdx];
3606 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
3607 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
3608 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
3609 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
3610 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
3612 vector<ColorClear> colorClears;
3613 Maybe<DepthStencilClear> depthStencilClear;
3614 Maybe<RenderQuad> renderQuad;
3616 lastSubpassWasSecondary = subpassIsSecondary;
3618 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
3620 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3622 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3624 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3625 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3626 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3627 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
3628 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
3629 const VkClearColorValue color = randomColorClearValue(attachment, rng);
3631 colorClears.push_back(ColorClear(offset, size, color));
3634 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3636 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
3637 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3638 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
3639 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
3640 const VkClearValue value = randomClearValue(attachment, rng);
3642 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
3646 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3647 renderQuad = tcu::just(RenderQuad(tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f)));
3649 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
3653 void checkTextureFormatSupport (TestLog& log,
3654 const InstanceInterface& vk,
3655 VkPhysicalDevice device,
3656 const vector<Attachment>& attachments)
3658 bool supported = true;
3660 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3662 const Attachment& attachment = attachments[attachmentNdx];
3663 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3664 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
3665 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
3666 VkFormatProperties properties;
3668 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
3670 if ((properties.optimalTilingFeatures & flags) != flags)
3673 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
3678 TCU_THROW(NotSupportedError, "Format not supported");
3681 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
3683 const UVec2 targetSize = config.targetSize;
3684 const UVec2 renderPos = config.renderPos;
3685 const UVec2 renderSize = config.renderSize;
3686 const RenderPass& renderPassInfo = config.renderPass;
3688 TestLog& log = context.getTestContext().getLog();
3689 de::Random rng (config.seed);
3691 vector<bool> attachmentIsLazy;
3692 vector<Maybe<VkClearValue> > imageClearValues;
3693 vector<Maybe<VkClearValue> > renderPassClearValues;
3695 vector<bool> subpassIsSecondary;
3696 vector<SubpassRenderInfo> subpassRenderInfo;
3697 vector<vector<VkClearColorValue> > subpassColorClearValues;
3699 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
3700 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
3701 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
3703 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
3704 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
3705 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
3707 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
3709 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
3712 const VkDevice device = context.getDevice();
3713 const DeviceInterface& vk = context.getDeviceInterface();
3714 const VkQueue queue = context.getUniversalQueue();
3715 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
3716 Allocator& allocator = context.getDefaultAllocator();
3718 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
3719 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
3720 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3721 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3722 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3724 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
3725 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
3726 vector<VkImageView> attachmentViews;
3728 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3730 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
3732 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentIsLazy[attachmentNdx])));
3733 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
3736 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3737 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
3738 endCommandBuffer(vk, *initializeImagesCommandBuffer);
3741 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
3743 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3744 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, subpassRenderInfo[subpassNdx])));
3746 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3747 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
3748 endCommandBuffer(vk, *renderCommandBuffer);
3750 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3751 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
3752 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
3754 const VkCommandBuffer commandBuffers[] =
3756 *initializeImagesCommandBuffer,
3757 *renderCommandBuffer,
3758 *readImagesToBuffersCommandBuffer
3760 const Unique<VkFence> fence (createFence(vk, device, 0u));
3762 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
3763 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
3767 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
3768 return tcu::TestStatus::pass("Pass");
3770 return tcu::TestStatus::fail("Result verification failed");
3774 // \todo Fill with actually required formats in the future
3775 static const VkFormat s_colorFormats[] =
3777 VK_FORMAT_R5G6B5_UNORM_PACK16,
3778 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3783 VK_FORMAT_R8G8_UNORM,
3784 VK_FORMAT_R8G8_SNORM,
3785 VK_FORMAT_R8G8_UINT,
3786 VK_FORMAT_R8G8_SINT,
3787 VK_FORMAT_R8G8B8_UNORM,
3788 VK_FORMAT_R8G8B8_SNORM,
3789 VK_FORMAT_R8G8B8_UINT,
3790 VK_FORMAT_R8G8B8_SINT,
3791 VK_FORMAT_R8G8B8_SRGB,
3792 VK_FORMAT_R8G8B8A8_UNORM,
3793 VK_FORMAT_R8G8B8A8_SNORM,
3794 VK_FORMAT_R8G8B8A8_UINT,
3795 VK_FORMAT_R8G8B8A8_SINT,
3796 VK_FORMAT_R8G8B8A8_SRGB,
3797 VK_FORMAT_R16_UNORM,
3798 VK_FORMAT_R16_SNORM,
3801 VK_FORMAT_R16_SFLOAT,
3802 VK_FORMAT_R16G16_UNORM,
3803 VK_FORMAT_R16G16_SNORM,
3804 VK_FORMAT_R16G16_UINT,
3805 VK_FORMAT_R16G16_SINT,
3806 VK_FORMAT_R16G16_SFLOAT,
3807 VK_FORMAT_R16G16B16_UNORM,
3808 VK_FORMAT_R16G16B16_SNORM,
3809 VK_FORMAT_R16G16B16_UINT,
3810 VK_FORMAT_R16G16B16_SINT,
3811 VK_FORMAT_R16G16B16_SFLOAT,
3812 VK_FORMAT_R16G16B16A16_UNORM,
3813 VK_FORMAT_R16G16B16A16_SNORM,
3814 VK_FORMAT_R16G16B16A16_UINT,
3815 VK_FORMAT_R16G16B16A16_SINT,
3816 VK_FORMAT_R16G16B16A16_SFLOAT,
3819 VK_FORMAT_R32_SFLOAT,
3820 VK_FORMAT_R32G32_UINT,
3821 VK_FORMAT_R32G32_SINT,
3822 VK_FORMAT_R32G32_SFLOAT,
3823 VK_FORMAT_R32G32B32_UINT,
3824 VK_FORMAT_R32G32B32_SINT,
3825 VK_FORMAT_R32G32B32_SFLOAT,
3826 VK_FORMAT_R32G32B32A32_UINT,
3827 VK_FORMAT_R32G32B32A32_SINT,
3828 VK_FORMAT_R32G32B32A32_SFLOAT
3831 static const VkFormat s_depthStencilFormats[] =
3833 VK_FORMAT_D16_UNORM,
3834 VK_FORMAT_X8_D24_UNORM_PACK32,
3835 VK_FORMAT_D32_SFLOAT,
3837 VK_FORMAT_D24_UNORM_S8_UINT
3840 de::MovePtr<tcu::TestCaseGroup> createAttachmentTestCaseGroup (tcu::TestContext& testCtx)
3842 const deUint32 attachmentCounts[] = { 1, 3, 8 };
3843 const VkAttachmentLoadOp loadOps[] =
3845 VK_ATTACHMENT_LOAD_OP_LOAD,
3846 VK_ATTACHMENT_LOAD_OP_CLEAR,
3847 VK_ATTACHMENT_LOAD_OP_DONT_CARE
3850 const VkAttachmentStoreOp storeOps[] =
3852 VK_ATTACHMENT_STORE_OP_STORE,
3853 VK_ATTACHMENT_STORE_OP_DONT_CARE
3856 const VkImageLayout initialAndFinalColorLayouts[] =
3858 VK_IMAGE_LAYOUT_GENERAL,
3859 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3860 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3861 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3862 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3865 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
3867 VK_IMAGE_LAYOUT_GENERAL,
3868 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3869 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
3870 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3871 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3872 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3875 const VkImageLayout subpassLayouts[] =
3877 VK_IMAGE_LAYOUT_GENERAL,
3878 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
3881 const VkImageLayout depthStencilLayouts[] =
3883 VK_IMAGE_LAYOUT_GENERAL,
3884 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
3887 const TestConfig::RenderTypes renderCommands[] =
3889 TestConfig::RENDERTYPES_NONE,
3890 TestConfig::RENDERTYPES_CLEAR,
3891 TestConfig::RENDERTYPES_DRAW,
3892 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
3895 const TestConfig::CommandBufferTypes commandBuffers[] =
3897 TestConfig::COMMANDBUFFERTYPES_INLINE,
3898 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
3899 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
3902 const TestConfig::ImageMemory imageMemories[] =
3904 TestConfig::IMAGEMEMORY_STRICT,
3905 TestConfig::IMAGEMEMORY_LAZY,
3906 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
3909 const UVec2 targetSizes[] =
3915 const UVec2 renderPositions[] =
3921 const UVec2 renderSizes[] =
3927 de::Random rng (1433774382u);
3928 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment", "Attachment format and count tests with load and store ops and image layouts"));
3930 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
3932 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
3933 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
3934 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
3936 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
3938 const bool useDepthStencil = rng.getBool();
3939 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
3940 vector<Attachment> attachments;
3941 vector<AttachmentReference> colorAttachmentReferences;
3943 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
3945 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3946 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_colorFormats), DE_ARRAY_END(s_colorFormats));
3947 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3948 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3950 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3951 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3952 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
3954 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3955 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3957 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3958 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
3961 if (useDepthStencil)
3963 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
3964 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_depthStencilFormats), DE_ARRAY_END(s_depthStencilFormats));
3965 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3966 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3968 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3969 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3971 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3972 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3974 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
3975 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3979 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
3980 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
3981 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
3982 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>()));
3983 const vector<SubpassDependency> deps;
3985 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
3986 const RenderPass renderPass (attachments, subpasses, deps);
3987 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
3988 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
3989 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
3991 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
3995 group->addChild(attachmentCountGroup.release());
4001 de::MovePtr<tcu::TestCaseGroup> createAttachmentAllocationTestGroup (tcu::TestContext& testCtx)
4003 const deUint32 attachmentCounts[] = { 4, 8 };
4004 const VkAttachmentLoadOp loadOps[] =
4006 VK_ATTACHMENT_LOAD_OP_LOAD,
4007 VK_ATTACHMENT_LOAD_OP_CLEAR,
4008 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4011 const VkAttachmentStoreOp storeOps[] =
4013 VK_ATTACHMENT_STORE_OP_STORE,
4014 VK_ATTACHMENT_STORE_OP_DONT_CARE
4017 const VkImageLayout initialAndFinalLayouts[] =
4019 VK_IMAGE_LAYOUT_GENERAL,
4020 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4021 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4022 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4023 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4024 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4025 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4028 const VkImageLayout subpassLayouts[] =
4030 VK_IMAGE_LAYOUT_GENERAL,
4031 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4036 // Each pass uses one more attachmen than previous one
4037 ALLOCATIONTYPE_GROW,
4038 // Each pass uses one less attachment than previous one
4039 ALLOCATIONTYPE_SHRINK,
4040 // Each pass drops one attachment and picks up new one
4041 ALLOCATIONTYPE_ROLL,
4042 // Start by growing and end by shrinking
4043 ALLOCATIONTYPE_GROW_SHRINK
4046 const AllocationType allocationTypes[] =
4048 ALLOCATIONTYPE_GROW,
4049 ALLOCATIONTYPE_SHRINK,
4050 ALLOCATIONTYPE_ROLL,
4051 ALLOCATIONTYPE_GROW_SHRINK
4054 const char* const allocationTypeStr[] =
4062 const TestConfig::RenderTypes renderCommands[] =
4064 TestConfig::RENDERTYPES_NONE,
4065 TestConfig::RENDERTYPES_CLEAR,
4066 TestConfig::RENDERTYPES_DRAW,
4067 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4070 const TestConfig::CommandBufferTypes commandBuffers[] =
4072 TestConfig::COMMANDBUFFERTYPES_INLINE,
4073 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4074 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4077 const TestConfig::ImageMemory imageMemories[] =
4079 TestConfig::IMAGEMEMORY_STRICT,
4080 TestConfig::IMAGEMEMORY_LAZY,
4081 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4084 const UVec2 targetSizes[] =
4090 const UVec2 renderPositions[] =
4096 const UVec2 renderSizes[] =
4102 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment_allocation", "Attachment allocation tests"));
4103 de::Random rng (3700649827u);
4105 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4107 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4108 const size_t testCaseCount = 100;
4109 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4111 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4113 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4114 vector<Attachment> attachments;
4115 vector<Subpass> subpasses;
4117 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4119 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4120 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_colorFormats), DE_ARRAY_END(s_colorFormats));
4121 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4122 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4124 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4125 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalLayouts), DE_ARRAY_END(initialAndFinalLayouts));
4127 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4128 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4130 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4133 if (allocationType == ALLOCATIONTYPE_GROW)
4135 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4137 vector<AttachmentReference> colorAttachmentReferences;
4139 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4141 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4143 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4146 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>()));
4149 else if (allocationType == ALLOCATIONTYPE_SHRINK)
4151 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4153 vector<AttachmentReference> colorAttachmentReferences;
4155 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4157 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4159 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4162 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4165 else if (allocationType == ALLOCATIONTYPE_ROLL)
4167 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
4169 vector<AttachmentReference> colorAttachmentReferences;
4171 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
4173 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4175 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
4178 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4181 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
4183 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4185 vector<AttachmentReference> colorAttachmentReferences;
4187 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4189 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4191 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4194 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4197 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4199 vector<AttachmentReference> colorAttachmentReferences;
4201 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4203 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4205 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4208 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>()));
4212 DE_FATAL("Unknown allocation type");
4215 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4216 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4217 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4219 const string testCaseName = de::toString(testCaseNdx);
4220 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4221 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4222 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4224 vector<SubpassDependency> deps;
4226 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
4228 const bool byRegion = rng.getBool();
4229 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
4230 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4231 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4232 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4233 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4235 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4236 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4237 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4238 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4240 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4241 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, // \todo [pyry] Correct?
4243 byRegion ? (VkBool32)VK_TRUE : (VkBool32)VK_FALSE));
4246 const RenderPass renderPass (attachments, subpasses, deps);
4248 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4252 group->addChild(allocationTypeGroup.release());
4258 de::MovePtr<tcu::TestCaseGroup> createSimpleTestGroup (tcu::TestContext& testCtx)
4260 const UVec2 targetSize (64, 64);
4261 const UVec2 renderPos (0, 0);
4262 const UVec2 renderSize (64, 64);
4263 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "simple", "Simple basic render pass tests"));
4267 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4268 VK_SAMPLE_COUNT_1_BIT,
4269 VK_ATTACHMENT_LOAD_OP_CLEAR,
4270 VK_ATTACHMENT_STORE_OP_STORE,
4271 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4272 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4273 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4274 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4275 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4277 vector<AttachmentReference>(),
4278 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4279 vector<AttachmentReference>(),
4280 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4281 vector<AttachmentReference>())),
4282 vector<SubpassDependency>());
4284 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));
4289 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4290 VK_SAMPLE_COUNT_1_BIT,
4291 VK_ATTACHMENT_LOAD_OP_CLEAR,
4292 VK_ATTACHMENT_STORE_OP_STORE,
4293 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4294 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4295 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4296 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4297 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4299 vector<AttachmentReference>(),
4300 vector<AttachmentReference>(),
4301 vector<AttachmentReference>(),
4302 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4303 vector<AttachmentReference>())),
4304 vector<SubpassDependency>());
4306 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));
4311 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
4312 VK_SAMPLE_COUNT_1_BIT,
4313 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4314 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4315 VK_ATTACHMENT_LOAD_OP_CLEAR,
4316 VK_ATTACHMENT_STORE_OP_STORE,
4317 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4318 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4319 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4321 vector<AttachmentReference>(),
4322 vector<AttachmentReference>(),
4323 vector<AttachmentReference>(),
4324 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4325 vector<AttachmentReference>())),
4326 vector<SubpassDependency>());
4328 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));
4333 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4334 VK_SAMPLE_COUNT_1_BIT,
4335 VK_ATTACHMENT_LOAD_OP_CLEAR,
4336 VK_ATTACHMENT_STORE_OP_STORE,
4337 VK_ATTACHMENT_LOAD_OP_CLEAR,
4338 VK_ATTACHMENT_STORE_OP_STORE,
4339 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4340 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4341 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4343 vector<AttachmentReference>(),
4344 vector<AttachmentReference>(),
4345 vector<AttachmentReference>(),
4346 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4347 vector<AttachmentReference>())),
4348 vector<SubpassDependency>());
4350 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));
4355 const Attachment attachments[] =
4357 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4358 VK_SAMPLE_COUNT_1_BIT,
4359 VK_ATTACHMENT_LOAD_OP_CLEAR,
4360 VK_ATTACHMENT_STORE_OP_STORE,
4361 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4362 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4363 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4364 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4365 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4366 VK_SAMPLE_COUNT_1_BIT,
4367 VK_ATTACHMENT_LOAD_OP_CLEAR,
4368 VK_ATTACHMENT_STORE_OP_STORE,
4369 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4370 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4371 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4372 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4375 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4376 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4378 vector<AttachmentReference>(),
4379 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4380 vector<AttachmentReference>(),
4381 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4382 vector<AttachmentReference>())),
4383 vector<SubpassDependency>());
4385 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));
4390 const Attachment attachments[] =
4392 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4393 VK_SAMPLE_COUNT_1_BIT,
4394 VK_ATTACHMENT_LOAD_OP_CLEAR,
4395 VK_ATTACHMENT_STORE_OP_STORE,
4396 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4397 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4398 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4399 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4400 Attachment(VK_FORMAT_S8_UINT,
4401 VK_SAMPLE_COUNT_1_BIT,
4402 VK_ATTACHMENT_LOAD_OP_CLEAR,
4403 VK_ATTACHMENT_STORE_OP_STORE,
4404 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4405 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4406 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4407 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4410 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4411 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4413 vector<AttachmentReference>(),
4414 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4415 vector<AttachmentReference>(),
4416 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4417 vector<AttachmentReference>())),
4418 vector<SubpassDependency>());
4421 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));
4424 // color_depth_stencil
4426 const Attachment attachments[] =
4428 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4429 VK_SAMPLE_COUNT_1_BIT,
4430 VK_ATTACHMENT_LOAD_OP_CLEAR,
4431 VK_ATTACHMENT_STORE_OP_STORE,
4432 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4433 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4434 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4435 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4436 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4437 VK_SAMPLE_COUNT_1_BIT,
4438 VK_ATTACHMENT_LOAD_OP_CLEAR,
4439 VK_ATTACHMENT_STORE_OP_STORE,
4440 VK_ATTACHMENT_LOAD_OP_CLEAR,
4441 VK_ATTACHMENT_STORE_OP_STORE,
4442 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4443 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4446 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4447 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4449 vector<AttachmentReference>(),
4450 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4451 vector<AttachmentReference>(),
4452 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4453 vector<AttachmentReference>())),
4454 vector<SubpassDependency>());
4456 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));
4462 std::string formatToName (VkFormat format)
4464 const std::string formatStr = de::toString(format);
4465 const std::string prefix = "VK_FORMAT_";
4467 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4469 return de::toLower(formatStr.substr(prefix.length()));
4472 de::MovePtr<tcu::TestCaseGroup> createFormatTestGroup(tcu::TestContext& testCtx)
4474 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "formats", "Tests for different image formats."));
4476 const UVec2 targetSize (64, 64);
4477 const UVec2 renderPos (0, 0);
4478 const UVec2 renderSize (64, 64);
4482 const char* const str;
4483 const VkAttachmentLoadOp op;
4486 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
4487 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
4488 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
4493 const char* const str;
4494 const TestConfig::RenderTypes types;
4497 { "clear", TestConfig::RENDERTYPES_CLEAR },
4498 { "draw", TestConfig::RENDERTYPES_DRAW },
4499 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
4502 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_colorFormats); formatNdx++)
4504 const VkFormat format = s_colorFormats[formatNdx];
4505 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4507 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4509 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4510 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4512 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4514 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4515 VK_SAMPLE_COUNT_1_BIT,
4517 VK_ATTACHMENT_STORE_OP_STORE,
4518 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4519 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4520 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4521 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4522 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4524 vector<AttachmentReference>(),
4525 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4526 vector<AttachmentReference>(),
4527 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4528 vector<AttachmentReference>())),
4529 vector<SubpassDependency>());
4531 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));
4534 formatGroup->addChild(loadOpGroup.release());
4537 group->addChild(formatGroup.release());
4545 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
4547 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
4549 renderpassTests->addChild(createSimpleTestGroup(testCtx).release());
4550 renderpassTests->addChild(createFormatTestGroup(testCtx).release());
4551 renderpassTests->addChild(createAttachmentTestCaseGroup(testCtx).release());
4552 renderpassTests->addChild(createAttachmentAllocationTestGroup(testCtx).release());
4554 return renderpassTests.release();