blob: 4ad4e057e1903e9f7b17721f34238853f60b1979 [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2019 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 Imageless Framebuffer Tests
*//*--------------------------------------------------------------------*/
#include "vktImagelessFramebufferTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"
#include "deUniquePtr.hpp"
#include "deRandom.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRGBA.hpp"
#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkBuilderUtil.hpp"
#include <iostream>
namespace vkt
{
namespace imageless
{
namespace
{
using namespace vk;
using de::MovePtr;
using de::UniquePtr;
using de::SharedPtr;
typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
enum TestType
{
TEST_TYPE_COLOR = 0,
TEST_TYPE_DEPTH_STENCIL,
TEST_TYPE_COLOR_RESOLVE,
TEST_TYPE_DEPTH_STENCIL_RESOLVE,
TEST_TYPE_MULTISUBPASS,
TEST_TYPE_LAST
};
enum AspectFlagBits
{
ASPECT_NONE = 0,
ASPECT_COLOR = (1<<0),
ASPECT_DEPTH = (1<<1),
ASPECT_STENCIL = (1<<2),
ASPECT_DEPTH_STENCIL = ASPECT_DEPTH | ASPECT_STENCIL,
};
typedef deUint32 AspectFlags;
const deUint32 NO_SAMPLE = static_cast<deUint32>(-1);
const deUint32 NO_SUBPASS = static_cast<deUint32>(-1);
struct TestParameters
{
TestType testType;
VkFormat colorFormat;
VkFormat dsFormat;
};
template<typename T>
inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
{
return SharedPtr<Unique<T> >(new Unique<T>(move));
}
VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
{
switch (count)
{
case 1: return VK_SAMPLE_COUNT_1_BIT;
case 2: return VK_SAMPLE_COUNT_2_BIT;
case 4: return VK_SAMPLE_COUNT_4_BIT;
case 8: return VK_SAMPLE_COUNT_8_BIT;
case 16: return VK_SAMPLE_COUNT_16_BIT;
case 32: return VK_SAMPLE_COUNT_32_BIT;
case 64: return VK_SAMPLE_COUNT_64_BIT;
default:
DE_FATAL("Invalid sample count");
return (VkSampleCountFlagBits)0x0;
}
}
VkAttachmentReference2KHR convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask)
{
const VkAttachmentReference2KHR attachmentReference2 =
{
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
attachmentReference.attachment, // deUint32 attachment;
attachmentReference.layout, // VkImageLayout layout;
aspectMask // VkImageAspectFlags aspectMask;
};
return attachmentReference2;
}
std::vector<VkAttachmentDescription2KHR> convertAttachmentDescriptions (const std::vector<VkAttachmentDescription>& attachmentDescriptions)
{
std::vector<VkAttachmentDescription2KHR> attachmentDescriptions2;
attachmentDescriptions2.reserve(attachmentDescriptions.size());
for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx)
{
const VkAttachmentDescription& attachmentDescription = attachmentDescriptions[adNdx];
const VkAttachmentDescription2KHR attachmentDescription2 =
{
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
attachmentDescription.flags, // VkAttachmentDescriptionFlags flags;
attachmentDescription.format, // VkFormat format;
attachmentDescription.samples, // VkSampleCountFlagBits samples;
attachmentDescription.loadOp, // VkAttachmentLoadOp loadOp;
attachmentDescription.storeOp, // VkAttachmentStoreOp storeOp;
attachmentDescription.stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp;
attachmentDescription.stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp;
attachmentDescription.initialLayout, // VkImageLayout initialLayout;
attachmentDescription.finalLayout, // VkImageLayout finalLayout;
};
attachmentDescriptions2.push_back(attachmentDescription2);
}
return attachmentDescriptions2;
}
Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
const VkDevice device,
const VkPipelineLayout pipelineLayout,
const VkRenderPass renderPass,
const VkShaderModule vertexModule,
const VkShaderModule fragmendModule,
const VkExtent2D renderSize,
const AspectFlags depthStencilAspects = ASPECT_NONE,
const VkSampleCountFlagBits sampleCountBits = VK_SAMPLE_COUNT_1_BIT,
const deUint32 subpass = 0)
{
const bool useDepth = (depthStencilAspects & ASPECT_DEPTH) != 0;
const bool useStencil = (depthStencilAspects & ASPECT_STENCIL) != 0;
const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
const VkStencilOpState stencilOpState =
{
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;
};
const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
useDepth ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable;
useDepth ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable;
VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
VK_FALSE, // VkBool32 depthBoundsTestEnable;
useStencil ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable;
stencilOpState, // VkStencilOpState front;
stencilOpState, // VkStencilOpState back;
0.0f, // float minDepthBounds;
1.0f // float maxDepthBounds;
};
const VkPipelineMultisampleStateCreateInfo multisampleState =
{
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
sampleCountBits, // VkSampleCountFlagBits rasterizationSamples;
VK_FALSE, // VkBool32 sampleShadingEnable;
0.0f, // float minSampleShading;
DE_NULL, // const VkSampleMask* pSampleMask;
VK_FALSE, // VkBool32 alphaToCoverageEnable;
VK_FALSE, // VkBool32 alphaToOneEnable;
};
return makeGraphicsPipeline(vk, // const DeviceInterface& vk
device, // const VkDevice device
pipelineLayout, // const VkPipelineLayout pipelineLayout
vertexModule, // const VkShaderModule vertexShaderModule
DE_NULL, // const VkShaderModule tessellationControlModule
DE_NULL, // const VkShaderModule tessellationEvalModule
DE_NULL, // const VkShaderModule geometryShaderModule
fragmendModule, // const VkShaderModule fragmentShaderModule
renderPass, // const VkRenderPass renderPass
viewports, // const std::vector<VkViewport>& viewports
scissors, // const std::vector<VkRect2D>& scissors
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,// const VkPrimitiveTopology topology
subpass, // const deUint32 subpass
0u, // const deUint32 patchControlPoints
DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
&multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
&pipelineDepthStencilStateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
}
Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
const VkDevice device,
const VkFormat colorFormat,
const VkFormat depthStencilFormat,
const VkSampleCountFlagBits colorSamples,
const VkSampleCountFlagBits depthStencilSamples = VK_SAMPLE_COUNT_1_BIT,
const VkAttachmentLoadOp loadOperation = VK_ATTACHMENT_LOAD_OP_CLEAR,
const VkImageLayout finalLayoutColor = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
const VkImageLayout finalLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
const VkImageLayout subpassLayoutColor = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
const VkImageLayout subpassLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
const VkAllocationCallbacks* const allocationCallbacks = DE_NULL)
{
const bool hasColor = colorFormat != VK_FORMAT_UNDEFINED;
const bool hasDepthStencil = depthStencilFormat != VK_FORMAT_UNDEFINED;
const bool hasColorResolve = hasColor && (colorSamples != VK_SAMPLE_COUNT_1_BIT);
const bool hasDepthStencilResolve = hasDepthStencil && (depthStencilSamples != VK_SAMPLE_COUNT_1_BIT);
const VkImageLayout initialLayoutColor = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
const VkImageLayout initialLayoutDepthStencil = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
const VkAttachmentDescription colorAttachmentDescription =
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
colorSamples, // VkSampleCountFlagBits samples;
loadOperation, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
initialLayoutColor, // VkImageLayout initialLayout;
finalLayoutColor // VkImageLayout finalLayout;
};
const VkAttachmentDescription depthStencilAttachmentDescription =
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
depthStencilFormat, // VkFormat format;
depthStencilSamples, // VkSampleCountFlagBits samples;
loadOperation, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
loadOperation, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
initialLayoutDepthStencil, // VkImageLayout initialLayout;
finalLayoutDepthStencil // VkImageLayout finalLayout;
};
const VkAttachmentDescription colorResolveAttachmentDescription =
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
initialLayoutColor, // VkImageLayout initialLayout;
finalLayoutColor // VkImageLayout finalLayout;
};
const VkAttachmentDescription depthStencilResolveAttachmentDescription =
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
depthStencilFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
initialLayoutDepthStencil, // VkImageLayout initialLayout;
finalLayoutDepthStencil // VkImageLayout finalLayout;
};
std::vector<VkAttachmentDescription> attachmentDescriptions;
if (hasColor)
attachmentDescriptions.push_back(colorAttachmentDescription);
if (hasDepthStencil)
attachmentDescriptions.push_back(depthStencilAttachmentDescription);
if (hasColorResolve)
attachmentDescriptions.push_back(colorResolveAttachmentDescription);
if (hasDepthStencilResolve)
attachmentDescriptions.push_back(depthStencilResolveAttachmentDescription);
deUint32 attachmentCounter = 0;
const VkAttachmentReference colorAttachmentRef =
{
hasColor ? attachmentCounter++ : 0u, // deUint32 attachment;
subpassLayoutColor // VkImageLayout layout;
};
const VkAttachmentReference depthStencilAttachmentRef =
{
hasDepthStencil ? attachmentCounter++ : 0u, // deUint32 attachment;
subpassLayoutDepthStencil // VkImageLayout layout;
};
const VkAttachmentReference colorResolveAttachmentRef =
{
hasColorResolve ? attachmentCounter++ : 0u, // deUint32 attachment;
subpassLayoutColor // VkImageLayout layout;
};
if (hasDepthStencilResolve)
{
const VkImageAspectFlags colorAspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
const VkImageAspectFlags depthStencilAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
const VkAttachmentReference2KHR colorAttachmentRef2 = convertAttachmentReference(colorAttachmentRef, colorAspectMask);
const VkAttachmentReference2KHR depthStencilAttachmentRef2 = convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
const VkAttachmentReference2KHR colorResolveAttachmentRef2 = convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
const VkAttachmentReference2KHR depthStencilResolveAttachmentRef2 =
{
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
hasDepthStencilResolve ? attachmentCounter++ : 0u, // deUint32 attachment;
subpassLayoutDepthStencil, // VkImageLayout layout;
depthStencilAspectMask // VkImageAspectFlags aspectMask;
};
const VkSubpassDescriptionDepthStencilResolveKHR subpassDescriptionDepthStencilResolve =
{
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_RESOLVE_MODE_AVERAGE_BIT_KHR, // VkResolveModeFlagBitsKHR depthResolveMode;
VK_RESOLVE_MODE_MAX_BIT_KHR, // VkResolveModeFlagBitsKHR stencilResolveMode;
&depthStencilResolveAttachmentRef2 // const VkAttachmentReference2KHR* pDepthStencilResolveAttachment;
};
const VkSubpassDescription2KHR subpassDescription2 =
{
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, // VkStructureType sType;
&subpassDescriptionDepthStencilResolve, // const void* pNext;
(VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0u, // deUint32 viewMask;
0u, // deUint32 inputAttachmentCount;
DE_NULL, // const VkAttachmentReference2KHR* pInputAttachments;
hasColor ? 1u : 0u, // deUint32 colorAttachmentCount;
hasColor ? &colorAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pColorAttachments;
hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pResolveAttachments;
hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pDepthStencilAttachment;
0u, // deUint32 preserveAttachmentCount;
DE_NULL // const deUint32* pPreserveAttachments;
};
const std::vector<VkAttachmentDescription2KHR> attachmentDescriptions2 = convertAttachmentDescriptions(attachmentDescriptions);
const VkRenderPassCreateInfo2KHR renderPassInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
(deUint32)attachmentDescriptions2.size(), // deUint32 attachmentCount;
&attachmentDescriptions2[0], // const VkAttachmentDescription2KHR* pAttachments;
1u, // deUint32 subpassCount;
&subpassDescription2, // const VkSubpassDescription2KHR* pSubpasses;
0u, // deUint32 dependencyCount;
DE_NULL, // const VkSubpassDependency2KHR* pDependencies;
0u, // deUint32 correlatedViewMaskCount;
DE_NULL // const deUint32* pCorrelatedViewMasks;
};
return createRenderPass2KHR(vk, device, &renderPassInfo, allocationCallbacks);
}
else
{
const VkSubpassDescription subpassDescription =
{
(VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0u, // deUint32 inputAttachmentCount;
DE_NULL, // const VkAttachmentReference* pInputAttachments;
hasColor ? 1u : 0u, // deUint32 colorAttachmentCount;
hasColor ? &colorAttachmentRef : DE_NULL, // const VkAttachmentReference* pColorAttachments;
hasColorResolve ? &colorResolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
0u, // deUint32 preserveAttachmentCount;
DE_NULL // const deUint32* pPreserveAttachments;
};
const VkRenderPassCreateInfo renderPassInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
(deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
&attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
1u, // deUint32 subpassCount;
&subpassDescription, // const VkSubpassDescription* pSubpasses;
0u, // deUint32 dependencyCount;
DE_NULL // const VkSubpassDependency* pDependencies;
};
return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
}
}
Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
const VkDevice device,
const VkFormat colorFormat,
const VkAllocationCallbacks* const allocationCallbacks)
{
const VkAttachmentDescription attachmentDescriptions[] =
{
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
},
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
},
};
const VkAttachmentReference colorAttachmentRef0 =
{
0u, // deUint32 attachment;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
};
const deUint32 preserveAttachment = 1u;
const VkAttachmentReference inputAttachmentRef1 =
{
0u, // deUint32 attachment;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
};
const VkAttachmentReference colorAttachmentRef1 =
{
1u, // deUint32 attachment;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
};
const VkSubpassDescription subpassDescriptions[] =
{
{
(VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0u, // deUint32 inputAttachmentCount;
DE_NULL, // const VkAttachmentReference* pInputAttachments;
1u, // deUint32 colorAttachmentCount;
&colorAttachmentRef0, // const VkAttachmentReference* pColorAttachments;
DE_NULL, // const VkAttachmentReference* pResolveAttachments;
DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
1u, // deUint32 preserveAttachmentCount;
&preserveAttachment // const deUint32* pPreserveAttachments;
},
{
(VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1u, // deUint32 inputAttachmentCount;
&inputAttachmentRef1, // const VkAttachmentReference* pInputAttachments;
1u, // deUint32 colorAttachmentCount;
&colorAttachmentRef1, // const VkAttachmentReference* pColorAttachments;
DE_NULL, // const VkAttachmentReference* pResolveAttachments;
DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
0u, // deUint32 preserveAttachmentCount;
DE_NULL // const deUint32* pPreserveAttachments;
},
};
const VkSubpassDependency subpassDependency =
{
0, // deUint32 srcSubpass;
1u, // deUint32 dstSubpass;
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask;
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask;
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask;
VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR, // VkDependencyFlags dependencyFlags;
};
const VkRenderPassCreateInfo renderPassInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
DE_LENGTH_OF_ARRAY(attachmentDescriptions), // deUint32 attachmentCount;
&attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
DE_LENGTH_OF_ARRAY(subpassDescriptions), // deUint32 subpassCount;
&subpassDescriptions[0], // const VkSubpassDescription* pSubpasses;
1u, // deUint32 dependencyCount;
&subpassDependency // const VkSubpassDependency* pDependencies;
};
return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
}
VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const VkExtent2D size, const VkImageUsageFlags usage, VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT)
{
const VkExtent3D extent = { size.width, size.height, 1u };
const VkImageCreateInfo imageParams =
{
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkImageCreateFlags flags;
VK_IMAGE_TYPE_2D, // VkImageType imageType;
format, // VkFormat format;
extent, // VkExtent3D extent;
1u, // deUint32 mipLevels;
1u, // deUint32 arrayLayers;
samples, // VkSampleCountFlagBits samples;
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
usage, // VkImageUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
0u, // deUint32 queueFamilyIndexCount;
DE_NULL, // const deUint32* pQueueFamilyIndices;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
};
return imageParams;
}
std::vector<VkFramebufferAttachmentImageInfoKHR> makeFramebufferAttachmentImageInfos (const VkExtent2D& renderSize,
const VkFormat* colorFormat,
const VkImageUsageFlags colorUsage,
const VkFormat* dsFormat,
const VkImageUsageFlags dsUsage,
const AspectFlags resolveAspects,
const deUint32 inputAttachmentCount)
{
const bool colorResolve = (resolveAspects & ASPECT_COLOR) != 0;
const bool depthStencilResolve = (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
std::vector<VkFramebufferAttachmentImageInfoKHR> framebufferAttachmentImageInfos;
DE_ASSERT(colorFormat != DE_NULL);
DE_ASSERT(dsFormat != DE_NULL);
if (*colorFormat != VK_FORMAT_UNDEFINED)
{
const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkImageCreateFlags)0u, // VkImageCreateFlags flags;
colorUsage, // VkImageUsageFlags usage;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layerCount;
1u, // deUint32 viewFormatCount;
colorFormat // const VkFormat* pViewFormats;
};
framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
}
if (*dsFormat != VK_FORMAT_UNDEFINED)
{
const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkImageCreateFlags)0u, // VkImageCreateFlags flags;
dsUsage, // VkImageUsageFlags usage;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layerCount;
1u, // deUint32 viewFormatCount;
dsFormat // const VkFormat* pViewFormats;
};
framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
}
if (colorResolve)
{
const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkImageCreateFlags)0u, // VkImageCreateFlags flags;
colorUsage, // VkImageUsageFlags usage;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layerCount;
1u, // deUint32 viewFormatCount;
colorFormat // const VkFormat* pViewFormats;
};
DE_ASSERT(*colorFormat != VK_FORMAT_UNDEFINED);
framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
}
if (depthStencilResolve)
{
const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkImageCreateFlags)0u, // VkImageCreateFlags flags;
dsUsage, // VkImageUsageFlags usage;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layerCount;
1u, // deUint32 viewFormatCount;
dsFormat // const VkFormat* pViewFormats;
};
DE_ASSERT(*dsFormat != VK_FORMAT_UNDEFINED);
framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
}
for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx)
{
const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkImageCreateFlags)0u, // VkImageCreateFlags flags;
colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, // VkImageUsageFlags usage;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layerCount;
1u, // deUint32 viewFormatCount;
colorFormat // const VkFormat* pViewFormats;
};
framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
}
return framebufferAttachmentImageInfos;
}
Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
const VkDevice device,
const VkRenderPass renderPass,
const VkExtent2D& renderSize,
const VkFormat* colorFormat,
const VkImageUsageFlags colorUsage,
const VkFormat* dsFormat,
const VkImageUsageFlags dsUsage = static_cast<VkImageUsageFlags>(0),
const AspectFlags resolveAspects = ASPECT_NONE,
const deUint32 inputAttachmentCount = 0)
{
const std::vector<VkFramebufferAttachmentImageInfoKHR> framebufferAttachmentImageInfos = makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount);
const deUint32 attachmentCount = static_cast<deUint32>(framebufferAttachmentImageInfos.size());
const VkFramebufferAttachmentsCreateInfoKHR framebufferAttachmentsCreateInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
attachmentCount, // deUint32 attachmentImageInfoCount;
&framebufferAttachmentImageInfos[0] // const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos;
};
const VkFramebufferCreateInfo framebufferInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
&framebufferAttachmentsCreateInfo, // const void* pNext;
VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR, // VkFramebufferCreateFlags flags;
renderPass, // VkRenderPass renderPass;
attachmentCount, // deUint32 attachmentCount;
DE_NULL, // const VkImageView* pAttachments;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
1u, // deUint32 layers;
};
return createFramebuffer(vk, device, &framebufferInfo);
}
Move<VkFramebuffer> makeVerifyFramebuffer (const DeviceInterface& vk,
const VkDevice device,
const VkRenderPass renderPass,
const VkImageView colorAttachment,
const VkExtent2D& renderSize,
const deUint32 layers = 1u)
{
const VkFramebufferCreateInfo framebufferInfo = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
renderPass, // VkRenderPass renderPass;
1u, // deUint32 attachmentCount;
&colorAttachment, // const VkImageView* pAttachments;
renderSize.width, // deUint32 width;
renderSize.height, // deUint32 height;
layers, // deUint32 layers;
};
return createFramebuffer(vk, device, &framebufferInfo);
}
Move<VkPipelineLayout> makeVerifyPipelineLayout (const DeviceInterface& vk,
const VkDevice device,
const VkDescriptorSetLayout descriptorSetLayout)
{
const VkPushConstantRange pushConstantRanges =
{
VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
0u, // deUint32 offset;
sizeof(deUint32) // deUint32 size;
};
const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1u, // deUint32 setLayoutCount;
&descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1u, // deUint32 pushConstantRangeCount;
&pushConstantRanges, // const VkPushConstantRange* pPushConstantRanges;
};
return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
}
Move<VkRenderPass> makeVerifyRenderPass (const DeviceInterface& vk,
const VkDevice device,
const VkFormat colorFormat)
{
return makeRenderPass(vk, device, colorFormat);
}
VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
const VkAccessFlags dstAccessMask,
const VkImageLayout oldLayout,
const VkImageLayout newLayout,
const VkImage image,
const VkImageSubresourceRange subresourceRange)
{
const VkImageMemoryBarrier barrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
srcAccessMask, // VkAccessFlags outputMask;
dstAccessMask, // VkAccessFlags inputMask;
oldLayout, // VkImageLayout oldLayout;
newLayout, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
image, // VkImage image;
subresourceRange, // VkImageSubresourceRange subresourceRange;
};
return barrier;
}
VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
const VkAccessFlags dstAccessMask,
const VkBuffer buffer,
const VkDeviceSize offset,
const VkDeviceSize bufferSizeBytes)
{
const VkBufferMemoryBarrier barrier =
{
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
srcAccessMask, // VkAccessFlags srcAccessMask;
dstAccessMask, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
buffer, // VkBuffer buffer;
offset, // VkDeviceSize offset;
bufferSizeBytes, // VkDeviceSize size;
};
return barrier;
}
VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
const VkImageSubresourceLayers subresourceLayers)
{
const VkBufferImageCopy copyParams =
{
0ull, // VkDeviceSize bufferOffset;
0u, // deUint32 bufferRowLength;
0u, // deUint32 bufferImageHeight;
subresourceLayers, // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
extent, // VkExtent3D imageExtent;
};
return copyParams;
}
inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo)
{
return createBuffer(vk, device, &createInfo);
}
inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
{
return createImage(vk, device, &createInfo);
}
MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
{
MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
return alloc;
}
MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
{
MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
return alloc;
}
Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
{
const VkSamplerCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkSamplerCreateFlags flags;
VK_FILTER_NEAREST, // VkFilter magFilter;
VK_FILTER_NEAREST, // VkFilter minFilter;
VK_SAMPLER_MIPMAP_MODE_LINEAR, // VkSamplerMipmapMode mipmapMode;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
0.0f, // float mipLodBias;
VK_FALSE, // VkBool32 anisotropyEnable;
1.0f, // float maxAnisotropy;
VK_FALSE, // VkBool32 compareEnable;
VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
0.0f, // float minLod;
0.0f, // float maxLod;
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
VK_FALSE // VkBool32 unnormalizedCoordinates;
};
return createSampler(vk, device, &createInfo);
}
void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, const void* data, const VkDeviceSize dataSize)
{
const VkMappedMemoryRange memRange =
{
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
DE_NULL, // const void* pNext;
bufferAlloc.getMemory(), // VkDeviceMemory memory;
bufferAlloc.getOffset(), // VkDeviceSize offset;
VK_WHOLE_SIZE // VkDeviceSize size;
};
const deUint32 dataSize32 = static_cast<deUint32>(dataSize);
deMemcpy(bufferAlloc.getHostPtr(), data, dataSize32);
VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
}
std::vector<float> getFullQuadVertices (void)
{
const float verticesData[] =
{
-1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, -1.0f, 0.0f, 1.0f,
+1.0f, +1.0f, 0.0f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
void checkImageFormatProperties (const InstanceInterface& vki,
const VkPhysicalDevice& physDevice,
const VkFormat format,
const VkImageUsageFlags imageUsageFlags,
const VkExtent2D& requiredSize2D)
{
const VkImageType imageType = VK_IMAGE_TYPE_2D;
const VkImageTiling imageTiling = VK_IMAGE_TILING_OPTIMAL;
const VkImageCreateFlags imageCreateFlags = static_cast<VkImageCreateFlags>(0u);
const deUint32 requiredLayers = 1u;
const VkExtent3D requiredSize = makeExtent3D(requiredSize2D.height, requiredSize2D.width, 1u);
VkImageFormatProperties imageFormatProperties;
VkResult result;
deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties));
result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
if (result != VK_SUCCESS ||
imageFormatProperties.maxArrayLayers < requiredLayers ||
imageFormatProperties.maxExtent.height < requiredSize.height ||
imageFormatProperties.maxExtent.width < requiredSize.width ||
imageFormatProperties.maxExtent.depth < requiredSize.depth)
{
TCU_THROW(NotSupportedError, "Depth/stencil format is not supported");
}
}
VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat)
{
const tcu::TextureFormat tcuFormat = mapVkFormat(depthStencilImageFormat);
const VkFormat result = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED;
DE_ASSERT(result != VK_FORMAT_UNDEFINED);
return result;
}
static MovePtr<tcu::TextureLevel> convertDepthToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
{
const tcu::ConstPixelBufferAccess srcImage (dataFormat, width, height, 1u, data);
MovePtr<tcu::TextureLevel> dstImage (new tcu::TextureLevel(targetFormat, width, height, 1u));
tcu::PixelBufferAccess dstAccess (dstImage->getAccess());
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
const float depth = srcImage.getPixDepth(x, y);
const tcu::Vec4 color = tcu::Vec4(depth, depth, depth, 1.0f);
dstAccess.setPixel(color, x, y);
}
return dstImage;
}
static MovePtr<tcu::TextureLevel> convertStencilToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
{
const int maxValue (4);
const tcu::ConstPixelBufferAccess srcImage (dataFormat, width, height, 1u, data);
MovePtr<tcu::TextureLevel> dstImage (new tcu::TextureLevel(targetFormat, width, height, 1u));
tcu::PixelBufferAccess dstAccess (dstImage->getAccess());
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
const int stencilInt = srcImage.getPixStencil(x, y);
const float stencil = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f;
const tcu::Vec4 color = tcu::Vec4(stencil, stencil, stencil, 1.0f);
dstAccess.setPixel(color, x, y);
}
return dstImage;
}
class ColorImagelessTestInstance : public TestInstance
{
public:
ColorImagelessTestInstance (Context& context, const TestParameters& parameters);
protected:
virtual tcu::TestStatus iterate (void);
virtual std::vector<float> getVertices (void);
void readOneSampleFromMultisampleImage (const VkFormat srcFormat,
const Unique<VkImage>& srcImage,
const deUint32 sampleID,
const VkFormat dstFormat,
const Unique<VkImage>& dstImage,
const Unique<VkBuffer>& dstBuffer,
const AspectFlags aspect);
virtual MovePtr<tcu::TextureLevel> generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass);
virtual bool verifyBuffer (const UniquePtr<Allocation>& bufAlloc,
const VkFormat bufferFormat,
const std::string& name,
const AspectFlags aspectFlags,
const deUint32 sample = NO_SAMPLE,
const deUint32 subpass = NO_SUBPASS);
virtual bool verifyBufferInternal (const void* resultData,
const tcu::TextureFormat& textureFormat,
const tcu::TextureLevel& referenceImage,
const std::string& name);
const bool m_extensions;
const VkExtent2D m_imageExtent2D;
const TestParameters m_parameters;
VkImageUsageFlags m_colorImageUsage;
};
ColorImagelessTestInstance::ColorImagelessTestInstance (Context& context, const TestParameters& parameters)
: TestInstance (context)
, m_extensions (context.requireDeviceExtension("VK_KHR_imageless_framebuffer"))
, m_imageExtent2D (makeExtent2D(32u, 32u))
, m_parameters (parameters)
, m_colorImageUsage (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
{
const InstanceInterface& vki = m_context.getInstanceInterface();
const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& imagelessFramebufferFeatures (context.getImagelessFramebufferFeatures());
if (imagelessFramebufferFeatures.imagelessFramebuffer == DE_FALSE)
TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported");
checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
}
void ColorImagelessTestInstance::readOneSampleFromMultisampleImage (const VkFormat srcFormat,
const Unique<VkImage>& srcImage,
const deUint32 sampleID,
const VkFormat dstFormat,
const Unique<VkImage>& dstImage,
const Unique<VkBuffer>& dstBuffer,
const AspectFlags aspect)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const bool color = ((aspect & ASPECT_COLOR) != 0);
const bool depth = ((aspect & ASPECT_DEPTH) != 0);
const bool stencil = ((aspect & ASPECT_STENCIL) != 0);
const VkImageAspectFlags srcAspect = color ? VK_IMAGE_ASPECT_COLOR_BIT
: depth ? VK_IMAGE_ASPECT_DEPTH_BIT
: VK_IMAGE_ASPECT_STENCIL_BIT;
const VkImageSubresourceRange srcSubresRange = makeImageSubresourceRange(srcAspect, 0u, 1u, 0u, 1u);
const Unique<VkImageView> srcImageView (makeImageView (vk, device, *srcImage, VK_IMAGE_VIEW_TYPE_2D, srcFormat, srcSubresRange));
const VkImageAspectFlags dstAspect = VK_IMAGE_ASPECT_COLOR_BIT;
const VkImageSubresourceRange dstSubresRange = makeImageSubresourceRange(dstAspect, 0u, 1u, 0u, 1u);
const Unique<VkImageView> dstAttachment (makeImageView (vk, device, *dstImage, VK_IMAGE_VIEW_TYPE_2D, dstFormat, dstSubresRange));
const std::string fragModuleInfix = color ? "-color"
: depth ? "-depth"
: stencil ? "-stencil"
: "";
const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("demultisample-vert"), 0u));
const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("demultisample" + fragModuleInfix + "-frag"), 0u));
const Unique<VkRenderPass> renderPass (makeVerifyRenderPass (vk, device, dstFormat));
const Unique<VkFramebuffer> framebuffer (makeVerifyFramebuffer (vk, device, *renderPass, *dstAttachment, m_imageExtent2D));
const VkDescriptorType samplerDescType (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
const Unique<VkSampler> sampler (makeSampler(vk, device));
const Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
.addSingleSamplerBinding(samplerDescType, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
.build(vk, device));
const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
.addType(samplerDescType)
.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
const VkDescriptorImageInfo imageDescriptorInfo (makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
DescriptorSetUpdateBuilder()
.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), samplerDescType, &imageDescriptorInfo)
.update(vk, device);
const Unique<VkPipelineLayout> pipelineLayout (makeVerifyPipelineLayout (vk, device, *descriptorSetLayout));
const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const std::vector<float> vertexArray (getFullQuadVertices());
const deUint32 vertexCount (static_cast<deUint32>(vertexArray.size() / 4u));
const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0]));
const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertexBufferOffset (0u);
fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
if (sampleID == 0)
{
if (color)
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
*srcImage, srcSubresRange);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
}
else if (depth)
{
const VkImageSubresourceRange preCopySubresRange = makeImageSubresourceRange (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
*srcImage, preCopySubresRange);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
}
}
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleID), &sampleID);
vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
}
endRenderPass(vk, *cmdBuffer);
// Image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*dstImage, dstSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *dstBuffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}
bool ColorImagelessTestInstance::verifyBufferInternal (const void* resultData, const tcu::TextureFormat& textureFormat, const tcu::TextureLevel& referenceImage, const std::string& name)
{
const int dataSize (m_imageExtent2D.width * m_imageExtent2D.height * textureFormat.getPixelSize());
const tcu::ConstPixelBufferAccess referenceAccess (referenceImage.getAccess());
if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
{
const tcu::ConstPixelBufferAccess resultImage (textureFormat, m_imageExtent2D.width, m_imageExtent2D.height, 1u, resultData);
bool ok;
ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
return ok;
}
return true;
}
bool ColorImagelessTestInstance::verifyBuffer (const UniquePtr<Allocation>& bufAlloc, const VkFormat bufferFormat, const std::string& name, const AspectFlags aspectFlags, const deUint32 sample, const deUint32 subpass)
{
invalidateMappedMemoryRange(m_context.getDeviceInterface(), m_context.getDevice(), bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
const tcu::TextureFormat bufferTextureFormat (mapVkFormat(bufferFormat));
const bool multisampled (sample != NO_SAMPLE);
const bool depth ((aspectFlags & ASPECT_DEPTH) != 0);
const bool stencil ((aspectFlags & ASPECT_STENCIL) != 0);
const bool convertRequired ((depth || stencil) && !multisampled);
const tcu::TextureFormat convertTextureFormat (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNORM_INT8));
const tcu::TextureFormat referenceTextureFormat (convertRequired ? convertTextureFormat : bufferTextureFormat);
const MovePtr<tcu::TextureLevel> referenceImage (generateReferenceImage(referenceTextureFormat, aspectFlags, sample, subpass));
if (!multisampled && depth)
{
MovePtr<tcu::TextureLevel> convertedImage (convertDepthToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
tcu::ConstPixelBufferAccess convertedAccess (convertedImage->getAccess());
return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
}
else if (!multisampled && stencil)
{
MovePtr<tcu::TextureLevel> convertedImage (convertStencilToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
tcu::ConstPixelBufferAccess convertedAccess (convertedImage->getAccess());
return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
}
else
{
const void* resultData (bufAlloc->getHostPtr());
return verifyBufferInternal(resultData, bufferTextureFormat, *referenceImage, name);
}
}
MovePtr<tcu::TextureLevel> ColorImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass)
{
const int width = m_imageExtent2D.width;
const int height = m_imageExtent2D.height;
const int componentValue (static_cast<int>(0.75f * 0x100));
const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
const tcu::Vec4 colorDraw (colorDrawRGBA.toVec());
const tcu::Vec4 colorFill (tcu::RGBA::black().toVec());
MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(textureFormat, width, height));
tcu::PixelBufferAccess access (image->getAccess());
DE_UNREF(aspectFlags);
DE_ASSERT(aspectFlags == ASPECT_COLOR);
DE_UNREF(sample);
DE_ASSERT(sample == NO_SAMPLE);
DE_UNREF(subpass);
DE_ASSERT(subpass == NO_SUBPASS);
for (int y = 0; y < height; ++y)
{
const tcu::Vec4& validColor = (y < height / 2) ? colorFill : colorDraw;
for (int x = 0; x < width; ++x)
access.setPixel(validColor, x, y);
}
return image;
}
std::vector<float> ColorImagelessTestInstance::getVertices (void)
{
const float verticesData[] =
{
-1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, 0.0f, 0.0f, 1.0f,
+1.0f, +1.0f, 0.0f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
tcu::TestStatus ColorImagelessTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const VkFormat colorFormat = m_parameters.colorFormat;
const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat));
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const std::vector<float> vertexArray (getVertices());
const deUint32 vertexCount (static_cast<deUint32>(vertexArray.size() / 4u));
const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0]));
const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertexBufferOffset (0u);
fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
1u, // deUint32 attachmentCount;
&*colorAttachment // const VkImageView* pAttachments;
};
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
}
endRenderPass(vk, *cmdBuffer);
// Color image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*colorImage, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
if (verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
return tcu::TestStatus::pass("Pass");
else
return tcu::TestStatus::fail("Fail");
}
class DepthImagelessTestInstance : public ColorImagelessTestInstance
{
public:
DepthImagelessTestInstance (Context& context, const TestParameters& parameters);
protected:
virtual tcu::TestStatus iterate (void);
virtual std::vector<float> getVertices (void);
virtual MovePtr<tcu::TextureLevel> generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass);
VkImageUsageFlags m_dsImageUsage;
};
DepthImagelessTestInstance::DepthImagelessTestInstance (Context& context, const TestParameters& parameters)
: ColorImagelessTestInstance (context, parameters)
, m_dsImageUsage (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
{
const InstanceInterface& vki = m_context.getInstanceInterface();
const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
}
MovePtr<tcu::TextureLevel> DepthImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass)
{
const bool color = ((aspectFlags & ASPECT_COLOR) != 0);
const bool depth = ((aspectFlags & ASPECT_DEPTH) != 0);
const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
const int width = m_imageExtent2D.width;
const int height = m_imageExtent2D.height;
MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(textureFormat, width, height));
tcu::PixelBufferAccess access (image->getAccess());
DE_ASSERT(dePop32(aspectFlags) == 1);
DE_UNREF(sample);
DE_ASSERT(sample == NO_SAMPLE);
DE_UNREF(subpass);
DE_ASSERT(subpass == NO_SUBPASS);
if (color)
{
const int componentValue (static_cast<int>(0.75f * 0x100));
const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
const tcu::Vec4 colorDraw (colorDrawRGBA.toVec());
const tcu::Vec4 colorDrawTop (tcu::RGBA::white().toVec());
const tcu::Vec4 colorFill (tcu::RGBA::black().toVec());
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const tcu::Vec4& validColor = (y < height / 2) ? colorFill
: (x < width / 2) ? colorDraw
: colorDrawTop;
access.setPixel(validColor, x, y);
}
}
if (depth)
{
const int colorFillValue (static_cast<int>(1.00f * 0x100));
const int colorDrawValue (static_cast<int>(0.50f * 0x100));
const int colorTopValue (static_cast<int>(0.25f * 0x100));
const tcu::IVec4 colorFill (colorFillValue, 0, 0, 0xFF);
const tcu::IVec4 colorDraw (colorDrawValue, 0, 0, 0xFF);
const tcu::IVec4 colorTop (colorTopValue, 0, 0, 0xFF);
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const tcu::IVec4& validColor = (y < height / 2) ? colorFill
: (x < width / 2) ? colorDraw
: colorTop;
access.setPixel(validColor, x, y);
}
}
if (stencil)
{
const int colorFillValue (static_cast<int>(0.00f * 0x100));
const int colorDrawValue (static_cast<int>(0.25f * 0x100));
const int colorTopValue (static_cast<int>(0.50f * 0x100));
const tcu::IVec4 colorFill (colorFillValue, 0, 0, 0xFF);
const tcu::IVec4 colorDraw (colorDrawValue, 0, 0, 0xFF);
const tcu::IVec4 colorTop (colorTopValue, 0, 0, 0xFF);
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const tcu::IVec4& validColor = (y < height / 2) ? colorFill
: (x < width / 2) ? colorDraw
: colorTop;
access.setPixel(validColor, x, y);
}
}
return image;
}
std::vector<float> DepthImagelessTestInstance::getVertices (void)
{
const float verticesData[] =
{
-1.0f, 0.0f, 0.50f, 1.0f,
-1.0f, +1.0f, 0.50f, 1.0f,
+1.0f, 0.0f, 0.50f, 1.0f,
-1.0f, +1.0f, 0.50f, 1.0f,
+1.0f, 0.0f, 0.50f, 1.0f,
+1.0f, +1.0f, 0.50f, 1.0f,
0.0f, 0.0f, 0.25f, 1.0f,
0.0f, +1.0f, 0.25f, 1.0f,
+1.0f, 0.0f, 0.25f, 1.0f,
0.0f, +1.0f, 0.25f, 1.0f,
+1.0f, 0.0f, 0.25f, 1.0f,
+1.0f, +1.0f, 0.25f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
tcu::TestStatus DepthImagelessTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const VkFormat colorFormat = m_parameters.colorFormat;
const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
const float clearDepth = 1.0f;
const deUint32 clearStencil = 0u;
const VkFormat dsFormat = m_parameters.dsFormat;
const deUint32 dsImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
const VkDeviceSize depthBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat);
const deUint32 stencilPixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
const Unique<VkImage> dsImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
const UniquePtr<Allocation> dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any));
const Unique<VkImageView> dsAttachment (makeImageView (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
const Unique<VkBuffer> depthBuffer (makeBuffer (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> depthBufferAlloc (bindBuffer (vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible));
const Unique<VkBuffer> stencilBuffer (makeBuffer (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> stencilBufferAlloc (bindBuffer (vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible));
const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, dsFormat));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &dsFormat, m_dsImageUsage));
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const std::vector<float> vertexArray (getVertices());
const deUint32 vertexCount (static_cast<deUint32>(vertexArray.size() / 4u));
const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0]));
const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertexBufferOffset (0u);
fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
const VkImageView attachments[] = { *colorAttachment, *dsAttachment };
const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount;
attachments // const VkImageView* pAttachments;
};
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
}
endRenderPass(vk, *cmdBuffer);
// Color image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*colorImage, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
// Depth/Stencil image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange);
const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarriers[] =
{
makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE),
makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE),
};
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion);
vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
{
std::string result;
if (!verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
result += " Color";
if (!verifyBuffer(depthBufferAlloc, dsFormat, "Depth", ASPECT_DEPTH))
result += " Depth";
if (!verifyBuffer(stencilBufferAlloc, stencilBufferFormat, "Stencil", ASPECT_STENCIL))
result += " Stencil";
if (result.empty())
return tcu::TestStatus::pass("Pass");
else
return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
}
}
class ColorResolveImagelessTestInstance : public ColorImagelessTestInstance
{
public:
ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters);
protected:
virtual tcu::TestStatus iterate (void);
virtual MovePtr<tcu::TextureLevel> generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass);
virtual std::vector<float> getVertices (void);
};
ColorResolveImagelessTestInstance::ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
: ColorImagelessTestInstance (context, parameters)
{
const InstanceInterface& vki = m_context.getInstanceInterface();
const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
// To validate per-sample image image must also be sampled
m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
}
MovePtr<tcu::TextureLevel> ColorResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass)
{
const int width = m_imageExtent2D.width;
const int height = m_imageExtent2D.height;
MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(textureFormat, width, height));
tcu::PixelBufferAccess access (image->getAccess());
const int componentValue (static_cast<int>(0.75f * 0x100));
const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
const tcu::Vec4 colorDraw (colorDrawRGBA.toVec());
const tcu::Vec4 colorFill (tcu::RGBA::black().toVec());
const tcu::Vec4 colorEdge0 (colorDraw);
const tcu::Vec4 colorEdge1 (colorFill);
const tcu::Vec4 colorEdge2 (colorDraw);
const tcu::Vec4 colorEdge3 (colorFill);
const tcu::Vec4 colorEdgeR ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w());
const tcu::Vec4& colorEdge = sample == 0 ? colorEdge0
: sample == 1 ? colorEdge1
: sample == 2 ? colorEdge2
: sample == 3 ? colorEdge3
: colorEdgeR;
DE_UNREF(aspectFlags);
DE_ASSERT(dePop32(aspectFlags) == 1);
DE_ASSERT(aspectFlags == ASPECT_COLOR);
DE_UNREF(subpass);
DE_ASSERT(subpass == NO_SUBPASS);
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const int mx = width - 1 - x;
const tcu::Vec4& validColor = (y == mx) ? colorEdge
: (y > mx) ? colorFill
: colorDraw;
access.setPixel(validColor, x, y);
}
return image;
}
std::vector<float> ColorResolveImagelessTestInstance::getVertices (void)
{
const float verticesData[] =
{
-1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, -1.0f, 0.0f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
tcu::TestStatus ColorResolveImagelessTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const VkFormat colorFormat = m_parameters.colorFormat;
const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCount)));
const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkImage> colorResolveImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> colorResolveImageAlloc (bindImage (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
const Unique<VkImageView> colorResolveAttachment (makeImageView (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> colorResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> colorResolveBufferAlloc (bindBuffer (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat, sampleCount));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, 0u, ASPECT_COLOR));
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_NONE, sampleCount));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const std::vector<float> vertexArray (getVertices());
const deUint32 vertexCount (static_cast<deUint32>(vertexArray.size() / 4u));
const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0]));
const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertexBufferOffset (0u);
fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
const VkImageView attachments[] = { *colorAttachment, *colorResolveAttachment };
const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount;
attachments // const VkImageView* pAttachments;
};
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
}
endRenderPass(vk, *cmdBuffer);
// Color image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*colorResolveImage, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
{
std::string result;
if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
result += " ResolveColor";
// Parse color aspect of separate samples of multisample image
for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
{
const std::string name ("Color" + de::toString(sampleNdx));
const Unique<VkImage> imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any));
const Unique<VkBuffer> imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);
if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
result += " " + name;
}
if (result.empty())
return tcu::TestStatus::pass("Pass");
else
return tcu::TestStatus::fail("Fail");
}
}
class DepthResolveImagelessTestInstance : public DepthImagelessTestInstance
{
public:
DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters);
protected:
virtual tcu::TestStatus iterate (void);
virtual MovePtr<tcu::TextureLevel> generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass);
virtual std::vector<float> getVertices (void);
};
DepthResolveImagelessTestInstance::DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
: DepthImagelessTestInstance (context, parameters)
{
context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");
const InstanceInterface& vki = m_context.getInstanceInterface();
const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
VkPhysicalDeviceProperties2 deviceProperties;
VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties;
deMemset(&deviceProperties, 0, sizeof(deviceProperties));
deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties));
deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
deviceProperties.pNext = &dsResolveProperties;
dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
dsResolveProperties.pNext = DE_NULL;
vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties);
if ((dsResolveProperties.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) == 0)
TCU_THROW(NotSupportedError, "Depth resolve does not support required VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
if ((dsResolveProperties.supportedStencilResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) == 0)
TCU_THROW(NotSupportedError, "Stencil resolve does not support required VK_RESOLVE_MODE_MAX_BIT_KHR");
m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
m_dsImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
}
MovePtr<tcu::TextureLevel> DepthResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass)
{
const bool color = ((aspectFlags & ASPECT_COLOR) != 0);
const bool depth = ((aspectFlags & ASPECT_DEPTH) != 0);
const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
const int width = m_imageExtent2D.width;
const int height = m_imageExtent2D.height;
MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(textureFormat, width, height));
tcu::PixelBufferAccess access (image->getAccess());
DE_ASSERT(dePop32(aspectFlags) == 1);
DE_UNREF(subpass);
if (color)
{
const tcu::Vec4 colorDraw (tcu::RGBA::blue().toVec());
const tcu::Vec4 colorFill (tcu::RGBA::black().toVec());
const tcu::Vec4 colorEdge0 (colorDraw);
const tcu::Vec4 colorEdge1 (colorFill);
const tcu::Vec4 colorEdge2 (colorDraw);
const tcu::Vec4 colorEdge3 (colorFill);
const tcu::Vec4 colorEdgeR ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w());
const tcu::Vec4& colorEdge = sample == 0 ? colorEdge0
: sample == 1 ? colorEdge1
: sample == 2 ? colorEdge2
: sample == 3 ? colorEdge3
: colorEdgeR;
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const int mx = width - 1 - x;
const tcu::Vec4& validColor = (y == mx) ? colorEdge
: (y > mx) ? colorFill
: colorDraw;
access.setPixel(validColor, x, y);
}
}
if (depth)
{
const int colorFillValue (static_cast<int>(1.00f * 0x100));
const int colorDrawValue (static_cast<int>(0.00f * 0x100));
const int colorEdgeValue (static_cast<int>(0.50f * 0x100));
const tcu::IVec4 colorFill (colorFillValue, colorFillValue, colorFillValue, 0xFF);
const tcu::IVec4 colorDraw (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
const tcu::IVec4 colorEdge0 (colorDraw);
const tcu::IVec4 colorEdge1 (colorFill);
const tcu::IVec4 colorEdge2 (colorDraw);
const tcu::IVec4 colorEdge3 (colorFill);
const tcu::IVec4 colorEdgeR (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF);
const tcu::IVec4& colorEdge = sample == 0 ? colorEdge0
: sample == 1 ? colorEdge1
: sample == 2 ? colorEdge2
: sample == 3 ? colorEdge3
: colorEdgeR;
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const int mx = width - 1 - x;
const tcu::IVec4& validColor = (y == mx) ? colorEdge
: (y > mx) ? colorFill
: colorDraw;
access.setPixel(validColor, x, y);
}
}
if (stencil)
{
const int colorFillValue ((0 * 0x100) / 4);
const int colorDrawValue ((1 * 0x100) / 4);
const int colorEdgeValue ((1 * 0x100) / 4);
const tcu::IVec4 colorFill (colorFillValue, colorFillValue, colorFillValue, 0xFF);
const tcu::IVec4 colorDraw (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
const tcu::IVec4 colorEdge0 (colorDraw);
const tcu::IVec4 colorEdge1 (colorFill);
const tcu::IVec4 colorEdge2 (colorDraw);
const tcu::IVec4 colorEdge3 (colorFill);
const tcu::IVec4 colorEdgeR (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF);
const tcu::IVec4& colorEdge = sample == 0 ? colorEdge0
: sample == 1 ? colorEdge1
: sample == 2 ? colorEdge2
: sample == 3 ? colorEdge3
: colorEdgeR;
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
{
const int mx = width - 1 - x;
const tcu::IVec4& validColor = (y == mx) ? colorEdge
: (y > mx) ? colorFill
: colorDraw;
access.setPixel(validColor, x, y);
}
}
return image;
}
std::vector<float> DepthResolveImagelessTestInstance::getVertices (void)
{
const float verticesData[] =
{
-1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.5f, 1.0f,
-1.0f, +1.0f, 0.5f, 1.0f,
+1.0f, -1.0f, 0.5f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
tcu::TestStatus DepthResolveImagelessTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const deUint32 sampleCount = 4u;
const VkSampleCountFlagBits sampleCountFlag = sampleCountBitFromSampleCount(sampleCount);
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const VkFormat colorFormat = m_parameters.colorFormat;
const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCountFlag)));
const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkImage> colorResolveImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> colorResolveImageAlloc (bindImage (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
const Unique<VkImageView> colorResolveAttachment (makeImageView (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> colorResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> colorResolveBufferAlloc (bindBuffer (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
const float clearDepth = 1.0f;
const deUint32 clearStencil = 0u;
const VkFormat dsFormat = m_parameters.dsFormat;
const deUint32 dsImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
const VkDeviceSize depthBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat);
const deUint32 stencilPixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
const Unique<VkImage> dsImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage, sampleCountFlag)));
const UniquePtr<Allocation> dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any));
const Unique<VkImageView> dsAttachment (makeImageView (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
const Unique<VkImage> dsResolveImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
const UniquePtr<Allocation> dsResolveImageAlloc (bindImage (vk, device, allocator, *dsResolveImage, MemoryRequirement::Any));
const Unique<VkImageView> dsResolveAttachment (makeImageView (vk, device, *dsResolveImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
const Unique<VkBuffer> depthResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> depthResolveBufferAlloc (bindBuffer (vk, device, allocator, *depthResolveBuffer, MemoryRequirement::HostVisible));
const Unique<VkBuffer> stencilResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> stencilResolveBufferAlloc (bindBuffer (vk, device, allocator, *stencilResolveBuffer, MemoryRequirement::HostVisible));
const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat, sampleCountFlag, sampleCountFlag));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, m_dsImageUsage, ASPECT_COLOR|ASPECT_DEPTH_STENCIL));
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL, sampleCountFlag));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const std::vector<float> vertexArray (getVertices());
const deUint32 vertexCount (static_cast<deUint32>(vertexArray.size() / 4u));
const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0]));
const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertexBufferOffset (0u);
fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
const VkImageView attachments[] = { *colorAttachment, *dsAttachment, *colorResolveAttachment, *dsResolveAttachment };
const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount;
attachments // const VkImageView* pAttachments;
};
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
}
endRenderPass(vk, *cmdBuffer);
// Color resolve image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*colorResolveImage, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
// Depth/Stencil resolve image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*dsResolveImage, dsSubresRange);
const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarriers[] =
{
makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthResolveBuffer, 0ull, VK_WHOLE_SIZE),
makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilResolveBuffer, 0ull, VK_WHOLE_SIZE),
};
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthResolveBuffer, 1u, &depthCopyRegion);
vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilResolveBuffer, 1u, &stencilCopyRegion);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
{
std::string result;
if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
result += " ResolveColor";
if (!verifyBuffer(depthResolveBufferAlloc, dsFormat, "ResolveDepth", ASPECT_DEPTH))
result += " ResolveDepth";
if (!verifyBuffer(stencilResolveBufferAlloc, stencilBufferFormat, "ResolveStencil", ASPECT_STENCIL))
result += " ResolveStencil";
// Parse color aspect of separate samples of multisample image
for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
{
const std::string name ("Color" + de::toString(sampleNdx));
const Unique<VkImage> imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any));
const Unique<VkBuffer> imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);
if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
result += " " + name;
}
// Parse depth aspect of separate samples of multisample image
for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
{
const std::string name ("Depth" + de::toString(sampleNdx));
const Unique<VkImage> imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any));
const Unique<VkBuffer> imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_DEPTH);
if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_DEPTH, sampleNdx))
result += " " + name;
}
// Parse stencil aspect of separate samples of multisample image
for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
{
const std::string name ("Stencil" + de::toString(sampleNdx));
const Unique<VkImage> imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
const UniquePtr<Allocation> imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any));
const Unique<VkBuffer> imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_STENCIL);
if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_STENCIL, sampleNdx))
result += " " + name;
}
if (result.empty())
return tcu::TestStatus::pass("Pass");
else
return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
}
}
class MultisubpassTestInstance : public ColorImagelessTestInstance
{
public:
MultisubpassTestInstance (Context& context, const TestParameters& parameters);
protected:
virtual tcu::TestStatus iterate (void);
virtual std::vector<float> getVertices (void);
virtual MovePtr<tcu::TextureLevel> generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass);
};
MultisubpassTestInstance::MultisubpassTestInstance (Context& context, const TestParameters& parameters)
: ColorImagelessTestInstance (context, parameters)
{
}
std::vector<float> MultisubpassTestInstance::getVertices (void)
{
const float verticesData[] =
{
-1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, 0.0f, 0.0f, 1.0f,
+1.0f, +1.0f, 0.0f, 1.0f,
};
const std::vector<float> vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
return vertices;
}
MovePtr<tcu::TextureLevel> MultisubpassTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat,
const AspectFlags aspectFlags,
const deUint32 sample,
const deUint32 subpass)
{
const int width = m_imageExtent2D.width;
const int height = m_imageExtent2D.height;
const tcu::Vec4 colorDraw0 (0.0f, 0.0f, 1.0f, 1.0f);
const tcu::Vec4 colorFill0 (tcu::RGBA::black().toVec());
const tcu::Vec4 colorDraw1 (colorDraw0.x(), 1.0f, colorDraw0.z(), 1.0f);
const tcu::Vec4 colorFill1 (colorFill0.x(), 1.0f, colorFill0.z(), 1.0f);
const tcu::Vec4& colorDraw ((subpass == 0) ? colorDraw0 : colorDraw1);
const tcu::Vec4& colorFill ((subpass == 0) ? colorFill0 : colorFill1);
MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(textureFormat, width, height));
tcu::PixelBufferAccess access (image->getAccess());
DE_UNREF(aspectFlags);
DE_ASSERT(aspectFlags == ASPECT_COLOR);
DE_UNREF(sample);
DE_ASSERT(sample == NO_SAMPLE);
DE_ASSERT(subpass != NO_SUBPASS);
for (int y = 0; y < height; ++y)
{
const tcu::Vec4& validColor = (y < height / 2) ? colorFill : colorDraw;
for (int x = 0; x < width; ++x)
access.setPixel(validColor, x, y);
}
return image;
}
tcu::TestStatus MultisubpassTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& allocator = m_context.getDefaultAllocator();
const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
const VkFormat colorFormat = m_parameters.colorFormat;
const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImage> color0Image (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
const UniquePtr<Allocation> color0ImageAlloc (bindImage (vk, device, allocator, *color0Image, MemoryRequirement::Any));
const Unique<VkImageView> color0Attachment (makeImageView (vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> color0Buffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> color0BufferAlloc (bindBuffer (vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible));
const Unique<VkImage> color1Image (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
const UniquePtr<Allocation> color1ImageAlloc (bindImage (vk, device, allocator, *color1Image, MemoryRequirement::Any));
const Unique<VkImageView> color1Attachment (makeImageView (vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
const Unique<VkBuffer> color1Buffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
const UniquePtr<Allocation> color1BufferAlloc (bindBuffer (vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible));
const VkDescriptorType descriptorType (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
const Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
.addSingleBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT)
.build(vk, device));
const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
.addType(descriptorType)
.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
const VkDescriptorImageInfo imageDescriptorInfo (makeDescriptorImageInfo(DE_NULL, *color0Attachment, VK_IMAGE_LAYOUT_GENERAL));
DescriptorSetUpdateBuilder()
.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageDescriptorInfo)
.update(vk, device);
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, DE_NULL));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, &colorFormat, m_colorImageUsage, &m_parameters.dsFormat, 0u, ASPECT_NONE, 1u));
const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const Unique<VkShaderModule> vertModule0 (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
const Unique<VkShaderModule> fragModule0 (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
const Unique<VkPipelineLayout> pipelineLayout0 (makePipelineLayout (vk, device));
const Unique<VkPipeline> pipeline0 (makeGraphicsPipeline (vk, device, *pipelineLayout0, *renderPass, *vertModule0, *fragModule0, m_imageExtent2D));
const Unique<VkShaderModule> vertModule1 (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert1"), 0u));
const Unique<VkShaderModule> fragModule1 (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag1"), 0u));
const Unique<VkPipelineLayout> pipelineLayout1 (makePipelineLayout (vk, device, 1u, &*descriptorSetLayout));
const Unique<VkPipeline> pipeline1 (makeGraphicsPipeline (vk, device, *pipelineLayout1, *renderPass, *vertModule1, *fragModule1, m_imageExtent2D, 0u, VK_SAMPLE_COUNT_1_BIT, 1u));
const std::vector<float> vertex0Array (getVertices());
const deUint32 vertex0Count (static_cast<deUint32>(vertex0Array.size() / 4u));
const VkDeviceSize vertex0ArraySize (vertex0Array.size() * sizeof(vertex0Array[0]));
const Unique<VkBuffer> vertex0Buffer (makeBuffer (vk, device, makeBufferCreateInfo(vertex0ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertex0BufferAlloc (bindBuffer (vk, device, allocator, *vertex0Buffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertex0BufferOffset (0u);
const std::vector<float> vertex1Array (getFullQuadVertices());
const deUint32 vertex1Count (static_cast<deUint32>(vertex1Array.size() / 4u));
const VkDeviceSize vertex1ArraySize (vertex1Array.size() * sizeof(vertex1Array[0]));
const Unique<VkBuffer> vertex1Buffer (makeBuffer (vk, device, makeBufferCreateInfo(vertex1ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
const UniquePtr<Allocation> vertex1BufferAlloc (bindBuffer (vk, device, allocator, *vertex1Buffer, MemoryRequirement::HostVisible));
const VkDeviceSize vertex1BufferOffset (0u);
fillBuffer(vk, device, *vertex0BufferAlloc, &vertex0Array[0], vertex0ArraySize);
fillBuffer(vk, device, *vertex1BufferAlloc, &vertex1Array[0], vertex1ArraySize);
beginCommandBuffer(vk, *cmdBuffer);
{
const VkImageView attachments[] = { *color0Attachment, *color1Attachment };
const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType;
DE_NULL, // const void* pNext;
DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount;
&attachments[0] // const VkImageView* pAttachments;
};
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
{
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline0);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex0Buffer, &vertex0BufferOffset);
vk.cmdDraw(*cmdBuffer, vertex0Count, 1u, 0u, 0u);
}
vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
{
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex1Buffer, &vertex1BufferOffset);
vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout1, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
vk.cmdDraw(*cmdBuffer, vertex1Count, 1u, 0u, 0u);
}
}
endRenderPass(vk, *cmdBuffer);
// Subpass0 color image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*color0Image, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
// Subpass1 color image copy
{
const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
*color1Image, colorSubresRange);
const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u, &region);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
{
std::string result;
if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u))
result += " ColorSubpass0";
if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u))
result += " ColorSubpass1";
if (result.empty())
return tcu::TestStatus::pass("Pass");
else
return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
}
}
class BaseTestCase : public TestCase
{
public:
BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters);
virtual ~BaseTestCase (void);
protected:
virtual void checkSupport (Context& context) const;
virtual void initPrograms (SourceCollections& programCollection) const;
virtual TestInstance* createInstance (Context& context) const;
const TestParameters m_parameters;
};
BaseTestCase::BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters)
: TestCase (context, name, description)
, m_parameters (parameters)
{
}