1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief RenderPass tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassTests.hpp"
26 #include "vktTestCaseUtil.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkStrUtil.hpp"
38 #include "vkTypeUtil.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuResultCollector.hpp"
42 #include "tcuFormatUtil.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuFloat.hpp"
45 #include "tcuMaybe.hpp"
46 #include "tcuVectorUtil.hpp"
48 #include "deUniquePtr.hpp"
49 #include "deSharedPtr.hpp"
50 #include "deStringUtil.hpp"
51 #include "deSTLUtil.hpp"
52 #include "deRandom.hpp"
69 using tcu::ConstPixelBufferAccess;
70 using tcu::PixelBufferAccess;
84 // Limit integer values that are representable as floats
85 MAX_INTEGER_VALUE = ((1u<<22u)-1u)
88 // Utility functions using flattened structs
89 Move<VkFence> createFence (const DeviceInterface& vk, VkDevice device, VkFenceCreateFlags flags)
91 const VkFenceCreateInfo pCreateInfo =
93 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
98 return createFence(vk, device, &pCreateInfo);
101 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
103 VkFramebufferCreateFlags pCreateInfo_flags,
104 VkRenderPass pCreateInfo_renderPass,
105 deUint32 pCreateInfo_attachmentCount,
106 const VkImageView* pCreateInfo_pAttachments,
107 deUint32 pCreateInfo_width,
108 deUint32 pCreateInfo_height,
109 deUint32 pCreateInfo_layers)
111 const VkFramebufferCreateInfo pCreateInfo =
113 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
116 pCreateInfo_renderPass,
117 pCreateInfo_attachmentCount,
118 pCreateInfo_pAttachments,
123 return createFramebuffer(vk, device, &pCreateInfo);
126 Move<VkImage> createImage (const DeviceInterface& vk,
128 VkImageCreateFlags pCreateInfo_flags,
129 VkImageType pCreateInfo_imageType,
130 VkFormat pCreateInfo_format,
131 VkExtent3D pCreateInfo_extent,
132 deUint32 pCreateInfo_mipLevels,
133 deUint32 pCreateInfo_arrayLayers,
134 VkSampleCountFlagBits pCreateInfo_samples,
135 VkImageTiling pCreateInfo_tiling,
136 VkImageUsageFlags pCreateInfo_usage,
137 VkSharingMode pCreateInfo_sharingMode,
138 deUint32 pCreateInfo_queueFamilyCount,
139 const deUint32* pCreateInfo_pQueueFamilyIndices,
140 VkImageLayout pCreateInfo_initialLayout)
142 const VkImageCreateInfo pCreateInfo =
144 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
147 pCreateInfo_imageType,
150 pCreateInfo_mipLevels,
151 pCreateInfo_arrayLayers,
155 pCreateInfo_sharingMode,
156 pCreateInfo_queueFamilyCount,
157 pCreateInfo_pQueueFamilyIndices,
158 pCreateInfo_initialLayout
160 return createImage(vk, device, &pCreateInfo);
163 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
165 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
168 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
170 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
173 Move<VkImageView> createImageView (const DeviceInterface& vk,
175 VkImageViewCreateFlags pCreateInfo_flags,
176 VkImage pCreateInfo_image,
177 VkImageViewType pCreateInfo_viewType,
178 VkFormat pCreateInfo_format,
179 VkComponentMapping pCreateInfo_components,
180 VkImageSubresourceRange pCreateInfo_subresourceRange)
182 const VkImageViewCreateInfo pCreateInfo =
184 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
188 pCreateInfo_viewType,
190 pCreateInfo_components,
191 pCreateInfo_subresourceRange,
193 return createImageView(vk, device, &pCreateInfo);
196 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
198 VkBufferCreateFlags pCreateInfo_flags,
199 VkDeviceSize pCreateInfo_size,
200 VkBufferUsageFlags pCreateInfo_usage,
201 VkSharingMode pCreateInfo_sharingMode,
202 deUint32 pCreateInfo_queueFamilyCount,
203 const deUint32* pCreateInfo_pQueueFamilyIndices)
205 const VkBufferCreateInfo pCreateInfo =
207 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
212 pCreateInfo_sharingMode,
213 pCreateInfo_queueFamilyCount,
214 pCreateInfo_pQueueFamilyIndices,
216 return createBuffer(vk, device, &pCreateInfo);
219 Move<VkCommandPool> createCommandPool (const DeviceInterface& vk,
221 VkCommandPoolCreateFlags pCreateInfo_flags,
222 deUint32 pCreateInfo_queueFamilyIndex)
224 const VkCommandPoolCreateInfo pCreateInfo =
226 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
229 pCreateInfo_queueFamilyIndex,
231 return createCommandPool(vk, device, &pCreateInfo);
234 void cmdBeginRenderPass (const DeviceInterface& vk,
235 VkCommandBuffer cmdBuffer,
236 VkRenderPass pRenderPassBegin_renderPass,
237 VkFramebuffer pRenderPassBegin_framebuffer,
238 VkRect2D pRenderPassBegin_renderArea,
239 deUint32 pRenderPassBegin_clearValueCount,
240 const VkClearValue* pRenderPassBegin_pAttachmentClearValues,
241 VkSubpassContents contents)
243 const VkRenderPassBeginInfo pRenderPassBegin =
245 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
247 pRenderPassBegin_renderPass,
248 pRenderPassBegin_framebuffer,
249 pRenderPassBegin_renderArea,
250 pRenderPassBegin_clearValueCount,
251 pRenderPassBegin_pAttachmentClearValues,
253 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
256 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface& vk,
258 VkCommandPool pCreateInfo_commandPool,
259 VkCommandBufferLevel pCreateInfo_level)
261 const VkCommandBufferAllocateInfo pAllocateInfo =
263 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
265 pCreateInfo_commandPool,
269 return allocateCommandBuffer(vk, device, &pAllocateInfo);
272 void beginCommandBuffer (const DeviceInterface& vk,
273 VkCommandBuffer cmdBuffer,
274 VkCommandBufferUsageFlags pBeginInfo_flags,
275 VkRenderPass pInheritanceInfo_renderPass,
276 deUint32 pInheritanceInfo_subpass,
277 VkFramebuffer pInheritanceInfo_framebuffer,
278 VkBool32 pInheritanceInfo_occlusionQueryEnable,
279 VkQueryControlFlags pInheritanceInfo_queryFlags,
280 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
282 const VkCommandBufferInheritanceInfo pInheritanceInfo =
284 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
286 pInheritanceInfo_renderPass,
287 pInheritanceInfo_subpass,
288 pInheritanceInfo_framebuffer,
289 pInheritanceInfo_occlusionQueryEnable,
290 pInheritanceInfo_queryFlags,
291 pInheritanceInfo_pipelineStatistics,
293 const VkCommandBufferBeginInfo pBeginInfo =
295 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
300 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
303 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
305 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
308 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
310 const VkSubmitInfo submitInfo =
312 VK_STRUCTURE_TYPE_SUBMIT_INFO,
314 0u, // waitSemaphoreCount
315 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
316 (const VkPipelineStageFlags*)DE_NULL,
317 cmdBufferCount, // commandBufferCount
319 0u, // signalSemaphoreCount
320 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
322 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
325 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
327 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
330 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
332 const tcu::TextureFormat format = mapVkFormat(vkFormat);
334 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
336 switch (format.order)
338 case tcu::TextureFormat::DS:
339 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
341 case tcu::TextureFormat::D:
342 return VK_IMAGE_ASPECT_DEPTH_BIT;
344 case tcu::TextureFormat::S:
345 return VK_IMAGE_ASPECT_STENCIL_BIT;
348 return VK_IMAGE_ASPECT_COLOR_BIT;
352 VkAccessFlags getAllMemoryReadFlags (void)
354 return VK_ACCESS_TRANSFER_READ_BIT
355 | VK_ACCESS_UNIFORM_READ_BIT
356 | VK_ACCESS_HOST_READ_BIT
357 | VK_ACCESS_INDEX_READ_BIT
358 | VK_ACCESS_SHADER_READ_BIT
359 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
360 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
361 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
362 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
363 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
366 VkAccessFlags getAllMemoryWriteFlags (void)
368 return VK_ACCESS_TRANSFER_WRITE_BIT
369 | VK_ACCESS_HOST_WRITE_BIT
370 | VK_ACCESS_SHADER_WRITE_BIT
371 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
372 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
375 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
379 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
380 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
381 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
382 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
383 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT;
384 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT;
385 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT;
388 return (VkAccessFlags)0;
392 VkPipelineStageFlags getAllPipelineStageFlags (void)
394 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
395 | VK_PIPELINE_STAGE_TRANSFER_BIT
396 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
397 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
398 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
399 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
400 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
401 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
402 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
403 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
404 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
405 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
406 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
409 class AttachmentReference
412 AttachmentReference (deUint32 attachment,
413 VkImageLayout layout)
414 : m_attachment (attachment)
419 deUint32 getAttachment (void) const { return m_attachment; }
420 VkImageLayout getImageLayout (void) const { return m_layout; }
423 deUint32 m_attachment;
424 VkImageLayout m_layout;
430 Subpass (VkPipelineBindPoint pipelineBindPoint,
431 VkSubpassDescriptionFlags flags,
432 const vector<AttachmentReference>& inputAttachments,
433 const vector<AttachmentReference>& colorAttachments,
434 const vector<AttachmentReference>& resolveAttachments,
435 AttachmentReference depthStencilAttachment,
436 const vector<AttachmentReference>& preserveAttachments)
437 : m_pipelineBindPoint (pipelineBindPoint)
439 , m_inputAttachments (inputAttachments)
440 , m_colorAttachments (colorAttachments)
441 , m_resolveAttachments (resolveAttachments)
442 , m_depthStencilAttachment (depthStencilAttachment)
443 , m_preserveAttachments (preserveAttachments)
447 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
448 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
449 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
450 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
451 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
452 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
453 const vector<AttachmentReference>& getPreserveAttachments (void) const { return m_preserveAttachments; }
456 VkPipelineBindPoint m_pipelineBindPoint;
457 VkSubpassDescriptionFlags m_flags;
459 vector<AttachmentReference> m_inputAttachments;
460 vector<AttachmentReference> m_colorAttachments;
461 vector<AttachmentReference> m_resolveAttachments;
462 AttachmentReference m_depthStencilAttachment;
464 vector<AttachmentReference> m_preserveAttachments;
467 class SubpassDependency
470 SubpassDependency (deUint32 srcPass,
473 VkPipelineStageFlags srcStageMask,
474 VkPipelineStageFlags dstStageMask,
476 VkAccessFlags outputMask,
477 VkAccessFlags inputMask,
479 VkDependencyFlags flags)
480 : m_srcPass (srcPass)
481 , m_dstPass (dstPass)
483 , m_srcStageMask (srcStageMask)
484 , m_dstStageMask (dstStageMask)
486 , m_outputMask (outputMask)
487 , m_inputMask (inputMask)
492 deUint32 getSrcPass (void) const { return m_srcPass; }
493 deUint32 getDstPass (void) const { return m_dstPass; }
495 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
496 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
498 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
499 VkAccessFlags getInputMask (void) const { return m_inputMask; }
501 VkDependencyFlags getFlags (void) const { return m_flags; }
507 VkPipelineStageFlags m_srcStageMask;
508 VkPipelineStageFlags m_dstStageMask;
510 VkAccessFlags m_outputMask;
511 VkAccessFlags m_inputMask;
512 VkDependencyFlags m_flags;
518 Attachment (VkFormat format,
519 VkSampleCountFlagBits samples,
521 VkAttachmentLoadOp loadOp,
522 VkAttachmentStoreOp storeOp,
524 VkAttachmentLoadOp stencilLoadOp,
525 VkAttachmentStoreOp stencilStoreOp,
527 VkImageLayout initialLayout,
528 VkImageLayout finalLayout)
530 , m_samples (samples)
533 , m_storeOp (storeOp)
535 , m_stencilLoadOp (stencilLoadOp)
536 , m_stencilStoreOp (stencilStoreOp)
538 , m_initialLayout (initialLayout)
539 , m_finalLayout (finalLayout)
543 VkFormat getFormat (void) const { return m_format; }
544 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
546 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
547 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
550 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
551 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
553 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
554 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
558 VkSampleCountFlagBits m_samples;
560 VkAttachmentLoadOp m_loadOp;
561 VkAttachmentStoreOp m_storeOp;
563 VkAttachmentLoadOp m_stencilLoadOp;
564 VkAttachmentStoreOp m_stencilStoreOp;
566 VkImageLayout m_initialLayout;
567 VkImageLayout m_finalLayout;
573 RenderPass (const vector<Attachment>& attachments,
574 const vector<Subpass>& subpasses,
575 const vector<SubpassDependency>& dependencies)
576 : m_attachments (attachments)
577 , m_subpasses (subpasses)
578 , m_dependencies (dependencies)
582 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
583 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
584 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
587 const vector<Attachment> m_attachments;
588 const vector<Subpass> m_subpasses;
589 const vector<SubpassDependency> m_dependencies;
596 RENDERTYPES_NONE = 0,
597 RENDERTYPES_CLEAR = (1<<1),
598 RENDERTYPES_DRAW = (1<<2)
601 enum CommandBufferTypes
603 COMMANDBUFFERTYPES_INLINE = (1<<0),
604 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
609 IMAGEMEMORY_STRICT = (1<<0),
610 IMAGEMEMORY_LAZY = (1<<1)
613 TestConfig (const RenderPass& renderPass_,
614 RenderTypes renderTypes_,
615 CommandBufferTypes commandBufferTypes_,
616 ImageMemory imageMemory_,
617 const UVec2& targetSize_,
618 const UVec2& renderPos_,
619 const UVec2& renderSize_,
621 : renderPass (renderPass_)
622 , renderTypes (renderTypes_)
623 , commandBufferTypes (commandBufferTypes_)
624 , imageMemory (imageMemory_)
625 , targetSize (targetSize_)
626 , renderPos (renderPos_)
627 , renderSize (renderSize_)
632 RenderPass renderPass;
633 RenderTypes renderTypes;
634 CommandBufferTypes commandBufferTypes;
635 ImageMemory imageMemory;
642 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
644 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
647 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
649 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
652 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
654 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
657 void logRenderPassInfo (TestLog& log,
658 const RenderPass& renderPass)
660 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
663 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
664 const vector<Attachment>& attachments = renderPass.getAttachments();
666 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
668 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
669 const Attachment& attachment = attachments[attachmentNdx];
671 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
672 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
674 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
675 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
677 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
678 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
680 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
681 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
686 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
687 const vector<Subpass>& subpasses = renderPass.getSubpasses();
689 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
691 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
692 const Subpass& subpass = subpasses[subpassNdx];
694 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
695 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
696 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
697 const vector<AttachmentReference>& preserveAttachments = subpass.getPreserveAttachments();
699 if (!inputAttachments.empty())
701 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
703 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
705 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
706 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
708 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
709 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
713 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
715 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
716 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
718 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
719 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
722 if (!colorAttachments.empty())
724 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
726 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
728 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
729 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
731 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
732 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
736 if (!resolveAttachments.empty())
738 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
740 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
742 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
743 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
745 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
746 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
750 if (!preserveAttachments.empty())
752 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
754 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
756 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
757 const AttachmentReference& preserveAttachment = preserveAttachments[preserveNdx];
759 log << TestLog::Message << "Attachment: " << preserveAttachment.getAttachment() << TestLog::EndMessage;
760 log << TestLog::Message << "Layout: " << preserveAttachment.getImageLayout() << TestLog::EndMessage;
767 if (!renderPass.getDependencies().empty())
769 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
771 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
773 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
774 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
776 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
777 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
779 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
780 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
782 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
783 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
784 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
789 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
791 const tcu::TextureFormat format = mapVkFormat(vkFormat);
792 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
793 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
795 std::ostringstream stream;
799 switch (channelClass)
801 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
802 for (int i = 0; i < 4; i++)
808 stream << value.int32[i];
814 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
815 for (int i = 0; i < 4; i++)
821 stream << value.uint32[i];
827 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
828 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
829 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
830 for (int i = 0; i < 4; i++)
836 stream << value.float32[i];
843 DE_FATAL("Unknown channel class");
851 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
853 const tcu::TextureFormat format = mapVkFormat(vkFormat);
855 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
857 std::ostringstream stream;
861 if (tcu::hasStencilComponent(format.order))
862 stream << "stencil: " << value.depthStencil.stencil;
864 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
867 if (tcu::hasDepthComponent(format.order))
868 stream << "depth: " << value.depthStencil.depth;
875 return clearColorToString(vkFormat, value.color);
878 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
880 const float clearNan = tcu::Float32::nan().asFloat();
881 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
882 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
883 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
884 VkClearColorValue clearColor;
886 switch (channelClass)
888 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
890 const tcu::IVec4 valueMin = tcu::getFormatMinIntValue(format);
891 const tcu::IVec4 valueMax = tcu::getFormatMaxIntValue(format);
893 for (int ndx = 0; ndx < 4; ndx++)
895 if (!channelMask[ndx])
896 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
898 clearColor.uint32[ndx] = rng.getInt(valueMin[ndx], valueMax[ndx]);
903 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
905 const UVec4 valueMax = tcu::getFormatMaxUintValue(format);
907 for (int ndx = 0; ndx < 4; ndx++)
909 if (!channelMask[ndx])
910 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
912 clearColor.uint32[ndx] = rng.getUint32() % valueMax[ndx];
917 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
918 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
919 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
921 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
923 for (int ndx = 0; ndx < 4; ndx++)
925 if (!channelMask[ndx])
926 clearColor.float32[ndx] = clearNan;
928 clearColor.float32[ndx] = formatInfo.valueMin[ndx] + rng.getFloat() * (formatInfo.valueMax[ndx] - formatInfo.valueMin[ndx]);
934 DE_FATAL("Unknown channel class");
940 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
942 const VkAttachmentDescription attachmentDescription =
946 attachment.getFormat(), // format
947 attachment.getSamples(), // samples
949 attachment.getLoadOp(), // loadOp
950 attachment.getStoreOp(), // storeOp
952 attachment.getStencilLoadOp(), // stencilLoadOp
953 attachment.getStencilStoreOp(), // stencilStoreOp
955 attachment.getInitialLayout(), // initialLayout
956 attachment.getFinalLayout(), // finalLayout
959 return attachmentDescription;
962 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
964 const VkAttachmentReference reference =
966 referenceInfo.getAttachment(), // attachment;
967 referenceInfo.getImageLayout() // layout;
973 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
974 vector<VkAttachmentReference>* attachmentReferenceLists,
975 vector<deUint32>* preserveAttachmentReferences)
977 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
978 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
979 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
980 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
982 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
983 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
985 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
986 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
988 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
989 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
991 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
993 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
994 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx].getAttachment());
996 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
999 const VkSubpassDescription subpassDescription =
1001 subpass.getFlags(), // flags;
1002 subpass.getPipelineBindPoint(), // pipelineBindPoint;
1004 (deUint32)inputAttachmentReferences.size(), // inputCount;
1005 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1007 (deUint32)colorAttachmentReferences.size(), // colorCount;
1008 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1009 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1011 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1012 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1013 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1016 return subpassDescription;
1020 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1022 const VkSubpassDependency dependency =
1024 dependencyInfo.getSrcPass(), // srcSubpass;
1025 dependencyInfo.getDstPass(), // destSubpass;
1027 dependencyInfo.getSrcStageMask(), // srcStageMask;
1028 dependencyInfo.getDstStageMask(), // destStageMask;
1030 dependencyInfo.getOutputMask(), // outputMask;
1031 dependencyInfo.getInputMask(), // inputMask;
1033 dependencyInfo.getFlags() // dependencyFlags;
1039 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1041 const RenderPass& renderPassInfo)
1043 const size_t perSubpassAttachmentReferenceLists = 4;
1044 vector<VkAttachmentDescription> attachments;
1045 vector<VkSubpassDescription> subpasses;
1046 vector<VkSubpassDependency> dependencies;
1047 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1048 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1050 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1051 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1053 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1054 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1056 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1057 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1060 const VkRenderPassCreateInfo createInfo =
1062 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1064 (VkRenderPassCreateFlags)0u,
1065 (deUint32)attachments.size(),
1066 (attachments.empty() ? DE_NULL : &attachments[0]),
1067 (deUint32)subpasses.size(),
1068 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1069 (deUint32)dependencies.size(),
1070 (dependencies.empty() ? DE_NULL : &dependencies[0])
1073 return createRenderPass(vk, device, &createInfo);
1077 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1079 VkRenderPass renderPass,
1081 const vector<VkImageView>& attachments)
1083 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1086 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1088 deUint32 queueIndex,
1091 VkSampleCountFlagBits samples,
1092 VkImageUsageFlags usageFlags,
1093 VkImageLayout layout)
1095 const VkExtent3D size_ = { size.x(), size.y(), 1u };
1096 VkImageUsageFlags targetUsageFlags = 0;
1097 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1099 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1101 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1105 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1108 return createImage(vk, device,
1109 (VkImageCreateFlags)0,
1116 VK_IMAGE_TILING_OPTIMAL,
1117 usageFlags | targetUsageFlags,
1118 VK_SHARING_MODE_EXCLUSIVE,
1124 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
1126 Allocator& allocator,
1130 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
1131 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1135 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1139 VkImageAspectFlags aspect)
1141 const VkImageSubresourceRange range =
1150 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1153 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1155 const float clearNan = tcu::Float32::nan().asFloat();
1156 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1158 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1160 VkClearValue clearValue;
1162 clearValue.depthStencil.depth = clearNan;
1163 clearValue.depthStencil.stencil = 255;
1165 if (tcu::hasStencilComponent(format.order))
1166 clearValue.depthStencil.stencil = rng.getInt(0, 255);
1168 if (tcu::hasDepthComponent(format.order))
1169 clearValue.depthStencil.depth = rng.getFloat();
1175 VkClearValue clearValue;
1177 clearValue.color = randomColorClearValue(attachment, rng);
1183 class AttachmentResources
1186 AttachmentResources (const DeviceInterface& vk,
1188 Allocator& allocator,
1189 deUint32 queueIndex,
1191 const Attachment& attachmentInfo,
1192 VkImageUsageFlags usageFlags)
1193 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1194 , m_imageMemory (createImageMemory(vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)))
1195 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1197 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1199 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1201 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1203 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1204 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1206 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1207 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.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());
1214 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1215 m_secondaryBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
1217 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1221 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1223 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1224 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1226 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1231 ~AttachmentResources (void)
1235 VkImageView getAttachmentView (void) const
1237 return *m_attachmentView;
1240 VkImage getImage (void) const
1245 VkBuffer getBuffer (void) const
1247 DE_ASSERT(*m_buffer != DE_NULL);
1251 VkDeviceSize getBufferSize (void) const
1253 DE_ASSERT(*m_buffer != DE_NULL);
1254 return m_bufferSize;
1257 const Allocation& getResultMemory (void) const
1259 DE_ASSERT(m_bufferMemory);
1260 return *m_bufferMemory;
1263 VkBuffer getSecondaryBuffer (void) const
1265 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1266 return *m_secondaryBuffer;
1269 VkDeviceSize getSecondaryBufferSize (void) const
1271 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1272 return m_secondaryBufferSize;
1275 const Allocation& getSecondaryResultMemory (void) const
1277 DE_ASSERT(m_secondaryBufferMemory);
1278 return *m_secondaryBufferMemory;
1282 const Unique<VkImage> m_image;
1283 const UniquePtr<Allocation> m_imageMemory;
1284 const Unique<VkImageView> m_attachmentView;
1286 Move<VkBuffer> m_buffer;
1287 VkDeviceSize m_bufferSize;
1288 de::MovePtr<Allocation> m_bufferMemory;
1290 Move<VkBuffer> m_secondaryBuffer;
1291 VkDeviceSize m_secondaryBufferSize;
1292 de::MovePtr<Allocation> m_secondaryBufferMemory;
1295 void uploadBufferData (const DeviceInterface& vk,
1297 const Allocation& memory,
1301 const VkMappedMemoryRange range =
1303 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1305 memory.getMemory(), // mem;
1306 memory.getOffset(), // offset;
1307 (VkDeviceSize)size // size;
1309 void* const ptr = memory.getHostPtr();
1311 deMemcpy(ptr, data, size);
1312 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1315 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1317 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1321 case tcu::TextureFormat::D:
1322 case tcu::TextureFormat::DS:
1323 return VK_IMAGE_ASPECT_DEPTH_BIT;
1325 case tcu::TextureFormat::S:
1326 return VK_IMAGE_ASPECT_STENCIL_BIT;
1329 return VK_IMAGE_ASPECT_COLOR_BIT;
1336 RenderQuad (const Vec4& posA, const Vec4& posB)
1339 m_vertices[0] = posA;
1340 m_vertices[1] = Vec4(posA[0], posB[1], posA[2], posA[3]);
1341 m_vertices[2] = posB;
1343 m_vertices[3] = posB;
1344 m_vertices[4] = Vec4(posB[0], posA[1], posB[2], posA[3]);
1345 m_vertices[5] = posA;
1348 const Vec4& getCornerA (void) const
1350 return m_vertices[0];
1353 const Vec4& getCornerB (void) const
1355 return m_vertices[2];
1358 const void* getVertexPointer (void) const
1360 return &m_vertices[0];
1363 size_t getVertexDataSize (void) const
1365 return sizeof(Vec4) * m_vertices.size();
1369 vector<Vec4> m_vertices;
1375 ColorClear (const UVec2& offset,
1377 const VkClearColorValue& color)
1384 const UVec2& getOffset (void) const { return m_offset; }
1385 const UVec2& getSize (void) const { return m_size; }
1386 const VkClearColorValue& getColor (void) const { return m_color; }
1391 VkClearColorValue m_color;
1394 class DepthStencilClear
1397 DepthStencilClear (const UVec2& offset,
1404 , m_stencil (stencil)
1408 const UVec2& getOffset (void) const { return m_offset; }
1409 const UVec2& getSize (void) const { return m_size; }
1410 float getDepth (void) const { return m_depth; }
1411 deUint32 getStencil (void) const { return m_stencil; }
1421 class SubpassRenderInfo
1424 SubpassRenderInfo (const RenderPass& renderPass,
1425 deUint32 subpassIndex,
1429 const UVec2& viewportOffset,
1430 const UVec2& viewportSize,
1432 const Maybe<RenderQuad>& renderQuad,
1433 const vector<ColorClear>& colorClears,
1434 const Maybe<DepthStencilClear>& depthStencilClear)
1435 : m_viewportOffset (viewportOffset)
1436 , m_viewportSize (viewportSize)
1437 , m_subpassIndex (subpassIndex)
1438 , m_isSecondary (isSecondary_)
1439 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1440 , m_renderQuad (renderQuad)
1441 , m_colorClears (colorClears)
1442 , m_depthStencilClear (depthStencilClear)
1443 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1445 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1446 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1448 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1450 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1451 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1455 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1456 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1458 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1459 bool isSecondary (void) const { return m_isSecondary; }
1461 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1462 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1463 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1465 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1466 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1467 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1468 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1469 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1470 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1471 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1472 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1474 UVec2 m_viewportOffset;
1475 UVec2 m_viewportSize;
1477 deUint32 m_subpassIndex;
1479 VkSubpassDescriptionFlags m_flags;
1481 Maybe<RenderQuad> m_renderQuad;
1482 vector<ColorClear> m_colorClears;
1483 Maybe<DepthStencilClear> m_depthStencilClear;
1485 vector<AttachmentReference> m_colorAttachments;
1486 vector<Attachment> m_colorAttachmentInfo;
1488 Maybe<AttachmentReference> m_depthStencilAttachment;
1489 Maybe<Attachment> m_depthStencilAttachmentInfo;
1492 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1494 VkRenderPass renderPass,
1495 VkShaderModule vertexShaderModule,
1496 VkShaderModule fragmentShaderModule,
1497 VkPipelineLayout pipelineLayout,
1498 const SubpassRenderInfo& renderInfo)
1500 const VkSpecializationInfo emptyShaderSpecializations =
1502 0u, // mapEntryCount
1508 Maybe<VkSampleCountFlagBits> rasterSamples;
1509 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1511 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1513 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1515 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1517 rasterSamples = attachment.getSamples();
1520 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1522 VK_FALSE, // blendEnable
1523 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1524 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1525 VK_BLEND_OP_ADD, // blendOpColor
1526 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1527 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1528 VK_BLEND_OP_ADD, // blendOpAlpha
1529 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1532 attachmentBlendStates.push_back(attachmentBlendState);
1536 if (renderInfo.getDepthStencilAttachment())
1538 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1540 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1541 rasterSamples = attachment.getSamples();
1544 // If there are no attachment use single sample
1546 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1548 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1551 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1553 (VkPipelineShaderStageCreateFlags)0u,
1554 VK_SHADER_STAGE_VERTEX_BIT, // stage
1555 vertexShaderModule, // shader
1557 &emptyShaderSpecializations
1560 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1562 (VkPipelineShaderStageCreateFlags)0u,
1563 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1564 fragmentShaderModule, // shader
1566 &emptyShaderSpecializations
1569 const VkVertexInputBindingDescription vertexBinding =
1572 (deUint32)sizeof(tcu::Vec4), // strideInBytes
1573 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1575 const VkVertexInputAttributeDescription vertexAttrib =
1579 VK_FORMAT_R32G32B32A32_SFLOAT, // format
1580 0u, // offsetInBytes
1582 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1584 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1586 (VkPipelineVertexInputStateCreateFlags)0u,
1588 &vertexBinding, // pVertexBindingDescriptions
1589 1u, // attributeCount
1590 &vertexAttrib, // pVertexAttributeDescriptions
1592 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1594 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1596 (VkPipelineInputAssemblyStateCreateFlags)0u,
1597 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1598 VK_FALSE, // primitiveRestartEnable
1600 const VkViewport viewport =
1602 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1603 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1606 const VkRect2D scissor =
1608 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1609 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1611 const VkPipelineViewportStateCreateInfo viewportState =
1613 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1615 (VkPipelineViewportStateCreateFlags)0u,
1621 const VkPipelineRasterizationStateCreateInfo rasterState =
1623 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1625 (VkPipelineRasterizationStateCreateFlags)0u,
1626 VK_TRUE, // depthClipEnable
1627 VK_FALSE, // rasterizerDiscardEnable
1628 VK_POLYGON_MODE_FILL, // fillMode
1629 VK_CULL_MODE_NONE, // cullMode
1630 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1631 VK_FALSE, // depthBiasEnable
1633 0.0f, // depthBiasClamp
1634 0.0f, // slopeScaledDepthBias
1637 const VkPipelineMultisampleStateCreateInfo multisampleState =
1639 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1641 (VkPipelineMultisampleStateCreateFlags)0u,
1642 *rasterSamples, // rasterSamples
1643 VK_FALSE, // sampleShadingEnable
1644 0.0f, // minSampleShading
1645 DE_NULL, // pSampleMask
1646 VK_FALSE, // alphaToCoverageEnable
1647 VK_FALSE, // alphaToOneEnable
1649 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1651 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1653 (VkPipelineDepthStencilStateCreateFlags)0u,
1654 VK_TRUE, // depthTestEnable
1655 VK_TRUE, // depthWriteEnable
1656 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1657 VK_FALSE, // depthBoundsEnable
1658 VK_TRUE, // stencilTestEnable
1660 VK_STENCIL_OP_REPLACE, // stencilFailOp
1661 VK_STENCIL_OP_REPLACE, // stencilPassOp
1662 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1663 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1664 ~0u, // stencilCompareMask
1665 ~0u, // stencilWriteMask
1666 STENCIL_VALUE // stencilReference
1669 VK_STENCIL_OP_REPLACE, // stencilFailOp
1670 VK_STENCIL_OP_REPLACE, // stencilPassOp
1671 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1672 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1673 ~0u, // stencilCompareMask
1674 ~0u, // stencilWriteMask
1675 STENCIL_VALUE // stencilReference
1678 0.0f, // minDepthBounds;
1679 1.0f // maxDepthBounds;
1681 const VkPipelineColorBlendStateCreateInfo blendState =
1683 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1685 (VkPipelineColorBlendStateCreateFlags)0u,
1686 VK_FALSE, // logicOpEnable
1687 VK_LOGIC_OP_COPY, // logicOp
1688 (deUint32)attachmentBlendStates.size(), // attachmentCount
1689 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1690 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1692 const VkGraphicsPipelineCreateInfo createInfo =
1694 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1696 (VkPipelineCreateFlags)0u,
1699 shaderStages, // pStages
1701 &vertexInputState, // pVertexInputState
1702 &inputAssemblyState, // pInputAssemblyState
1703 DE_NULL, // pTessellationState
1704 &viewportState, // pViewportState
1705 &rasterState, // pRasterState
1706 &multisampleState, // pMultisampleState
1707 &depthStencilState, // pDepthStencilState
1708 &blendState, // pColorBlendState
1709 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1710 pipelineLayout, // layout
1712 renderPass, // renderPass
1713 renderInfo.getSubpassIndex(), // subpass
1714 DE_NULL, // basePipelineHandle
1715 0u // basePipelineIndex
1718 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1721 class SubpassRenderer
1724 SubpassRenderer (Context& context,
1725 const DeviceInterface& vk,
1727 Allocator& allocator,
1728 VkRenderPass renderPass,
1729 VkFramebuffer framebuffer,
1730 VkCommandPool commandBufferPool,
1731 deUint32 queueFamilyIndex,
1732 const SubpassRenderInfo& renderInfo)
1733 : m_renderInfo (renderInfo)
1735 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1737 if (renderInfo.getRenderQuad())
1739 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1740 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1742 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1744 (vk::VkPipelineLayoutCreateFlags)0,
1745 0u, // descriptorSetCount;
1746 DE_NULL, // pSetLayouts;
1747 0u, // pushConstantRangeCount;
1748 DE_NULL, // pPushConstantRanges;
1751 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1752 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1753 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1754 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1756 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1757 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1759 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1760 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1763 if (renderInfo.isSecondary())
1765 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1767 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
1768 pushRenderCommands(vk, *m_commandBuffer);
1769 endCommandBuffer(vk, *m_commandBuffer);
1773 bool isSecondary (void) const
1775 return m_commandBuffer;
1778 VkCommandBuffer getCommandBuffer (void) const
1780 DE_ASSERT(isSecondary());
1781 return *m_commandBuffer;
1784 void pushRenderCommands (const DeviceInterface& vk,
1785 VkCommandBuffer commandBuffer)
1787 if (!m_renderInfo.getColorClears().empty())
1789 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
1791 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
1793 const ColorClear& colorClear = colorClears[attachmentNdx];
1794 const VkClearAttachment attachment =
1796 VK_IMAGE_ASPECT_COLOR_BIT,
1798 makeClearValue(colorClear.getColor()),
1800 const VkClearRect rect =
1803 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
1804 { colorClear.getSize().x(), colorClear.getSize().y() }
1806 0u, // baseArrayLayer
1810 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1814 if (m_renderInfo.getDepthStencilClear())
1816 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
1817 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
1818 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
1819 const VkClearAttachment attachment =
1821 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1822 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1824 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
1826 const VkClearRect rect =
1829 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
1830 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
1832 0u, // baseArrayLayer
1836 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1839 if (m_renderInfo.getRenderQuad())
1841 const VkDeviceSize offset = 0;
1842 const VkBuffer vertexBuffer = *m_vertexBuffer;
1844 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1845 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
1846 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
1851 const SubpassRenderInfo m_renderInfo;
1852 Move<VkCommandBuffer> m_commandBuffer;
1853 Move<VkPipeline> m_pipeline;
1854 Move<VkPipelineLayout> m_pipelineLayout;
1856 Move<VkShaderModule> m_vertexShaderModule;
1858 Move<VkShaderModule> m_fragmentShaderModule;
1860 Move<VkBuffer> m_vertexBuffer;
1861 de::MovePtr<Allocation> m_vertexBufferMemory;
1864 void pushImageInitializationCommands (const DeviceInterface& vk,
1865 VkCommandBuffer commandBuffer,
1866 const vector<Attachment>& attachmentInfo,
1867 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
1868 deUint32 queueIndex,
1869 const vector<Maybe<VkClearValue> >& clearValues)
1872 vector<VkImageMemoryBarrier> initializeLayouts;
1874 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1876 if (!clearValues[attachmentNdx])
1879 const VkImageMemoryBarrier barrier =
1881 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1884 (VkAccessFlags)0, // srcAccessMask
1885 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
1887 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
1888 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
1890 queueIndex, // srcQueueFamilyIndex;
1891 queueIndex, // destQueueFamilyIndex;
1893 attachmentResources[attachmentNdx]->getImage(), // image;
1894 { // subresourceRange;
1895 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1898 0, // baseArraySlice;
1903 initializeLayouts.push_back(barrier);
1906 if (!initializeLayouts.empty())
1907 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1908 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1909 0, (const VkMemoryBarrier*)DE_NULL,
1910 0, (const VkBufferMemoryBarrier*)DE_NULL,
1911 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
1914 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1916 if (!clearValues[attachmentNdx])
1919 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
1921 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
1923 const float clearNan = tcu::Float32::nan().asFloat();
1924 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
1925 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : ~0u;
1926 const VkClearDepthStencilValue depthStencil =
1931 const VkImageSubresourceRange range =
1933 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1934 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1941 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
1945 const VkImageSubresourceRange range =
1947 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
1950 0, // baseArrayLayer;
1953 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
1955 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
1960 vector<VkImageMemoryBarrier> renderPassLayouts;
1962 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1964 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
1965 const VkImageMemoryBarrier barrier =
1967 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1970 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask
1971 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
1973 oldLayout, // oldLayout
1974 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
1976 queueIndex, // srcQueueFamilyIndex;
1977 queueIndex, // destQueueFamilyIndex;
1979 attachmentResources[attachmentNdx]->getImage(), // image;
1980 { // subresourceRange;
1981 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1984 0, // baseArraySlice;
1989 renderPassLayouts.push_back(barrier);
1992 if (!renderPassLayouts.empty())
1993 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1994 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1995 0, (const VkMemoryBarrier*)DE_NULL,
1996 0, (const VkBufferMemoryBarrier*)DE_NULL,
1997 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2001 void pushRenderPassCommands (const DeviceInterface& vk,
2002 VkCommandBuffer commandBuffer,
2003 VkRenderPass renderPass,
2004 VkFramebuffer framebuffer,
2005 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2006 const UVec2& renderPos,
2007 const UVec2& renderSize,
2008 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2009 TestConfig::RenderTypes render)
2011 const float clearNan = tcu::Float32::nan().asFloat();
2012 vector<VkClearValue> attachmentClearValues;
2014 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2016 if (renderPassClearValues[attachmentNdx])
2017 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2019 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2023 const VkRect2D renderArea =
2025 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2026 { renderSize.x(), renderSize.y() }
2029 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2031 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2033 if (subpassNdx == 0)
2034 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2036 vk.cmdNextSubpass(commandBuffer, contents);
2040 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2042 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2044 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2046 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2047 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2050 DE_FATAL("Invalid contents");
2054 vk.cmdEndRenderPass(commandBuffer);
2058 void pushReadImagesToBuffers (const DeviceInterface& vk,
2059 VkCommandBuffer commandBuffer,
2060 deUint32 queueIndex,
2062 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2063 const vector<Attachment>& attachmentInfo,
2064 const vector<bool>& isLazy,
2066 const UVec2& targetSize)
2069 vector<VkImageMemoryBarrier> imageBarriers;
2071 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2073 if (isLazy[attachmentNdx])
2076 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2077 const VkImageMemoryBarrier barrier =
2079 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2082 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2083 getAllMemoryReadFlags(), // dstAccessMask
2085 oldLayout, // oldLayout
2086 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2088 queueIndex, // srcQueueFamilyIndex
2089 queueIndex, // destQueueFamilyIndex
2091 attachmentResources[attachmentNdx]->getImage(), // image
2092 { // subresourceRange
2093 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2096 0, // baseArraySlice
2101 imageBarriers.push_back(barrier);
2104 if (!imageBarriers.empty())
2105 vk.cmdPipelineBarrier(commandBuffer,
2106 getAllPipelineStageFlags(),
2107 getAllPipelineStageFlags(),
2108 (VkDependencyFlags)0,
2109 0, (const VkMemoryBarrier*)DE_NULL,
2110 0, (const VkBufferMemoryBarrier*)DE_NULL,
2111 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2114 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2116 if (isLazy[attachmentNdx])
2119 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2120 const VkBufferImageCopy rect =
2123 0, // bufferRowLength
2124 0, // bufferImageHeight
2125 { // imageSubresource
2126 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2131 { 0, 0, 0 }, // imageOffset
2132 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2135 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2137 if (tcu::TextureFormat::DS == order)
2139 const VkBufferImageCopy stencilRect =
2142 0, // bufferRowLength
2143 0, // bufferImageHeight
2144 { // imageSubresource
2145 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2150 { 0, 0, 0 }, // imageOffset
2151 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2154 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2159 vector<VkBufferMemoryBarrier> bufferBarriers;
2161 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2163 if (isLazy[attachmentNdx])
2166 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2167 const VkBufferMemoryBarrier bufferBarrier =
2169 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2172 getAllMemoryWriteFlags(),
2173 getAllMemoryReadFlags(),
2178 attachmentResources[attachmentNdx]->getBuffer(),
2180 attachmentResources[attachmentNdx]->getBufferSize()
2183 bufferBarriers.push_back(bufferBarrier);
2185 if (tcu::TextureFormat::DS == order)
2187 const VkBufferMemoryBarrier secondaryBufferBarrier =
2189 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2192 getAllMemoryWriteFlags(),
2193 getAllMemoryReadFlags(),
2198 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2200 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2203 bufferBarriers.push_back(secondaryBufferBarrier);
2207 if (!bufferBarriers.empty())
2208 vk.cmdPipelineBarrier(commandBuffer,
2209 getAllPipelineStageFlags(),
2210 getAllPipelineStageFlags(),
2211 (VkDependencyFlags)0,
2212 0, (const VkMemoryBarrier*)DE_NULL,
2213 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2214 0, (const VkImageMemoryBarrier*)DE_NULL);
2218 void clear (const PixelBufferAccess& access, const VkClearValue& value)
2220 const tcu::TextureFormat& format = access.getFormat();
2222 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2224 if (tcu::hasDepthComponent(format.order))
2225 tcu::clearDepth(access, value.depthStencil.depth);
2227 if (tcu::hasStencilComponent(format.order))
2228 tcu::clearStencil(access, value.depthStencil.stencil);
2232 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT
2233 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
2234 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
2236 const tcu::Vec4 color (value.color.float32[0],
2237 value.color.float32[1],
2238 value.color.float32[2],
2239 value.color.float32[3]);
2241 if (tcu::isSRGB(format))
2242 tcu::clear(access, tcu::linearToSRGB(color));
2244 tcu::clear(access, color);
2246 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2248 const tcu::UVec4 color (value.color.uint32[0],
2249 value.color.uint32[1],
2250 value.color.uint32[2],
2251 value.color.uint32[3]);
2253 tcu::clear(access, color);
2255 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2257 const tcu::IVec4 color (value.color.int32[0],
2258 value.color.int32[1],
2259 value.color.int32[2],
2260 value.color.int32[3]);
2262 tcu::clear(access, color);
2265 DE_FATAL("Unknown channel class");
2269 Vec4 computeUvs (const IVec2& posA, const IVec2& posB, const IVec2& pos)
2271 const float u = de::clamp((float)(pos.x() - posA.x()) / (float)(posB.x() - posA.x()), 0.0f, 1.0f);
2272 const float v = de::clamp((float)(pos.y() - posA.y()) / (float)(posB.y() - posA.y()), 0.0f, 1.0f);
2274 return Vec4(u, v, u * v, (u + v) / 2.0f);
2277 void renderReferenceImages (vector<tcu::TextureLevel>& referenceAttachments,
2278 const RenderPass& renderPassInfo,
2279 const UVec2& targetSize,
2280 const vector<Maybe<VkClearValue> >& imageClearValues,
2281 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2282 const vector<SubpassRenderInfo>& subpassRenderInfo,
2283 const UVec2& renderPos,
2284 const UVec2& renderSize)
2286 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2287 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2289 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2291 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2293 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2294 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2295 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2296 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2297 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
2299 reference = tcu::TextureLevel(format, targetSize.x(), targetSize.y());
2301 if (imageClearValues[attachmentNdx])
2302 clear(reference.getAccess(), *imageClearValues[attachmentNdx]);
2305 // Fill with grid if image contentst are undefined before renderpass
2306 if (isDepthOrStencilAttachment)
2308 if (tcu::hasDepthComponent(format.order))
2309 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), 2, textureInfo.valueMin, textureInfo.valueMax);
2311 if (tcu::hasStencilComponent(format.order))
2312 tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), 2, textureInfo.valueMin, textureInfo.valueMax);
2315 tcu::fillWithGrid(reference.getAccess(), 2, textureInfo.valueMin, textureInfo.valueMax);
2319 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2321 const Subpass& subpass = subpasses[subpassNdx];
2322 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2323 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2325 // Apply load op if attachment was used for the first time
2326 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2328 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2330 if (!attachmentUsed[attachmentIndex])
2332 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2333 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2335 DE_ASSERT(!tcu::hasDepthComponent(reference.getFormat().order));
2336 DE_ASSERT(!tcu::hasStencilComponent(reference.getFormat().order));
2338 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2339 clear(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2340 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2342 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2344 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2347 attachmentUsed[attachmentIndex] = true;
2351 // Apply load op to depth/stencil attachment if it was used for the first time
2352 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED && !attachmentUsed[subpass.getDepthStencilAttachment().getAttachment()])
2354 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2356 // Apply load op if attachment was used for the first time
2357 if (!attachmentUsed[attachmentIndex])
2359 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2360 tcu::TextureLevel& reference = referenceAttachments[attachmentIndex];
2362 if (tcu::hasDepthComponent(reference.getFormat().order))
2364 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2365 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2366 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2368 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2370 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);
2374 if (tcu::hasStencilComponent(reference.getFormat().order))
2376 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2377 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2378 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2380 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2382 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);
2387 attachmentUsed[attachmentIndex] = true;
2390 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2392 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2393 const UVec2 offset = colorClear.getOffset();
2394 const UVec2 size = colorClear.getSize();
2395 tcu::TextureLevel& reference = referenceAttachments[subpass.getColorAttachments()[colorClearNdx].getAttachment()];
2398 value.color = colorClear.getColor();
2400 clear(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), value);
2403 if (renderInfo.getDepthStencilClear())
2405 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
2406 const UVec2 offset = dsClear.getOffset();
2407 const UVec2 size = dsClear.getSize();
2408 tcu::TextureLevel& reference = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2410 if (tcu::hasDepthComponent(reference.getFormat().order))
2411 clearDepth(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getDepth());
2413 if (tcu::hasStencilComponent(reference.getFormat().order))
2414 clearStencil(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getStencil());
2417 if (renderInfo.getRenderQuad())
2419 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2420 const Vec4 posA = renderQuad.getCornerA();
2421 const Vec4 posB = renderQuad.getCornerB();
2422 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2423 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2424 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
2425 (deInt32)(origin.y() + (p.y() * posA.y())));
2426 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
2427 (deInt32)(origin.y() + (p.y() * posB.y())));
2429 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
2431 const Attachment attachment = renderPassInfo.getAttachments()[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2432 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(mapVkFormat(attachment.getFormat()));
2433 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2434 const bool srgb = tcu::isSRGB(referenceTexture.getFormat());
2435 const PixelBufferAccess reference = referenceTexture.getAccess();
2436 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2437 const float clampMax = (float)(MAX_INTEGER_VALUE);
2438 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2439 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2440 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2441 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2443 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2444 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2445 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2446 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2448 DE_ASSERT(posAI.x() < posBI.x());
2449 DE_ASSERT(posAI.y() < posBI.y());
2451 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2452 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2454 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2455 const Vec4 color = valueMax * uvs + valueMin * (Vec4(1.0f) - uvs);
2458 reference.setPixel(tcu::linearToSRGB(color), x, y);
2460 reference.setPixel(color, x, y);
2464 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2466 tcu::TextureLevel& referenceTexture = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2467 const PixelBufferAccess reference = referenceTexture.getAccess();
2469 DE_ASSERT(posAI.x() < posBI.x());
2470 DE_ASSERT(posAI.y() < posBI.y());
2472 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2473 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2475 const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2477 if (tcu::hasDepthComponent(reference.getFormat().order))
2478 reference.setPixDepth(uvs.x(), x, y);
2480 if (tcu::hasStencilComponent(reference.getFormat().order))
2481 reference.setPixStencil(STENCIL_VALUE, x, y);
2487 // Mark all attachments that were used but not stored as undefined
2488 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2490 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2491 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2492 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2493 tcu::TextureLevel& reference = referenceAttachments[attachmentNdx];
2495 if (attachmentUsed[attachmentNdx] && renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
2496 tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2500 Maybe<deUint32> findColorAttachment (const Subpass& subpass,
2501 deUint32 attachmentIndex)
2503 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpass.getColorAttachments().size(); colorAttachmentNdx++)
2505 if (subpass.getColorAttachments()[colorAttachmentNdx].getAttachment() == attachmentIndex)
2506 return tcu::just((deUint32)colorAttachmentNdx);
2509 return tcu::nothing<deUint32>();
2512 int calcFloatDiff (float a, float b)
2514 const deUint32 au = tcu::Float32(a).bits();
2515 const deUint32 bu = tcu::Float32(b).bits();
2517 const bool asign = (au & (0x1u << 31u)) != 0u;
2518 const bool bsign = (bu & (0x1u << 31u)) != 0u;
2520 const deUint32 avalue = (au & ((0x1u << 31u) - 1u));
2521 const deUint32 bvalue = (bu & ((0x1u << 31u) - 1u));
2524 return avalue + bvalue + 1u;
2525 else if (avalue < bvalue)
2526 return bvalue - avalue;
2528 return avalue - bvalue;
2531 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess& access,
2536 const tcu::TextureFormat format = tcu::getEffectiveDepthStencilTextureFormat(access.getFormat(), tcu::Sampler::MODE_DEPTH);
2537 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2539 switch (channelClass)
2541 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2542 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2544 const int bitDepth = tcu::getTextureFormatBitDepth(format).x();
2545 const float depth = access.getPixDepth(x, y);
2546 const float threshold = 2.0f / (float)((1 << bitDepth) - 1);
2548 return deFloatAbs(depth - ref) <= threshold;
2551 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2553 const float depth = access.getPixDepth(x, y);
2554 const int mantissaBits = tcu::getTextureFormatMantissaBitDepth(format).x();
2555 const int threshold = 10 * 1 << (23 - mantissaBits);
2557 DE_ASSERT(mantissaBits <= 23);
2559 return calcFloatDiff(depth, ref) <= threshold;
2563 DE_FATAL("Invalid channel class");
2568 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess& access,
2573 const deUint32 stencil = access.getPixStencil(x, y);
2575 return stencil == ref;
2578 bool comparePixelToColorClearValue (const ConstPixelBufferAccess& access,
2581 const VkClearColorValue& ref)
2583 const tcu::TextureFormat format = access.getFormat();
2584 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2585 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2587 switch (channelClass)
2589 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2590 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2592 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
2593 const Vec4 resColor (access.getPixel(x, y));
2594 const Vec4 refColor (ref.float32[0],
2598 const Vec4 threshold (bitDepth[0] > 0 ? 20.0f / (float)((1 << bitDepth[0]) - 1) : 1.0f,
2599 bitDepth[1] > 0 ? 20.0f / (float)((1 << bitDepth[1]) - 1) : 1.0f,
2600 bitDepth[2] > 0 ? 20.0f / (float)((1 << bitDepth[2]) - 1) : 1.0f,
2601 bitDepth[3] > 0 ? 20.0f / (float)((1 << bitDepth[3]) - 1) : 1.0f);
2603 if (tcu::isSRGB(access.getFormat()))
2604 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, tcu::linearToSRGB(refColor)), threshold), channelMask), channelMask));
2606 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2609 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2611 const UVec4 resColor (access.getPixelUint(x, y));
2612 const UVec4 refColor (ref.uint32[0],
2616 const UVec4 threshold (1);
2618 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2621 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2623 const IVec4 resColor (access.getPixelInt(x, y));
2624 const IVec4 refColor (ref.int32[0],
2628 const IVec4 threshold (1);
2630 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2633 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2635 const Vec4 resColor (access.getPixel(x, y));
2636 const Vec4 refColor (ref.float32[0],
2640 const IVec4 mantissaBits (tcu::getTextureFormatMantissaBitDepth(format));
2641 const IVec4 threshold (10 * IVec4(1) << (23 - mantissaBits));
2643 DE_ASSERT(tcu::allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true)));
2645 for (int ndx = 0; ndx < 4; ndx++)
2647 if (calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx])
2655 DE_FATAL("Invalid channel class");
2665 STATUS_UNDEFINED = 0,
2672 PixelStatus (Status color, Status depth, Status stencil)
2673 : m_status ((deUint8)((color << COLOR_OFFSET)
2674 | (depth << DEPTH_OFFSET)
2675 | (stencil << STENCIL_OFFSET)))
2679 Status getColorStatus (void) const { return (Status)((m_status & COLOR_MASK) >> COLOR_OFFSET); }
2680 Status getDepthStatus (void) const { return (Status)((m_status & DEPTH_MASK) >> DEPTH_OFFSET); }
2681 Status getStencilStatus (void) const { return (Status)((m_status & STENCIL_MASK) >> STENCIL_OFFSET); }
2683 void setColorStatus (Status status)
2685 DE_ASSERT(getColorStatus() == STATUS_UNDEFINED);
2686 m_status |= (deUint8)(status << COLOR_OFFSET);
2689 void setDepthStatus (Status status)
2691 DE_ASSERT(getDepthStatus() == STATUS_UNDEFINED);
2692 m_status |= (deUint8)(status << DEPTH_OFFSET);
2695 void setStencilStatus (Status status)
2697 DE_ASSERT(getStencilStatus() == STATUS_UNDEFINED);
2698 m_status |= (deUint8)(status << STENCIL_OFFSET);
2708 COLOR_MASK = (3<<COLOR_OFFSET),
2709 DEPTH_MASK = (3<<DEPTH_OFFSET),
2710 STENCIL_MASK = (3<<STENCIL_OFFSET),
2715 void checkDepthRenderQuad (const ConstPixelBufferAccess& result,
2718 vector<PixelStatus>& status)
2720 for (int y = posA.y(); y <= posB.y(); y++)
2721 for (int x = posA.x(); x <= posB.x(); x++)
2723 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2725 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2727 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2728 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2729 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2730 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2731 const float resDepth = result.getPixDepth(x, y);
2733 if (resDepth >= minUvs.x() && resDepth <= maxUvs.x())
2734 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2735 else if (!softCheck)
2736 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2741 void checkStencilRenderQuad (const ConstPixelBufferAccess& result,
2744 vector<PixelStatus>& status)
2746 for (int y = posA.y(); y <= posB.y(); y++)
2747 for (int x = posA.x(); x <= posB.x(); x++)
2749 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2751 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2753 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2754 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2756 if (result.getPixStencil(x, y) == STENCIL_VALUE)
2757 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2758 else if (!softCheck)
2759 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
2764 void checkColorRenderQuad (const ConstPixelBufferAccess& result,
2767 vector<PixelStatus>& status)
2769 const tcu::TextureFormat& format = result.getFormat();
2770 const bool srgb = tcu::isSRGB(format);
2771 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2772 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(format);
2773 const float clampMin = (float)(-MAX_INTEGER_VALUE);
2774 const float clampMax = (float)(MAX_INTEGER_VALUE);
2775 const Vec4 valueMax (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2776 de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2777 de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2778 de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2780 const Vec4 valueMin (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2781 de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2782 de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2783 de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2784 const BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2786 IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(format);
2787 Vec4 threshold = Vec4(1.0f) / Vec4((float)(1 << formatBitDepths.x()),
2788 (float)(1 << formatBitDepths.y()),
2789 (float)(1 << formatBitDepths.z()),
2790 (float)(1 << formatBitDepths.w()));
2792 switch (channelClass)
2794 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2795 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2796 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2798 for (int y = posA.y(); y <= posB.y(); y++)
2799 for (int x = posA.x(); x <= posB.x(); x++)
2801 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2803 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2805 const Vec4 minDiff = Vec4(1.0f) / (IVec4(1) << tcu::getTextureFormatMantissaBitDepth(format)).cast<float>();
2806 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2807 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2808 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2809 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2811 const Vec4 resColor (result.getPixel(x, y));
2813 Vec4 minRefColor = srgb ? tcu::linearToSRGB(valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs))
2814 : valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs) - threshold;
2815 Vec4 maxRefColor = srgb ? tcu::linearToSRGB(valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs))
2816 : valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs) + threshold;
2818 // Take into account rounding and quantization
2819 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
2821 minRefColor = tcu::min(minRefColor * (Vec4(1.0f) - minDiff), minRefColor * (Vec4(1.0f) + minDiff));
2822 maxRefColor = tcu::max(maxRefColor * (Vec4(1.0f) - minDiff), maxRefColor * (Vec4(1.0f) + minDiff));
2826 minRefColor = minRefColor - minDiff;
2827 maxRefColor = maxRefColor + minDiff;
2830 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2831 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2832 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2833 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2835 if (tcu::anyNotEqual(tcu::logicalAnd(
2836 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2837 lessThanEqual(resColor, maxRefColor)),
2838 channelMask), channelMask))
2841 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2844 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2851 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2853 for (int y = posA.y(); y <= posB.y(); y++)
2854 for (int x = posA.x(); x <= posB.x(); x++)
2856 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2858 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2860 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2861 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2862 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2863 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2865 const UVec4 resColor (result.getPixelUint(x, y));
2867 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2868 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2870 const UVec4 minRefColor (minRefColorF.asUint());
2871 const UVec4 maxRefColor (maxRefColorF.asUint());
2873 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2874 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2875 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2876 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2878 if (tcu::anyNotEqual(tcu::logicalAnd(
2879 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2880 lessThanEqual(resColor, maxRefColor)),
2881 channelMask), channelMask))
2884 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2887 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2894 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2896 for (int y = posA.y(); y <= posB.y(); y++)
2897 for (int x = posA.x(); x <= posB.x(); x++)
2899 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2901 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2903 const Vec4 minUvs = computeUvs(posA, posB, IVec2(x-1, y-1));
2904 const Vec4 maxUvs = computeUvs(posA, posB, IVec2(x+1, y+1));
2905 const bool softCheck = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2906 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2908 const IVec4 resColor (result.getPixelInt(x, y));
2910 const Vec4 minRefColorF = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2911 const Vec4 maxRefColorF = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2913 const IVec4 minRefColor (minRefColorF.asInt());
2914 const IVec4 maxRefColor (maxRefColorF.asInt());
2916 DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2917 DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2918 DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2919 DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2921 if (tcu::anyNotEqual(tcu::logicalAnd(
2922 tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2923 lessThanEqual(resColor, maxRefColor)),
2924 channelMask), channelMask))
2927 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2930 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2938 DE_FATAL("Invalid channel class");
2942 void checkColorClear (const ConstPixelBufferAccess& result,
2943 const UVec2& offset,
2945 vector<PixelStatus>& status,
2946 const VkClearColorValue& color)
2948 DE_ASSERT(offset.x() + size.x() <= (deUint32)result.getWidth());
2949 DE_ASSERT(offset.y() + size.y() <= (deUint32)result.getHeight());
2951 DE_ASSERT(result.getWidth() * result.getHeight() == (int)status.size());
2953 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2954 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2956 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2958 DE_ASSERT(x + y * result.getWidth() < (int)status.size());
2960 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2962 if (comparePixelToColorClearValue(result, x, y, color))
2963 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2965 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2970 void checkDepthClear (const ConstPixelBufferAccess& result,
2971 const UVec2& offset,
2973 vector<PixelStatus>& status,
2976 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2977 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2979 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2981 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2983 if (comparePixelToDepthClearValue(result, x, y, depth))
2984 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2986 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2991 void checkStencilClear (const ConstPixelBufferAccess& result,
2992 const UVec2& offset,
2994 vector<PixelStatus>& status,
2997 for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2998 for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
3000 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3002 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
3004 if (comparePixelToStencilClearValue(result, x, y, stencil))
3005 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3007 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
3012 bool verifyAttachment (const ConstPixelBufferAccess& result,
3013 const Maybe<ConstPixelBufferAccess>& secondaryResult,
3014 const RenderPass& renderPassInfo,
3015 const Maybe<VkClearValue>& renderPassClearValue,
3016 const Maybe<VkClearValue>& imageClearValue,
3017 const vector<Subpass>& subpasses,
3018 const vector<SubpassRenderInfo>& subpassRenderInfo,
3019 const PixelBufferAccess& errorImage,
3020 deUint32 attachmentIndex,
3021 const UVec2& renderPos,
3022 const UVec2& renderSize)
3024 const tcu::TextureFormat& format = result.getFormat();
3025 const bool hasDepth = tcu::hasDepthComponent(format.order);
3026 const bool hasStencil = tcu::hasStencilComponent(format.order);
3027 const bool isColorFormat = !hasDepth && !hasStencil;
3028 const PixelStatus initialStatus (isColorFormat ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3029 hasDepth ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3030 hasStencil ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK);
3032 bool attachmentIsUsed = false;
3033 vector<PixelStatus> status (result.getWidth() * result.getHeight(), initialStatus);
3034 tcu::clear(errorImage, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3036 // Check if attachment is used
3037 for (int subpassNdx = 0; subpassNdx < (int)subpasses.size(); subpassNdx++)
3039 const Subpass& subpass = subpasses[subpassNdx];
3040 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3042 if (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex)
3043 attachmentIsUsed = true;
3046 // Set all pixels that have undefined values to OK
3047 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3048 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)))
3050 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3051 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3053 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3055 if (isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3056 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3059 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3060 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3062 if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3063 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3068 // Check renderpass rendering results
3069 if (renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3070 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE))
3072 // Check subpass rendering results
3073 for (int subpassNdx = (int)subpasses.size() - 1; subpassNdx >= 0; subpassNdx--)
3075 const Subpass& subpass = subpasses[subpassNdx];
3076 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3077 const Maybe<deUint32> attachmentNdx = findColorAttachment(subpass, attachmentIndex);
3079 // Check rendered quad
3080 if (renderInfo.getRenderQuad() && (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex))
3082 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3083 const Vec4 posA = renderQuad.getCornerA();
3084 const Vec4 posB = renderQuad.getCornerB();
3085 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3086 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3087 const IVec2 posAI ((deInt32)(origin.x() + (p.x() * posA.x())),
3088 (deInt32)(origin.y() + (p.y() * posA.y())));
3089 const IVec2 posBI ((deInt32)(origin.x() + (p.x() * posB.x())),
3090 (deInt32)(origin.y() + (p.y() * posB.y())));
3093 checkColorRenderQuad(result, posAI, posBI, status);
3097 checkDepthRenderQuad(result, posAI, posBI, status);
3099 if (hasDepth && hasStencil)
3100 checkStencilRenderQuad(*secondaryResult, posAI, posBI, status);
3101 else if (hasStencil)
3102 checkStencilRenderQuad(result, posAI, posBI, status);
3106 // Check color attachment clears
3107 if (attachmentNdx && !renderInfo.getColorClears().empty())
3109 const ColorClear& clear = renderInfo.getColorClears()[*attachmentNdx];
3111 checkColorClear(result, clear.getOffset(), clear.getSize(), status, clear.getColor());
3114 // Check depth/stencil attachment clears
3115 if (subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex && renderInfo.getDepthStencilClear())
3117 const DepthStencilClear clear = *renderInfo.getDepthStencilClear();
3120 checkDepthClear(result, clear.getOffset(), clear.getSize(), status, clear.getDepth());
3122 if (hasDepth && hasStencil)
3123 checkStencilClear(*secondaryResult, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3124 else if (hasStencil)
3125 checkStencilClear(result, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3129 // Check renderpas clear results
3130 if (attachmentIsUsed && renderPassClearValue)
3134 if (renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3135 checkColorClear(result, renderPos, renderSize, status, renderPassClearValue->color);
3139 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3140 checkDepthClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.depth);
3142 if (hasDepth && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3143 checkStencilClear(*secondaryResult, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3144 else if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3145 checkStencilClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3150 // Set all pixels that have undefined values fater renderpass to OK
3151 if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3152 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)))
3154 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3155 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3157 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3159 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED
3160 && isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3161 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3164 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED
3165 && hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3166 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3168 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED
3169 && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3170 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3175 if (imageClearValue)
3178 checkColorClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->color);
3182 checkDepthClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.depth);
3184 if (hasDepth && hasStencil)
3185 checkStencilClear(*secondaryResult, UVec2(0, 0), UVec2(secondaryResult->getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3186 else if (hasStencil)
3187 checkStencilClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3194 for(int y = 0; y < result.getHeight(); y++)
3195 for(int x = 0; x < result.getWidth(); x++)
3197 const PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3201 if (pixelStatus.getColorStatus() != PixelStatus::STATUS_OK)
3203 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
3204 errorImage.setPixel(Vec4(1.0f, 1.0f, 0.0f, 1.0f), x, y);
3205 else if (pixelStatus.getColorStatus() == PixelStatus::STATUS_FAIL)
3206 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3213 if (hasDepth && pixelStatus.getDepthStatus() != PixelStatus::STATUS_OK)
3215 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3219 if (hasStencil && pixelStatus.getStencilStatus() != PixelStatus::STATUS_OK)
3221 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3231 bool logAndVerifyImages (TestLog& log,
3232 const DeviceInterface& vk,
3234 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3235 const vector<bool>& attachmentIsLazy,
3236 const RenderPass& renderPassInfo,
3237 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3238 const vector<Maybe<VkClearValue> >& imageClearValues,
3239 const vector<SubpassRenderInfo>& subpassRenderInfo,
3240 const UVec2& targetSize,
3241 const TestConfig& config)
3243 vector<tcu::TextureLevel> referenceAttachments;
3246 log << TestLog::Message << "Reference images fill undefined pixels with grid pattern." << TestLog::EndMessage;
3248 renderReferenceImages(referenceAttachments, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3250 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3252 if (!attachmentIsLazy[attachmentNdx])
3254 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3255 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3257 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3259 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3260 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3261 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3263 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3264 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3265 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3267 const VkMappedMemoryRange ranges[] =
3270 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3272 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3273 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3274 depthBufferSize // size;
3277 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3279 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3280 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3281 stencilBufferSize // size;
3284 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3287 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3288 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3289 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3291 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3292 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3294 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3296 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3297 && !verifyAttachment(depthAccess, tcu::just(stencilAccess), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3299 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3306 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3307 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3309 const VkMappedMemoryRange range =
3311 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3313 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3314 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3317 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3320 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3321 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3323 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3324 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3326 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3327 && !verifyAttachment(access, tcu::nothing<ConstPixelBufferAccess>(), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3329 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3340 std::string getAttachmentType (VkFormat vkFormat)
3342 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3343 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3345 switch (channelClass)
3347 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3350 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3353 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3354 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3355 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3359 DE_FATAL("Unknown channel class");
3364 void createTestShaders (SourceCollections& dst, TestConfig config)
3366 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3368 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3370 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3372 const Subpass& subpass = subpasses[subpassNdx];
3373 std::ostringstream vertexShader;
3374 std::ostringstream fragmentShader;
3376 vertexShader << "#version 310 es\n"
3377 << "layout(location = 0) in highp vec4 a_position;\n"
3378 << "layout(location = 0) out highp vec2 v_color;\n"
3379 << "void main (void) {\n"
3380 << "\thighp float a = 0.5 + a_position.x;\n"
3381 << "\thighp float b = 0.5 + a_position.y;\n"
3382 << "\tv_color = vec2(a, b);\n"
3383 << "\tgl_Position = a_position;\n"
3386 fragmentShader << "#version 310 es\n"
3387 << "layout(location = 0) in highp vec2 v_color;\n";
3389 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3391 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3392 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3395 fragmentShader << "void main (void) {\n"
3396 << "\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";
3398 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3400 const tcu::TextureFormat format = mapVkFormat(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3401 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
3402 const float clampMin = (float)(-MAX_INTEGER_VALUE);
3403 const float clampMax = (float)(MAX_INTEGER_VALUE);
3404 const Vec4 valueMax (de::clamp(formatInfo.valueMax[0], clampMin, clampMax),
3405 de::clamp(formatInfo.valueMax[1], clampMin, clampMax),
3406 de::clamp(formatInfo.valueMax[2], clampMin, clampMax),
3407 de::clamp(formatInfo.valueMax[3], clampMin, clampMax));
3409 const Vec4 valueMin (de::clamp(formatInfo.valueMin[0], clampMin, clampMax),
3410 de::clamp(formatInfo.valueMin[1], clampMin, clampMax),
3411 de::clamp(formatInfo.valueMin[2], clampMin, clampMax),
3412 de::clamp(formatInfo.valueMin[3], clampMin, clampMax));
3413 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3415 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4" << valueMin << " + vec4" << (valueMax - valueMin) << " * scale);\n";
3418 fragmentShader << "}\n";
3420 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3421 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3426 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3428 bool lastAttachmentWasLazy = false;
3430 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3432 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3433 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3434 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3435 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3437 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3439 attachmentIsLazy.push_back(true);
3440 lastAttachmentWasLazy = true;
3442 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3444 attachmentIsLazy.push_back(false);
3445 lastAttachmentWasLazy = false;
3448 DE_FATAL("Unknown imageMemory");
3451 attachmentIsLazy.push_back(false);
3455 enum AttachmentRefType
3457 ATTACHMENTREFTYPE_COLOR,
3458 ATTACHMENTREFTYPE_DEPTH_STENCIL,
3459 ATTACHMENTREFTYPE_INPUT,
3460 ATTACHMENTREFTYPE_RESOLVE,
3463 VkImageUsageFlags getImageUsageFromLayout(VkImageLayout layout)
3467 case VK_IMAGE_LAYOUT_GENERAL:
3468 case VK_IMAGE_LAYOUT_PREINITIALIZED:
3470 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3471 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3472 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3473 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3474 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3475 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3476 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3477 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3478 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3479 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3480 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3482 DE_FATAL("Unexpected image layout");
3487 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
3489 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
3491 const deUint32 attachment = references[referenceNdx].getAttachment();
3493 if (attachment != VK_ATTACHMENT_UNUSED)
3495 VkImageUsageFlags usage;
3499 case ATTACHMENTREFTYPE_COLOR:
3500 case ATTACHMENTREFTYPE_RESOLVE:
3501 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3503 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
3504 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3506 case ATTACHMENTREFTYPE_INPUT:
3507 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3510 DE_FATAL("Unexpected attachment reference type");
3515 attachmentImageUsage[attachment] |= usage;
3520 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
3522 if (!references.empty())
3524 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
3528 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
3530 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
3532 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
3534 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
3536 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
3537 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
3538 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
3539 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
3542 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3544 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
3546 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
3547 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
3549 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
3550 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
3552 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
3553 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
3555 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
3556 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
3558 if (!attachmentIsLazy[attachmentNdx])
3560 if (clearValues[attachmentNdx])
3561 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3563 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3568 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3570 bool lastSubpassWasSecondary = false;
3572 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3574 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3576 subpassIsSecondary.push_back(true);
3577 lastSubpassWasSecondary = true;
3579 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3581 subpassIsSecondary.push_back(false);
3582 lastSubpassWasSecondary = false;
3585 DE_FATAL("Unknown commandBuffer");
3589 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3591 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3593 if (!isLazy[attachmentNdx])
3594 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3596 clearValues.push_back(nothing<VkClearValue>());
3600 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3602 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3604 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3605 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3607 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3610 clearValues.push_back(nothing<VkClearValue>());
3614 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
3616 clearValues.resize(renderPass.getSubpasses().size());
3618 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3620 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
3621 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3623 clearValues[subpassNdx].resize(colorAttachments.size());
3625 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3627 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3628 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3630 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
3635 void logSubpassRenderInfo (TestLog& log,
3636 const SubpassRenderInfo& info)
3638 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
3640 if (info.isSecondary())
3641 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
3643 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
3645 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
3647 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
3649 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
3650 << ". Offset: " << colorClear.getOffset()
3651 << ", Size: " << colorClear.getSize()
3652 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
3655 if (info.getDepthStencilClear())
3657 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
3659 log << TestLog::Message << "Clearing depth stencil attachment"
3660 << ". Offset: " << depthStencilClear.getOffset()
3661 << ", Size: " << depthStencilClear.getSize()
3662 << ", Depth: " << depthStencilClear.getDepth()
3663 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
3666 if (info.getRenderQuad())
3668 const RenderQuad& renderQuad = *info.getRenderQuad();
3670 log << TestLog::Message << "Rendering gradient quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
3674 void logTestCaseInfo (TestLog& log,
3675 const TestConfig& config,
3676 const vector<bool>& attachmentIsLazy,
3677 const vector<Maybe<VkClearValue> >& imageClearValues,
3678 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3679 const vector<SubpassRenderInfo>& subpassRenderInfo)
3681 const RenderPass& renderPass = config.renderPass;
3683 logRenderPassInfo(log, renderPass);
3685 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
3686 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
3687 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
3689 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
3690 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
3692 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
3694 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
3696 if (attachmentIsLazy[attachmentNdx])
3697 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
3699 if (imageClearValues[attachmentNdx])
3700 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
3702 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
3703 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
3706 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3708 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
3710 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
3714 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
3716 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
3717 const vector<Subpass>& subpasses = renderPass.getSubpasses();
3718 bool lastSubpassWasSecondary = false;
3720 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
3722 const Subpass& subpass = subpasses[subpassNdx];
3723 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
3724 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
3725 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
3726 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
3727 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
3729 vector<ColorClear> colorClears;
3730 Maybe<DepthStencilClear> depthStencilClear;
3731 Maybe<RenderQuad> renderQuad;
3733 lastSubpassWasSecondary = subpassIsSecondary;
3735 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
3737 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3739 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3741 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
3742 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
3743 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3744 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
3745 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
3746 const VkClearColorValue color = randomColorClearValue(attachment, rng);
3748 colorClears.push_back(ColorClear(offset, size, color));
3751 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3753 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
3754 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
3755 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
3756 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
3757 const VkClearValue value = randomClearValue(attachment, rng);
3759 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
3763 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3765 // (-0.5,-0.5) - (0.5,0.5) rounded to pixel edges
3766 const float x = (float)(viewportSize.x() / 4) / (float)(viewportSize.x() / 2);
3767 const float y = (float)(viewportSize.y() / 4) / (float)(viewportSize.y() / 2);
3768 renderQuad = tcu::just(RenderQuad(tcu::Vec4(-x, -y, 0.0f, 1.0f), tcu::Vec4(x, y, 1.0f, 1.0f)));
3771 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
3775 void checkTextureFormatSupport (TestLog& log,
3776 const InstanceInterface& vk,
3777 VkPhysicalDevice device,
3778 const vector<Attachment>& attachments)
3780 bool supported = true;
3782 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3784 const Attachment& attachment = attachments[attachmentNdx];
3785 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3786 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
3787 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
3788 VkFormatProperties properties;
3790 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
3792 if ((properties.optimalTilingFeatures & flags) != flags)
3795 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
3800 TCU_THROW(NotSupportedError, "Format not supported");
3803 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
3805 const UVec2 targetSize = config.targetSize;
3806 const UVec2 renderPos = config.renderPos;
3807 const UVec2 renderSize = config.renderSize;
3808 const RenderPass& renderPassInfo = config.renderPass;
3810 TestLog& log = context.getTestContext().getLog();
3811 de::Random rng (config.seed);
3813 vector<bool> attachmentIsLazy;
3814 vector<VkImageUsageFlags> attachmentImageUsage;
3815 vector<Maybe<VkClearValue> > imageClearValues;
3816 vector<Maybe<VkClearValue> > renderPassClearValues;
3818 vector<bool> subpassIsSecondary;
3819 vector<SubpassRenderInfo> subpassRenderInfo;
3820 vector<vector<VkClearColorValue> > subpassColorClearValues;
3822 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
3823 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
3824 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
3825 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
3827 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
3828 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
3829 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
3831 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
3833 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
3836 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3838 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
3840 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3842 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
3843 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
3848 const VkDevice device = context.getDevice();
3849 const DeviceInterface& vk = context.getDeviceInterface();
3850 const VkQueue queue = context.getUniversalQueue();
3851 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
3852 Allocator& allocator = context.getDefaultAllocator();
3854 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
3855 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
3856 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3857 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3858 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3860 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
3861 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
3862 vector<VkImageView> attachmentViews;
3864 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3866 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
3868 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx])));
3869 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
3872 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3873 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
3874 endCommandBuffer(vk, *initializeImagesCommandBuffer);
3877 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
3879 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3880 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, subpassRenderInfo[subpassNdx])));
3882 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3883 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
3884 endCommandBuffer(vk, *renderCommandBuffer);
3886 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3887 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
3888 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
3890 const VkCommandBuffer commandBuffers[] =
3892 *initializeImagesCommandBuffer,
3893 *renderCommandBuffer,
3894 *readImagesToBuffersCommandBuffer
3896 const Unique<VkFence> fence (createFence(vk, device, 0u));
3898 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
3899 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
3903 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
3904 return tcu::TestStatus::pass("Pass");
3906 return tcu::TestStatus::fail("Result verification failed");
3910 static const VkFormat s_coreColorFormats[] =
3912 VK_FORMAT_R5G6B5_UNORM_PACK16,
3917 VK_FORMAT_R8G8_UNORM,
3918 VK_FORMAT_R8G8_SNORM,
3919 VK_FORMAT_R8G8_UINT,
3920 VK_FORMAT_R8G8_SINT,
3921 VK_FORMAT_R8G8B8A8_UNORM,
3922 VK_FORMAT_R8G8B8A8_SNORM,
3923 VK_FORMAT_R8G8B8A8_UINT,
3924 VK_FORMAT_R8G8B8A8_SINT,
3925 VK_FORMAT_R8G8B8A8_SRGB,
3926 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3927 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3928 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3929 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3930 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3931 VK_FORMAT_B8G8R8A8_UNORM,
3932 VK_FORMAT_B8G8R8A8_SRGB,
3933 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3934 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3935 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3936 VK_FORMAT_R16_UNORM,
3937 VK_FORMAT_R16_SNORM,
3940 VK_FORMAT_R16_SFLOAT,
3941 VK_FORMAT_R16G16_UNORM,
3942 VK_FORMAT_R16G16_SNORM,
3943 VK_FORMAT_R16G16_UINT,
3944 VK_FORMAT_R16G16_SINT,
3945 VK_FORMAT_R16G16_SFLOAT,
3946 VK_FORMAT_R16G16B16A16_UNORM,
3947 VK_FORMAT_R16G16B16A16_SNORM,
3948 VK_FORMAT_R16G16B16A16_UINT,
3949 VK_FORMAT_R16G16B16A16_SINT,
3950 VK_FORMAT_R16G16B16A16_SFLOAT,
3953 VK_FORMAT_R32_SFLOAT,
3954 VK_FORMAT_R32G32_UINT,
3955 VK_FORMAT_R32G32_SINT,
3956 VK_FORMAT_R32G32_SFLOAT,
3957 VK_FORMAT_R32G32B32A32_UINT,
3958 VK_FORMAT_R32G32B32A32_SINT,
3959 VK_FORMAT_R32G32B32A32_SFLOAT
3962 static const VkFormat s_coreDepthStencilFormats[] =
3964 VK_FORMAT_D16_UNORM,
3966 VK_FORMAT_X8_D24_UNORM_PACK32,
3967 VK_FORMAT_D32_SFLOAT,
3969 VK_FORMAT_D24_UNORM_S8_UINT,
3970 VK_FORMAT_D32_SFLOAT_S8_UINT
3973 de::MovePtr<tcu::TestCaseGroup> createAttachmentTestCaseGroup (tcu::TestContext& testCtx)
3975 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
3976 const VkAttachmentLoadOp loadOps[] =
3978 VK_ATTACHMENT_LOAD_OP_LOAD,
3979 VK_ATTACHMENT_LOAD_OP_CLEAR,
3980 VK_ATTACHMENT_LOAD_OP_DONT_CARE
3983 const VkAttachmentStoreOp storeOps[] =
3985 VK_ATTACHMENT_STORE_OP_STORE,
3986 VK_ATTACHMENT_STORE_OP_DONT_CARE
3989 const VkImageLayout initialAndFinalColorLayouts[] =
3991 VK_IMAGE_LAYOUT_GENERAL,
3992 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3993 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3994 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3995 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3998 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4000 VK_IMAGE_LAYOUT_GENERAL,
4001 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4002 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4003 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4004 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4005 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4008 const VkImageLayout subpassLayouts[] =
4010 VK_IMAGE_LAYOUT_GENERAL,
4011 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4014 const VkImageLayout depthStencilLayouts[] =
4016 VK_IMAGE_LAYOUT_GENERAL,
4017 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4020 const TestConfig::RenderTypes renderCommands[] =
4022 TestConfig::RENDERTYPES_NONE,
4023 TestConfig::RENDERTYPES_CLEAR,
4024 TestConfig::RENDERTYPES_DRAW,
4025 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4028 const TestConfig::CommandBufferTypes commandBuffers[] =
4030 TestConfig::COMMANDBUFFERTYPES_INLINE,
4031 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4032 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4035 const TestConfig::ImageMemory imageMemories[] =
4037 TestConfig::IMAGEMEMORY_STRICT,
4038 TestConfig::IMAGEMEMORY_LAZY,
4039 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4042 const UVec2 targetSizes[] =
4048 const UVec2 renderPositions[] =
4054 const UVec2 renderSizes[] =
4060 de::Random rng (1433774382u);
4061 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment", "Attachment format and count tests with load and store ops and image layouts"));
4063 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4065 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4066 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4067 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4069 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4071 const bool useDepthStencil = rng.getBool();
4072 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4073 vector<Attachment> attachments;
4074 vector<AttachmentReference> colorAttachmentReferences;
4076 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4078 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4079 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4080 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4081 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4083 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4084 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4085 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4087 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4088 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4090 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4091 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4094 if (useDepthStencil)
4096 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4097 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4098 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4099 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4101 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4102 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4104 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4105 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4107 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
4108 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4112 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4113 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4114 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4115 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>()));
4116 const vector<SubpassDependency> deps;
4118 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4119 const RenderPass renderPass (attachments, subpasses, deps);
4120 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4121 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4122 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4124 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
4128 group->addChild(attachmentCountGroup.release());
4134 de::MovePtr<tcu::TestCaseGroup> createAttachmentAllocationTestGroup (tcu::TestContext& testCtx)
4136 const deUint32 attachmentCounts[] = { 4, 8 };
4137 const VkAttachmentLoadOp loadOps[] =
4139 VK_ATTACHMENT_LOAD_OP_LOAD,
4140 VK_ATTACHMENT_LOAD_OP_CLEAR,
4141 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4144 const VkAttachmentStoreOp storeOps[] =
4146 VK_ATTACHMENT_STORE_OP_STORE,
4147 VK_ATTACHMENT_STORE_OP_DONT_CARE
4150 const VkImageLayout initialAndFinalColorLayouts[] =
4152 VK_IMAGE_LAYOUT_GENERAL,
4153 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4154 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4155 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4156 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4159 const VkImageLayout subpassLayouts[] =
4161 VK_IMAGE_LAYOUT_GENERAL,
4162 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4167 // Each pass uses one more attachmen than previous one
4168 ALLOCATIONTYPE_GROW,
4169 // Each pass uses one less attachment than previous one
4170 ALLOCATIONTYPE_SHRINK,
4171 // Each pass drops one attachment and picks up new one
4172 ALLOCATIONTYPE_ROLL,
4173 // Start by growing and end by shrinking
4174 ALLOCATIONTYPE_GROW_SHRINK
4177 const AllocationType allocationTypes[] =
4179 ALLOCATIONTYPE_GROW,
4180 ALLOCATIONTYPE_SHRINK,
4181 ALLOCATIONTYPE_ROLL,
4182 ALLOCATIONTYPE_GROW_SHRINK
4185 const char* const allocationTypeStr[] =
4193 const TestConfig::RenderTypes renderCommands[] =
4195 TestConfig::RENDERTYPES_NONE,
4196 TestConfig::RENDERTYPES_CLEAR,
4197 TestConfig::RENDERTYPES_DRAW,
4198 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4201 const TestConfig::CommandBufferTypes commandBuffers[] =
4203 TestConfig::COMMANDBUFFERTYPES_INLINE,
4204 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4205 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4208 const TestConfig::ImageMemory imageMemories[] =
4210 TestConfig::IMAGEMEMORY_STRICT,
4211 TestConfig::IMAGEMEMORY_LAZY,
4212 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4215 const UVec2 targetSizes[] =
4221 const UVec2 renderPositions[] =
4227 const UVec2 renderSizes[] =
4233 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment_allocation", "Attachment allocation tests"));
4234 de::Random rng (3700649827u);
4236 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4238 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4239 const size_t testCaseCount = 100;
4240 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4242 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4244 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4245 vector<Attachment> attachments;
4246 vector<Subpass> subpasses;
4248 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4250 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4251 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4252 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4253 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4255 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4256 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4258 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4259 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4261 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4264 if (allocationType == ALLOCATIONTYPE_GROW)
4266 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4268 vector<AttachmentReference> colorAttachmentReferences;
4270 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4272 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4274 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4277 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>()));
4280 else if (allocationType == ALLOCATIONTYPE_SHRINK)
4282 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4284 vector<AttachmentReference> colorAttachmentReferences;
4286 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4288 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4290 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4293 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>()));
4296 else if (allocationType == ALLOCATIONTYPE_ROLL)
4298 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
4300 vector<AttachmentReference> colorAttachmentReferences;
4302 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
4304 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4306 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
4309 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>()));
4312 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
4314 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4316 vector<AttachmentReference> colorAttachmentReferences;
4318 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4320 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4322 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4325 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>()));
4328 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4330 vector<AttachmentReference> colorAttachmentReferences;
4332 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4334 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4336 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4339 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>()));
4343 DE_FATAL("Unknown allocation type");
4346 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4347 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4348 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4350 const string testCaseName = de::toString(testCaseNdx);
4351 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4352 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4353 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4355 vector<SubpassDependency> deps;
4357 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
4359 const bool byRegion = rng.getBool();
4360 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
4361 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4362 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4363 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4364 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4366 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4367 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4368 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4369 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4371 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4372 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, // \todo [pyry] Correct?
4374 byRegion ? (VkBool32)VK_TRUE : (VkBool32)VK_FALSE));
4377 const RenderPass renderPass (attachments, subpasses, deps);
4379 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4383 group->addChild(allocationTypeGroup.release());
4389 de::MovePtr<tcu::TestCaseGroup> createSimpleTestGroup (tcu::TestContext& testCtx)
4391 const UVec2 targetSize (64, 64);
4392 const UVec2 renderPos (0, 0);
4393 const UVec2 renderSize (64, 64);
4394 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "simple", "Simple basic render pass tests"));
4398 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4399 VK_SAMPLE_COUNT_1_BIT,
4400 VK_ATTACHMENT_LOAD_OP_CLEAR,
4401 VK_ATTACHMENT_STORE_OP_STORE,
4402 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4403 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4404 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4405 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4406 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4408 vector<AttachmentReference>(),
4409 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4410 vector<AttachmentReference>(),
4411 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4412 vector<AttachmentReference>())),
4413 vector<SubpassDependency>());
4415 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));
4420 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4421 VK_SAMPLE_COUNT_1_BIT,
4422 VK_ATTACHMENT_LOAD_OP_CLEAR,
4423 VK_ATTACHMENT_STORE_OP_STORE,
4424 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4425 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4426 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4427 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4428 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4430 vector<AttachmentReference>(),
4431 vector<AttachmentReference>(),
4432 vector<AttachmentReference>(),
4433 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4434 vector<AttachmentReference>())),
4435 vector<SubpassDependency>());
4437 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));
4442 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
4443 VK_SAMPLE_COUNT_1_BIT,
4444 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4445 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4446 VK_ATTACHMENT_LOAD_OP_CLEAR,
4447 VK_ATTACHMENT_STORE_OP_STORE,
4448 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4449 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4450 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4452 vector<AttachmentReference>(),
4453 vector<AttachmentReference>(),
4454 vector<AttachmentReference>(),
4455 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4456 vector<AttachmentReference>())),
4457 vector<SubpassDependency>());
4459 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));
4464 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4465 VK_SAMPLE_COUNT_1_BIT,
4466 VK_ATTACHMENT_LOAD_OP_CLEAR,
4467 VK_ATTACHMENT_STORE_OP_STORE,
4468 VK_ATTACHMENT_LOAD_OP_CLEAR,
4469 VK_ATTACHMENT_STORE_OP_STORE,
4470 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4471 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4472 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4474 vector<AttachmentReference>(),
4475 vector<AttachmentReference>(),
4476 vector<AttachmentReference>(),
4477 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4478 vector<AttachmentReference>())),
4479 vector<SubpassDependency>());
4481 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));
4486 const Attachment attachments[] =
4488 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4489 VK_SAMPLE_COUNT_1_BIT,
4490 VK_ATTACHMENT_LOAD_OP_CLEAR,
4491 VK_ATTACHMENT_STORE_OP_STORE,
4492 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4493 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4494 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4495 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4496 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4497 VK_SAMPLE_COUNT_1_BIT,
4498 VK_ATTACHMENT_LOAD_OP_CLEAR,
4499 VK_ATTACHMENT_STORE_OP_STORE,
4500 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4501 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4502 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4503 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4506 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4507 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4509 vector<AttachmentReference>(),
4510 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4511 vector<AttachmentReference>(),
4512 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4513 vector<AttachmentReference>())),
4514 vector<SubpassDependency>());
4516 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));
4521 const Attachment attachments[] =
4523 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4524 VK_SAMPLE_COUNT_1_BIT,
4525 VK_ATTACHMENT_LOAD_OP_CLEAR,
4526 VK_ATTACHMENT_STORE_OP_STORE,
4527 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4528 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4529 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4530 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4531 Attachment(VK_FORMAT_S8_UINT,
4532 VK_SAMPLE_COUNT_1_BIT,
4533 VK_ATTACHMENT_LOAD_OP_CLEAR,
4534 VK_ATTACHMENT_STORE_OP_STORE,
4535 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4536 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4537 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4538 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4541 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4542 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4544 vector<AttachmentReference>(),
4545 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4546 vector<AttachmentReference>(),
4547 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4548 vector<AttachmentReference>())),
4549 vector<SubpassDependency>());
4552 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));
4555 // color_depth_stencil
4557 const Attachment attachments[] =
4559 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4560 VK_SAMPLE_COUNT_1_BIT,
4561 VK_ATTACHMENT_LOAD_OP_CLEAR,
4562 VK_ATTACHMENT_STORE_OP_STORE,
4563 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4564 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4565 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4566 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4567 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4568 VK_SAMPLE_COUNT_1_BIT,
4569 VK_ATTACHMENT_LOAD_OP_CLEAR,
4570 VK_ATTACHMENT_STORE_OP_STORE,
4571 VK_ATTACHMENT_LOAD_OP_CLEAR,
4572 VK_ATTACHMENT_STORE_OP_STORE,
4573 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4574 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4577 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4578 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4580 vector<AttachmentReference>(),
4581 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4582 vector<AttachmentReference>(),
4583 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4584 vector<AttachmentReference>())),
4585 vector<SubpassDependency>());
4587 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));
4593 std::string formatToName (VkFormat format)
4595 const std::string formatStr = de::toString(format);
4596 const std::string prefix = "VK_FORMAT_";
4598 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4600 return de::toLower(formatStr.substr(prefix.length()));
4603 de::MovePtr<tcu::TestCaseGroup> createFormatTestGroup(tcu::TestContext& testCtx)
4605 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "formats", "Tests for different image formats."));
4607 const UVec2 targetSize (64, 64);
4608 const UVec2 renderPos (0, 0);
4609 const UVec2 renderSize (64, 64);
4613 const char* const str;
4614 const VkAttachmentLoadOp op;
4617 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
4618 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
4619 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
4624 const char* const str;
4625 const TestConfig::RenderTypes types;
4628 { "clear", TestConfig::RENDERTYPES_CLEAR },
4629 { "draw", TestConfig::RENDERTYPES_DRAW },
4630 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
4634 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
4636 const VkFormat format = s_coreColorFormats[formatNdx];
4637 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4639 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4641 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4642 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4644 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4646 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
4647 VK_SAMPLE_COUNT_1_BIT,
4649 VK_ATTACHMENT_STORE_OP_STORE,
4650 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4651 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4652 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4653 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4654 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4656 vector<AttachmentReference>(),
4657 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4658 vector<AttachmentReference>(),
4659 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4660 vector<AttachmentReference>())),
4661 vector<SubpassDependency>());
4663 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));
4666 formatGroup->addChild(loadOpGroup.release());
4669 group->addChild(formatGroup.release());
4672 // Depth stencil formats
4673 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
4675 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
4676 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
4678 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4680 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
4681 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4683 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4685 const tcu::TextureFormat format = mapVkFormat(vkFormat);
4686 const bool isStencilAttachment = hasStencilComponent(format.order);
4687 const bool isDepthAttachment = hasDepthComponent(format.order);
4688 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
4689 VK_SAMPLE_COUNT_1_BIT,
4690 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4691 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
4692 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4693 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
4694 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4695 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4696 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4698 vector<AttachmentReference>(),
4699 vector<AttachmentReference>(),
4700 vector<AttachmentReference>(),
4701 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4702 vector<AttachmentReference>())),
4703 vector<SubpassDependency>());
4705 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));
4708 formatGroup->addChild(loadOpGroup.release());
4711 group->addChild(formatGroup.release());
4719 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
4721 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
4723 renderpassTests->addChild(createSimpleTestGroup(testCtx).release());
4724 renderpassTests->addChild(createFormatTestGroup(testCtx).release());
4725 renderpassTests->addChild(createAttachmentTestCaseGroup(testCtx).release());
4726 renderpassTests->addChild(createAttachmentAllocationTestGroup(testCtx).release());
4728 return renderpassTests.release();