| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2017 The Khronos Group 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 Vulkan Multi View Render Tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktMultiViewRenderTests.hpp" |
| #include "vktMultiViewRenderUtil.hpp" |
| #include "vktMultiViewRenderPassUtil.hpp" |
| #include "vktCustomInstancesDevices.hpp" |
| |
| #include "vktTestCase.hpp" |
| #include "vkBuilderUtil.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkPlatform.hpp" |
| #include "vkMemUtil.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vkCmdUtil.hpp" |
| #include "vkObjUtil.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuResource.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuCommandLine.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuRGBA.hpp" |
| |
| #include "deRandom.hpp" |
| #include "deMath.h" |
| #include "deSharedPtr.hpp" |
| |
| namespace vkt |
| { |
| namespace MultiView |
| { |
| namespace |
| { |
| |
| using namespace vk; |
| using de::MovePtr; |
| using de::UniquePtr; |
| using std::vector; |
| using std::map; |
| using std::string; |
| |
| enum TestType |
| { |
| TEST_TYPE_VIEW_MASK, |
| TEST_TYPE_VIEW_INDEX_IN_VERTEX, |
| TEST_TYPE_VIEW_INDEX_IN_FRAGMENT, |
| TEST_TYPE_VIEW_INDEX_IN_GEOMETRY, |
| TEST_TYPE_VIEW_INDEX_IN_TESELLATION, |
| TEST_TYPE_INPUT_ATTACHMENTS, |
| TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY, |
| TEST_TYPE_INSTANCED_RENDERING, |
| TEST_TYPE_INPUT_RATE_INSTANCE, |
| TEST_TYPE_DRAW_INDIRECT, |
| TEST_TYPE_DRAW_INDIRECT_INDEXED, |
| TEST_TYPE_DRAW_INDEXED, |
| TEST_TYPE_CLEAR_ATTACHMENTS, |
| TEST_TYPE_SECONDARY_CMD_BUFFER, |
| TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY, |
| TEST_TYPE_POINT_SIZE, |
| TEST_TYPE_MULTISAMPLE, |
| TEST_TYPE_QUERIES, |
| TEST_TYPE_NON_PRECISE_QUERIES, |
| TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR, |
| TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR, |
| TEST_TYPE_DEPTH, |
| TEST_TYPE_DEPTH_DIFFERENT_RANGES, |
| TEST_TYPE_STENCIL, |
| TEST_TYPE_LAST |
| }; |
| |
| enum RenderingType |
| { |
| RENDERING_TYPE_RENDERPASS_LEGACY = 0, |
| RENDERING_TYPE_RENDERPASS2, |
| RENDERING_TYPE_DYNAMIC_RENDERING |
| }; |
| |
| struct TestParameters |
| { |
| VkExtent3D extent; |
| vector<deUint32> viewMasks; |
| TestType viewIndex; |
| VkSampleCountFlagBits samples; |
| VkFormat colorFormat; |
| RenderingType renderingType; |
| }; |
| |
| const int TEST_POINT_SIZE_SMALL = 2; |
| const int TEST_POINT_SIZE_WIDE = 4; |
| |
| vk::Move<vk::VkRenderPass> makeRenderPass (const DeviceInterface& vk, |
| const VkDevice device, |
| const VkFormat colorFormat, |
| const vector<deUint32>& viewMasks, |
| RenderingType renderingType, |
| const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT, |
| const VkAttachmentLoadOp colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, |
| const VkFormat dsFormat = VK_FORMAT_UNDEFINED) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: |
| return MultiView::makeRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat); |
| case RENDERING_TYPE_RENDERPASS2: |
| return MultiView::makeRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat); |
| default: |
| TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| vk::Move<vk::VkRenderPass> makeRenderPassWithAttachments (const DeviceInterface& vk, |
| const VkDevice device, |
| const VkFormat colorFormat, |
| const vector<deUint32>& viewMasks, |
| RenderingType renderingType) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: |
| return MultiView::makeRenderPassWithAttachments<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, false); |
| case RENDERING_TYPE_RENDERPASS2: |
| return MultiView::makeRenderPassWithAttachments<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, true); |
| default: |
| TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| vk::Move<vk::VkRenderPass> makeRenderPassWithDepth (const DeviceInterface& vk, |
| const VkDevice device, |
| const VkFormat colorFormat, |
| const vector<deUint32>& viewMasks, |
| const VkFormat dsFormat, |
| RenderingType renderingType) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: |
| return MultiView::makeRenderPassWithDepth<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, dsFormat); |
| case RENDERING_TYPE_RENDERPASS2: |
| return MultiView::makeRenderPassWithDepth<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, dsFormat); |
| default: |
| TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| template<typename RenderpassSubpass> |
| void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents) |
| { |
| const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents); |
| |
| RenderpassSubpass::cmdBeginRenderPass(vkd, cmdBuffer, pRenderPassBegin, &subpassBeginInfo); |
| } |
| |
| void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents, RenderingType renderingType) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: cmdBeginRenderPass<RenderpassSubpass1>(vkd, cmdBuffer, pRenderPassBegin, contents); break; |
| case RENDERING_TYPE_RENDERPASS2: cmdBeginRenderPass<RenderpassSubpass2>(vkd, cmdBuffer, pRenderPassBegin, contents); break; |
| default: TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| template<typename RenderpassSubpass> |
| void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents) |
| { |
| const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents); |
| const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL); |
| |
| RenderpassSubpass::cmdNextSubpass(vkd, cmdBuffer, &subpassBeginInfo, &subpassEndInfo); |
| } |
| |
| void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents, RenderingType renderingType) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: cmdNextSubpass<RenderpassSubpass1>(vkd, cmdBuffer, contents); break; |
| case RENDERING_TYPE_RENDERPASS2: cmdNextSubpass<RenderpassSubpass2>(vkd, cmdBuffer, contents); break; |
| default: TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| template<typename RenderpassSubpass> |
| void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer) |
| { |
| const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL); |
| |
| RenderpassSubpass::cmdEndRenderPass(vkd, cmdBuffer, &subpassEndInfo); |
| } |
| |
| void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, RenderingType renderingType) |
| { |
| switch (renderingType) |
| { |
| case RENDERING_TYPE_RENDERPASS_LEGACY: cmdEndRenderPass<RenderpassSubpass1>(vkd, cmdBuffer); break; |
| case RENDERING_TYPE_RENDERPASS2: cmdEndRenderPass<RenderpassSubpass2>(vkd, cmdBuffer); break; |
| default: TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| class ImageAttachment |
| { |
| public: |
| ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT); |
| VkImageView getImageView (void) const |
| { |
| return *m_imageView; |
| } |
| VkImage getImage (void) const |
| { |
| return *m_image; |
| } |
| private: |
| Move<VkImage> m_image; |
| MovePtr<Allocation> m_allocationImage; |
| Move<VkImageView> m_imageView; |
| }; |
| |
| ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples) |
| { |
| const bool depthStencilFormat = isDepthStencilFormat(colorFormat); |
| const VkImageAspectFlags aspectFlags = depthStencilFormat ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT; |
| const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, 0u, extent.depth); |
| const VkImageUsageFlags imageUsageFlagsDependent = depthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| const VkImageUsageFlags imageUsageFlags = imageUsageFlagsDependent | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| const VkImageCreateInfo colorAttachmentImageInfo = makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, imageUsageFlags, samples); |
| |
| m_image = createImage(device, logicalDevice, &colorAttachmentImageInfo); |
| m_allocationImage = allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any); |
| VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset())); |
| m_imageView = makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange); |
| } |
| |
| class MultiViewRenderTestInstance : public TestInstance |
| { |
| public: |
| MultiViewRenderTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| typedef de::SharedPtr<Unique<VkPipeline> > PipelineSp; |
| typedef de::SharedPtr<Unique<VkShaderModule> > ShaderModuleSP; |
| |
| virtual tcu::TestStatus iterate (void); |
| virtual void beforeRenderPass (void); |
| virtual void afterRenderPass (void); |
| virtual void bindResources (void) {} |
| virtual void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| virtual void createVertexData (void); |
| virtual MovePtr<tcu::Texture2DArray> imageData (void) const; |
| TestParameters fillMissingParameters (const TestParameters& parameters); |
| void createVertexBuffer (void); |
| void createMultiViewDevices (void); |
| void createCommandBuffer (void); |
| void madeShaderModule (map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams); |
| Move<VkPipeline> makeGraphicsPipeline (const VkRenderPass renderPass, |
| const VkPipelineLayout pipelineLayout, |
| const deUint32 pipelineShaderStageCount, |
| const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, |
| const deUint32 subpass, |
| const VkVertexInputRate vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX, |
| const bool useDepthTest = false, |
| const bool useStencilTest = false, |
| const float minDepth = 0.0f, |
| const float maxDepth = 1.0f, |
| const VkFormat dsFormat = VK_FORMAT_UNDEFINED); |
| void readImage (VkImage image, const tcu::PixelBufferAccess& dst); |
| bool checkImage (tcu::ConstPixelBufferAccess& dst); |
| const tcu::Vec4 getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background = true, const deUint32 subpassNdx = 0u) const; |
| void appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color); |
| void setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const; |
| void fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const; |
| void fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const; |
| void fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const; |
| |
| const TestParameters m_parameters; |
| const bool m_useDynamicRendering; |
| const int m_seed; |
| const deUint32 m_squareCount; |
| Move<VkDevice> m_logicalDevice; |
| MovePtr<DeviceInterface> m_device; |
| MovePtr<Allocator> m_allocator; |
| deUint32 m_queueFamilyIndex; |
| VkQueue m_queue; |
| vector<tcu::Vec4> m_vertexCoord; |
| Move<VkBuffer> m_vertexCoordBuffer; |
| MovePtr<Allocation> m_vertexCoordAlloc; |
| vector<tcu::Vec4> m_vertexColor; |
| Move<VkBuffer> m_vertexColorBuffer; |
| MovePtr<Allocation> m_vertexColorAlloc; |
| vector<deUint32> m_vertexIndices; |
| Move<VkBuffer> m_vertexIndicesBuffer; |
| MovePtr<Allocation> m_vertexIndicesAllocation; |
| Move<VkCommandPool> m_cmdPool; |
| Move<VkCommandBuffer> m_cmdBuffer; |
| de::SharedPtr<ImageAttachment> m_colorAttachment; |
| VkBool32 m_hasMultiDrawIndirect; |
| vector<tcu::Vec4> m_colorTable; |
| }; |
| |
| MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters) |
| : TestInstance (context) |
| , m_parameters (fillMissingParameters(parameters)) |
| , m_useDynamicRendering (parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) |
| , m_seed (context.getTestContext().getCommandLine().getBaseSeed()) |
| , m_squareCount (4u) |
| , m_queueFamilyIndex (0u) |
| { |
| const float v = 0.75f; |
| const float o = 0.25f; |
| |
| m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f)); |
| m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f)); |
| |
| createMultiViewDevices(); |
| |
| // Color attachment |
| m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples)); |
| } |
| |
| tcu::TestStatus MultiViewRenderTestInstance::iterate (void) |
| { |
| const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); |
| Move<VkRenderPass> renderPass; |
| Move<VkFramebuffer> frameBuffer; |
| |
| // FrameBuffer & renderPass |
| if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) |
| { |
| renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType); |
| frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); |
| } |
| |
| // pipelineLayout |
| Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); |
| |
| // pipelines |
| map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; |
| vector<PipelineSp> pipelines(subpassCount); |
| const VkVertexInputRate vertexInputRate = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; |
| |
| { |
| vector<VkPipelineShaderStageCreateInfo> shaderStageParams; |
| madeShaderModule(shaderModule, shaderStageParams); |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) |
| pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate)))); |
| } |
| |
| createCommandBuffer(); |
| createVertexData(); |
| createVertexBuffer(); |
| |
| draw(subpassCount, *renderPass, *frameBuffer, pipelines); |
| |
| { |
| vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); |
| tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); |
| |
| readImage(m_colorAttachment->getImage(), dst); |
| |
| if (!checkImage(dst)) |
| return tcu::TestStatus::fail("Fail"); |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| void MultiViewRenderTestInstance::beforeRenderPass (void) |
| { |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; |
| 0u, //deUint32 baseMipLevel; |
| 1u, //deUint32 levelCount; |
| 0u, //deUint32 baseArrayLayer; |
| m_parameters.extent.depth, //deUint32 layerCount; |
| }; |
| imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 0, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); |
| |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); |
| |
| imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); |
| } |
| |
| void MultiViewRenderTestInstance::afterRenderPass (void) |
| { |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; |
| 0u, //deUint32 baseMipLevel; |
| 1u, //deUint32 levelCount; |
| 0u, //deUint32 baseArrayLayer; |
| m_parameters.extent.depth, //deUint32 layerCount; |
| }; |
| |
| imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); |
| } |
| |
| void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED) |
| m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32); |
| |
| bindResources(); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED) |
| m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u); |
| else |
| m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| void MultiViewRenderTestInstance::createVertexData (void) |
| { |
| tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); |
| |
| appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| |
| color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color); |
| |
| color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f); |
| appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color); |
| |
| color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color); |
| |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| { |
| const size_t verticesCount = m_vertexCoord.size(); |
| vector<tcu::Vec4> vertexColor (verticesCount); |
| vector<tcu::Vec4> vertexCoord (verticesCount); |
| |
| m_vertexIndices.clear(); |
| m_vertexIndices.reserve(verticesCount); |
| for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) |
| m_vertexIndices.push_back(vertexIdx); |
| |
| de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end()); |
| |
| for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) |
| vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx]; |
| m_vertexColor.assign(vertexColor.begin(), vertexColor.end()); |
| |
| for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) |
| vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx]; |
| m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end()); |
| } |
| } |
| |
| TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters) |
| { |
| if (!parameters.viewMasks.empty()) |
| return parameters; |
| else |
| { |
| const InstanceInterface& instance = m_context.getInstanceInterface(); |
| const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); |
| |
| VkPhysicalDeviceMultiviewProperties multiviewProperties = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, // VkStructureType sType; |
| DE_NULL, // void* pNext; |
| 0u, // deUint32 maxMultiviewViewCount; |
| 0u // deUint32 maxMultiviewInstanceIndex; |
| }; |
| |
| VkPhysicalDeviceProperties2 deviceProperties2; |
| deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; |
| deviceProperties2.pNext = &multiviewProperties; |
| |
| instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); |
| |
| TestParameters newParameters = parameters; |
| newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount; |
| |
| vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount); |
| for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++) |
| viewMasks[i] = 1 << i; |
| newParameters.viewMasks = viewMasks; |
| |
| return newParameters; |
| } |
| } |
| |
| void MultiViewRenderTestInstance::createVertexBuffer (void) |
| { |
| DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size()); |
| DE_ASSERT(m_vertexCoord.size() != 0); |
| |
| const size_t nonCoherentAtomSize = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize); |
| |
| // Upload vertex coordinates |
| { |
| const size_t dataSize = static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0])); |
| const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); |
| const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
| |
| m_vertexCoordBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); |
| m_vertexCoordAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible); |
| |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset())); |
| deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize)); |
| flushAlloc(*m_device, *m_logicalDevice, *m_vertexCoordAlloc); |
| } |
| |
| // Upload vertex colors |
| { |
| const size_t dataSize = static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0])); |
| const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); |
| const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
| |
| m_vertexColorBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); |
| m_vertexColorAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible); |
| |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset())); |
| deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize)); |
| flushAlloc(*m_device, *m_logicalDevice, *m_vertexColorAlloc); |
| } |
| |
| // Upload vertex indices |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| { |
| const size_t dataSize = static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0])); |
| const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); |
| const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
| |
| DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size()); |
| |
| m_vertexIndicesBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); |
| m_vertexIndicesAllocation = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible); |
| |
| // Init host buffer data |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset())); |
| deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize)); |
| flushAlloc(*m_device, *m_logicalDevice, *m_vertexIndicesAllocation); |
| } |
| else |
| DE_ASSERT(m_vertexIndices.empty()); |
| } |
| |
| void MultiViewRenderTestInstance::createMultiViewDevices (void) |
| { |
| const InstanceInterface& instance = m_context.getInstanceInterface(); |
| const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); |
| const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice); |
| |
| for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex) |
| { |
| if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) |
| break; |
| } |
| |
| const float queuePriorities = 1.0f; |
| const VkDeviceQueueCreateInfo queueInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //VkStructureType sType; |
| DE_NULL, //const void* pNext; |
| (VkDeviceQueueCreateFlags)0u, //VkDeviceQueueCreateFlags flags; |
| m_queueFamilyIndex, //deUint32 queueFamilyIndex; |
| 1u, //deUint32 queueCount; |
| &queuePriorities //const float* pQueuePriorities; |
| }; |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, // VkStructureType sType; |
| DE_NULL, // void* pNext; |
| DE_FALSE, // VkBool32 dynamicRendering |
| }; |
| |
| VkPhysicalDeviceMultiviewFeatures multiviewFeatures = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR, // VkStructureType sType; |
| &dynamicRenderingFeatures, // void* pNext; |
| DE_FALSE, // VkBool32 multiview; |
| DE_FALSE, // VkBool32 multiviewGeometryShader; |
| DE_FALSE, // VkBool32 multiviewTessellationShader; |
| }; |
| |
| VkPhysicalDeviceFeatures2 enabledFeatures; |
| enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |
| enabledFeatures.pNext = &multiviewFeatures; |
| |
| instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures); |
| |
| if (!multiviewFeatures.multiview) |
| TCU_THROW(NotSupportedError, "MultiView not supported"); |
| |
| bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) || |
| (TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex) || |
| (TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex); |
| |
| if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader) |
| TCU_THROW(NotSupportedError, "Geometry shader is not supported"); |
| |
| if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader) |
| TCU_THROW(NotSupportedError, "Tessellation shader is not supported"); |
| |
| VkPhysicalDeviceMultiviewProperties multiviewProperties = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, //VkStructureType sType; |
| DE_NULL, //void* pNext; |
| 0u, //deUint32 maxMultiviewViewCount; |
| 0u //deUint32 maxMultiviewInstanceIndex; |
| }; |
| |
| VkPhysicalDeviceProperties2 propertiesDeviceProperties2; |
| propertiesDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; |
| propertiesDeviceProperties2.pNext = &multiviewProperties; |
| |
| instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2); |
| |
| if (multiviewProperties.maxMultiviewViewCount < 6u) |
| TCU_FAIL("maxMultiviewViewCount below min value"); |
| |
| if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1 |
| TCU_FAIL("maxMultiviewInstanceIndex below min value"); |
| |
| if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth) |
| TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test"); |
| |
| m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect; |
| |
| { |
| vector<const char*> deviceExtensions; |
| |
| if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview")) |
| deviceExtensions.push_back("VK_KHR_multiview"); |
| |
| if ((m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2) && |
| !isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2")) |
| deviceExtensions.push_back("VK_KHR_create_renderpass2"); |
| if ((m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) && |
| !isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_dynamic_rendering")) |
| deviceExtensions.push_back("VK_KHR_dynamic_rendering"); |
| |
| if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES) |
| deviceExtensions.push_back("VK_EXT_depth_range_unrestricted"); |
| |
| const VkDeviceCreateInfo deviceInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //VkStructureType sType; |
| &enabledFeatures, //const void* pNext; |
| 0u, //VkDeviceCreateFlags flags; |
| 1u, //deUint32 queueCreateInfoCount; |
| &queueInfo, //const VkDeviceQueueCreateInfo* pQueueCreateInfos; |
| 0u, //deUint32 enabledLayerCount; |
| DE_NULL, //const char* const* ppEnabledLayerNames; |
| static_cast<deUint32>(deviceExtensions.size()), //deUint32 enabledExtensionCount; |
| deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0], //const char* const* pEnabledExtensionNames; |
| DE_NULL //const VkPhysicalDeviceFeatures* pEnabledFeatures; |
| }; |
| |
| m_logicalDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), instance, physicalDevice, &deviceInfo); |
| m_device = MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_logicalDevice)); |
| m_allocator = MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice))); |
| m_device->getDeviceQueue (*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue); |
| } |
| } |
| |
| void MultiViewRenderTestInstance::createCommandBuffer (void) |
| { |
| // cmdPool |
| { |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCmdPoolCreateFlags flags; |
| m_queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams); |
| } |
| |
| // cmdBuffer |
| { |
| const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *m_cmdPool, // VkCommandPool commandPool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // deUint32 bufferCount; |
| }; |
| m_cmdBuffer = allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo); |
| } |
| } |
| |
| void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams) |
| { |
| // create shaders modules |
| switch (m_parameters.viewIndex) |
| { |
| case TEST_TYPE_VIEW_MASK: |
| case TEST_TYPE_VIEW_INDEX_IN_VERTEX: |
| case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: |
| case TEST_TYPE_INSTANCED_RENDERING: |
| case TEST_TYPE_INPUT_RATE_INSTANCE: |
| case TEST_TYPE_DRAW_INDIRECT: |
| case TEST_TYPE_DRAW_INDIRECT_INDEXED: |
| case TEST_TYPE_DRAW_INDEXED: |
| case TEST_TYPE_CLEAR_ATTACHMENTS: |
| case TEST_TYPE_SECONDARY_CMD_BUFFER: |
| case TEST_TYPE_INPUT_ATTACHMENTS: |
| case TEST_TYPE_POINT_SIZE: |
| case TEST_TYPE_MULTISAMPLE: |
| case TEST_TYPE_QUERIES: |
| case TEST_TYPE_NON_PRECISE_QUERIES: |
| case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR: |
| case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR: |
| case TEST_TYPE_DEPTH: |
| case TEST_TYPE_DEPTH_DIFFERENT_RANGES: |
| case TEST_TYPE_STENCIL: |
| shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); |
| shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); |
| break; |
| case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: |
| case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY: |
| case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY: |
| shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); |
| shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0)))); |
| shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); |
| break; |
| case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: |
| shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); |
| shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0)))); |
| shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0)))); |
| shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); |
| break; |
| default: |
| DE_ASSERT(0); |
| break; |
| } |
| |
| VkPipelineShaderStageCreateInfo pipelineShaderStage = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; |
| (VkShaderStageFlagBits)0, // VkShaderStageFlagBits stage; |
| (VkShaderModule)0, // VkShaderModule module; |
| "main", // const char* pName; |
| (const VkSpecializationInfo*)DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; |
| }; |
| |
| for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it) |
| { |
| pipelineShaderStage.stage = it->first; |
| pipelineShaderStage.module = **it->second; |
| shaderStageParams.push_back(pipelineShaderStage); |
| } |
| } |
| |
| Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass renderPass, |
| const VkPipelineLayout pipelineLayout, |
| const deUint32 pipelineShaderStageCount, |
| const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, |
| const deUint32 subpass, |
| const VkVertexInputRate vertexInputRate, |
| const bool useDepthTest, |
| const bool useStencilTest, |
| const float minDepth, |
| const float maxDepth, |
| const VkFormat dsFormat) |
| { |
| const VkVertexInputBindingDescription vertexInputBindingDescriptions[] = |
| { |
| { |
| 0u, // binding; |
| static_cast<deUint32>(sizeof(m_vertexCoord[0])), // stride; |
| vertexInputRate // inputRate |
| }, |
| { |
| 1u, // binding; |
| static_cast<deUint32>(sizeof(m_vertexColor[0])), // stride; |
| vertexInputRate // inputRate |
| } |
| }; |
| |
| const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = |
| { |
| { |
| 0u, // deUint32 location; |
| 0u, // deUint32 binding; |
| VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; |
| 0u // deUint32 offset; |
| }, // VertexElementData::position |
| { |
| 1u, // deUint32 location; |
| 1u, // deUint32 binding; |
| VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; |
| 0u // deUint32 offset; |
| }, // VertexElementData::color |
| }; |
| |
| const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; |
| NULL, // const void* pNext; |
| 0u, // VkPipelineVertexInputStateCreateFlags flags; |
| DE_LENGTH_OF_ARRAY(vertexInputBindingDescriptions), // deUint32 vertexBindingDescriptionCount; |
| vertexInputBindingDescriptions, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; |
| DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // deUint32 vertexAttributeDescriptionCount; |
| vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; |
| }; |
| |
| const VkPrimitiveTopology topology = (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : |
| (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : |
| VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; |
| |
| const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineInputAssemblyStateCreateFlags flags; |
| topology, // VkPrimitiveTopology topology; |
| VK_FALSE, // VkBool32 primitiveRestartEnable; |
| }; |
| |
| const VkViewport viewport = makeViewport(0.0f, 0.0f, (float)m_parameters.extent.width, (float)m_parameters.extent.height, minDepth, maxDepth); |
| const VkRect2D scissor = makeRect2D(m_parameters.extent); |
| |
| const VkPipelineViewportStateCreateInfo viewportStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineViewportStateCreateFlags flags; |
| 1u, // deUint32 viewportCount; |
| &viewport, // const VkViewport* pViewports; |
| 1u, // deUint32 scissorCount; |
| &scissor // const VkRect2D* pScissors; |
| }; |
| |
| const VkPipelineRasterizationStateCreateInfo rasterStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineRasterizationStateCreateFlags flags; |
| VK_FALSE, // VkBool32 depthClampEnable; |
| VK_FALSE, // VkBool32 rasterizerDiscardEnable; |
| VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; |
| VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; |
| VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; |
| VK_FALSE, // VkBool32 depthBiasEnable; |
| 0.0f, // float depthBiasConstantFactor; |
| 0.0f, // float depthBiasClamp; |
| 0.0f, // float depthBiasSlopeFactor; |
| 1.0f, // float lineWidth; |
| }; |
| |
| const VkSampleCountFlagBits sampleCountFlagBits = (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) ? VK_SAMPLE_COUNT_4_BIT : |
| VK_SAMPLE_COUNT_1_BIT; |
| const VkPipelineMultisampleStateCreateInfo multisampleStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineMultisampleStateCreateFlags flags; |
| sampleCountFlagBits, // VkSampleCountFlagBits rasterizationSamples; |
| VK_FALSE, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| VK_FALSE, // VkBool32 alphaToCoverageEnable; |
| VK_FALSE, // VkBool32 alphaToOneEnable; |
| }; |
| |
| VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineDepthStencilStateCreateFlags flags; |
| useDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable; |
| useDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable; |
| VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp; |
| VK_FALSE, // VkBool32 depthBoundsTestEnable; |
| useStencilTest ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable; |
| // VkStencilOpState front; |
| { |
| VK_STENCIL_OP_KEEP, // VkStencilOp failOp; |
| VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; |
| VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; |
| VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; |
| ~0u, // deUint32 compareMask; |
| ~0u, // deUint32 writeMask; |
| 0u, // deUint32 reference; |
| }, |
| // VkStencilOpState back; |
| { |
| VK_STENCIL_OP_KEEP, // VkStencilOp failOp; |
| VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; |
| VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; |
| VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; |
| ~0u, // deUint32 compareMask; |
| ~0u, // deUint32 writeMask; |
| 0u, // deUint32 reference; |
| }, |
| 0.0f, // float minDepthBounds; |
| 1.0f, // float maxDepthBounds; |
| }; |
| |
| const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = |
| { |
| VK_FALSE, // VkBool32 blendEnable; |
| VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; |
| VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; |
| VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; |
| VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; |
| VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; |
| VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; |
| VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask; |
| VK_COLOR_COMPONENT_G_BIT | |
| VK_COLOR_COMPONENT_B_BIT | |
| VK_COLOR_COMPONENT_A_BIT |
| }; |
| |
| const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkPipelineColorBlendStateCreateFlags flags; |
| VK_FALSE, // VkBool32 logicOpEnable; |
| VK_LOGIC_OP_COPY, // VkLogicOp logicOp; |
| 1u, // deUint32 attachmentCount; |
| &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; |
| { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; |
| }; |
| |
| VkPipelineTessellationStateCreateInfo TessellationState = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; |
| 4u // deUint32 patchControlPoints; |
| }; |
| |
| VkPipelineRenderingCreateInfoKHR renderingCreateInfo |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, |
| DE_NULL, |
| m_parameters.viewMasks[subpass], |
| 1u, |
| &m_parameters.colorFormat, |
| dsFormat, |
| dsFormat |
| }; |
| |
| const VkGraphicsPipelineCreateInfo graphicsPipelineParams |
| { |
| VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; |
| (renderPass == 0) ? &renderingCreateInfo : DE_NULL, // const void* pNext; |
| (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags; |
| pipelineShaderStageCount, // deUint32 stageCount; |
| pipelineShaderStageCreate, // const VkPipelineShaderStageCreateInfo* pStages; |
| &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; |
| &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; |
| (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; |
| &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; |
| &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterState; |
| &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; |
| &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; |
| &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; |
| (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; |
| pipelineLayout, // VkPipelineLayout layout; |
| renderPass, // VkRenderPass renderPass; |
| subpass, // deUint32 subpass; |
| 0u, // VkPipeline basePipelineHandle; |
| 0, // deInt32 basePipelineIndex; |
| }; |
| |
| return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams); |
| } |
| |
| void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst) |
| { |
| Move<VkBuffer> buffer; |
| MovePtr<Allocation> bufferAlloc; |
| const VkDeviceSize pixelDataSize = dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_parameters.colorFormat).getPixelSize(); |
| |
| // Create destination buffer |
| { |
| const VkBufferCreateInfo bufferParams = |
| { |
| VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkBufferCreateFlags flags; |
| pixelDataSize, // VkDeviceSize size; |
| VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1u, // deUint32 queueFamilyIndexCount; |
| &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; |
| }; |
| |
| buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); |
| bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); |
| |
| deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize)); |
| flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc); |
| } |
| |
| const VkBufferMemoryBarrier bufferBarrier = |
| { |
| VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; |
| VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; |
| VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; |
| VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; |
| *buffer, // VkBuffer buffer; |
| 0u, // VkDeviceSize offset; |
| pixelDataSize // VkDeviceSize size; |
| }; |
| |
| // Copy image to buffer |
| const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); |
| const VkBufferImageCopy copyRegion = |
| { |
| 0u, // VkDeviceSize bufferOffset; |
| (deUint32)dst.getWidth(), // deUint32 bufferRowLength; |
| (deUint32)dst.getHeight(), // deUint32 bufferImageHeight; |
| { |
| aspect, // VkImageAspectFlags aspect; |
| 0u, // deUint32 mipLevel; |
| 0u, // deUint32 baseArrayLayer; |
| m_parameters.extent.depth, // deUint32 layerCount; |
| }, // VkImageSubresourceLayers imageSubresource; |
| { 0, 0, 0 }, // VkOffset3D imageOffset; |
| { m_parameters.extent.width, m_parameters.extent.height, 1u } // VkExtent3D imageExtent; |
| }; |
| |
| beginCommandBuffer (*m_device, *m_cmdBuffer); |
| { |
| VkImageSubresourceRange subresourceRange = |
| { |
| aspect, // VkImageAspectFlags aspectMask; |
| 0u, // deUint32 baseMipLevel; |
| 1u, // deUint32 mipLevels; |
| 0u, // deUint32 baseArraySlice; |
| m_parameters.extent.depth, // deUint32 arraySize; |
| }; |
| |
| imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); |
| |
| m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); |
| m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL); |
| } |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| |
| // Read buffer data |
| invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc); |
| tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); |
| } |
| |
| bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame) |
| { |
| const MovePtr<tcu::Texture2DArray> referenceFrame = imageData(); |
| const bool result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), |
| "Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR); |
| |
| if (!result) |
| for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++) |
| { |
| tcu::ConstPixelBufferAccess ref (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx)); |
| tcu::ConstPixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx)); |
| tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING); |
| } |
| |
| return result; |
| } |
| |
| const tcu::Vec4 MultiViewRenderTestInstance::getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background, const deUint32 subpassNdx) const |
| { |
| // this function is used for genrating same colors while rendering and while creating reference |
| |
| switch (m_parameters.viewIndex) |
| { |
| case TEST_TYPE_VIEW_MASK: |
| return m_vertexColor[colorNdx]; |
| |
| case TEST_TYPE_DRAW_INDEXED: |
| return m_vertexColor[m_vertexIndices[colorNdx]]; |
| |
| case TEST_TYPE_INSTANCED_RENDERING: |
| return m_vertexColor[0] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0); |
| |
| case TEST_TYPE_INPUT_RATE_INSTANCE: |
| return m_vertexColor[colorNdx / 4] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0); |
| |
| case TEST_TYPE_DRAW_INDIRECT_INDEXED: |
| return m_vertexColor[m_vertexIndices[colorNdx]] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); |
| |
| case TEST_TYPE_VIEW_INDEX_IN_VERTEX: |
| case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: |
| case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: |
| case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: |
| case TEST_TYPE_INPUT_ATTACHMENTS: |
| case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY: |
| case TEST_TYPE_DRAW_INDIRECT: |
| case TEST_TYPE_CLEAR_ATTACHMENTS: |
| case TEST_TYPE_SECONDARY_CMD_BUFFER: |
| case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY: |
| return m_vertexColor[colorNdx] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); |
| |
| case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR: |
| if (background) |
| return m_colorTable[4 + quarterNdx % 4]; |
| else |
| return m_colorTable[layerNdx % 4]; |
| |
| case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR: |
| if (background) |
| return m_colorTable[4 + quarterNdx % 4]; |
| else |
| return m_colorTable[0]; |
| |
| case TEST_TYPE_POINT_SIZE: |
| case TEST_TYPE_MULTISAMPLE: |
| if (background) |
| return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f); |
| else |
| return m_vertexColor[colorNdx]; |
| |
| case TEST_TYPE_DEPTH: |
| if (background) |
| if (subpassNdx < 4) |
| return tcu::Vec4(0.66f, 0.0f, 0.0f, 1.0f); |
| else |
| return tcu::Vec4(0.33f, 0.0f, 0.0f, 1.0f); |
| else |
| return tcu::Vec4(0.99f, 0.0f, 0.0f, 1.0f); |
| |
| case TEST_TYPE_DEPTH_DIFFERENT_RANGES: |
| // for quads from partA generate 1.20, 0.90, 0.60, 0.30 |
| // for quads from partB generate 0.55, 0.35, 0.15, -0.05 |
| // depth ranges in views are <0;0.5>, <0;1> or <0.5;1> so |
| // at least one quad from partA/partB will always be drawn |
| if (subpassNdx < 4) |
| return tcu::Vec4(1.2f - 0.3f * static_cast<float>(subpassNdx), 0.0f, 0.0f, 1.0f); |
| return tcu::Vec4(0.55f - 0.2f * static_cast<float>(subpassNdx % 4), 0.0f, 0.0f, 1.0f); |
| |
| case TEST_TYPE_STENCIL: |
| if (background) |
| return tcu::Vec4(0.33f, 0.0f, 0.0f, 0.0f); // Increment value |
| else |
| return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); |
| |
| default: |
| TCU_THROW(InternalError, "Impossible"); |
| } |
| } |
| |
| void MultiViewRenderTestInstance::setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const |
| { |
| DE_ASSERT(TEST_POINT_SIZE_WIDE > TEST_POINT_SIZE_SMALL); |
| |
| const int pointOffset = 1 + TEST_POINT_SIZE_WIDE / 2 - (pointSize + 1) / 2; |
| const int offsetX = pointOffset + static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u); |
| const int offsetY = pointOffset + static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u); |
| |
| for (int y = 0; y < pointSize; ++y) |
| for (int x = 0; x < pointSize; ++x) |
| pixelBuffer.setPixel(pointColor, offsetX + x, offsetY + y, layerNdx); |
| } |
| |
| void MultiViewRenderTestInstance::fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const |
| { |
| const int offsetX = static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u); |
| const int offsetY = static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u); |
| const int maxY = static_cast<int>(m_parameters.extent.height / 2u); |
| const tcu::Vec4 multisampledColor = tcu::Vec4(color[0], color[1], color[2], color[3]) * 0.5f; |
| |
| for (int y = 0; y < maxY; ++y) |
| { |
| for (int x = 0; x < y; ++x) |
| pixelBuffer.setPixel(color, offsetX + x, offsetY + (maxY - 1) - y, layerNdx); |
| |
| // Multisampled pixel is on the triangle margin |
| pixelBuffer.setPixel(multisampledColor, offsetX + y, offsetY + (maxY - 1) - y, layerNdx); |
| } |
| } |
| |
| void MultiViewRenderTestInstance::fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const |
| { |
| for (deUint32 y = 0u; y < m_parameters.extent.height; ++y) |
| for (deUint32 x = 0u; x < m_parameters.extent.width; ++x) |
| pixelBuffer.setPixel(color, x, y, layerNdx); |
| } |
| |
| void MultiViewRenderTestInstance::fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const |
| { |
| const int h = m_parameters.extent.height; |
| const int h2 = h / 2; |
| const int w = m_parameters.extent.width; |
| const int w2 = w / 2; |
| int xStart = 0; |
| int xEnd = 0; |
| int yStart = 0; |
| int yEnd = 0; |
| |
| switch (quarter) |
| { |
| case 0: xStart = 0u; xEnd = w2; yStart = 0u; yEnd = h2; break; |
| case 1: xStart = 0u; xEnd = w2; yStart = h2; yEnd = h; break; |
| case 2: xStart = w2; xEnd = w; yStart = 0u; yEnd = h2; break; |
| case 3: xStart = w2; xEnd = w; yStart = h2; yEnd = h; break; |
| default: TCU_THROW(InternalError, "Impossible"); |
| } |
| |
| if (TEST_TYPE_STENCIL == m_parameters.viewIndex || |
| TEST_TYPE_DEPTH == m_parameters.viewIndex || |
| TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex) |
| { |
| if (subpassNdx < 4) |
| { // Part A: Horizontal bars near X axis |
| yStart = h2 + (yStart - h2) / 2; |
| yEnd = h2 + (yEnd - h2) / 2; |
| } |
| else |
| { // Part B: Vertical bars near Y axis (drawn twice) |
| xStart = w2 + (xStart - w2) / 2; |
| xEnd = w2 + (xEnd - w2) / 2; |
| } |
| |
| // Update pixels in area |
| if (TEST_TYPE_STENCIL == m_parameters.viewIndex) |
| { |
| for (int y = yStart; y < yEnd; ++y) |
| for (int x = xStart; x < xEnd; ++x) |
| pixelBuffer.setPixel(pixelBuffer.getPixel(x, y, layerNdx) + color, x, y, layerNdx); |
| } |
| |
| if (TEST_TYPE_DEPTH == m_parameters.viewIndex || |
| TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex) |
| { |
| for (int y = yStart; y < yEnd; ++y) |
| for (int x = xStart; x < xEnd; ++x) |
| { |
| const tcu::Vec4 currentColor = pixelBuffer.getPixel(x, y, layerNdx); |
| const tcu::Vec4& newColor = (currentColor[0] < color[0]) ? currentColor : color; |
| |
| pixelBuffer.setPixel(newColor, x, y, layerNdx); |
| } |
| } |
| } |
| else |
| { |
| for (int y = yStart; y < yEnd; ++y) |
| for (int x = xStart; x < xEnd; ++x) |
| pixelBuffer.setPixel(color , x, y, layerNdx); |
| } |
| } |
| |
| MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void) const |
| { |
| MovePtr<tcu::Texture2DArray> referenceFrame = MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth)); |
| const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); |
| referenceFrame->allocLevel(0); |
| |
| deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize()); |
| |
| if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex) |
| { |
| deUint32 clearedViewMask = 0; |
| |
| // Start from last clear command color, which actually takes effect |
| for (int subpassNdx = static_cast<int>(subpassCount) - 1; subpassNdx >= 0; --subpassNdx) |
| { |
| deUint32 subpassToClearViewMask = m_parameters.viewMasks[subpassNdx] & ~clearedViewMask; |
| |
| if (subpassToClearViewMask == 0) |
| continue; |
| |
| for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx) |
| if ((subpassToClearViewMask & (1 << layerNdx)) != 0 && (clearedViewMask & (1 << layerNdx)) == 0) |
| fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, subpassNdx, false), layerNdx); |
| |
| // These has been cleared. Exclude these layers from upcoming attempts to clear |
| clearedViewMask |= subpassToClearViewMask; |
| } |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| int layerNdx = 0; |
| deUint32 mask = m_parameters.viewMasks[subpassNdx]; |
| |
| // iterate over image layers |
| while (mask > 0u) |
| { |
| int colorNdx = 0; |
| |
| if (mask & 1u) |
| { |
| if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) |
| { |
| struct ColorDataRGBA |
| { |
| deUint8 r; |
| deUint8 g; |
| deUint8 b; |
| deUint8 a; |
| }; |
| |
| ColorDataRGBA clear = |
| { |
| tcu::floatToU8 (1.0f), |
| tcu::floatToU8 (0.0f), |
| tcu::floatToU8 (0.0f), |
| tcu::floatToU8 (1.0f) |
| }; |
| |
| ColorDataRGBA* dataSrc = (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx); |
| ColorDataRGBA* dataDes = dataSrc + 1; |
| deUint32 copySize = 1u; |
| deUint32 layerSize = m_parameters.extent.width * m_parameters.extent.height - copySize; |
| deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA)); |
| |
| while (layerSize > 0) |
| { |
| deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA)); |
| dataDes = dataDes + copySize; |
| layerSize = layerSize - copySize; |
| copySize = 2u * copySize; |
| if (copySize >= layerSize) |
| copySize = layerSize; |
| } |
| } |
| |
| const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount; |
| if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) |
| { |
| const tcu::Vec4 color = getQuarterRefColor(0u, colorNdx, layerNdx, true, subpassNdx); |
| |
| fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 0u, subpassNdx); |
| } |
| |
| colorNdx += 4; |
| if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) |
| { |
| const tcu::Vec4 color = getQuarterRefColor(1u, colorNdx, layerNdx, true, subpassNdx); |
| |
| fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 1u, subpassNdx); |
| } |
| |
| colorNdx += 4; |
| if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) |
| { |
| const tcu::Vec4 color = getQuarterRefColor(2u, colorNdx, layerNdx, true, subpassNdx); |
| |
| fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 2u, subpassNdx); |
| } |
| |
| colorNdx += 4; |
| if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) |
| { |
| const tcu::Vec4 color = getQuarterRefColor(3u, colorNdx, layerNdx, true, subpassNdx); |
| |
| fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 3u, subpassNdx); |
| } |
| |
| if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) |
| { |
| const tcu::Vec4 color (0.0f, 0.0f, 1.0f, 1.0f); |
| const int maxY = static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f); |
| const int maxX = static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f); |
| for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y) |
| for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x) |
| referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); |
| } |
| |
| if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) |
| { |
| const deUint32 vertexPerPrimitive = 1u; |
| const deUint32 unusedQuarterNdx = 0u; |
| const int pointSize = static_cast<int>(layerNdx == 0u ? TEST_POINT_SIZE_WIDE : TEST_POINT_SIZE_SMALL); |
| |
| if (subpassCount == 1) |
| for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx) |
| setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), pointSize, layerNdx, drawNdx); |
| else |
| setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), pointSize, layerNdx, subpassQuarterNdx); |
| } |
| |
| if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) |
| { |
| const deUint32 vertexPerPrimitive = 3u; |
| const deUint32 unusedQuarterNdx = 0u; |
| |
| if (subpassCount == 1) |
| for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx) |
| fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), layerNdx, drawNdx); |
| else |
| fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), layerNdx, subpassQuarterNdx); |
| } |
| } |
| |
| mask = mask >> 1; |
| ++layerNdx; |
| } |
| } |
| return referenceFrame; |
| } |
| |
| void MultiViewRenderTestInstance::appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color) |
| { |
| m_vertexCoord.push_back(coord); |
| m_vertexColor.push_back(color); |
| } |
| |
| class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| tcu::TestStatus iterate (void) override; |
| void beforeRenderPass (void) override; |
| void bindResources (void) override; |
| void setImageData (VkImage image); |
| de::SharedPtr<ImageAttachment> m_inputAttachment; |
| Move<VkDescriptorPool> m_descriptorPool; |
| Move<VkDescriptorSet> m_descriptorSet; |
| Move<VkDescriptorSetLayout> m_descriptorSetLayout; |
| Move<VkPipelineLayout> m_pipelineLayout; |
| |
| }; |
| |
| MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void) |
| { |
| const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); |
| Move<VkRenderPass> renderPass; |
| Move<VkFramebuffer> frameBuffer; |
| |
| // All color attachment |
| m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat)); |
| m_inputAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat)); |
| |
| // FrameBuffer & renderPass |
| if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) |
| { |
| vector<VkImageView> attachments |
| { |
| m_colorAttachment->getImageView(), |
| m_inputAttachment->getImageView() |
| }; |
| renderPass = makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType); |
| frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height); |
| } |
| |
| // pipelineLayout |
| m_descriptorSetLayout = makeDescriptorSetLayout(*m_device, *m_logicalDevice); |
| m_pipelineLayout = makePipelineLayout(*m_device, *m_logicalDevice, m_descriptorSetLayout.get()); |
| |
| // pipelines |
| map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; |
| vector<PipelineSp> pipelines(subpassCount); |
| |
| { |
| vector<VkPipelineShaderStageCreateInfo> shaderStageParams; |
| madeShaderModule(shaderModule, shaderStageParams); |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) |
| pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx)))); |
| } |
| |
| createVertexData(); |
| createVertexBuffer(); |
| |
| createCommandBuffer(); |
| setImageData(m_inputAttachment->getImage()); |
| draw(subpassCount, *renderPass, *frameBuffer, pipelines); |
| |
| { |
| vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); |
| tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); |
| |
| readImage (m_colorAttachment->getImage(), dst); |
| if (!checkImage(dst)) |
| return tcu::TestStatus::fail("Fail"); |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| void MultiViewAttachmentsTestInstance::beforeRenderPass (void) |
| { |
| const VkDescriptorPoolSize poolSize = |
| { |
| vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, |
| 1u |
| }; |
| |
| const VkDescriptorPoolCreateInfo createInfo = |
| { |
| vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, |
| DE_NULL, |
| VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, |
| 1u, |
| 1u, |
| &poolSize |
| }; |
| |
| m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo); |
| |
| const VkDescriptorSetAllocateInfo allocateInfo = |
| { |
| vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, |
| DE_NULL, |
| *m_descriptorPool, |
| 1u, |
| &m_descriptorSetLayout.get() |
| }; |
| |
| m_descriptorSet = vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo); |
| |
| const VkDescriptorImageInfo imageInfo = |
| { |
| (VkSampler)0, |
| m_inputAttachment->getImageView(), |
| VK_IMAGE_LAYOUT_GENERAL |
| }; |
| |
| const VkWriteDescriptorSet write = |
| { |
| VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, //VkStructureType sType; |
| DE_NULL, //const void* pNext; |
| *m_descriptorSet, //VkDescriptorSet dstSet; |
| 0u, //deUint32 dstBinding; |
| 0u, //deUint32 dstArrayElement; |
| 1u, //deUint32 descriptorCount; |
| VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, //VkDescriptorType descriptorType; |
| &imageInfo, //const VkDescriptorImageInfo* pImageInfo; |
| DE_NULL, //const VkDescriptorBufferInfo* pBufferInfo; |
| DE_NULL, //const VkBufferView* pTexelBufferView; |
| }; |
| |
| m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL); |
| |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; |
| 0u, //deUint32 baseMipLevel; |
| 1u, //deUint32 levelCount; |
| 0u, //deUint32 baseArrayLayer; |
| m_parameters.extent.depth, //deUint32 layerCount; |
| }; |
| |
| imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 0, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); |
| |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); |
| |
| imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); |
| } |
| |
| void MultiViewAttachmentsTestInstance::bindResources (void) |
| { |
| m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL); |
| } |
| |
| void MultiViewAttachmentsTestInstance::setImageData (VkImage image) |
| { |
| const MovePtr<tcu::Texture2DArray> data = imageData(); |
| Move<VkBuffer> buffer; |
| const deUint32 bufferSize = m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_parameters.colorFormat)); |
| MovePtr<Allocation> bufferAlloc; |
| |
| // Create source buffer |
| { |
| const VkBufferCreateInfo bufferParams = |
| { |
| VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkBufferCreateFlags flags; |
| bufferSize, // VkDeviceSize size; |
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1u, // deUint32 queueFamilyIndexCount; |
| &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; |
| }; |
| |
| buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); |
| bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); |
| } |
| |
| // Barriers for copying buffer to image |
| const VkBufferMemoryBarrier preBufferBarrier = |
| { |
| VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; |
| VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; |
| VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; |
| VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; |
| *buffer, // VkBuffer buffer; |
| 0u, // VkDeviceSize offset; |
| bufferSize // VkDeviceSize size; |
| }; |
| |
| const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(m_parameters.colorFormat)); |
| VkImageSubresourceRange subresourceRange = |
| { // VkImageSubresourceRange subresourceRange; |
| formatAspect, // VkImageAspectFlags aspect; |
| 0u, // deUint32 baseMipLevel; |
| 1u, // deUint32 mipLevels; |
| 0u, // deUint32 baseArraySlice; |
| m_parameters.extent.depth, // deUint32 arraySize; |
| }; |
| |
| const VkBufferImageCopy copyRegion = |
| { |
| 0u, // VkDeviceSize bufferOffset; |
| (deUint32)data->getLevel(0).getWidth(), // deUint32 bufferRowLength; |
| (deUint32)data->getLevel(0).getHeight(), // deUint32 bufferImageHeight; |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect; |
| 0u, // deUint32 mipLevel; |
| 0u, // deUint32 baseArrayLayer; |
| m_parameters.extent.depth, // deUint32 layerCount; |
| }, // VkImageSubresourceLayers imageSubresource; |
| { 0, 0, 0 }, // VkOffset3D imageOffset; |
| {m_parameters.extent.width, m_parameters.extent.height, 1u} // VkExtent3D imageExtent; |
| }; |
| |
| // Write buffer data |
| deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize); |
| flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc); |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 0u, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); |
| m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); |
| imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| void createVertexData (void); |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| void MultiViewInstancedTestInstance::createVertexData (void) |
| { |
| const tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); |
| |
| appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| } |
| |
| void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount); |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| void createVertexData (void); |
| |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| void MultiViewInputRateInstanceTestInstance::createVertexData (void) |
| { |
| appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f)); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f)); |
| appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f)); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f)); |
| } |
| |
| void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u); |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewDrawIndirectTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewDrawIndirectTestInstance::MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| void MultiViewDrawIndirectTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| typedef de::SharedPtr<Unique<VkBuffer> > BufferSP; |
| typedef de::SharedPtr<UniquePtr<Allocation> > AllocationSP; |
| |
| const size_t nonCoherentAtomSize = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize); |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| const deUint32 strideInBuffer = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| ? static_cast<deUint32>(sizeof(vk::VkDrawIndexedIndirectCommand)) |
| : static_cast<deUint32>(sizeof(vk::VkDrawIndirectCommand)); |
| vector< BufferSP > indirectBuffers (subpassCount); |
| vector< AllocationSP > indirectAllocations (subpassCount); |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| vector<VkDrawIndirectCommand> drawCommands; |
| vector<VkDrawIndexedIndirectCommand> drawCommandsIndexed; |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| { |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| { |
| const VkDrawIndexedIndirectCommand drawCommandIndexed = |
| { |
| 4u, // deUint32 indexCount; |
| 1u, // deUint32 instanceCount; |
| (drawNdx + subpassNdx % m_squareCount) * 4u, // deUint32 firstIndex; |
| 0u, // deInt32 vertexOffset; |
| 0u, // deUint32 firstInstance; |
| }; |
| |
| drawCommandsIndexed.push_back(drawCommandIndexed); |
| } |
| else |
| { |
| const VkDrawIndirectCommand drawCommand = |
| { |
| 4u, // deUint32 vertexCount; |
| 1u, // deUint32 instanceCount; |
| (drawNdx + subpassNdx % m_squareCount) * 4u, // deUint32 firstVertex; |
| 0u // deUint32 firstInstance; |
| }; |
| |
| drawCommands.push_back(drawCommand); |
| } |
| } |
| |
| const size_t drawCommandsLength = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| ? drawCommandsIndexed.size() |
| : drawCommands.size(); |
| const void* drawCommandsDataPtr = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| ? (void*)&drawCommandsIndexed[0] |
| : (void*)&drawCommands[0]; |
| const size_t dataSize = static_cast<size_t>(drawCommandsLength * strideInBuffer); |
| const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); |
| const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); |
| Move<VkBuffer> indirectBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); |
| MovePtr<Allocation> allocationBuffer = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *indirectBuffer), MemoryRequirement::HostVisible); |
| |
| DE_ASSERT(drawCommandsLength != 0); |
| |
| VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset())); |
| |
| deMemcpy(allocationBuffer->getHostPtr(), drawCommandsDataPtr, static_cast<size_t>(dataSize)); |
| |
| flushAlloc(*m_device, *m_logicalDevice, *allocationBuffer); |
| indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer))); |
| indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer))); |
| } |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| if (m_hasMultiDrawIndirect) |
| { |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer); |
| else |
| m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer); |
| } |
| else |
| { |
| for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++) |
| { |
| if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) |
| m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer); |
| else |
| m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer); |
| } |
| } |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| VkClearAttachment clearAttachment = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask |
| 0u, // deUint32 colorAttachment |
| makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) // VkClearValue clearValue |
| }; |
| |
| const VkOffset2D offset[2] = |
| { |
| {0, 0}, |
| {static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)} |
| }; |
| |
| const VkExtent2D extent[2] = |
| { |
| {m_parameters.extent.width, m_parameters.extent.height}, |
| {static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)} |
| }; |
| |
| const VkRect2D rect2D[2] = |
| { |
| {offset[0], extent[0]}, |
| {offset[1], extent[1]} |
| }; |
| |
| VkClearRect clearRect = |
| { |
| rect2D[0], // VkRect2D rect |
| 0u, // deUint32 baseArrayLayer |
| 1u, // deUint32 layerCount |
| }; |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); |
| |
| clearRect.rect = rect2D[1]; |
| clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| } |
| |
| void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| typedef de::SharedPtr<Unique<VkCommandBuffer> > VkCommandBufferSp; |
| |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType); |
| } |
| |
| //Create secondary buffer |
| const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *m_cmdPool, // VkCommandPool commandPool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u, // deUint32 bufferCount; |
| }; |
| vector<VkCommandBufferSp> cmdBufferSecondary; |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo)))); |
| |
| const VkCommandBufferInheritanceRenderingInfoKHR secCmdBufInheritRenderingInfo |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR, // VkRenderingFlagsKHR flags; |
| m_parameters.viewMasks[subpassNdx], // uint32_t viewMask; |
| 1u, // uint32_t colorAttachmentCount; |
| &m_parameters.colorFormat, // const VkFormat* pColorAttachmentFormats; |
| VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat; |
| VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat; |
| m_parameters.samples // VkSampleCountFlagBits rasterizationSamples; |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType; |
| m_useDynamicRendering ? &secCmdBufInheritRenderingInfo : DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| subpassNdx, // deUint32 subpass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| VK_FALSE, // VkBool32 occlusionQueryEnable; |
| (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags; |
| (VkQueryPipelineStatisticFlags)0u, // VkQueryPipelineStatisticFlags pipelineStatistics; |
| }; |
| |
| const VkCommandBufferBeginInfo info |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // VkCommandBufferUsageFlags flags; |
| &secCmdBufInheritInfo, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; |
| }; |
| |
| VK_CHECK(m_device->beginCommandBuffer(cmdBufferSecondary.back().get()->get(), &info)); |
| |
| m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); |
| |
| VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get())); |
| |
| m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get()); |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewPointSizeTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| void validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize); |
| void createVertexData (void); |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| }; |
| |
| MultiViewPointSizeTestInstance::MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| const InstanceInterface& vki = m_context.getInstanceInterface(); |
| const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); |
| const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits; |
| |
| validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_WIDE)); |
| validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_SMALL)); |
| } |
| |
| void MultiViewPointSizeTestInstance::validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize) |
| { |
| const float testPointSizeFloat = static_cast<float>(pointSize); |
| float granuleCount = 0.0f; |
| |
| if (!de::inRange(testPointSizeFloat, limits.pointSizeRange[0], limits.pointSizeRange[1])) |
| TCU_THROW(NotSupportedError, "Required point size is outside of the the limits range"); |
| |
| granuleCount = static_cast<float>(deCeilFloatToInt32((testPointSizeFloat - limits.pointSizeRange[0]) / limits.pointSizeGranularity)); |
| |
| if (limits.pointSizeRange[0] + granuleCount * limits.pointSizeGranularity != testPointSizeFloat) |
| TCU_THROW(NotSupportedError, "Granuliraty does not allow to get required point size"); |
| |
| DE_ASSERT(pointSize + 1 <= m_parameters.extent.width / 2); |
| DE_ASSERT(pointSize + 1 <= m_parameters.extent.height / 2); |
| } |
| |
| void MultiViewPointSizeTestInstance::createVertexData (void) |
| { |
| const float pixelStepX = 2.0f / static_cast<float>(m_parameters.extent.width); |
| const float pixelStepY = 2.0f / static_cast<float>(m_parameters.extent.height); |
| const int pointMargin = 1 + TEST_POINT_SIZE_WIDE / 2; |
| |
| appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); |
| appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.5f, 0.3f, 1.0f)); |
| } |
| |
| void MultiViewPointSizeTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) |
| { |
| const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; |
| const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); |
| const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; |
| const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; |
| const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; |
| |
| beginCommandBuffer(*m_device, *m_cmdBuffer); |
| |
| beforeRenderPass(); |
| |
| if (!m_useDynamicRendering) |
| { |
| const VkRenderPassBeginInfo renderPassBeginInfo |
| { |
| VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| renderPass, // VkRenderPass renderPass; |
| frameBuffer, // VkFramebuffer framebuffer; |
| renderArea, // VkRect2D renderArea; |
| 1u, // uint32_t clearValueCount; |
| &renderPassClearValue, // const VkClearValue* pClearValues; |
| }; |
| cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) |
| { |
| m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); |
| |
| m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); |
| |
| if (m_useDynamicRendering) |
| { |
| beginRendering( |
| *m_device, |
| *m_cmdBuffer, |
| m_colorAttachment->getImageView(), |
| renderArea, |
| renderPassClearValue, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), |
| 0u, |
| m_parameters.extent.depth, |
| m_parameters.viewMasks[subpassNdx]); |
| } |
| |
| for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) |
| m_device->cmdDraw(*m_cmdBuffer, 1u, 1u, drawNdx + subpassNdx % m_squareCount, 0u); |
| |
| if (m_useDynamicRendering) |
| endRendering(*m_device, *m_cmdBuffer); |
| else if (subpassNdx < subpassCount - 1u) |
| cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); |
| } |
| |
| if (!m_useDynamicRendering) |
| cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); |
| |
| afterRenderPass(); |
| |
| VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); |
| submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); |
| } |
| |
| class MultiViewMultsampleTestInstance : public MultiViewRenderTestInstance |
| { |
| public: |
| MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters); |
| protected: |
| tcu::TestStatus iterate (void); |
| void createVertexData (void); |
| |
| void draw (const deUint32 subpassCount, |
| VkRenderPass renderPass, |
| VkFramebuffer frameBuffer, |
| vector<PipelineSp>& pipelines); |
| void afterRenderPass (void); |
| private: |
| de::SharedPtr<ImageAttachment> m_resolveAttachment; |
| }; |
| |
| MultiViewMultsampleTestInstance::MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters) |
| : MultiViewRenderTestInstance (context, parameters) |
| { |
| // Color attachment |
| m_resolveAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, VK_SAMPLE_COUNT_1_BIT)); |
| } |
| |
| tcu::TestStatus MultiViewMultsampleTestInstance::iterate (void) |
| { |
| const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); |
| Move<VkRenderPass> renderPass; |
| Move<VkFramebuffer> frameBuffer; |
| |
| // FrameBuffer & renderPass |
| if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) |
| { |
| renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_4_BIT); |
| frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); |
| } |
| |
| // pipelineLayout |
| Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); |
| |
| // pipelines |
| map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; |
| vector<PipelineSp> pipelines(subpassCount); |
| const VkVertexInputRate vertexInputRate = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; |
| |
| { |
| vector<VkPipelineShaderStageCreateInfo> shaderStageParams; |
| madeShaderModule(shaderModule, shaderStageParams); |
| for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) |
| pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate)))); |
| } |
| |
| createCommandBuffer(); |
| createVertexData(); |
| createVertexBuffer(); |
| |
| draw(subpassCount, *renderPass, *frameBuffer, pipelines); |
| |
| { |
| vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); |
| tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); |
| |
| readImage(m_resolveAttachment->getImage(), dst); |
| |
| if (!checkImage(dst)) |
| return tcu::TestStatus::fail("Fail"); |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| void MultiViewMultsampleTestInstance::createVertexData (void) |
| { |
| tcu::Vec4 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); |
| |
| color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); |
| |
| color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); |
| appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); |
| appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); |
| |
| color = tcu::Vec4(0.0f, |