/*------------------------------------------------------------------------ * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2021 The Khronos Group Inc. * Copyright (c) 2021 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Tests load and store op "none" *//*--------------------------------------------------------------------*/ #include "vktRenderPassLoadStoreOpNoneTests.hpp" #include "pipeline/vktPipelineImageUtil.hpp" #include "vktRenderPassTestsUtil.hpp" #include "vktTestCase.hpp" #include "vkImageUtil.hpp" #include "vkMemUtil.hpp" #include "vkPrograms.hpp" #include "vkQueryUtil.hpp" #include "vkCmdUtil.hpp" #include "vkRef.hpp" #include "vkRefUtil.hpp" #include "vkTypeUtil.hpp" #include "vkObjUtil.hpp" #include "tcuImageCompare.hpp" #include "tcuPlatform.hpp" #include "tcuTestLog.hpp" #include "tcuTextureUtil.hpp" #include "deStringUtil.hpp" #include "deUniquePtr.hpp" #include "deRandom.hpp" #include #include #include namespace vkt { namespace renderpass { using namespace vk; namespace { enum AttachmentInit { ATTACHMENT_INIT_PRE = 1, ATTACHMENT_INIT_CMD_CLEAR = 2 }; enum AttachmentUsage { ATTACHMENT_USAGE_UNDEFINED = 0, ATTACHMENT_USAGE_COLOR = 1, ATTACHMENT_USAGE_DEPTH = 2, ATTACHMENT_USAGE_STENCIL = 4, ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL, ATTACHMENT_USAGE_INPUT = 8, ATTACHMENT_USAGE_COLOR_WRITE_OFF = 16, ATTACHMENT_USAGE_DEPTH_WRITE_OFF = 32, ATTACHMENT_USAGE_STENCIL_WRITE_OFF = 64, ATTACHMENT_USAGE_DEPTH_TEST_OFF = 128, ATTACHMENT_USAGE_STENCIL_TEST_OFF = 256, ATTACHMENT_USAGE_MULTISAMPLE = 512, ATTACHMENT_USAGE_RESOLVE_TARGET = 1024, ATTACHMENT_USAGE_INTEGER = 2048 }; struct VerifyAspect { VkImageAspectFlagBits aspect; bool verifyInner; tcu::Vec4 innerRef; bool verifyOuter; tcu::Vec4 outerRef; }; struct AttachmentParams { deUint32 usage; VkAttachmentLoadOp loadOp; VkAttachmentStoreOp storeOp; VkAttachmentLoadOp stencilLoadOp; VkAttachmentStoreOp stencilStoreOp; deUint32 init; std::vector verifyAspects; }; struct AttachmentRef { deUint32 idx; deUint32 usage; }; struct SubpassParams { std::vector attachmentRefs; deUint32 numDraws; }; struct TestParams { std::vector attachments; std::vector subpasses; const SharedGroupParams groupParams; VkFormat depthStencilFormat; bool alphaBlend; }; struct Vertex4RGBA { tcu::Vec4 position; tcu::Vec4 color; }; template inline de::SharedPtr > makeSharedPtr(vk::Move move) { return de::SharedPtr >(new vk::Move(move)); } std::vector createQuad (void) { std::vector vertices; const float size = 1.0f; const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 blue (0.0f, 0.0f, 1.0f, 1.0f); const Vertex4RGBA lowerLeftVertexRed = {tcu::Vec4(-size, -size, 0.0f, 1.0f), red}; const Vertex4RGBA lowerRightVertexRed = {tcu::Vec4(size, -size, 0.0f, 1.0f), red}; const Vertex4RGBA upperLeftVertexRed = {tcu::Vec4(-size, size, 0.0f, 1.0f), red}; const Vertex4RGBA upperRightVertexRed = {tcu::Vec4(size, size, 0.0f, 1.0f), red}; const Vertex4RGBA lowerLeftVertexBlue = {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue}; const Vertex4RGBA lowerRightVertexBlue = {tcu::Vec4(size, -size, 0.0f, 1.0f), blue}; const Vertex4RGBA upperLeftVertexBlue = {tcu::Vec4(-size, size, 0.0f, 1.0f), blue}; const Vertex4RGBA upperRightVertexBlue = {tcu::Vec4(size, size, 0.0f, 1.0f), blue}; vertices.push_back(lowerLeftVertexRed); vertices.push_back(lowerRightVertexRed); vertices.push_back(upperLeftVertexRed); vertices.push_back(upperLeftVertexRed); vertices.push_back(lowerRightVertexRed); vertices.push_back(upperRightVertexRed); vertices.push_back(lowerLeftVertexBlue); vertices.push_back(lowerRightVertexBlue); vertices.push_back(upperLeftVertexBlue); vertices.push_back(upperLeftVertexBlue); vertices.push_back(lowerRightVertexBlue); vertices.push_back(upperRightVertexBlue); return vertices; } deUint32 getFirstUsage (deUint32 attachmentIdx, const std::vector& subpasses) { for (const auto& subpass : subpasses) for (const auto& ref : subpass.attachmentRefs) if (ref.idx == attachmentIdx) return ref.usage; return ATTACHMENT_USAGE_UNDEFINED; } std::string getFormatCaseName(VkFormat format) { return de::toLower(de::toString(getFormatStr(format)).substr(10)); } // Selects an image format based on the usage flags. VkFormat getFormat (deUint32 usage, VkFormat depthStencilFormat) { if (usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { return depthStencilFormat; } if (usage & ATTACHMENT_USAGE_INTEGER) { // Color attachment using integer format. return VK_FORMAT_R8G8B8A8_UINT; } return VK_FORMAT_R8G8B8A8_UNORM; } template Move createRenderPass (const DeviceInterface& vk, VkDevice vkDevice, const TestParams testParams) { const VkImageAspectFlags aspectMask = testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT; std::vector attachmentDescriptions; std::vector subpassDescriptions; struct Refs { std::vector colorAttachmentRefs; std::vector resolveAttachmentRefs; std::vector depthStencilAttachmentRefs; std::vector inputAttachmentRefs; }; std::vector subpassRefs; bool hasInputAttachment = false; for (size_t i = 0; i < testParams.attachments.size(); i++) { VkImageLayout initialLayout; VkImageLayout finalLayout; VkFormat format = getFormat(testParams.attachments[i].usage, testParams.depthStencilFormat); // Search for the first reference to determine the initial layout. deUint32 firstUsage = getFirstUsage((deUint32)i, testParams.subpasses); // No subpasses using this attachment. Use the usage flags of the attachment. if (firstUsage == ATTACHMENT_USAGE_UNDEFINED) firstUsage = testParams.attachments[i].usage; if (firstUsage & ATTACHMENT_USAGE_COLOR) initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL) initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; else { DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT); initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } // Set final layout to transfer src if it's being verified. Otherwise // just use the initial layout as it's known to be supported by // the usage flags. if (!testParams.attachments[i].verifyAspects.empty()) finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; else finalLayout = initialLayout; const VkSampleCountFlagBits sampleCount = testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT; const AttachmentDesc attachmentDesc = { DE_NULL, // const void* pNext (VkAttachmentDescriptionFlags) 0, // VkAttachmentDescriptionFlags flags format, // VkFormat format sampleCount, // VkSampleCountFlagBits samples testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp testParams.attachments[i].stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp testParams.attachments[i].stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp initialLayout, // VkImageLayout initialLayout finalLayout // VkImageLayout finalLayout }; attachmentDescriptions.push_back(attachmentDesc); } for (const auto& subpass : testParams.subpasses) { subpassRefs.push_back({}); auto& refs = subpassRefs.back(); for (const auto& ref : subpass.attachmentRefs) { VkImageLayout layout; if (ref.usage & ATTACHMENT_USAGE_RESOLVE_TARGET) { layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; refs.resolveAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask}); } else if (ref.usage & ATTACHMENT_USAGE_COLOR) { layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; refs.colorAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask}); } else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; const auto depthStencilAspectMask = testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : getImageAspectFlags(mapVkFormat(testParams.depthStencilFormat)); refs.depthStencilAttachmentRefs.push_back({DE_NULL, ref.idx, layout, depthStencilAspectMask}); } else { DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT); layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; refs.inputAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask}); hasInputAttachment = true; } } const SubpassDesc subpassDescription = { DE_NULL, (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 0u, // deUint32 viewMask (deUint32)refs.inputAttachmentRefs.size(), // deUint32 inputAttachmentCount refs.inputAttachmentRefs.empty() ? DE_NULL : refs.inputAttachmentRefs.data(), // const VkAttachmentReference* pInputAttachments (deUint32)refs.colorAttachmentRefs.size(), // deUint32 colorAttachmentCount refs.colorAttachmentRefs.empty() ? DE_NULL : refs.colorAttachmentRefs.data(), // const VkAttachmentReference* pColorAttachments refs.resolveAttachmentRefs.empty() ? DE_NULL : refs.resolveAttachmentRefs.data(), // const VkAttachmentReference* pResolveAttachments refs.depthStencilAttachmentRefs.empty() ? DE_NULL : refs.depthStencilAttachmentRefs.data(), // const VkAttachmentReference* pDepthStencilAttachment 0u, // deUint32 preserveAttachmentCount DE_NULL // const deUint32* pPreserveAttachments }; subpassDescriptions.push_back(subpassDescription); } // Dependency of color attachment of subpass 0 to input attachment of subpass 1. // Determined later if it's being used. const SubpassDep subpassDependency = { DE_NULL, // const void* pNext 0u, // uint32_t srcSubpass 1u, // uint32_t dstSubpass VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags 0u // deInt32 viewOffset }; const RenderPassCreateInfo renderPassInfo = { DE_NULL, // const void* pNext (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments (deUint32)subpassDescriptions.size(), // deUint32 subpassCount subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses hasInputAttachment ? 1u : 0u, // deUint32 dependencyCount hasInputAttachment ? &subpassDependency : DE_NULL, // const VkSubpassDependency* pDependencies 0u, // deUint32 correlatedViewMaskCount DE_NULL // const deUint32* pCorrelatedViewMasks }; return renderPassInfo.createRenderPass(vk, vkDevice); } class LoadStoreOpNoneTest : public vkt::TestCase { public: LoadStoreOpNoneTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const TestParams& testParams); virtual ~LoadStoreOpNoneTest (void); virtual void initPrograms (SourceCollections& sourceCollections) const; virtual void checkSupport (Context& context) const; virtual TestInstance* createInstance (Context& context) const; private: const TestParams m_testParams; }; class LoadStoreOpNoneTestInstance : public vkt::TestInstance { public: LoadStoreOpNoneTestInstance (Context& context, const TestParams& testParams); virtual ~LoadStoreOpNoneTestInstance (void); virtual tcu::TestStatus iterate (void); template void createCommandBuffer (const DeviceInterface& vk, VkDevice vkDevice, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines); void createCommandBuffer (const DeviceInterface& vk, VkDevice vkDevice, std::vector>& imageViews, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines); void drawCommands (VkCommandBuffer cmdBuffer, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines) const; private: TestParams m_testParams; const tcu::UVec2 m_imageSize; const tcu::UVec2 m_renderSize; Move m_descriptorPool; Move m_renderPass; Move m_framebuffer; Move m_vertexBuffer; std::vector m_vertices; de::MovePtr m_vertexBufferAlloc; Move m_cmdPool; Move m_cmdBuffer; Move m_secCmdBuffer; }; LoadStoreOpNoneTest::LoadStoreOpNoneTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const TestParams& testParams) : vkt::TestCase (testContext, name, description) , m_testParams(testParams) { } LoadStoreOpNoneTest::~LoadStoreOpNoneTest (void) { } TestInstance* LoadStoreOpNoneTest::createInstance (Context& context) const { return new LoadStoreOpNoneTestInstance(context, m_testParams); } void LoadStoreOpNoneTest::checkSupport (Context& ctx) const { // Check for renderpass2 extension if used. if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2"); // Check for dynamic_rendering extension if used if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering"); ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none"); // Check depth/stencil format support. for (const auto& att : m_testParams.attachments) { if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { const VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat); VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; const auto aspectFlags = getImageAspectFlags(mapVkFormat(format)); if (att.usage & ATTACHMENT_USAGE_DEPTH) DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT) != 0u); if (att.usage & ATTACHMENT_USAGE_STENCIL) DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0u); DE_UNREF(aspectFlags); // For release builds. if (!att.verifyAspects.empty()) usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; if (att.init & ATTACHMENT_INIT_PRE) usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; const auto& vki = ctx.getInstanceInterface(); const auto physDev = ctx.getPhysicalDevice(); const auto imgType = VK_IMAGE_TYPE_2D; const auto tiling = VK_IMAGE_TILING_OPTIMAL; VkImageFormatProperties properties; const auto result = vki.getPhysicalDeviceImageFormatProperties(physDev, format, imgType, tiling, usage, 0u, &properties); if (result != VK_SUCCESS) TCU_THROW(NotSupportedError, "Depth-stencil format not supported"); } } } void LoadStoreOpNoneTest::initPrograms (SourceCollections& sourceCollections) const { std::ostringstream fragmentSource; sourceCollections.glslSources.add("color_vert") << glu::VertexSource( "#version 450\n" "layout(location = 0) in highp vec4 position;\n" "layout(location = 1) in highp vec4 color;\n" "layout(location = 0) out highp vec4 vtxColor;\n" "void main (void)\n" "{\n" " gl_Position = position;\n" " vtxColor = color;\n" "}\n"); sourceCollections.glslSources.add("color_frag") << glu::FragmentSource( "#version 450\n" "layout(location = 0) in highp vec4 vtxColor;\n" "layout(location = 0) out highp vec4 fragColor;\n" "void main (void)\n" "{\n" " fragColor = vtxColor;\n" " gl_FragDepth = 1.0;\n" "}\n"); sourceCollections.glslSources.add("color_frag_uint") << glu::FragmentSource( "#version 450\n" "layout(location = 0) in highp vec4 vtxColor;\n" "layout(location = 0) out highp uvec4 fragColor;\n" "void main (void)\n" "{\n" " fragColor = uvec4(vtxColor * vec4(255));\n" " gl_FragDepth = 1.0;\n" "}\n"); sourceCollections.glslSources.add("color_frag_blend") << glu::FragmentSource( "#version 450\n" "layout(location = 0) in highp vec4 vtxColor;\n" "layout(location = 0) out highp vec4 fragColor;\n" "void main (void)\n" "{\n" " fragColor = vec4(vtxColor.rgb, 0.5);\n" " gl_FragDepth = 1.0;\n" "}\n"); sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource( "#version 450\n" "layout(location = 0) in highp vec4 vtxColor;\n" "layout(location = 0) out highp vec4 fragColor;\n" "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;\n" "void main (void)\n" "{\n" " fragColor = subpassLoad(inputColor) + vtxColor;\n" " gl_FragDepth = 1.0;\n" "}\n"); } LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance (Context& context, const TestParams& testParams) : vkt::TestInstance (context) , m_testParams (testParams) , m_imageSize (32u, 32u) , m_renderSize (27u, 19u) , m_vertices (createQuad()) { } LoadStoreOpNoneTestInstance::~LoadStoreOpNoneTestInstance (void) { } template void LoadStoreOpNoneTestInstance::createCommandBuffer (const DeviceInterface& vk, VkDevice vkDevice, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines) { const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE); const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL); m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); beginCommandBuffer(vk, *m_cmdBuffer, 0u); const VkRenderPassBeginInfo renderPassBeginInfo { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType DE_NULL, // const void* pNext *m_renderPass, // VkRenderPass renderPass *m_framebuffer, // VkFramebuffer framebuffer makeRect2D(m_renderSize), // VkRect2D renderArea 0u, // uint32_t clearValueCount DE_NULL // const VkClearValue* pClearValues }; RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo); drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines); RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo); endCommandBuffer(vk, *m_cmdBuffer); } void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface& vk, VkDevice vkDevice, std::vector>& imageViews, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines) { std::vector colorAttachments; VkRenderingAttachmentInfoKHR depthAttachment { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; DE_NULL, // VkImageView imageView; VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; DE_NULL, // VkImageView resolveImageView; VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; makeClearValueDepthStencil(0.0f, 0u) // VkClearValue clearValue; }; VkRenderingAttachmentInfoKHR stencilAttachment { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; DE_NULL, // VkImageView imageView; VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; DE_NULL, // VkImageView resolveImageView; VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; makeClearValueDepthStencil(0.0f, 0u) // VkClearValue clearValue; }; bool useDepth = false; bool useStencil = false; VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; std::vector colorAttachmentFormats; for (size_t i = 0; i < imageViews.size(); i++) { if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE) { DE_ASSERT(m_testParams.attachments[i + 1].usage & ATTACHMENT_USAGE_RESOLVE_TARGET); const auto resolveMode = ((m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INTEGER) ? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT : VK_RESOLVE_MODE_AVERAGE_BIT); colorAttachments.push_back({ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; *imageViews[i], // VkImageView imageView; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; resolveMode, // VkResolveModeFlagBits resolveMode; *imageViews[i + 1], // VkImageView resolveImageView; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout resolveImageLayout; m_testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp; m_testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp; makeClearValueColor(tcu::Vec4(0.0f)) // VkClearValue clearValue; }); colorAttachmentFormats.push_back(getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat)); sampleCount = VK_SAMPLE_COUNT_4_BIT; i += 1; } else if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_COLOR) { colorAttachments.push_back({ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; *imageViews[i], // VkImageView imageView; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; DE_NULL, // VkImageView resolveImageView; VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; m_testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp; m_testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp; makeClearValueColor(tcu::Vec4(0.0f)) // VkClearValue clearValue; }); colorAttachmentFormats.push_back(getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat)); } else { deUint32 usage = m_testParams.attachments[i].usage; useDepth = usage & ATTACHMENT_USAGE_DEPTH; useStencil = usage & ATTACHMENT_USAGE_STENCIL; depthAttachment.imageView = *imageViews[i]; depthAttachment.loadOp = m_testParams.attachments[i].loadOp; depthAttachment.storeOp = m_testParams.attachments[i].storeOp; stencilAttachment.imageView = *imageViews[i]; stencilAttachment.loadOp = m_testParams.attachments[i].stencilLoadOp; stencilAttachment.storeOp = m_testParams.attachments[i].stencilStoreOp; } } VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkRenderingFlagsKHR flags; 0u, // uint32_t viewMask; static_cast(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount; colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats; useDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat; useStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat; sampleCount // VkSampleCountFlagBits rasterizationSamples; }; const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo); VkCommandBufferBeginInfo commandBufBeginParams { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; &bufferInheritanceInfo }; VkRenderingInfoKHR renderingInfo { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, DE_NULL, 0u, // VkRenderingFlagsKHR flags; makeRect2D(m_renderSize), // VkRect2D renderArea; 1u, // deUint32 layerCount; 0u, // deUint32 viewMask; (deUint32)colorAttachments.size(), // deUint32 colorAttachmentCount; de::dataOrNull(colorAttachments), // const VkRenderingAttachmentInfoKHR* pColorAttachments; useDepth ? &depthAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment; useStencil ? &stencilAttachment : DE_NULL // const VkRenderingAttachmentInfoKHR* pStencilAttachment; }; m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); if (m_testParams.groupParams->useSecondaryCmdBuffer) { m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); // record secondary command buffer if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass) { inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT; vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams); vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo); } else { commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams); } drawCommands(*m_secCmdBuffer, descriptorSets, pipelineLayouts, pipelines); if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass) vk.cmdEndRendering(*m_secCmdBuffer); endCommandBuffer(vk, *m_secCmdBuffer); // record primary command buffer beginCommandBuffer(vk, *m_cmdBuffer, 0u); if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass) { renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo); } vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer); if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass) vk.cmdEndRendering(*m_cmdBuffer); endCommandBuffer(vk, *m_cmdBuffer); } else { beginCommandBuffer(vk, *m_cmdBuffer, 0u); vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo); drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines); vk.cmdEndRendering(*m_cmdBuffer); endCommandBuffer(vk, *m_cmdBuffer); } } void LoadStoreOpNoneTestInstance::drawCommands(VkCommandBuffer cmdBuffer, std::vector>& descriptorSets, std::vector>& pipelineLayouts, std::vector>& pipelines) const { const DeviceInterface& vk = m_context.getDeviceInterface(); const VkClearRect rect = { makeRect2D(m_renderSize), 0u, 1u }; const VkDeviceSize vertexBufferOffset = 0; // Add clear commands for selected attachments std::vector clearAttachments; deUint32 colorAttIdx = 0u; for (const auto& att : m_testParams.attachments) { if (att.init & ATTACHMENT_INIT_CMD_CLEAR) { if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { VkImageAspectFlags aspectMask = 0; if (att.usage & ATTACHMENT_USAGE_DEPTH) aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; if (att.usage & ATTACHMENT_USAGE_STENCIL) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; clearAttachments.push_back({ aspectMask, 0u, makeClearValueDepthStencil(0.25, 64) }); } else { clearAttachments.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++, makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f) }); } } } if (!clearAttachments.empty()) vk.cmdClearAttachments(cmdBuffer, (deUint32)clearAttachments.size(), clearAttachments.data(), 1u, &rect); vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); deUint32 descriptorSetIdx = 0u; deUint32 vertexOffset = 0u; for (size_t i = 0; i < m_testParams.subpasses.size(); i++) { if (i != 0) { // multi subpass tests should not be executed for dynamic rendering DE_ASSERT(m_testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING); vk.cmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); } vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[i]); bool hasInput = false; for (const auto& ref : m_testParams.subpasses[i].attachmentRefs) if (ref.usage & ATTACHMENT_USAGE_INPUT) hasInput = true; if (hasInput) vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1, &descriptorSets[descriptorSetIdx++].get(), 0, DE_NULL); for (deUint32 d = 0; d < m_testParams.subpasses[i].numDraws; d++) { vk.cmdDraw(cmdBuffer, 6u, 1, vertexOffset, 0); vertexOffset += 6u; } } } tcu::TestStatus LoadStoreOpNoneTestInstance::iterate (void) { const DeviceInterface& vk = m_context.getDeviceInterface(); const VkDevice vkDevice = m_context.getDevice(); const VkQueue queue = m_context.getUniversalQueue(); const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; bool depthIsUndefined = false; std::vector> attachmentImages; std::vector> attachmentImageAllocs; std::vector> imageViews; std::vector> pipelines; for (const auto& att : m_testParams.attachments) { VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat); VkImageUsageFlags usage = 0; VkImageAspectFlags aspectFlags; if (!att.verifyAspects.empty()) usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; if (att.init & ATTACHMENT_INIT_PRE) usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { aspectFlags = getImageAspectFlags(mapVkFormat(format)); usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; // If depth load op is NONE and the depth buffer is not initialized in the render pass // then its contents during the render pass are undefined and we need to be careful // when programming the depth test. if (att.loadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT && !(att.init & ATTACHMENT_INIT_CMD_CLEAR)) depthIsUndefined = true; } else { // Color and input attachments. aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; if (att.usage & ATTACHMENT_USAGE_COLOR) usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; if (att.usage & ATTACHMENT_USAGE_INPUT) usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; } const VkSampleCountFlagBits sampleCount = att.usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT; const VkImageCreateInfo imageParams = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkImageCreateFlags flags VK_IMAGE_TYPE_2D, // VkImageType imageType format, // VkFormat format { m_imageSize.x(), m_imageSize.y(), 1u }, // VkExtent3D extent 1u, // deUint32 mipLevels 1u, // deUint32 arrayLayers sampleCount, // VkSampleCountFlagBits samples VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling usage, // VkImageUsageFlags usage VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 1u, // deUint32 queueFamilyIndexCount &queueFamilyIndex, // const deUint32* pQueueFamilyIndices VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout }; attachmentImages.push_back(createImage(vk, vkDevice, &imageParams)); // Allocate and bind image memory. attachmentImageAllocs.push_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any)); VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(), attachmentImageAllocs.back()->getOffset())); // Create image view. const VkImageViewCreateInfo imageViewParams = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkImageViewCreateFlags flags *attachmentImages.back(), // VkImage image VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType format, // VkFormat format componentMappingRGBA, // VkChannelMapping channels { aspectFlags, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange }; imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams)); if (att.init & ATTACHMENT_INIT_PRE) { // Preinitialize image deUint32 firstUsage = getFirstUsage((deUint32)attachmentImages.size() - 1, m_testParams.subpasses); if (firstUsage == ATTACHMENT_USAGE_UNDEFINED) firstUsage = att.usage; if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL) { const auto dstAccess = (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); const auto dstStage = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), format, 0.5f, 128u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, dstAccess, dstStage); } else { const auto dstAccess = (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); const auto dstStage = (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); const auto clearColor = ((att.usage & ATTACHMENT_USAGE_INTEGER) ? makeClearValueColorU32(0u, 255u, 0u, 255u).color : makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f).color); const auto layout = ((firstUsage & ATTACHMENT_USAGE_COLOR) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), clearColor, VK_IMAGE_LAYOUT_UNDEFINED, layout, dstAccess, dstStage); } } } if (m_testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) { // Create render pass. if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY) m_renderPass = createRenderPass(vk, vkDevice, m_testParams); else m_renderPass = createRenderPass(vk, vkDevice, m_testParams); std::vector views; for (const auto& view : imageViews) views.push_back(*view); // Create framebuffer. const VkFramebufferCreateInfo framebufferParams = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkFramebufferCreateFlags flags *m_renderPass, // VkRenderPass renderPass (deUint32)views.size(), // deUint32 attachmentCount views.data(), // const VkImageView* pAttachments (deUint32)m_imageSize.x(), // deUint32 width (deUint32)m_imageSize.y(), // deUint32 height 1u // deUint32 layers }; m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); } // Create shader modules Unique vertexShaderModule (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0)); Unique fragmentShaderModule (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0)); Unique fragmentShaderModuleUint (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_uint"), 0)); Unique fragmentShaderModuleBlend (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0)); Unique fragmentShaderModuleInput (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0)); // Create descriptor pool. Prepare for using one input attachment at most. { const VkDescriptorPoolSize descriptorPoolSize = { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type 1u // deUint32 descriptorCount }; const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags 1u, // deUint32 maxSets 1u, // deUint32 poolSizeCount &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes }; m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo); } std::vector> descriptorSetLayouts; std::vector> descriptorSets; std::vector> pipelineLayouts; for (const auto& subpass : m_testParams.subpasses) { deUint32 numInputAttachments = 0u; bool noColorWrite = false; bool depthTest = false; bool stencilTest = false; bool depthWrite = true; bool stencilWrite = true; bool multisample = false; bool uintColorBuffer = false; VkCompareOp depthCompareOp = VK_COMPARE_OP_GREATER; // Create pipeline layout. { std::vector layoutBindings; for (const auto ref : subpass.attachmentRefs) { if (ref.usage & ATTACHMENT_USAGE_INPUT) { const VkDescriptorSetLayoutBinding layoutBinding = { 0u, // deUint32 binding VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType 1u, // deUint32 descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags DE_NULL // const VkSampler* pImmutableSamplers }; layoutBindings.push_back(layoutBinding); numInputAttachments++; } if (ref.usage & ATTACHMENT_USAGE_COLOR) { if (ref.usage & ATTACHMENT_USAGE_COLOR_WRITE_OFF) noColorWrite = true; } if (ref.usage & ATTACHMENT_USAGE_DEPTH) { if (!(ref.usage & ATTACHMENT_USAGE_DEPTH_TEST_OFF)) depthTest = true; if (ref.usage & ATTACHMENT_USAGE_DEPTH_WRITE_OFF) depthWrite = false; // Enabling depth testing with undefined depth buffer contents. Let's make sure // all samples pass the depth test. if (depthIsUndefined && depthTest) depthCompareOp = VK_COMPARE_OP_ALWAYS; } if (ref.usage & ATTACHMENT_USAGE_STENCIL) { if (!(ref.usage & ATTACHMENT_USAGE_STENCIL_TEST_OFF)) stencilTest = true; if (ref.usage & ATTACHMENT_USAGE_STENCIL_WRITE_OFF) stencilWrite = false; } if (ref.usage & ATTACHMENT_USAGE_MULTISAMPLE) { multisample = true; } if (ref.usage & ATTACHMENT_USAGE_INTEGER) { uintColorBuffer = true; } } const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkDescriptorSetLayoutCreateFlags flags (deUint32) layoutBindings.size(), // deUint32 bindingCount layoutBindings.empty() ? DE_NULL : layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings }; descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams)); const VkPipelineLayoutCreateInfo pipelineLayoutParams = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkPipelineLayoutCreateFlags flags 1u, // deUint32 setLayoutCount &descriptorSetLayouts.back().get(), // const VkDescriptorSetLayout* pSetLayouts 0u, // deUint32 pushConstantRangeCount DE_NULL // const VkPushConstantRange* pPushConstantRanges }; pipelineLayouts.push_back(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams)); } // Update descriptor set if needed. if (numInputAttachments > 0u) { // Assuming there's only one input attachment at most. DE_ASSERT(numInputAttachments == 1u); const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext *m_descriptorPool, // VkDescriptorPool descriptorPool 1u, // deUint32 descriptorSetCount &descriptorSetLayouts.back().get(), // const VkDescriptorSetLayout* pSetLayouts }; descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo)); for (size_t i = 0; i < imageViews.size(); i++) { if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT) { const VkDescriptorImageInfo inputImageInfo = { DE_NULL, // VkSampler sampler *imageViews[i], // VkImageView imageView VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout }; const VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType DE_NULL, // const void* pNext *descriptorSets.back(), // VkDescriptorSet dstSet 0u, // deUint32 dstBinding 0u, // deUint32 dstArrayElement 1u, // deUint32 descriptorCount VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType &inputImageInfo, // const VkDescriptorImageInfo* pImageInfo DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo DE_NULL // const VkBufferView* pTexelBufferView }; vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL); } } } // Create pipeline. { const VkVertexInputBindingDescription vertexInputBindingDescription = { 0u, // deUint32 binding (deUint32)sizeof(Vertex4RGBA), // deUint32 strideInBytes VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate }; const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = { { 0u, // deUint32 location 0u, // deUint32 binding VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format 0u // deUint32 offset }, { 1u, // deUint32 location 0u, // deUint32 binding VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format (deUint32)(sizeof(float) * 4), // deUint32 offset } }; const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkPipelineVertexInputStateCreateFlags flags 1u, // deUint32 vertexBindingDescriptionCount &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions 2u, // deUint32 vertexAttributeDescriptionCount vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions }; const VkColorComponentFlags writeMask = noColorWrite ? 0 : VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = { m_testParams.alphaBlend, // VkBool32 blendEnable VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp writeMask // VkColorComponentFlags colorWriteMask }; const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkPipelineColorBlendStateCreateFlags flags VK_FALSE, // VkBool32 logicOpEnable VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp 1u, // deUint32 attachmentCount &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4] }; const VkStencilOpState stencilOpState = { VK_STENCIL_OP_KEEP, // VkStencilOp failOp stencilWrite ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP, // VkStencilOp passOp VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp VK_COMPARE_OP_GREATER, // VkCompareOp compareOp 0xff, // deUint32 compareMask 0xff, // deUint32 writeMask 0xff // deUint32 reference }; const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkPipelineDepthStencilStateCreateFlags flags depthTest, // VkBool32 depthTestEnable depthWrite ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable depthCompareOp, // VkCompareOp depthCompareOp VK_FALSE, // VkBool32 depthBoundsTestEnable stencilTest, // VkBool32 stencilTestEnable stencilOpState, // VkStencilOpState front stencilOpState, // VkStencilOpState back 0.0f, // float minDepthBounds 1.0f, // float maxDepthBounds }; const VkPipelineMultisampleStateCreateInfo multisampleStateParams = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkPipelineMultisampleStateCreateFlags flags multisample ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples VK_FALSE, // VkBool32 sampleShadingEnable 1.0f, // float minSampleShading DE_NULL, // const VkSampleMask* pSampleMask VK_FALSE, // VkBool32 alphaToCoverageEnable VK_FALSE // VkBool32 alphaToOneEnable }; const std::vector viewports (1, makeViewport(m_imageSize)); const std::vector scissors (1, makeRect2D(m_renderSize)); VkShaderModule fragShader = *fragmentShaderModule; if (numInputAttachments > 0u) fragShader = *fragmentShaderModuleInput; else if (uintColorBuffer) fragShader = *fragmentShaderModuleUint; else if (m_testParams.alphaBlend) fragShader = *fragmentShaderModuleBlend; VkPipelineRenderingCreateInfoKHR renderingCreateInfo { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, DE_NULL, 0u, 0u, DE_NULL, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }; std::vector colorVector; for (const auto& att : m_testParams.attachments) { VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat); if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL) { const auto tcuFormat = mapVkFormat(format); const auto hasDepth = tcu::hasDepthComponent(tcuFormat.order); const auto hasStencil = tcu::hasStencilComponent(tcuFormat.order); renderingCreateInfo.depthAttachmentFormat = (hasDepth ? format : VK_FORMAT_UNDEFINED); renderingCreateInfo.stencilAttachmentFormat = (hasStencil ? format : VK_FORMAT_UNDEFINED); } else if (!(att.usage & ATTACHMENT_USAGE_RESOLVE_TARGET)) { colorVector.push_back(format); } } vk::VkPipelineRenderingCreateInfoKHR* nextPtr = DE_NULL; if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) { renderingCreateInfo.colorAttachmentCount = static_cast(colorVector.size()); renderingCreateInfo.pColorAttachmentFormats = colorVector.data(); nextPtr = &renderingCreateInfo; } pipelines.push_back(makeGraphicsPipeline( vk, // const DeviceInterface& vk vkDevice, // const VkDevice device *pipelineLayouts.back(), // const VkPipelineLayout pipelineLayout *vertexShaderModule, // const VkShaderModule vertexShaderModule DE_NULL, // const VkShaderModule tessellationControlModule DE_NULL, // const VkShaderModule tessellationEvalModule DE_NULL, // const VkShaderModule geometryShaderModule fragShader, // const VkShaderModule fragmentShaderModule *m_renderPass, // const VkRenderPass renderPass viewports, // const std::vector& viewports scissors, // const std::vector& scissors VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology (deUint32)pipelines.size(), // const deUint32 subpass 0u, // const deUint32 patchControlPoints &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo nextPtr)); // const void* pNext } } // Create vertex buffer. { const VkBufferCreateInfo vertexBufferParams = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType DE_NULL, // const void* pNext 0u, // VkBufferCreateFlags flags (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 1u, // deUint32 queueFamilyIndexCount &queueFamilyIndex // const deUint32* pQueueFamilyIndices }; m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); // Upload vertex data. deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA)); flushAlloc(vk, vkDevice, *m_vertexBufferAlloc); } // Create command pool. m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); // Create command buffer. if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY) createCommandBuffer(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines); else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) createCommandBuffer(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines); else createCommandBuffer(vk, vkDevice, imageViews, descriptorSets, pipelineLayouts, pipelines); // Submit commands. submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); bool pass = true; // Verify selected attachments. for (size_t i = 0; i < m_testParams.attachments.size(); i++) { bool transitioned = false; for (const auto& verify : m_testParams.attachments[i].verifyAspects) { de::MovePtr textureLevelResult; SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); VkFormat format = getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat); if (verify.aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { VkImageLayout layout = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; textureLevelResult = pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], m_testParams.depthStencilFormat, m_imageSize, layout); transitioned = true; } else if (verify.aspect == VK_IMAGE_ASPECT_STENCIL_BIT) { VkImageLayout layout = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; textureLevelResult = pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], m_testParams.depthStencilFormat, m_imageSize, layout); transitioned = true; } else { DE_ASSERT(verify.aspect == VK_IMAGE_ASPECT_COLOR_BIT); VkImageLayout layout = ((m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], format, m_imageSize, layout); transitioned = true; } const tcu::ConstPixelBufferAccess& access = textureLevelResult->getAccess(); // Log attachment contents m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "") << tcu::TestLog::Image("Attachment " + de::toString(i), "", access) << tcu::TestLog::EndImageSet; for (int y = 0; y < access.getHeight(); y++) for (int x = 0; x < access.getWidth(); x++) { const bool inner = x < (int)m_renderSize.x() && y < (int)m_renderSize.y(); if (inner && !verify.verifyInner) continue; if (!inner && !verify.verifyOuter) continue; const tcu::Vec4 ref = inner ? verify.innerRef : verify.outerRef; const tcu::Vec4 p = access.getPixel(x, y); for (int c = 0; c < 4; c++) if (fabs(p[c] - ref[c]) > 0.01f) pass = false; } } } if (pass) return tcu::TestStatus::pass("Pass"); else return tcu::TestStatus::fail("Fail"); } } // anonymous tcu::TestCaseGroup* createRenderPassLoadStoreOpNoneTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams) { de::MovePtr opNoneTests (new tcu::TestCaseGroup(testCtx, "load_store_op_none", "")); const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); const tcu::Vec4 magenta (1.0f, 0.0f, 1.0f, 1.0f); const tcu::Vec4 darkBlue (0.0f, 0.0f, 0.5f, 1.0f); const tcu::Vec4 blend (0.5f, 0.0f, 0.25f, 0.5f); const tcu::Vec4 depthInit (0.5f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 depthFull (1.0f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 stencilInit (128.0f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 stencilFull (255.0f, 0.0f, 0.0f, 1.0f); const tcu::Vec4 redUint (255.0f, 0.0f, 0.0f, 255.0f); const tcu::Vec4 greenUint (0.0f, 255.0f, 0.0f, 255.0f); // Preinitialize attachments 0 and 1 to green. // Subpass 0: draw a red rectangle inside attachment 0. // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to // attachment 1. // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the // preinitialized green outside the render area and magenta inside. if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}} }, { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}, {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", "", params)); } // Preinitialize color attachment to green. Use a render pass with load and store ops none, but // disable color writes using an empty color mask. The color attachment image should have the original // preinitialized value after the render pass. { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, green, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_COLOR_WRITE_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", "", params)); } // Preinitialize color attachment to green. Use a render pass with load and store ops none, and // write a rectangle to the color buffer. The render area is undefined, but the outside area should // still have the preinitialized color. { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", "", params)); } // Preinitialize color attachment to green. Use a subpass with no draw calls but instead // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized // data and store op store causes the cleared blue render area to be present after the render pass. { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_COLOR_BIT, true, darkBlue, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}}, 0u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", "", params)); } // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed // by an alpha blender draw. Load op none preserves the preinitialized data and store op store // keeps the blended color inside the render area after the render pass. { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_COLOR_BIT, true, blend, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; true // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", "", params)); } // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined because load op 'none'. // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values. // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1. // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care', // but the outside area should still have the preinitialized content. // Attachment 1 should have the preinitialized green outside render area and magenta inside. if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}} }, { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}, {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", "", params)); } // Preinitialize color attachment to green. Use a render pass with load and store ops none for a multisample color // target. Write a red rectangle and check it ends up in the resolved buffer even though the multisample attachment // doesn't store the results. { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {} }, { ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET | ATTACHMENT_USAGE_INTEGER, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, redUint, true, greenUint}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER}, {1u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET}}, 1u} }, groupParams, // const SharedGroupParams groupParams; VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_resolve", "", params)); } std::vector formats = { VK_FORMAT_D16_UNORM, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_S8_UINT }; for (deUint32 f = 0; f < formats.size(); ++f) { const auto tcuFormat = mapVkFormat(formats[f]); const bool hasDepth = tcu::hasDepthComponent(tcuFormat.order); const bool hasStencil = tcu::hasStencilComponent(tcuFormat.order); const std::string formatName = getFormatCaseName(formats[f]); // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5. // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update // depth buffer to 1.0. // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time // the depth test fails and nothing is written. // After the renderpass the red color should remain inside the render area of the color buffer. // Store op 'none' for depth buffer makes the written values undefined, but the pixels outside // render area should still contain the original value of 0.5. if (hasDepth) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthInit, true, depthInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_"+formatName+"_load_op_load_store_op_none", "", params)); } // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but // disable depth test which also disables depth writes. The depth attachment should have the original // preinitialized value after the render pass. if (hasDepth) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_none_write_off", "", params)); } // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the // shader updated value of 1.0. if (hasDepth) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}}} }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_store", "", params)); } // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass. // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render // area is undefined because of store op 'don't care', but the outside should have the original value of 0.5. if (hasDepth) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthFull, true, depthInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_dontcare", "", params)); } // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128. // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time // the stencil test fails and nothing is written. // After the renderpass the red color should remain inside the render area of the color buffer. // Store op 'none' for stencil buffer makes the written values undefined, but the pixels outside // render area should still contain the original value of 128. if (hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_STENCIL, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_NONE_EXT, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilInit, true, stencilInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_load_store_op_none", "", params)); } // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but // disable stencil test which also disables stencil writes. The stencil attachment should have the original // preinitialized value after the render pass. if (hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_STENCIL, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_none_write_off", "", params)); } // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64 // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the // shader updated value of 255. if (hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_STENCIL, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_STORE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_store", "", params)); } // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64 // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass. // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render // are is undefined because of store op 'don't care', but the outside should have the original value of 128. if (hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_STENCIL, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilFull, true, stencilInit}} } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_dontcare", "", params)); } // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and // store ops none, and stencil writes are disabled by disabling stencil test. Therefore, stencil should not be modified even when // the depth aspect is written. if (hasDepth && hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH_STENCIL, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, ATTACHMENT_INIT_PRE, { {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}, {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}, } } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_test_off", "", params)); } // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store // ops none, and depth writes are disabled by having depth test off. Therefore, depth should not be modified even when the stencil aspect is // written. if (hasDepth && hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH_STENCIL, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, ATTACHMENT_INIT_PRE, { {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}, {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit} } } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_test_off", "", params)); } // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and // store ops none, and stencil writes are disabled. Therefore, stencil should not be modified even when the depth aspect is written. if (hasDepth && hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH_STENCIL, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, ATTACHMENT_INIT_PRE, { {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}, {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}, } } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_WRITE_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_write_off", "", params)); } // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store // ops none, the depth buffer contents will be undefined and depth test is enabled but op will be 'always' so depth testing will pass. Depth // writes are disabled, so depth should not be modified even when the stencil aspect is written. if (hasDepth && hasStencil) { TestParams params { { // std::vector attachments; { ATTACHMENT_USAGE_COLOR, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, ATTACHMENT_INIT_PRE, {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}} }, { ATTACHMENT_USAGE_DEPTH_STENCIL, VK_ATTACHMENT_LOAD_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, ATTACHMENT_INIT_PRE, { {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}, {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit} } } }, { // std::vector subpasses; {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_WRITE_OFF}}, 1u} }, groupParams, // const SharedGroupParams groupParams; formats[f], // VkFormat depthStencilFormat; false // bool alphaBlend; }; opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_write_off", "", params)); } } return opNoneTests.release(); } } // renderpass } // vkt