From 74960221b0e09b87c6ed10964b99b90490131034 Mon Sep 17 00:00:00 2001 From: Ari Suonpaa Date: Thu, 1 Jul 2021 01:11:44 +0300 Subject: [PATCH] Add tests for VK_EXT_load_store_op_none VK-GL-CTS Issue: 2971 New tests: dEQP-VK.renderpass*.load_store_op_none.* Components: Vulkan Change-Id: If3eb79e75b14f96037d14fcaa469230d3434a729 (cherry picked from commit b0025b814cad4fd699761578eaec575fe76f7f75) --- AndroidGen.mk | 1 + .../cts/master/vk-master-2021-03-01/renderpass.txt | 14 + .../master/vk-master-2021-03-01/renderpass2.txt | 14 + android/cts/master/vk-master/renderpass.txt | 14 + android/cts/master/vk-master/renderpass2.txt | 14 + .../vulkan/pipeline/vktPipelineImageUtil.cpp | 5 +- .../vulkan/pipeline/vktPipelineImageUtil.hpp | 3 +- .../modules/vulkan/renderpass/CMakeLists.txt | 2 + .../vktRenderPassLoadStoreOpNoneTests.cpp | 1383 ++++++++++++++++++++ .../vktRenderPassLoadStoreOpNoneTests.hpp | 40 + .../vulkan/renderpass/vktRenderPassTests.cpp | 2 + .../mustpass/master/vk-default/renderpass.txt | 14 + .../mustpass/master/vk-default/renderpass2.txt | 14 + 13 files changed, 1517 insertions(+), 3 deletions(-) create mode 100644 external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.cpp create mode 100644 external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.hpp diff --git a/AndroidGen.mk b/AndroidGen.mk index 4c32d4b..9dbde6c 100644 --- a/AndroidGen.mk +++ b/AndroidGen.mk @@ -332,6 +332,7 @@ LOCAL_SRC_FILES := \ external/vulkancts/modules/vulkan/reconvergence/vktReconvergenceTests.cpp \ external/vulkancts/modules/vulkan/renderpass/vktRenderPassDepthStencilResolveTests.cpp \ external/vulkancts/modules/vulkan/renderpass/vktRenderPassFragmentDensityMapTests.cpp \ + external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.cpp \ external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.cpp \ external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleResolveTests.cpp \ external/vulkancts/modules/vulkan/renderpass/vktRenderPassMultisampleTests.cpp \ diff --git a/android/cts/master/vk-master-2021-03-01/renderpass.txt b/android/cts/master/vk-master-2021-03-01/renderpass.txt index 9508ad8..8df9aa8 100644 --- a/android/cts/master/vk-master-2021-03-01/renderpass.txt +++ b/android/cts/master/vk-master-2021-03-01/renderpass.txt @@ -1299,4 +1299,18 @@ dEQP-VK.renderpass.suballocation.subpass_dependencies.single_attachment.b8g8r8a8 dEQP-VK.renderpass.suballocation.subpass_dependencies.single_attachment.r16g16b16a16_sfloat dEQP-VK.renderpass.suballocation.subpass_dependencies.single_attachment.r5g6b5_unorm_pack16 dEQP-VK.renderpass.suballocation.subpass_dependencies.single_attachment.a1r5g5b5_unorm_pack16 +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass.multiple_subpasses_multiple_command_buffers.test diff --git a/android/cts/master/vk-master-2021-03-01/renderpass2.txt b/android/cts/master/vk-master-2021-03-01/renderpass2.txt index e999dac..97ee244 100644 --- a/android/cts/master/vk-master-2021-03-01/renderpass2.txt +++ b/android/cts/master/vk-master-2021-03-01/renderpass2.txt @@ -1308,6 +1308,20 @@ dEQP-VK.renderpass2.suballocation.subpass_dependencies.single_attachment.b8g8r8a dEQP-VK.renderpass2.suballocation.subpass_dependencies.single_attachment.r16g16b16a16_sfloat dEQP-VK.renderpass2.suballocation.subpass_dependencies.single_attachment.r5g6b5_unorm_pack16 dEQP-VK.renderpass2.suballocation.subpass_dependencies.single_attachment.a1r5g5b5_unorm_pack16 +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass2.multiple_subpasses_multiple_command_buffers.test dEQP-VK.renderpass2.depth_stencil_resolve.image_2d_32_32.samples_2.d16_unorm_s8_uint.compatibility_depth_none_stencil_zero_testing_depth dEQP-VK.renderpass2.depth_stencil_resolve.image_2d_32_32.samples_2.d16_unorm_s8_uint.compatibility_depth_none_stencil_zero_testing_stencil diff --git a/android/cts/master/vk-master/renderpass.txt b/android/cts/master/vk-master/renderpass.txt index b397279..cbd1655 100644 --- a/android/cts/master/vk-master/renderpass.txt +++ b/android/cts/master/vk-master/renderpass.txt @@ -8755,6 +8755,20 @@ dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_15 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_31 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_63 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_127 +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass.dedicated_allocation.simple.color dEQP-VK.renderpass.dedicated_allocation.simple.depth dEQP-VK.renderpass.dedicated_allocation.simple.stencil diff --git a/android/cts/master/vk-master/renderpass2.txt b/android/cts/master/vk-master/renderpass2.txt index bf35342..1c24a15 100644 --- a/android/cts/master/vk-master/renderpass2.txt +++ b/android/cts/master/vk-master/renderpass2.txt @@ -6712,6 +6712,20 @@ dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_15 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_31 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_63 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_127 +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass2.dedicated_allocation.simple.color dEQP-VK.renderpass2.dedicated_allocation.simple.depth dEQP-VK.renderpass2.dedicated_allocation.simple.stencil diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp index 62c3c64..6a18add 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp @@ -211,7 +211,8 @@ de::MovePtr readColorAttachment (const vk::DeviceInterface& v vk::Allocator& allocator, vk::VkImage image, vk::VkFormat format, - const tcu::UVec2& renderSize) + const tcu::UVec2& renderSize, + vk::VkImageLayout oldLayout) { Move buffer; de::MovePtr bufferAlloc; @@ -249,7 +250,7 @@ de::MovePtr readColorAttachment (const vk::DeviceInterface& v fence = createFence(vk, device); beginCommandBuffer(vk, *cmdBuffer); - copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y())); + copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, oldLayout); endCommandBuffer(vk, *cmdBuffer); submitCommandsAndWait(vk, device, queue, cmdBuffer.get()); diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp index 8e80de6..4bcd64a 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp @@ -86,7 +86,8 @@ de::MovePtr readColorAttachment (const vk::DeviceInterface vk::Allocator& allocator, vk::VkImage image, vk::VkFormat format, - const tcu::UVec2& renderSize); + const tcu::UVec2& renderSize, + vk::VkImageLayout oldLayout = vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); /*--------------------------------------------------------------------*//*! diff --git a/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt b/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt index b4fcc66..5459742 100644 --- a/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/renderpass/CMakeLists.txt @@ -29,6 +29,8 @@ set(DEQP_VK_RENDER_PASS_SRCS vktRenderPassFragmentDensityMapTests.hpp vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.cpp vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp + vktRenderPassLoadStoreOpNoneTests.cpp + vktRenderPassLoadStoreOpNoneTests.hpp ) set(DEQP_VK_RENDER_PASS_LIBS diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.cpp new file mode 100644 index 0000000..d961bb2 --- /dev/null +++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.cpp @@ -0,0 +1,1383 @@ +/*------------------------------------------------------------------------ + * 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 "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 "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_INPUT = 8, + ATTACHMENT_USAGE_WRITE_OFF = 16, + ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL +}; + +struct AttachmentParams +{ + deUint32 usage; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + deUint32 init; + bool verifyInner; + tcu::Vec4 innerRef; + bool verifyOuter; + tcu::Vec4 outerRef; +}; + +struct AttachmentRef +{ + deUint32 idx; + deUint32 usage; +}; + +struct SubpassParams +{ + std::vector attachmentRefs; + deUint32 numDraws; +}; + +struct TestParams +{ + std::vector attachments; + std::vector subpasses; + RenderPassType renderPassType; + 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; +} + +template +Move createRenderPass (const DeviceInterface& vk, + VkDevice vkDevice, + const TestParams testParams) +{ + const VkImageAspectFlags aspectMask = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT; + const VkImageAspectFlags depthStencilAspectMask = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + std::vector attachmentDescriptions; + std::vector subpassDescriptions; + + struct Refs + { + std::vector colorAttachmentRefs; + 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; + + if (testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH_STENCIL) + { + format = VK_FORMAT_D24_UNORM_S8_UINT; + } + else + { + // Color and input attachments. + format = VK_FORMAT_R8G8B8A8_UNORM; + } + + // 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].verifyInner || testParams.attachments[i].verifyOuter) + finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + else + finalLayout = initialLayout; + + const AttachmentDesc attachmentDesc = + { + DE_NULL, // const void* pNext + (VkAttachmentDescriptionFlags) 0, // VkAttachmentDescriptionFlags flags + format, // VkFormat format + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples + testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp + testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp + testParams.attachments[i].loadOp, // VkAttachmentLoadOp stencilLoadOp + testParams.attachments[i].storeOp, // 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_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; + 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 + DE_NULL, // 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); +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; +}; + +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.renderPassType == RENDERPASS_TYPE_RENDERPASS2) + ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2"); + + ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none"); +} + +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_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;" + "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); + + const VkDeviceSize vertexBufferOffset = 0; + + 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); + + // 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) + { + clearAttachments.push_back({VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 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()) + { + VkClearRect rect = { makeRect2D(m_renderSize), 0u, 1u }; + vk.cmdClearAttachments(*m_cmdBuffer, (deUint32) clearAttachments.size(), clearAttachments.data(), 1u, &rect); + } + + vk.cmdBindVertexBuffers(*m_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) + vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); + + vk.cmdBindPipeline(*m_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(*m_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(*m_cmdBuffer, 6u, 1, vertexOffset, 0); + vertexOffset += 6u; + } + } + RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo); + endCommandBuffer(vk, *m_cmdBuffer); +} + +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 }; + + std::vector> attachmentImages; + std::vector> attachmentImageAllocs; + std::vector> imageViews; + std::vector> pipelines; + + for (const auto& att : m_testParams.attachments) + { + VkFormat format; + VkImageUsageFlags usage = 0; + VkImageAspectFlags aspectFlags; + + if (att.verifyInner || att.verifyOuter) 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) + { + format = VK_FORMAT_D24_UNORM_S8_UINT; + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + else + { + // Color and input attachments. + format = VK_FORMAT_R8G8B8A8_UNORM; + 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 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 + VK_SAMPLE_COUNT_1_BIT, // 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) + { + clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), 0.5f, 128u, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + } + else + { + clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), + VK_IMAGE_LAYOUT_UNDEFINED, firstUsage & ATTACHMENT_USAGE_COLOR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + } + } + } + + // Create render pass. + if (m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY) + m_renderPass = createRenderPass(vk, vkDevice, m_testParams); + else + m_renderPass = createRenderPass(vk, vkDevice, m_testParams); + + // Create framebuffer. + { + std::vector views; + for (const auto& view : imageViews) + views.push_back(*view); + + 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 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; + + // 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_WRITE_OFF) + noColorWrite = true; + } + if (ref.usage & ATTACHMENT_USAGE_DEPTH) + { + if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF)) + depthTest = true; + } + if (ref.usage & ATTACHMENT_USAGE_STENCIL) + { + if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF)) + stencilTest = 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 + VK_STENCIL_OP_REPLACE, // 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 + VK_TRUE, // VkBool32 depthWriteEnable + VK_COMPARE_OP_GREATER, // VkCompareOp depthCompareOp + VK_FALSE, // VkBool32 depthBoundsTestEnable + stencilTest, // VkBool32 stencilTestEnable + stencilOpState, // VkStencilOpState front + stencilOpState, // VkStencilOpState back + 0.0f, // float minDepthBounds + 1.0f, // float maxDepthBounds + }; + + 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 (m_testParams.alphaBlend) + fragShader = *fragmentShaderModuleBlend; + + 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 + DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo + &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo + &colorBlendStateParams)); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo + } + } + + // 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.renderPassType == RENDERPASS_TYPE_LEGACY) + createCommandBuffer(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines); + else + createCommandBuffer(vk, vkDevice, 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++) + { + if (m_testParams.attachments[i].verifyInner || m_testParams.attachments[i].verifyOuter) + { + de::MovePtr textureLevelResult; + + SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); + + if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH) + { + textureLevelResult = pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + } + else if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_STENCIL) + { + textureLevelResult = pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + } + else + { + textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_R8G8B8A8_UNORM, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + } + + 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 && !m_testParams.attachments[i].verifyInner) + continue; + if (!inner && !m_testParams.attachments[i].verifyOuter) + continue; + + const tcu::Vec4 ref = inner ? m_testParams.attachments[i].innerRef : m_testParams.attachments[i].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 RenderPassType renderPassType) +{ + 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); + + // 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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + false, green, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, magenta, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}); + + 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; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + true, green, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_WRITE_OFF}}, 1u}); + + 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 rectange to the color buffer. The render area is undefined, but the outside area should + // still have the preinitialized color. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + false, green, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}); + + 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; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + true, darkBlue, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 0u}); + + 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 is none preserves the preinitialized data and store op store + // keeps the blended color inside the render area after the render pass. + { + TestParams params; + params.alphaBlend = true; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + true, blend, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}); + + 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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + ATTACHMENT_INIT_PRE, + false, green, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, magenta, + true, green}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", "", params)); + } + + // 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 'store' for depth buffer makes the written values undefined, but the pixels outside + // render area should still contain the original value of 0.5. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_DEPTH, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + false, depthInit, + true, depthInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_DEPTH, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + true, depthInit, + true, depthInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_WRITE_OFF}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_DEPTH, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + true, depthFull, + true, depthInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_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 + // are is undefined because of store op 'don't care', but the outside should have the original value of 0.5. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_DEPTH, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + false, depthFull, + true, depthInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_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 'store' for stencil buffer makes the written values undefined, but the pixels outside + // render area should still contain the original value of 128. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_STENCIL, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + false, stencilInit, + true, stencilInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_STENCIL, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE_EXT, + ATTACHMENT_INIT_PRE, + true, stencilInit, + true, stencilInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_WRITE_OFF}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_STENCIL, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + true, stencilFull, + true, stencilInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_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. + { + TestParams params; + params.alphaBlend = false; + params.renderPassType = renderPassType; + params.attachments.push_back({ATTACHMENT_USAGE_COLOR, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + ATTACHMENT_INIT_PRE, + true, red, + true, green}); + params.attachments.push_back({ATTACHMENT_USAGE_STENCIL, + VK_ATTACHMENT_LOAD_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR, + false, stencilFull, + true, stencilInit}); + params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}); + + opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_dontcare", "", params)); + } + + return opNoneTests.release(); +} + +} // renderpass +} // vkt diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.hpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.hpp new file mode 100644 index 0000000..cfb0563 --- /dev/null +++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassLoadStoreOpNoneTests.hpp @@ -0,0 +1,40 @@ +#ifndef _VKTRENDERPASSLOADSTOREOPNONETESTS_HPP +#define _VKTRENDERPASSLOADSTOREOPNONETESTS_HPP +/*------------------------------------------------------------------------ + * 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 "vktTestCase.hpp" +#include "vktRenderPassTestsUtil.hpp" + +namespace vkt +{ +namespace renderpass +{ + +tcu::TestCaseGroup* createRenderPassLoadStoreOpNoneTests (tcu::TestContext& testCtx, const RenderPassType renderPassType); + +} // renderpass +} // vkt + +#endif // _VKTRENDERPASSLOADSTOREOPNONETESTS_HPP diff --git a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp index 7c52992..817945b 100644 --- a/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp +++ b/external/vulkancts/modules/vulkan/renderpass/vktRenderPassTests.cpp @@ -35,6 +35,7 @@ #include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp" #include "vktRenderPassFragmentDensityMapTests.hpp" #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp" +#include "vktRenderPassLoadStoreOpNoneTests.hpp" #include "vktTestCaseUtil.hpp" #include "vktTestGroupUtil.hpp" @@ -7175,6 +7176,7 @@ tcu::TestCaseGroup* createRenderPassTestsInternal (tcu::TestContext& testCtx, Re suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderPassType)); suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, renderPassType)); suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderPassType)); + suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, renderPassType)); renderpassTests->addChild(suballocationTestGroup.release()); renderpassTests->addChild(dedicatedAllocationTestGroup.release()); diff --git a/external/vulkancts/mustpass/master/vk-default/renderpass.txt b/external/vulkancts/mustpass/master/vk-default/renderpass.txt index b397279..cbd1655 100644 --- a/external/vulkancts/mustpass/master/vk-default/renderpass.txt +++ b/external/vulkancts/mustpass/master/vk-default/renderpass.txt @@ -8755,6 +8755,20 @@ dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_15 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_31 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_63 dEQP-VK.renderpass.suballocation.attachment_sparse_filling.input_attachment_127 +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass.dedicated_allocation.simple.color dEQP-VK.renderpass.dedicated_allocation.simple.depth dEQP-VK.renderpass.dedicated_allocation.simple.stencil diff --git a/external/vulkancts/mustpass/master/vk-default/renderpass2.txt b/external/vulkancts/mustpass/master/vk-default/renderpass2.txt index bf35342..1c24a15 100644 --- a/external/vulkancts/mustpass/master/vk-default/renderpass2.txt +++ b/external/vulkancts/mustpass/master/vk-default/renderpass2.txt @@ -6712,6 +6712,20 @@ dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_15 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_31 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_63 dEQP-VK.renderpass2.suballocation.attachment_sparse_filling.input_attachment_127 +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_store_alphablend +dEQP-VK.renderpass2.suballocation.load_store_op_none.color_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.depth_load_op_none_store_op_dontcare +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_load_store_op_none +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_none_write_off +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_store +dEQP-VK.renderpass2.suballocation.load_store_op_none.stencil_load_op_none_store_op_dontcare dEQP-VK.renderpass2.dedicated_allocation.simple.color dEQP-VK.renderpass2.dedicated_allocation.simple.depth dEQP-VK.renderpass2.dedicated_allocation.simple.stencil -- 2.7.4