| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2015 The Khronos Group Inc. |
| * Copyright (c) 2015 Imagination Technologies Ltd. |
| * Copyright (c) 2017 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 Multisample Tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktPipelineMultisampleTests.hpp" |
| #include "vktPipelineMultisampleImageTests.hpp" |
| #include "vktPipelineMultisampleSampleLocationsExtTests.hpp" |
| #include "vktPipelineClearUtil.hpp" |
| #include "vktPipelineImageUtil.hpp" |
| #include "vktPipelineVertexUtil.hpp" |
| #include "vktPipelineReferenceRenderer.hpp" |
| #include "vktTestCase.hpp" |
| #include "vktTestCaseUtil.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vkMemUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "vkRef.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkCmdUtil.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkObjUtil.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuTestLog.hpp" |
| #include "deUniquePtr.hpp" |
| #include "deSharedPtr.hpp" |
| #include "deStringUtil.hpp" |
| #include "deMemory.h" |
| |
| #include <sstream> |
| #include <vector> |
| #include <map> |
| |
| namespace vkt |
| { |
| namespace pipeline |
| { |
| |
| using namespace vk; |
| |
| namespace |
| { |
| enum GeometryType |
| { |
| GEOMETRY_TYPE_OPAQUE_TRIANGLE, |
| GEOMETRY_TYPE_OPAQUE_LINE, |
| GEOMETRY_TYPE_OPAQUE_POINT, |
| GEOMETRY_TYPE_OPAQUE_QUAD, |
| GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH, //!< placed at z = 0.5 |
| GEOMETRY_TYPE_TRANSLUCENT_QUAD, |
| GEOMETRY_TYPE_INVISIBLE_TRIANGLE, |
| GEOMETRY_TYPE_INVISIBLE_QUAD, |
| GEOMETRY_TYPE_GRADIENT_QUAD |
| }; |
| |
| enum TestModeBits |
| { |
| TEST_MODE_DEPTH_BIT = 1u, |
| TEST_MODE_STENCIL_BIT = 2u, |
| }; |
| typedef deUint32 TestModeFlags; |
| |
| enum RenderType |
| { |
| // resolve multisample rendering to single sampled image |
| RENDER_TYPE_RESOLVE = 0u, |
| |
| // copy samples to an array of single sampled images |
| RENDER_TYPE_COPY_SAMPLES = 1u, |
| |
| // render first with only depth/stencil and then with color + depth/stencil |
| RENDER_TYPE_DEPTHSTENCIL_ONLY = 2u, |
| |
| // render using color attachment at location 1 and location 0 set as unused |
| RENDER_TYPE_UNUSED_ATTACHMENT = 3u |
| }; |
| |
| enum ImageBackingMode |
| { |
| IMAGE_BACKING_MODE_REGULAR = 0u, |
| IMAGE_BACKING_MODE_SPARSE |
| }; |
| |
| struct MultisampleTestParams |
| { |
| GeometryType geometryType; |
| float pointSize; |
| ImageBackingMode backingMode; |
| }; |
| |
| void checkLargePointsSupport (Context& context, VkPrimitiveTopology topology, float pointSize) |
| { |
| if (topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && pointSize > 1.0f && !context.getDeviceFeatures().largePoints) |
| TCU_THROW(NotSupportedError, "Large points feature not supported."); |
| } |
| |
| void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params); |
| bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples); |
| bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format); |
| VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void); |
| deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image); |
| VkImageAspectFlags getImageAspectFlags (const VkFormat format); |
| VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType); |
| std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType); |
| VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil); |
| |
| class MultisampleTest : public vkt::TestCase |
| { |
| public: |
| |
| MultisampleTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode); |
| virtual ~MultisampleTest (void) {} |
| |
| virtual void initPrograms (SourceCollections& programCollection) const; |
| virtual TestInstance* createInstance (Context& context) const; |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const = 0; |
| VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const GeometryType m_geometryType; |
| const float m_pointSize; |
| const ImageBackingMode m_backingMode; |
| std::vector<VkSampleMask> m_sampleMask; |
| }; |
| |
| class RasterizationSamplesTest : public MultisampleTest |
| { |
| public: |
| RasterizationSamplesTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode, |
| TestModeFlags modeFlags = 0u); |
| virtual ~RasterizationSamplesTest (void) {} |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples); |
| |
| const ImageBackingMode m_backingMode; |
| const TestModeFlags m_modeFlags; |
| }; |
| |
| class MinSampleShadingTest : public MultisampleTest |
| { |
| public: |
| MinSampleShadingTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| float minSampleShading, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode); |
| virtual ~MinSampleShadingTest (void) {} |
| |
| protected: |
| virtual void initPrograms (SourceCollections& programCollection) const; |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading); |
| |
| const float m_pointSize; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class SampleMaskTest : public MultisampleTest |
| { |
| public: |
| SampleMaskTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| const std::vector<VkSampleMask>& sampleMask, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode); |
| |
| virtual ~SampleMaskTest (void) {} |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask); |
| |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToOneTest : public MultisampleTest |
| { |
| public: |
| AlphaToOneTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| ImageBackingMode backingMode); |
| |
| virtual ~AlphaToOneTest (void) {} |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples); |
| static VkPipelineColorBlendAttachmentState getAlphaToOneBlendState (void); |
| |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageTest : public MultisampleTest |
| { |
| public: |
| AlphaToCoverageTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| |
| virtual ~AlphaToCoverageTest (void) {} |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples); |
| |
| GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest |
| { |
| public: |
| AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| |
| virtual ~AlphaToCoverageNoColorAttachmentTest (void) {} |
| |
| protected: |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples); |
| |
| GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest |
| { |
| public: |
| AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| |
| virtual ~AlphaToCoverageColorUnusedAttachmentTest (void) {} |
| |
| protected: |
| virtual void initPrograms (SourceCollections& programCollection) const; |
| |
| virtual TestInstance* createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const; |
| |
| static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples); |
| |
| GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class SampleMaskWithDepthTestTest : public vkt::TestCase |
| { |
| public: |
| SampleMaskWithDepthTestTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| const VkSampleCountFlagBits rasterizationSamples, |
| const bool enablePostDepthCoverage = false); |
| |
| ~SampleMaskWithDepthTestTest (void) {} |
| |
| void initPrograms (SourceCollections& programCollection) const; |
| TestInstance* createInstance (Context& context) const; |
| private: |
| const VkSampleCountFlagBits m_rasterizationSamples; |
| const bool m_enablePostDepthCoverage; |
| }; |
| |
| typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp; |
| |
| class MultisampleRenderer |
| { |
| public: |
| MultisampleRenderer (Context& context, |
| const VkFormat colorFormat, |
| const tcu::IVec2& renderSize, |
| const VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const RenderType renderType, |
| const ImageBackingMode backingMode); |
| |
| MultisampleRenderer (Context& context, |
| const VkFormat colorFormat, |
| const VkFormat depthStencilFormat, |
| const tcu::IVec2& renderSize, |
| const bool useDepth, |
| const bool useStencil, |
| const deUint32 numTopologies, |
| const VkPrimitiveTopology* pTopology, |
| const std::vector<Vertex4RGBA>* pVertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const RenderType renderType, |
| const ImageBackingMode backingMode, |
| const float depthClearValue = 1.0f); |
| |
| virtual ~MultisampleRenderer (void); |
| |
| de::MovePtr<tcu::TextureLevel> render (void); |
| de::MovePtr<tcu::TextureLevel> getSingleSampledImage (deUint32 sampleId); |
| |
| protected: |
| void initialize (Context& context, |
| const deUint32 numTopologies, |
| const VkPrimitiveTopology* pTopology, |
| const std::vector<Vertex4RGBA>* pVertices); |
| |
| Context& m_context; |
| |
| const Unique<VkSemaphore> m_bindSemaphore; |
| |
| const VkFormat m_colorFormat; |
| const VkFormat m_depthStencilFormat; |
| tcu::IVec2 m_renderSize; |
| const bool m_useDepth; |
| const bool m_useStencil; |
| |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| |
| const RenderType m_renderType; |
| |
| Move<VkImage> m_colorImage; |
| de::MovePtr<Allocation> m_colorImageAlloc; |
| Move<VkImageView> m_colorAttachmentView; |
| |
| Move<VkImage> m_resolveImage; |
| de::MovePtr<Allocation> m_resolveImageAlloc; |
| Move<VkImageView> m_resolveAttachmentView; |
| |
| struct PerSampleImage |
| { |
| Move<VkImage> m_image; |
| de::MovePtr<Allocation> m_imageAlloc; |
| Move<VkImageView> m_attachmentView; |
| }; |
| std::vector<de::SharedPtr<PerSampleImage> > m_perSampleImages; |
| |
| Move<VkImage> m_depthStencilImage; |
| de::MovePtr<Allocation> m_depthStencilImageAlloc; |
| Move<VkImageView> m_depthStencilAttachmentView; |
| |
| Move<VkRenderPass> m_renderPass; |
| Move<VkFramebuffer> m_framebuffer; |
| |
| Move<VkShaderModule> m_vertexShaderModule; |
| Move<VkShaderModule> m_fragmentShaderModule; |
| |
| Move<VkShaderModule> m_copySampleVertexShaderModule; |
| Move<VkShaderModule> m_copySampleFragmentShaderModule; |
| |
| Move<VkBuffer> m_vertexBuffer; |
| de::MovePtr<Allocation> m_vertexBufferAlloc; |
| |
| Move<VkPipelineLayout> m_pipelineLayout; |
| std::vector<VkPipelineSp> m_graphicsPipelines; |
| |
| Move<VkDescriptorSetLayout> m_copySampleDesciptorLayout; |
| Move<VkDescriptorPool> m_copySampleDesciptorPool; |
| Move<VkDescriptorSet> m_copySampleDesciptorSet; |
| |
| Move<VkPipelineLayout> m_copySamplePipelineLayout; |
| std::vector<VkPipelineSp> m_copySamplePipelines; |
| |
| Move<VkCommandPool> m_cmdPool; |
| Move<VkCommandBuffer> m_cmdBuffer; |
| |
| std::vector<de::SharedPtr<Allocation> > m_allocations; |
| |
| ImageBackingMode m_backingMode; |
| const float m_depthClearValue; |
| }; |
| |
| class RasterizationSamplesInstance : public vkt::TestInstance |
| { |
| public: |
| RasterizationSamplesInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const TestModeFlags modeFlags, |
| ImageBackingMode backingMode); |
| virtual ~RasterizationSamplesInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); |
| |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const float m_pointSize; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const std::vector<Vertex4RGBA> m_fullQuadVertices; //!< used by depth/stencil case |
| const TestModeFlags m_modeFlags; |
| de::MovePtr<MultisampleRenderer> m_multisampleRenderer; |
| }; |
| |
| class MinSampleShadingInstance : public vkt::TestInstance |
| { |
| public: |
| MinSampleShadingInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| ImageBackingMode backingMode); |
| virtual ~MinSampleShadingInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& testShadingImages, |
| const tcu::ConstPixelBufferAccess& noSampleshadingImage); |
| |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class SampleMaskInstance : public vkt::TestInstance |
| { |
| public: |
| SampleMaskInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| ImageBackingMode backingMode); |
| virtual ~SampleMaskInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, |
| const tcu::ConstPixelBufferAccess& minShadingImage, |
| const tcu::ConstPixelBufferAccess& maxShadingImage); |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToOneInstance : public vkt::TestInstance |
| { |
| public: |
| AlphaToOneInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| ImageBackingMode backingMode); |
| virtual ~AlphaToOneInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, |
| const tcu::ConstPixelBufferAccess& noAlphaOneImage); |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageInstance : public vkt::TestInstance |
| { |
| public: |
| AlphaToCoverageInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| virtual ~AlphaToCoverageInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance |
| { |
| public: |
| AlphaToCoverageNoColorAttachmentInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| virtual ~AlphaToCoverageNoColorAttachmentInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); |
| const VkFormat m_colorFormat; |
| const VkFormat m_depthStencilFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance |
| { |
| public: |
| AlphaToCoverageColorUnusedAttachmentInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode); |
| virtual ~AlphaToCoverageColorUnusedAttachmentInstance (void) {} |
| |
| virtual tcu::TestStatus iterate (void); |
| |
| protected: |
| virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); |
| const VkFormat m_colorFormat; |
| const tcu::IVec2 m_renderSize; |
| const VkPrimitiveTopology m_primitiveTopology; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_colorBlendState; |
| const GeometryType m_geometryType; |
| const ImageBackingMode m_backingMode; |
| }; |
| |
| class SampleMaskWithDepthTestInstance : public vkt::TestInstance |
| { |
| public: |
| SampleMaskWithDepthTestInstance (Context& context, |
| const VkSampleCountFlagBits rasterizationSamples, |
| const bool enablePostDepthCoverage); |
| ~SampleMaskWithDepthTestInstance (void) {} |
| |
| tcu::TestStatus iterate (void); |
| |
| protected: |
| VkPipelineMultisampleStateCreateInfo getMultisampleState (const VkSampleCountFlagBits rasterizationSamples); |
| std::vector<Vertex4RGBA> generateVertices (void); |
| tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); |
| |
| struct SampleCoverage |
| { |
| SampleCoverage() {}; |
| SampleCoverage(deUint32 min_, deUint32 max_) |
| : min(min_), max(max_) {}; |
| |
| deUint32 min; |
| deUint32 max; |
| }; |
| |
| const VkSampleCountFlagBits m_rasterizationSamples; |
| const bool m_enablePostDepthCoverage; |
| const VkFormat m_colorFormat; |
| const VkFormat m_depthStencilFormat; |
| const tcu::IVec2 m_renderSize; |
| const bool m_useDepth; |
| const bool m_useStencil; |
| const VkPrimitiveTopology m_topology; |
| const tcu::Vec4 m_renderColor; |
| const std::vector<Vertex4RGBA> m_vertices; |
| const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; |
| const VkPipelineColorBlendAttachmentState m_blendState; |
| const RenderType m_renderType; |
| const ImageBackingMode m_imageBackingMode; |
| const float m_depthClearValue; |
| std::map<VkSampleCountFlagBits, SampleCoverage> m_refCoverageAfterDepthTest; |
| }; |
| |
| |
| // Helper functions |
| |
| void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params) |
| { |
| const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string(""); |
| std::ostringstream vertexSource; |
| |
| vertexSource << |
| "#version 310 es\n" |
| "layout(location = 0) in vec4 position;\n" |
| "layout(location = 1) in vec4 color;\n" |
| "layout(location = 0) out highp vec4 vtxColor;\n" |
| "void main (void)\n" |
| "{\n" |
| " gl_Position = position;\n" |
| " vtxColor = color;\n" |
| << pointSize |
| << "}\n"; |
| |
| static const char* fragmentSource = |
| "#version 310 es\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" |
| "}\n"; |
| |
| sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); |
| sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); |
| } |
| |
| void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params) |
| { |
| { |
| const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string(""); |
| std::ostringstream vertexSource; |
| |
| vertexSource << |
| "#version 440\n" |
| "layout(location = 0) in vec4 position;\n" |
| "layout(location = 1) in vec4 color;\n" |
| "void main (void)\n" |
| "{\n" |
| " gl_Position = position;\n" |
| << pointSize |
| << "}\n"; |
| |
| static const char* fragmentSource = |
| "#version 440\n" |
| "layout(location = 0) out highp vec4 fragColor;\n" |
| "void main (void)\n" |
| "{\n" |
| " fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n" |
| "}\n"; |
| |
| sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); |
| sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); |
| } |
| |
| { |
| static const char* vertexSource = |
| "#version 440\n" |
| "void main (void)\n" |
| "{\n" |
| " const vec4 positions[4] = vec4[4](\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0)\n" |
| " );\n" |
| " gl_Position = positions[gl_VertexIndex];\n" |
| "}\n"; |
| |
| static const char* fragmentSource = |
| "#version 440\n" |
| "precision highp float;\n" |
| "layout(location = 0) out highp vec4 fragColor;\n" |
| "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n" |
| "layout(push_constant) uniform PushConstantsBlock\n" |
| "{\n" |
| " int sampleId;\n" |
| "} pushConstants;\n" |
| "void main (void)\n" |
| "{\n" |
| " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n" |
| "}\n"; |
| |
| sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource); |
| sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource); |
| } |
| } |
| |
| void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources) |
| { |
| std::ostringstream vertexSource; |
| |
| vertexSource << |
| "#version 310 es\n" |
| "layout(location = 0) in vec4 position;\n" |
| "layout(location = 1) in vec4 color;\n" |
| "layout(location = 0) out highp vec4 vtxColor;\n" |
| "void main (void)\n" |
| "{\n" |
| " gl_Position = position;\n" |
| " vtxColor = color;\n" |
| "}\n"; |
| |
| // Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel. |
| static const char* fragmentSource = |
| "#version 310 es\n" |
| "layout(location = 0) in highp vec4 vtxColor;\n" |
| "layout(location = 0) out highp vec4 fragColor0;\n" |
| "layout(location = 1) out highp vec3 fragColor1;\n" |
| "void main (void)\n" |
| "{\n" |
| " fragColor0 = vtxColor;\n" |
| " fragColor1 = vtxColor.rgb;\n" |
| "}\n"; |
| |
| sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); |
| sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); |
| } |
| |
| bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples) |
| { |
| VkPhysicalDeviceProperties deviceProperties; |
| |
| instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties); |
| |
| return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples); |
| } |
| |
| VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void) |
| { |
| const VkPipelineColorBlendAttachmentState colorBlendState = |
| { |
| false, // VkBool32 blendEnable; |
| VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; |
| VK_BLEND_FACTOR_ZERO, // 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; |
| VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; |
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT |
| }; |
| |
| return colorBlendState; |
| } |
| |
| deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image) |
| { |
| DE_ASSERT(image.getFormat().getPixelSize() == 4); |
| |
| std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> |
| const deUint32 pixelCount = image.getWidth() * image.getHeight() * image.getDepth(); |
| |
| for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) |
| { |
| const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx); |
| |
| if (histogram.find(pixelValue) != histogram.end()) |
| histogram[pixelValue]++; |
| else |
| histogram[pixelValue] = 1; |
| } |
| |
| return (deUint32)histogram.size(); |
| } |
| |
| VkImageAspectFlags getImageAspectFlags (const VkFormat format) |
| { |
| const tcu::TextureFormat tcuFormat = mapVkFormat(format); |
| |
| if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; |
| else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; |
| else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; |
| |
| DE_ASSERT(false); |
| return 0u; |
| } |
| |
| std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType) |
| { |
| std::vector<Vertex4RGBA> vertices; |
| |
| switch (geometryType) |
| { |
| case GEOMETRY_TYPE_OPAQUE_TRIANGLE: |
| case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: |
| { |
| Vertex4RGBA vertexData[3] = |
| { |
| { |
| tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| } |
| }; |
| |
| if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE) |
| { |
| for (int i = 0; i < 3; i++) |
| vertexData[i].color = tcu::Vec4(); |
| } |
| |
| vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3); |
| break; |
| } |
| |
| case GEOMETRY_TYPE_OPAQUE_LINE: |
| { |
| const Vertex4RGBA vertexData[2] = |
| { |
| { |
| tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| } |
| }; |
| |
| vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2); |
| break; |
| } |
| |
| case GEOMETRY_TYPE_OPAQUE_POINT: |
| { |
| const Vertex4RGBA vertex = |
| { |
| tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }; |
| |
| vertices = std::vector<Vertex4RGBA>(1, vertex); |
| break; |
| } |
| |
| case GEOMETRY_TYPE_OPAQUE_QUAD: |
| case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: |
| case GEOMETRY_TYPE_TRANSLUCENT_QUAD: |
| case GEOMETRY_TYPE_INVISIBLE_QUAD: |
| case GEOMETRY_TYPE_GRADIENT_QUAD: |
| { |
| Vertex4RGBA vertexData[4] = |
| { |
| { |
| tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| } |
| }; |
| |
| if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD) |
| { |
| for (int i = 0; i < 4; i++) |
| vertexData[i].color.w() = 0.25f; |
| } |
| else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD) |
| { |
| for (int i = 0; i < 4; i++) |
| vertexData[i].color.w() = 0.0f; |
| } |
| else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD) |
| { |
| vertexData[0].color.w() = 0.0f; |
| vertexData[2].color.w() = 0.0f; |
| } |
| else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH) |
| { |
| for (int i = 0; i < 4; i++) |
| vertexData[i].position.z() = 0.5f; |
| } |
| |
| vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4); |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| } |
| return vertices; |
| } |
| |
| VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType) |
| { |
| switch (geometryType) |
| { |
| case GEOMETRY_TYPE_OPAQUE_TRIANGLE: |
| case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; |
| |
| case GEOMETRY_TYPE_OPAQUE_LINE: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; |
| case GEOMETRY_TYPE_OPAQUE_POINT: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; |
| |
| case GEOMETRY_TYPE_OPAQUE_QUAD: |
| case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: |
| case GEOMETRY_TYPE_TRANSLUCENT_QUAD: |
| case GEOMETRY_TYPE_INVISIBLE_QUAD: |
| case GEOMETRY_TYPE_GRADIENT_QUAD: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; |
| |
| default: |
| DE_ASSERT(false); |
| return VK_PRIMITIVE_TOPOLOGY_LAST; |
| } |
| } |
| |
| bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format) |
| { |
| VkFormatProperties formatProps; |
| vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps); |
| return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; |
| } |
| |
| VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil) |
| { |
| if (useDepth && !useStencil) |
| return VK_FORMAT_D16_UNORM; // must be supported |
| |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| const VkPhysicalDevice physDevice = context.getPhysicalDevice(); |
| |
| // One of these formats must be supported. |
| |
| if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT)) |
| return VK_FORMAT_D24_UNORM_S8_UINT; |
| |
| if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT)) |
| return VK_FORMAT_D32_SFLOAT_S8_UINT; |
| |
| return VK_FORMAT_UNDEFINED; |
| } |
| |
| |
| // MultisampleTest |
| |
| MultisampleTest::MultisampleTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode) |
| : vkt::TestCase (testContext, name, description) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_geometryType (geometryType) |
| , m_pointSize (pointSize) |
| , m_backingMode (backingMode) |
| { |
| if (m_multisampleStateParams.pSampleMask) |
| { |
| // Copy pSampleMask to avoid dependencies with other classes |
| |
| const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32); |
| |
| for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++) |
| m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]); |
| |
| m_multisampleStateParams.pSampleMask = m_sampleMask.data(); |
| } |
| } |
| |
| void MultisampleTest::initPrograms (SourceCollections& programCollection) const |
| { |
| MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode}; |
| initMultisamplePrograms(programCollection, params); |
| } |
| |
| TestInstance* MultisampleTest::createInstance (Context& context) const |
| { |
| return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState); |
| } |
| |
| |
| // RasterizationSamplesTest |
| |
| RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode, |
| TestModeFlags modeFlags) |
| : MultisampleTest (testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode) |
| , m_backingMode (backingMode) |
| , m_modeFlags (modeFlags) |
| { |
| } |
| |
| VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| return new RasterizationSamplesInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode); |
| } |
| |
| |
| // MinSampleShadingTest |
| |
| MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| float minSampleShading, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode) |
| , m_pointSize (pointSize) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const |
| { |
| MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode}; |
| initSampleShadingPrograms(programCollection, params); |
| } |
| |
| TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| true, // VkBool32 sampleShadingEnable; |
| minSampleShading, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| |
| // SampleMaskTest |
| |
| SampleMaskTest::SampleMaskTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| const std::vector<VkSampleMask>& sampleMask, |
| GeometryType geometryType, |
| float pointSize, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| TestInstance* SampleMaskTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| DE_UNREF(pointSize); |
| return new SampleMaskInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| sampleMask.data(), // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| |
| // AlphaToOneTest |
| |
| AlphaToOneTest::AlphaToOneTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode) |
| , m_backingMode(backingMode) |
| { |
| } |
| |
| TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| DE_UNREF(pointSize); |
| return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| true // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void) |
| { |
| const VkPipelineColorBlendAttachmentState colorBlendState = |
| { |
| true, // 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_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; |
| VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor; |
| VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; |
| VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; |
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT |
| }; |
| |
| return colorBlendState; |
| } |
| |
| |
| // AlphaToCoverageTest |
| |
| AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| DE_UNREF(pointSize); |
| return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| true, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| // AlphaToCoverageNoColorAttachmentTest |
| |
| AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| DE_UNREF(pointSize); |
| return new AlphaToCoverageNoColorAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| true, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| // AlphaToCoverageColorUnusedAttachmentTest |
| |
| AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| VkSampleCountFlagBits rasterizationSamples, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : MultisampleTest (testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const |
| { |
| initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection); |
| } |
| |
| TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState) const |
| { |
| DE_UNREF(pointSize); |
| return new AlphaToCoverageColorUnusedAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| true, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| // SampleMaskWithDepthTestTest |
| |
| SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext& testContext, |
| const std::string& name, |
| const std::string& description, |
| const VkSampleCountFlagBits rasterizationSamples, |
| const bool enablePostDepthCoverage) |
| : vkt::TestCase (testContext, name, description) |
| , m_rasterizationSamples (rasterizationSamples) |
| , m_enablePostDepthCoverage (enablePostDepthCoverage) |
| { |
| } |
| |
| void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const |
| { |
| DE_ASSERT((int)m_rasterizationSamples <= 32); |
| |
| static const char* vertexSource = |
| "#version 440\n" |
| "layout(location = 0) in vec4 position;\n" |
| "layout(location = 1) in vec4 color;\n" |
| "layout(location = 0) out vec4 vtxColor;\n" |
| "out gl_PerVertex\n" |
| "{\n" |
| " vec4 gl_Position;\n" |
| "};\n" |
| "\n" |
| "void main (void)\n" |
| "{\n" |
| " gl_Position = position;\n" |
| " vtxColor = color;\n" |
| "}\n"; |
| |
| std::ostringstream fragmentSource; |
| fragmentSource << |
| "#version 440\n" |
| << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") << |
| "layout(early_fragment_tests) in;\n" |
| << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") << |
| "layout(location = 0) in vec4 vtxColor;\n" |
| "layout(location = 0) out vec4 fragColor;\n" |
| "void main (void)\n" |
| "{\n" |
| " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n" |
| " fragColor = vtxColor * (1.0 / " << (int)m_rasterizationSamples << " * coveredSamples);\n" |
| "}\n"; |
| |
| programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource); |
| programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str()); |
| } |
| |
| TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const |
| { |
| return new SampleMaskWithDepthTestInstance(context, m_rasterizationSamples, m_enablePostDepthCoverage); |
| } |
| |
| // RasterizationSamplesInstance |
| |
| RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const TestModeFlags modeFlags, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_pointSize (pointSize) |
| , m_vertices (vertices) |
| , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)) |
| , m_modeFlags (modeFlags) |
| { |
| checkLargePointsSupport(context, topology, pointSize); |
| |
| if (m_modeFlags != 0) |
| { |
| const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0; |
| const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0; |
| const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil); |
| |
| if (depthStencilFormat == VK_FORMAT_UNDEFINED) |
| TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported"); |
| |
| const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }; |
| const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices }; |
| |
| m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( |
| new MultisampleRenderer( |
| context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode)); |
| } |
| else |
| { |
| m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( |
| new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode)); |
| } |
| } |
| |
| tcu::TestStatus RasterizationSamplesInstance::iterate (void) |
| { |
| de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render()); |
| return verifyImage(level->getAccess()); |
| } |
| |
| tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) |
| { |
| // Verify range of unique pixels |
| { |
| const deUint32 numUniqueColors = getUniqueColorsCount(result); |
| const deUint32 minUniqueColors = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3; |
| |
| tcu::TestLog& log = m_context.getTestContext().getLog(); |
| |
| log << tcu::TestLog::Message |
| << "\nMin. unique colors expected: " << minUniqueColors << "\n" |
| << "Unique colors found: " << numUniqueColors << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| if (numUniqueColors < minUniqueColors) |
| return tcu::TestStatus::fail("Unique colors out of expected bounds"); |
| } |
| |
| // Verify shape of the rendered primitive (fuzzy-compare) |
| { |
| const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); |
| const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); |
| const ColorVertexShader vertexShader; |
| const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); |
| const rr::Program program (&vertexShader, &fragmentShader); |
| ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); |
| rr::RenderState renderState (refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits); |
| |
| if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) |
| { |
| VkPhysicalDeviceProperties deviceProperties; |
| |
| m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties); |
| |
| // gl_PointSize is clamped to pointSizeRange |
| renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]); |
| } |
| |
| if (m_modeFlags == 0) |
| { |
| refRenderer.colorClear(tcu::Vec4(0.0f)); |
| refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); |
| } |
| else |
| { |
| // For depth/stencil case the primitive is invisible and the surroundings are filled red. |
| refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); |
| } |
| |
| if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT)) |
| return tcu::TestStatus::fail("Primitive has unexpected shape"); |
| } |
| |
| return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds"); |
| } |
| |
| |
| // MinSampleShadingInstance |
| |
| MinSampleShadingInstance::MinSampleShadingInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& colorBlendState, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (colorBlendState) |
| , m_backingMode (backingMode) |
| { |
| checkLargePointsSupport(context, topology, pointSize); |
| |
| VkPhysicalDeviceFeatures deviceFeatures; |
| |
| m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures); |
| |
| if (!deviceFeatures.sampleRateShading) |
| throw tcu::NotSupportedError("Sample shading is not supported"); |
| } |
| |
| tcu::TestStatus MinSampleShadingInstance::iterate (void) |
| { |
| de::MovePtr<tcu::TextureLevel> noSampleshadingImage; |
| std::vector<tcu::TextureLevel> sampleShadedImages; |
| |
| // Render and resolve without sample shading |
| { |
| VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams; |
| multisampleStateParms.sampleShadingEnable = VK_FALSE; |
| multisampleStateParms.minSampleShading = 0.0; |
| |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| noSampleshadingImage = renderer.render(); |
| } |
| |
| // Render with test minSampleShading and collect per-sample images |
| { |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode); |
| renderer.render(); |
| |
| sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples); |
| for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) |
| { |
| sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId); |
| } |
| } |
| |
| // Log images |
| { |
| tcu::TestLog& testLog = m_context.getTestContext().getLog(); |
| |
| testLog << tcu::TestLog::ImageSet("Images", "Images") |
| << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess()); |
| |
| for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) |
| { |
| testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess()); |
| } |
| testLog << tcu::TestLog::EndImageSet; |
| } |
| |
| return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess()); |
| } |
| |
| tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage) |
| { |
| const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth(); |
| |
| bool anyPixelCovered = false; |
| |
| for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) |
| { |
| const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx); |
| |
| if (noSampleShadingValue == 0) |
| { |
| // non-covered pixel, continue |
| continue; |
| } |
| else |
| { |
| anyPixelCovered = true; |
| } |
| |
| int numNotCoveredSamples = 0; |
| |
| std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> |
| |
| // Collect histogram of occurrences or each pixel across all samples |
| for (size_t i = 0; i < sampleShadedImages.size(); ++i) |
| { |
| const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx); |
| |
| if (sampleShadedValue == 0) |
| { |
| numNotCoveredSamples++; |
| continue; |
| } |
| |
| if (histogram.find(sampleShadedValue) != histogram.end()) |
| histogram[sampleShadedValue]++; |
| else |
| histogram[sampleShadedValue] = 1; |
| } |
| |
| if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size())) |
| { |
| return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected"); |
| } |
| |
| const int uniqueColorsCount = (int)histogram.size(); |
| const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f); |
| |
| if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount) |
| { |
| return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading"); |
| } |
| } |
| |
| if (!anyPixelCovered) |
| { |
| return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading"); |
| } |
| |
| return tcu::TestStatus::pass("Got proper count of unique colors"); |
| } |
| |
| SampleMaskInstance::SampleMaskInstance (Context& context, |
| VkPrimitiveTopology topology, |
| float pointSize, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_backingMode (backingMode) |
| { |
| checkLargePointsSupport(context, topology, pointSize); |
| } |
| |
| tcu::TestStatus SampleMaskInstance::iterate (void) |
| { |
| de::MovePtr<tcu::TextureLevel> testSampleMaskImage; |
| de::MovePtr<tcu::TextureLevel> minSampleMaskImage; |
| de::MovePtr<tcu::TextureLevel> maxSampleMaskImage; |
| |
| // Render with test flags |
| { |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| testSampleMaskImage = renderer.render(); |
| } |
| |
| // Render with all flags off |
| { |
| VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; |
| const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0); |
| |
| multisampleParams.pSampleMask = sampleMask.data(); |
| |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| minSampleMaskImage = renderer.render(); |
| } |
| |
| // Render with all flags on |
| { |
| VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; |
| const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0)); |
| |
| multisampleParams.pSampleMask = sampleMask.data(); |
| |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| maxSampleMaskImage = renderer.render(); |
| } |
| |
| return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess()); |
| } |
| |
| tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage, |
| const tcu::ConstPixelBufferAccess& minSampleMaskImage, |
| const tcu::ConstPixelBufferAccess& maxSampleMaskImage) |
| { |
| const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage); |
| const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage); |
| const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage); |
| |
| tcu::TestLog& log = m_context.getTestContext().getLog(); |
| |
| log << tcu::TestLog::Message |
| << "\nColors found: " << testColorCount << "\n" |
| << "Min. colors expected: " << minColorCount << "\n" |
| << "Max. colors expected: " << maxColorCount << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| if (minColorCount > testColorCount || testColorCount > maxColorCount) |
| return tcu::TestStatus::fail("Unique colors out of expected bounds"); |
| else |
| return tcu::TestStatus::pass("Unique colors within expected bounds"); |
| } |
| |
| tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params) |
| { |
| const VkSampleCountFlagBits samples[] = |
| { |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_SAMPLE_COUNT_2_BIT, |
| VK_SAMPLE_COUNT_4_BIT, |
| VK_SAMPLE_COUNT_8_BIT, |
| VK_SAMPLE_COUNT_16_BIT, |
| VK_SAMPLE_COUNT_32_BIT, |
| VK_SAMPLE_COUNT_64_BIT |
| }; |
| |
| const Vertex4RGBA vertexData[3] = |
| { |
| { |
| tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| }, |
| { |
| tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) |
| } |
| }; |
| |
| const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3); |
| deUint32 prevUniqueColors = 2; |
| int renderCount = 0; |
| |
| // Do not render with 1 sample (start with samplesNdx = 1). |
| for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) |
| { |
| if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx])) |
| continue; |
| |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode); |
| de::MovePtr<tcu::TextureLevel> result = renderer.render(); |
| const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess()); |
| |
| renderCount++; |
| |
| if (prevUniqueColors > uniqueColors) |
| { |
| std::ostringstream message; |
| |
| message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx]; |
| return tcu::TestStatus::fail(message.str()); |
| } |
| |
| prevUniqueColors = uniqueColors; |
| } |
| |
| if (renderCount == 0) |
| throw tcu::NotSupportedError("Multisampling is unsupported"); |
| |
| return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases"); |
| } |
| |
| |
| // AlphaToOneInstance |
| |
| AlphaToOneInstance::AlphaToOneInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_backingMode (backingMode) |
| { |
| VkPhysicalDeviceFeatures deviceFeatures; |
| |
| context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures); |
| |
| if (!deviceFeatures.alphaToOne) |
| throw tcu::NotSupportedError("Alpha-to-one is not supported"); |
| } |
| |
| tcu::TestStatus AlphaToOneInstance::iterate (void) |
| { |
| DE_ASSERT(m_multisampleStateParams.alphaToOneEnable); |
| DE_ASSERT(m_colorBlendState.blendEnable); |
| |
| de::MovePtr<tcu::TextureLevel> alphaOneImage; |
| de::MovePtr<tcu::TextureLevel> noAlphaOneImage; |
| |
| // Render with blend enabled and alpha to one on |
| { |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| alphaOneImage = renderer.render(); |
| } |
| |
| // Render with blend enabled and alpha to one off |
| { |
| VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; |
| multisampleParams.alphaToOneEnable = false; |
| |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| noAlphaOneImage = renderer.render(); |
| } |
| |
| return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess()); |
| } |
| |
| tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, |
| const tcu::ConstPixelBufferAccess& noAlphaOneImage) |
| { |
| for (int y = 0; y < m_renderSize.y(); y++) |
| { |
| for (int x = 0; x < m_renderSize.x(); x++) |
| { |
| if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y)))) |
| { |
| std::ostringstream message; |
| message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y); |
| return tcu::TestStatus::fail(message.str()); |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one"); |
| } |
| |
| |
| // AlphaToCoverageInstance |
| |
| AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| tcu::TestStatus AlphaToCoverageInstance::iterate (void) |
| { |
| DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); |
| |
| de::MovePtr<tcu::TextureLevel> result; |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode); |
| |
| result = renderer.render(); |
| |
| return verifyImage(result->getAccess()); |
| } |
| |
| tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) |
| { |
| float maxColorValue; |
| |
| switch (m_geometryType) |
| { |
| case GEOMETRY_TYPE_OPAQUE_QUAD: |
| maxColorValue = 1.01f; |
| break; |
| |
| case GEOMETRY_TYPE_TRANSLUCENT_QUAD: |
| maxColorValue = 0.52f; |
| break; |
| |
| case GEOMETRY_TYPE_INVISIBLE_QUAD: |
| maxColorValue = 0.01f; |
| break; |
| |
| default: |
| maxColorValue = 0.0f; |
| DE_ASSERT(false); |
| } |
| |
| for (int y = 0; y < m_renderSize.y(); y++) |
| { |
| for (int x = 0; x < m_renderSize.x(); x++) |
| { |
| if (result.getPixel(x, y).x() > maxColorValue) |
| { |
| std::ostringstream message; |
| message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")"; |
| return tcu::TestStatus::fail(message.str()); |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("Image matches reference value"); |
| } |
| |
| // AlphaToCoverageNoColorAttachmentInstance |
| |
| AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_depthStencilFormat (VK_FORMAT_D16_UNORM) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void) |
| { |
| DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); |
| |
| de::MovePtr<tcu::TextureLevel> result; |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, 1.0f); |
| |
| result = renderer.render(); |
| |
| return verifyImage(result->getAccess()); |
| } |
| |
| tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) |
| { |
| for (int y = 0; y < m_renderSize.y(); y++) |
| { |
| for (int x = 0; x < m_renderSize.x(); x++) |
| { |
| // Expect full red for each pixel. Fail if clear color is showing. |
| if (result.getPixel(x, y).x() < 1.0f) |
| { |
| // Log result image when failing. |
| m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet; |
| |
| return tcu::TestStatus::fail("Fail"); |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| // AlphaToCoverageColorUnusedAttachmentInstance |
| |
| AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context& context, |
| VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| GeometryType geometryType, |
| ImageBackingMode backingMode) |
| : vkt::TestInstance (context) |
| , m_colorFormat (VK_FORMAT_R5G6B5_UNORM_PACK16) |
| , m_renderSize (32, 32) |
| , m_primitiveTopology (topology) |
| , m_vertices (vertices) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_geometryType (geometryType) |
| , m_backingMode (backingMode) |
| { |
| } |
| |
| tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void) |
| { |
| DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); |
| |
| de::MovePtr<tcu::TextureLevel> result; |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode); |
| |
| result = renderer.render(); |
| |
| return verifyImage(result->getAccess()); |
| } |
| |
| tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) |
| { |
| for (int y = 0; y < m_renderSize.y(); y++) |
| { |
| for (int x = 0; x < m_renderSize.x(); x++) |
| { |
| // Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused. |
| // The coverage should still be affected by the alpha written to location 0. |
| if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f) |
| || (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f)) |
| { |
| // Log result image when failing. |
| m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet; |
| |
| return tcu::TestStatus::fail("Fail"); |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| // SampleMaskWithDepthTestInstance |
| |
| SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context& context, |
| const VkSampleCountFlagBits rasterizationSamples, |
| const bool enablePostDepthCoverage) |
| : vkt::TestInstance (context) |
| , m_rasterizationSamples (rasterizationSamples) |
| , m_enablePostDepthCoverage (enablePostDepthCoverage) |
| , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) |
| , m_depthStencilFormat (VK_FORMAT_D16_UNORM) |
| , m_renderSize (tcu::IVec2(3, 3)) |
| , m_useDepth (true) |
| , m_useStencil (false) |
| , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) |
| , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) |
| , m_vertices (generateVertices()) |
| , m_multisampleStateParams (getMultisampleState(rasterizationSamples)) |
| , m_blendState (getDefaultColorBlendAttachmentState()) |
| , m_renderType (RENDER_TYPE_RESOLVE) |
| , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR) |
| , m_depthClearValue (0.667f) |
| { |
| if (!m_context.getDeviceProperties().limits.standardSampleLocations) |
| TCU_THROW(NotSupportedError, "standardSampleLocations required"); |
| |
| std::vector<VkExtensionProperties> supportedExtensions = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL); |
| |
| if (!isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_post_depth_coverage"))) |
| TCU_THROW(NotSupportedError, "VK_EXT_post_depth_coverage not supported"); |
| |
| m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT] = SampleCoverage(1u, 1u); // !< Sample coverage of the diagonally halved pixel, |
| m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT] = SampleCoverage(2u, 2u); // !< with max possible subPixelPrecisionBits threshold |
| m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT] = SampleCoverage(2u, 6u); // !< |
| m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT] = SampleCoverage(6u, 11u); // !< |
| } |
| |
| tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void) |
| { |
| de::MovePtr<tcu::TextureLevel> result; |
| |
| MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology, |
| &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue); |
| result = renderer.render(); |
| |
| return verifyImage(result->getAccess()); |
| } |
| |
| VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples) |
| { |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; |
| false, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| false, // VkBool32 alphaToCoverageEnable; |
| false // VkBool32 alphaToOneEnable; |
| }; |
| |
| return multisampleStateParams; |
| } |
| |
| std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void) |
| { |
| std::vector<Vertex4RGBA> vertices; |
| |
| { |
| const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor }; |
| vertices.push_back(vertexInput); |
| } |
| { |
| const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor }; |
| vertices.push_back(vertexInput); |
| } |
| { |
| const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), m_renderColor }; |
| vertices.push_back(vertexInput); |
| } |
| |
| return vertices; |
| } |
| |
| tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) |
| { |
| bool pass = true; |
| const int width = result.getWidth(); |
| const int height = result.getHeight(); |
| tcu::TestLog& log = m_context.getTestContext().getLog(); |
| |
| DE_ASSERT(width == 3); |
| DE_ASSERT(height == 3); |
| |
| const tcu::Vec4 clearColor = tcu::Vec4(0.0f); |
| |
| for (int x = 0; x < width; ++x) |
| for (int y = 0; y < height; ++y) |
| { |
| const tcu::Vec4 resultPixel = result.getPixel(x, y); |
| |
| if (x + y == 0) |
| { |
| if (resultPixel != m_renderColor) |
| { |
| log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel |
| << " Reference: " << m_renderColor << tcu::TestLog::EndMessage; |
| pass = false; |
| } |
| } |
| else if (x + y == 1) |
| { |
| // default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test) |
| // post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test) |
| const float threshold = 0.02f; |
| const float minCoverage = (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f) |
| * ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples); |
| const float maxCoverage = (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f) |
| * ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples); |
| |
| bool localPass = true; |
| for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx) |
| { |
| if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold) |
| || resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold))) |
| localPass = false; |
| } |
| |
| if (!localPass) |
| { |
| log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel |
| << " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage; |
| pass = false; |
| } |
| } |
| else |
| { |
| if (resultPixel != clearColor) |
| { |
| log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel |
| << " Reference: " << clearColor << tcu::TestLog::EndMessage; |
| pass = false; |
| } |
| } |
| } |
| |
| if (pass) |
| return tcu::TestStatus::pass("Passed"); |
| else |
| return tcu::TestStatus::fail("Failed"); |
| } |
| |
| // MultisampleRenderer |
| |
| MultisampleRenderer::MultisampleRenderer (Context& context, |
| const VkFormat colorFormat, |
| const tcu::IVec2& renderSize, |
| const VkPrimitiveTopology topology, |
| const std::vector<Vertex4RGBA>& vertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const RenderType renderType, |
| const ImageBackingMode backingMode) |
| : m_context (context) |
| , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice())) |
| , m_colorFormat (colorFormat) |
| , m_depthStencilFormat (VK_FORMAT_UNDEFINED) |
| , m_renderSize (renderSize) |
| , m_useDepth (false) |
| , m_useStencil (false) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_renderType (renderType) |
| , m_backingMode (backingMode) |
| , m_depthClearValue (1.0f) |
| { |
| initialize(context, 1u, &topology, &vertices); |
| } |
| |
| MultisampleRenderer::MultisampleRenderer (Context& context, |
| const VkFormat colorFormat, |
| const VkFormat depthStencilFormat, |
| const tcu::IVec2& renderSize, |
| const bool useDepth, |
| const bool useStencil, |
| const deUint32 numTopologies, |
| const VkPrimitiveTopology* pTopology, |
| const std::vector<Vertex4RGBA>* pVertices, |
| const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, |
| const VkPipelineColorBlendAttachmentState& blendState, |
| const RenderType renderType, |
| const ImageBackingMode backingMode, |
| const float depthClearValue) |
| : m_context (context) |
| , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice())) |
| , m_colorFormat (colorFormat) |
| , m_depthStencilFormat (depthStencilFormat) |
| , m_renderSize (renderSize) |
| , m_useDepth (useDepth) |
| , m_useStencil (useStencil) |
| , m_multisampleStateParams (multisampleStateParams) |
| , m_colorBlendState (blendState) |
| , m_renderType (renderType) |
| , m_backingMode (backingMode) |
| , m_depthClearValue (depthClearValue) |
| { |
| initialize(context, numTopologies, pTopology, pVertices); |
| } |
| |
| void MultisampleRenderer::initialize (Context& context, |
| const deUint32 numTopologies, |
| const VkPrimitiveTopology* pTopology, |
| const std::vector<Vertex4RGBA>* pVertices) |
| { |
| if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples)) |
| throw tcu::NotSupportedError("Unsupported number of rasterization samples"); |
| |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice vkDevice = context.getDevice(); |
| const VkPhysicalDeviceFeatures features = context.getDeviceFeatures(); |
| const deUint32 queueFamilyIndices[] = { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() }; |
| const bool sparse = m_backingMode == IMAGE_BACKING_MODE_SPARSE; |
| const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; |
| const VkImageCreateFlags imageCreateFlags = sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u; |
| const VkSharingMode sharingMode = (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; |
| Allocator& memAlloc = m_context.getDefaultAllocator(); |
| const bool usesResolveImage = m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT; |
| |
| if (sparse) |
| { |
| bool sparseSamplesSupported = false; |
| switch(m_multisampleStateParams.rasterizationSamples) |
| { |
| case VK_SAMPLE_COUNT_2_BIT: |
| sparseSamplesSupported = features.sparseResidency2Samples; |
| break; |
| case VK_SAMPLE_COUNT_4_BIT: |
| sparseSamplesSupported = features.sparseResidency4Samples; |
| break; |
| case VK_SAMPLE_COUNT_8_BIT: |
| sparseSamplesSupported = features.sparseResidency8Samples; |
| break; |
| case VK_SAMPLE_COUNT_16_BIT: |
| sparseSamplesSupported = features.sparseResidency16Samples; |
| break; |
| default: |
| break; |
| } |
| |
| if (!sparseSamplesSupported) |
| throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency"); |
| } |
| |
| if (sparse && !context.getDeviceFeatures().sparseBinding) |
| throw tcu::NotSupportedError("No sparseBinding support"); |
| |
| // Create color image |
| { |
| const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | |
| (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u); |
| |
| const VkImageCreateInfo colorImageParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| imageCreateFlags, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| m_colorFormat, // VkFormat format; |
| { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; |
| 1u, // deUint32 mipLevels; |
| 1u, // deUint32 arrayLayers; |
| m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| imageUsageFlags, // VkImageUsageFlags usage; |
| sharingMode, // VkSharingMode sharingMode; |
| sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // deUint32 queueFamilyIndexCount; |
| queueFamilyIndices, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; |
| }; |
| |
| if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams)) |
| TCU_THROW(NotSupportedError, "The image format does not support sparse operations."); |
| |
| m_colorImage = createImage(vk, vkDevice, &colorImageParams); |
| |
| // Allocate and bind color image memory |
| if (sparse) |
| { |
| allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage); |
| } |
| else |
| { |
| m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); |
| VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); |
| } |
| } |
| |
| // Create resolve image |
| if (usesResolveImage) |
| { |
| const VkImageCreateInfo resolveImageParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| m_colorFormat, // VkFormat format; |
| { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; |
| 1u, // deUint32 mipLevels; |
| 1u, // deUint32 arrayLayers; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT, |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1u, // deUint32 queueFamilyIndexCount; |
| queueFamilyIndices, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; |
| }; |
| |
| m_resolveImage = createImage(vk, vkDevice, &resolveImageParams); |
| |
| // Allocate and bind resolve image memory |
| m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any); |
| VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset())); |
| |
| // Create resolve attachment view |
| { |
| const VkImageViewCreateInfo resolveAttachmentViewParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageViewCreateFlags flags; |
| *m_resolveImage, // VkImage image; |
| VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; |
| m_colorFormat, // VkFormat format; |
| componentMappingRGBA, // VkComponentMapping components; |
| { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; |
| }; |
| |
| m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams); |
| } |
| } |
| |
| // Create per-sample output images |
| if (m_renderType == RENDER_TYPE_COPY_SAMPLES) |
| { |
| const VkImageCreateInfo perSampleImageParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| m_colorFormat, // VkFormat format; |
| { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; |
| 1u, // deUint32 mipLevels; |
| 1u, // deUint32 arrayLayers; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT, |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1u, // deUint32 queueFamilyIndexCount; |
| queueFamilyIndices, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; |
| }; |
| |
| m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples)); |
| |
| for (size_t i = 0; i < m_perSampleImages.size(); ++i) |
| { |
| m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage); |
| PerSampleImage& image = *m_perSampleImages[i]; |
| |
| image.m_image = createImage(vk, vkDevice, &perSampleImageParams); |
| |
| // Allocate and bind image memory |
| image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any); |
| VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset())); |
| |
| // Create per-sample attachment view |
| { |
| const VkImageViewCreateInfo perSampleAttachmentViewParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageViewCreateFlags flags; |
| *image.m_image, // VkImage image; |
| VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; |
| m_colorFormat, // VkFormat format; |
| componentMappingRGBA, // VkComponentMapping components; |
| { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; |
| }; |
| |
| image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams); |
| } |
| } |
| } |
| |
| // Create a depth/stencil image |
| if (m_useDepth || m_useStencil) |
| { |
| const VkImageCreateInfo depthStencilImageParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| m_depthStencilFormat, // VkFormat format; |
| { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; |
| 1u, // deUint32 mipLevels; |
| 1u, // deUint32 arrayLayers; |
| m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1u, // deUint32 queueFamilyIndexCount; |
| queueFamilyIndices, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; |
| }; |
| |
| m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams); |
| |
| // Allocate and bind depth/stencil image memory |
| m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any); |
| VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset())); |
| } |
| |
| // Create color attachment view |
| { |
| const VkImageViewCreateInfo colorAttachmentViewParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageViewCreateFlags flags; |
| *m_colorImage, // VkImage image; |
| VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; |
| m_colorFormat, // VkFormat format; |
| componentMappingRGBA, // VkComponentMapping components; |
| { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; |
| }; |
| |
| m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); |
| } |
| |
| VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0; |
| |
| // Create depth/stencil attachment view |
| if (m_useDepth || m_useStencil) |
| { |
| depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat); |
| |
| const VkImageViewCreateInfo depthStencilAttachmentViewParams = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageViewCreateFlags flags; |
| *m_depthStencilImage, // VkImage image; |
| VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; |
| m_depthStencilFormat, // VkFormat format; |
| componentMappingRGBA, // VkComponentMapping components; |
| { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; |
| }; |
| |
| m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams); |
| } |
| |
| // Create render pass |
| { |
| std::vector<VkAttachmentDescription> attachmentDescriptions; |
| { |
| const VkAttachmentDescription colorAttachmentDescription = |
| { |
| 0u, // VkAttachmentDescriptionFlags flags; |
| m_colorFormat, // VkFormat format; |
| m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; |
| VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; |
| VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; |
| }; |
| attachmentDescriptions.push_back(colorAttachmentDescription); |
| } |
| |
| deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED; |
| |
| if (usesResolveImage) |
| { |
| resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); |
| |
| const VkAttachmentDescription resolveAttachmentDescription = |
| { |
| 0u, // VkAttachmentDescriptionFlags flags; |
| m_colorFormat, // VkFormat format; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; |
| VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; |
| }; |
| attachmentDescriptions.push_back(resolveAttachmentDescription); |
| } |
| |
| deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED; |
| |
| if (m_renderType == RENDER_TYPE_COPY_SAMPLES) |
| { |
| perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); |
| |
| const VkAttachmentDescription perSampleAttachmentDescription = |
| { |
| 0u, // VkAttachmentDescriptionFlags flags; |
| m_colorFormat, // VkFormat format; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; |
| VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; |
| }; |
| |
| for (size_t i = 0; i < m_perSampleImages.size(); ++i) |
| { |
| attachmentDescriptions.push_back(perSampleAttachmentDescription); |
| } |
| } |
| |
| deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED; |
| |
| if (m_useDepth || m_useStencil) |
| { |
| depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); |
| |
| const VkAttachmentDescription depthStencilAttachmentDescription = |
| { |
| 0u, // VkAttachmentDescriptionFlags flags; |
| m_depthStencilFormat, // VkFormat format; |
| m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; |
| (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp; |
| (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp; |
| (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp; |
| (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp; |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; |
| }; |
| attachmentDescriptions.push_back(depthStencilAttachmentDescription); |
| }; |
| |
| const VkAttachmentReference colorAttachmentReference = |
| { |
| 0u, // deUint32 attachment; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; |
| }; |
| |
| const VkAttachmentReference inputAttachmentReference = |
| { |
| 0u, // deUint32 attachment; |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout; |
| }; |
| |
| const VkAttachmentReference resolveAttachmentReference = |
| { |
| resolveAttachmentIndex, // deUint32 attachment; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; |
| }; |
| |
| const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] = |
| { |
| { |
| VK_ATTACHMENT_UNUSED, // deUint32 attachment |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout |
| }, |
| { |
| 0u, // deUint32 attachment |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout |
| } |
| }; |
| |
| const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] = |
| { |
| { |
| VK_ATTACHMENT_UNUSED, // deUint32 attachment |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout |
| }, |
| { |
| resolveAttachmentIndex, // deUint32 attachment |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout |
| } |
| }; |
| |
| std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size()); |
| if (m_renderType == RENDER_TYPE_COPY_SAMPLES) |
| { |
| for (size_t i = 0; i < m_perSampleImages.size(); ++i) |
| { |
| const VkAttachmentReference perSampleAttachmentReference = |
| { |
| perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; |
| }; |
| perSampleAttachmentReferences[i] = perSampleAttachmentReference; |
| } |
| } |
| |
| const VkAttachmentReference depthStencilAttachmentReference = |
| { |
| depthStencilAttachmentIndex, // deUint32 attachment; |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; |
| }; |
| |
| std::vector<VkSubpassDescription> subpassDescriptions; |
| std::vector<VkSubpassDependency> subpassDependencies; |
| |
| if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) |
| { |
| const VkSubpassDescription subpassDescription0 = |
| { |
| 0u, // VkSubpassDescriptionFlags flags |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint |
| 0u, // deUint32 inputAttachmentCount |
| DE_NULL, // const VkAttachmentReference* pInputAttachments |
| 0u, // deUint32 colorAttachmentCount |
| DE_NULL, // const VkAttachmentReference* pColorAttachments |
| DE_NULL, // const VkAttachmentReference* pResolveAttachments |
| &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment |
| 0u, // deUint32 preserveAttachmentCount |
| DE_NULL // const VkAttachmentReference* pPreserveAttachments |
| }; |
| |
| const VkSubpassDescription subpassDescription1 = |
| { |
| 0u, // VkSubpassDescriptionFlags flags |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint |
| 0u, // deUint32 inputAttachmentCount |
| DE_NULL, // const VkAttachmentReference* pInputAttachments |
| 1u, // deUint32 colorAttachmentCount |
| &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments |
| &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments |
| &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment |
| 0u, // deUint32 preserveAttachmentCount |
| DE_NULL // const VkAttachmentReference* pPreserveAttachments |
| }; |
| |
| const VkSubpassDependency subpassDependency = |
| { |
| 0u, // deUint32 srcSubpass |
| 1u, // deUint32 dstSubpass |
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask |
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask |
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask |
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask |
| 0u // VkDependencyFlags dependencyFlags |
| }; |
| |
| subpassDescriptions.push_back(subpassDescription0); |
| subpassDescriptions.push_back(subpassDescription1); |
| subpassDependencies.push_back(subpassDependency); |
| } |
| else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT) |
| { |
| const VkSubpassDescription renderSubpassDescription = |
| { |
| 0u, // VkSubpassDescriptionFlags flags |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint |
| 0u, // deUint32 inputAttachmentCount |
| DE_NULL, // const VkAttachmentReference* pInputAttachments |
| 2u, // deUint32 colorAttachmentCount |
| colorAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pColorAttachments |
| resolveAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pResolveAttachments |
| DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment |
| 0u, // deUint32 preserveAttachmentCount |
| DE_NULL // const VkAttachmentReference* pPreserveAttachments |
| }; |
| |
| subpassDescriptions.push_back(renderSubpassDescription); |
| } |
| else |
| { |
| { |
| const VkSubpassDescription renderSubpassDescription = |
| { |
| 0u, // VkSubpassDescriptionFlags flags; |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; |
| 0u, // deUint32 inputAttachmentCount; |
| DE_NULL, // const VkAttachmentReference* pInputAttachments; |
| 1u, // deUint32 colorAttachmentCount; |
| &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; |
| usesResolveImage ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments; |
| (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment; |
| 0u, // deUint32 preserveAttachmentCount; |
| DE_NULL // const VkAttachmentReference* pPreserveAttachments; |
| }; |
| subpassDescriptions.push_back(renderSubpassDescription); |
| } |
| |
| if (m_renderType == RENDER_TYPE_COPY_SAMPLES) |
| { |
| |
| for (size_t i = 0; i < m_perSampleImages.size(); ++i) |
| { |
| const VkSubpassDescription copySampleSubpassDescription = |
| { |
| 0u, // VkSubpassDescriptionFlags flags; |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; |
| 1u, // deUint32 inputAttachmentCount; |
| &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments; |
| 1u, // deUint32 colorAttachmentCount; |
| &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments; |
| DE_NULL, // const VkAttachmentReference* pResolveAttachments; |
| DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; |
| 0u, // deUint32 preserveAttachmentCount; |
| DE_NULL // const VkAttachmentReference* pPreserveAttachments; |
| }; |
| subpassDescriptions.push_back(copySampleSubpassDescription); |
| |
| const VkSubpassDependency copySampleSubpassDependency = |
| { |
| 0u, // deUint32 srcSubpass |
| 1u + static_cast<deUint32>(i), // deUint32 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 |
| 0u, // VkDependencyFlags dependencyFlags |
| }; |
| subpassDependencies.push_back(copySampleSubpassDependency); |
| } |
| } |
| } |
| |
| const VkRenderPassCreateInfo renderPassParams = |
| { |
|