};
typedef deUint32 TestModeFlags;
+enum RenderType
+{
+ // resolve multisample rendering to single sampled image
+ RENDER_TYPE_RESOLVE = 0u,
+
+ // copy samples to an array of single sampled images
+ RENDER_TYPE_COPY_SAMPLES
+};
+
void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType);
bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
virtual ~MinSampleShadingTest (void) {}
protected:
+ virtual void initPrograms (SourceCollections& programCollection) const;
virtual TestInstance* createMultisampleTestInstance (Context& context,
VkPrimitiveTopology topology,
const std::vector<Vertex4RGBA>& vertices,
const VkPrimitiveTopology topology,
const std::vector<Vertex4RGBA>& vertices,
const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
- const VkPipelineColorBlendAttachmentState& blendState);
+ const VkPipelineColorBlendAttachmentState& blendState,
+ const RenderType renderType);
MultisampleRenderer (Context& context,
const VkFormat colorFormat,
const VkPrimitiveTopology* pTopology,
const std::vector<Vertex4RGBA>* pVertices,
const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
- const VkPipelineColorBlendAttachmentState& blendState);
+ const VkPipelineColorBlendAttachmentState& blendState,
+ const RenderType renderType);
virtual ~MultisampleRenderer (void);
de::MovePtr<tcu::TextureLevel> render (void);
+ de::MovePtr<tcu::TextureLevel> getSingleSampledImage (deUint32 sampleId);
protected:
void initialize (Context& context,
const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
const VkPipelineColorBlendAttachmentState m_colorBlendState;
+ const RenderType m_renderType;
+
Move<VkImage> m_colorImage;
de::MovePtr<Allocation> m_colorImageAlloc;
Move<VkImageView> m_colorAttachmentView;
de::MovePtr<Allocation> m_resolveImageAlloc;
Move<VkImageView> m_resolveAttachmentView;
+ struct PerSampleImage
+ {
+ Move<VkImage> m_image;
+ de::MovePtr<Allocation> m_imageAlloc;
+ Move<VkImageView> m_attachmentView;
+ };
+ std::vector<de::SharedPtr<PerSampleImage> > m_perSampleImages;
+
Move<VkImage> m_depthStencilImage;
de::MovePtr<Allocation> m_depthStencilImageAlloc;
Move<VkImageView> m_depthStencilAttachmentView;
Move<VkShaderModule> m_vertexShaderModule;
Move<VkShaderModule> m_fragmentShaderModule;
+ Move<VkShaderModule> m_copySampleVertexShaderModule;
+ Move<VkShaderModule> m_copySampleFragmentShaderModule;
+
Move<VkBuffer> m_vertexBuffer;
de::MovePtr<Allocation> m_vertexBufferAlloc;
Move<VkPipelineLayout> m_pipelineLayout;
std::vector<VkPipelineSp> m_graphicsPipelines;
+ Move<VkDescriptorSetLayout> m_copySampleDesciptorLayout;
+ Move<VkDescriptorPool> m_copySampleDesciptorPool;
+ Move<VkDescriptorSet> m_copySampleDesciptorSet;
+
+ Move<VkPipelineLayout> m_copySamplePipelineLayout;
+ std::vector<VkPipelineSp> m_copySamplePipelines;
+
Move<VkCommandPool> m_cmdPool;
Move<VkCommandBuffer> m_cmdBuffer;
virtual tcu::TestStatus iterate (void);
protected:
- virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage,
- const tcu::ConstPixelBufferAccess& minShadingImage,
- const tcu::ConstPixelBufferAccess& maxShadingImage);
+ virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& testShadingImages,
+ const tcu::ConstPixelBufferAccess& noSampleshadingImage);
+
const VkFormat m_colorFormat;
const tcu::IVec2 m_renderSize;
const VkPrimitiveTopology m_primitiveTopology;
" gl_Position = position;\n"
" vtxColor = color;\n"
<< (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? " gl_PointSize = 3.0f;\n"
- : "" )
+ : "")
<< "}\n";
static const char* fragmentSource =
sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
}
+void initSampleShadingPrograms (SourceCollections& sources, GeometryType geometryType)
+{
+ {
+ std::ostringstream vertexSource;
+
+ vertexSource <<
+ "#version 440\n"
+ "layout(location = 0) in vec4 position;\n"
+ "layout(location = 1) in vec4 color;\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ << (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? " gl_PointSize = 3.0f;\n"
+ : "")
+ << "}\n";
+
+ static const char* fragmentSource =
+ "#version 440\n"
+ "layout(location = 0) out highp vec4 fragColor;\n"
+ "void main (void)\n"
+ "{\n"
+ " fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
+ "}\n";
+
+ sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
+ sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
+ }
+
+ {
+ static const char* vertexSource =
+ "#version 440\n"
+ "void main (void)\n"
+ "{\n"
+ " const vec4 positions[4] = vec4[4](\n"
+ " vec4(-1.0, -1.0, 0.0, 1.0),\n"
+ " vec4(-1.0, 1.0, 0.0, 1.0),\n"
+ " vec4( 1.0, -1.0, 0.0, 1.0),\n"
+ " vec4( 1.0, 1.0, 0.0, 1.0)\n"
+ " );\n"
+ " gl_Position = positions[gl_VertexIndex];\n"
+ "}\n";
+
+ static const char* fragmentSource =
+ "#version 440\n"
+ "precision highp float;\n"
+ "layout(location = 0) out highp vec4 fragColor;\n"
+ "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
+ "layout(push_constant) uniform PushConstantsBlock\n"
+ "{\n"
+ " int sampleId;\n"
+ "} pushConstants;\n"
+ "void main (void)\n"
+ "{\n"
+ " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
+ "}\n";
+
+ sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
+ sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
+ }
+}
+
bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
{
VkPhysicalDeviceProperties deviceProperties;
{
}
+void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
+{
+ initSampleShadingPrograms(programCollection, m_geometryType);
+}
+
TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context,
VkPrimitiveTopology topology,
const std::vector<Vertex4RGBA>& vertices,
m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
new MultisampleRenderer(
- context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState));
+ context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE));
}
else
{
m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
- new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState));
+ new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE));
}
}
tcu::TestStatus MinSampleShadingInstance::iterate (void)
{
- de::MovePtr<tcu::TextureLevel> testShadingImage;
- de::MovePtr<tcu::TextureLevel> minShadingImage;
- de::MovePtr<tcu::TextureLevel> maxShadingImage;
+ de::MovePtr<tcu::TextureLevel> noSampleshadingImage;
+ std::vector<tcu::TextureLevel> sampleShadedImages;
- // Render with test minSampleShading
+ // Render and resolve without sample shading
{
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
- testShadingImage = renderer.render();
+ VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
+ multisampleStateParms.sampleShadingEnable = VK_FALSE;
+ multisampleStateParms.minSampleShading = 0.0;
+
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE);
+ noSampleshadingImage = renderer.render();
}
- // Render with minSampleShading = 0.0f
+ // Render with test minSampleShading and collect per-sample images
{
- VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
- multisampleParams.minSampleShading = 0.0f;
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES);
+ renderer.render();
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
- minShadingImage = renderer.render();
+ sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
+ for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
+ {
+ sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
+ }
}
- // Render with minSampleShading = 1.0f
+ // Log images
{
- VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
- multisampleParams.minSampleShading = 1.0f;
+ tcu::TestLog& testLog = m_context.getTestContext().getLog();
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
- maxShadingImage = renderer.render();
+ testLog << tcu::TestLog::ImageSet("Images", "Images")
+ << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
+
+ for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
+ {
+ testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
+ }
+ testLog << tcu::TestLog::EndImageSet;
}
- return verifyImage(testShadingImage->getAccess(), minShadingImage->getAccess(), maxShadingImage->getAccess());
+ return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
}
-tcu::TestStatus MinSampleShadingInstance::verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, const tcu::ConstPixelBufferAccess& minShadingImage, const tcu::ConstPixelBufferAccess& maxShadingImage)
+tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
{
- const deUint32 testColorCount = getUniqueColorsCount(testShadingImage);
- const deUint32 minColorCount = getUniqueColorsCount(minShadingImage);
- const deUint32 maxColorCount = getUniqueColorsCount(maxShadingImage);
+ const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
- tcu::TestLog& log = m_context.getTestContext().getLog();
+ bool anyPixelCovered = false;
- log << tcu::TestLog::Message
- << "\nColors found: " << testColorCount << "\n"
- << "Min. colors expected: " << minColorCount << "\n"
- << "Max. colors expected: " << maxColorCount << "\n"
- << tcu::TestLog::EndMessage;
+ for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
+ {
+ const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
- if (minColorCount > testColorCount || testColorCount > maxColorCount)
- return tcu::TestStatus::fail("Unique colors out of expected bounds");
- else
- return tcu::TestStatus::pass("Unique colors within expected bounds");
+ if (noSampleShadingValue == 0)
+ {
+ // non-covered pixel, continue
+ continue;
+ }
+ else
+ {
+ anyPixelCovered = true;
+ }
+
+ int numNotCoveredSamples = 0;
+
+ std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences>
+
+ // Collect histogram of occurrences or each pixel across all samples
+ for (size_t i = 0; i < sampleShadedImages.size(); ++i)
+ {
+ const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
+
+ if (sampleShadedValue == 0)
+ {
+ numNotCoveredSamples++;
+ continue;
+ }
+
+ if (histogram.find(sampleShadedValue) != histogram.end())
+ histogram[sampleShadedValue]++;
+ else
+ histogram[sampleShadedValue] = 1;
+ }
+
+ if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
+ {
+ return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
+ }
+
+ const int uniqueColorsCount = (int)histogram.size();
+ const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
+
+ if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
+ {
+ return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
+ }
+ }
+
+ if (!anyPixelCovered)
+ {
+ return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
+ }
+
+ return tcu::TestStatus::pass("Got proper count of unique colors");
}
SampleMaskInstance::SampleMaskInstance (Context& context,
// Render with test flags
{
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES);
testSampleMaskImage = renderer.render();
}
multisampleParams.pSampleMask = sampleMask.data();
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES);
minSampleMaskImage = renderer.render();
}
multisampleParams.pSampleMask = sampleMask.data();
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES);
maxSampleMaskImage = renderer.render();
}
false // VkBool32 alphaToOneEnable;
};
- MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState());
+ MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE);
de::MovePtr<tcu::TextureLevel> result = renderer.render();
const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess());
// Render with blend enabled and alpha to one on
{
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
alphaOneImage = renderer.render();
}
VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
multisampleParams.alphaToOneEnable = false;
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
noAlphaOneImage = renderer.render();
}
DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
de::MovePtr<tcu::TextureLevel> result;
- MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
+ MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
result = renderer.render();
const VkPrimitiveTopology topology,
const std::vector<Vertex4RGBA>& vertices,
const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
- const VkPipelineColorBlendAttachmentState& blendState)
+ const VkPipelineColorBlendAttachmentState& blendState,
+ const RenderType renderType)
: m_context (context)
, m_colorFormat (colorFormat)
, m_depthStencilFormat (VK_FORMAT_UNDEFINED)
, m_useStencil (false)
, m_multisampleStateParams (multisampleStateParams)
, m_colorBlendState (blendState)
+ , m_renderType (renderType)
{
initialize(context, 1u, &topology, &vertices);
}
const VkPrimitiveTopology* pTopology,
const std::vector<Vertex4RGBA>* pVertices,
const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
- const VkPipelineColorBlendAttachmentState& blendState)
+ const VkPipelineColorBlendAttachmentState& blendState,
+ const RenderType renderType)
: m_context (context)
, m_colorFormat (colorFormat)
, m_depthStencilFormat (depthStencilFormat)
, m_useStencil (useStencil)
, m_multisampleStateParams (multisampleStateParams)
, m_colorBlendState (blendState)
+ , m_renderType (renderType)
{
initialize(context, numTopologies, pTopology, pVertices);
}
// Create color image
{
+
+ const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
+
const VkImageCreateInfo colorImageParams =
{
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1u, // deUint32 arrayLayers;
m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
+ imageUsageFlags, // VkImageUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1u, // deUint32 queueFamilyIndexCount;
&queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
}
// Create resolve image
+ if (m_renderType == RENDER_TYPE_RESOLVE)
{
const VkImageCreateInfo resolveImageParams =
{
// Allocate and bind resolve image memory
m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
+
+ // Create resolve attachment view
+ {
+ const VkImageViewCreateInfo resolveAttachmentViewParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_resolveImage, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_colorFormat, // VkFormat format;
+ componentMappingRGBA, // VkComponentMapping components;
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
+ };
+
+ m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
+ }
+ }
+
+ // Create per-sample output images
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ const VkImageCreateInfo perSampleImageParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageCreateFlags flags;
+ VK_IMAGE_TYPE_2D, // VkImageType imageType;
+ m_colorFormat, // VkFormat format;
+ { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
+ 1u, // deUint32 mipLevels;
+ 1u, // deUint32 arrayLayers;
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
+ VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage;
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
+ };
+
+ m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
+
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage);
+ PerSampleImage& image = *m_perSampleImages[i];
+
+ image.m_image = createImage(vk, vkDevice, &perSampleImageParams);
+
+ // Allocate and bind image memory
+ image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
+ VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
+
+ // Create per-sample attachment view
+ {
+ const VkImageViewCreateInfo perSampleAttachmentViewParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *image.m_image, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_colorFormat, // VkFormat format;
+ componentMappingRGBA, // VkComponentMapping components;
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
+ };
+
+ image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
+ }
+ }
}
// Create a depth/stencil image
m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
}
- // Create resolve attachment view
- {
- const VkImageViewCreateInfo resolveAttachmentViewParams =
- {
- VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- 0u, // VkImageViewCreateFlags flags;
- *m_resolveImage, // VkImage image;
- VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
- m_colorFormat, // VkFormat format;
- componentMappingRGBA, // VkComponentMapping components;
- { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
- };
-
- m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
- }
-
VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0;
- const deUint32 numUsedAttachments = (m_useDepth || m_useStencil ? 3u : 2u);
// Create depth/stencil attachment view
if (m_useDepth || m_useStencil)
// Create render pass
{
- const VkAttachmentDescription attachmentDescriptions[3] =
+ std::vector<VkAttachmentDescription> attachmentDescriptions;
{
+ const VkAttachmentDescription colorAttachmentDescription =
{
0u, // VkAttachmentDescriptionFlags flags;
m_colorFormat, // VkFormat format;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
- },
+ };
+ attachmentDescriptions.push_back(colorAttachmentDescription);
+ }
+
+ deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
+
+ if (m_renderType == RENDER_TYPE_RESOLVE)
+ {
+ resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
+
+ const VkAttachmentDescription resolveAttachmentDescription =
{
0u, // VkAttachmentDescriptionFlags flags;
m_colorFormat, // VkFormat format;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
- },
+ };
+ attachmentDescriptions.push_back(resolveAttachmentDescription);
+ }
+
+ deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
+
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
+
+ const VkAttachmentDescription perSampleAttachmentDescription =
+ {
+ 0u, // VkAttachmentDescriptionFlags flags;
+ m_colorFormat, // VkFormat format;
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
+ VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
+ VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
+ VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
+ };
+
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ attachmentDescriptions.push_back(perSampleAttachmentDescription);
+ }
+ }
+
+ deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
+
+ if (m_useDepth || m_useStencil)
+ {
+ depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
+
+ const VkAttachmentDescription depthStencilAttachmentDescription =
{
0u, // VkAttachmentDescriptionFlags flags;
m_depthStencilFormat, // VkFormat format;
(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
- },
+ };
+ attachmentDescriptions.push_back(depthStencilAttachmentDescription);
};
const VkAttachmentReference colorAttachmentReference =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
+ const VkAttachmentReference inputAttachmentReference =
+ {
+ 0u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout;
+ };
+
const VkAttachmentReference resolveAttachmentReference =
{
- 1u, // deUint32 attachment;
+ resolveAttachmentIndex, // deUint32 attachment;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
+ std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ const VkAttachmentReference perSampleAttachmentReference =
+ {
+ perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+ perSampleAttachmentReferences[i] = perSampleAttachmentReference;
+ }
+ }
+
const VkAttachmentReference depthStencilAttachmentReference =
{
- 2u, // deUint32 attachment;
+ depthStencilAttachmentIndex, // deUint32 attachment;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
- const VkSubpassDescription subpassDescription =
- {
- 0u, // VkSubpassDescriptionFlags flags;
- VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
- 0u, // deUint32 inputAttachmentCount;
- DE_NULL, // const VkAttachmentReference* pInputAttachments;
- 1u, // deUint32 colorAttachmentCount;
- &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
- &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments;
- (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment;
- 0u, // deUint32 preserveAttachmentCount;
- DE_NULL // const VkAttachmentReference* pPreserveAttachments;
- };
+ std::vector<VkSubpassDescription> subpassDescriptions;
+ std::vector<VkSubpassDependency> subpassDependencies;
+
+ {
+ const VkSubpassDescription renderSubpassDescription =
+ {
+ 0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 0u, // deUint32 inputAttachmentCount;
+ DE_NULL, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
+ (m_renderType == RENDER_TYPE_RESOLVE) ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
+ (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment;
+ 0u, // deUint32 preserveAttachmentCount;
+ DE_NULL // const VkAttachmentReference* pPreserveAttachments;
+ };
+ subpassDescriptions.push_back(renderSubpassDescription);
+ }
+
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ const VkSubpassDescription copySampleSubpassDescription =
+ {
+ 0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 1u, // deUint32 inputAttachmentCount;
+ &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
+ DE_NULL, // const VkAttachmentReference* pResolveAttachments;
+ DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
+ 0u, // deUint32 preserveAttachmentCount;
+ DE_NULL // const VkAttachmentReference* pPreserveAttachments;
+ };
+ subpassDescriptions.push_back(copySampleSubpassDescription);
+
+ const VkSubpassDependency copySampleSubpassDependency =
+ {
+ 0u, // deUint32 srcSubpass
+ 1u + static_cast<deUint32>(i), // deUint32 dstSubpass
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
+ VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
+ 0u, // VkDependencyFlags dependencyFlags
+ };
+ subpassDependencies.push_back(copySampleSubpassDependency);
+ }
+ }
const VkRenderPassCreateInfo renderPassParams =
{
- VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- 0u, // VkRenderPassCreateFlags flags;
- numUsedAttachments, // deUint32 attachmentCount;
- attachmentDescriptions, // const VkAttachmentDescription* pAttachments;
- 1u, // deUint32 subpassCount;
- &subpassDescription, // const VkSubpassDescription* pSubpasses;
- 0u, // deUint32 dependencyCount;
- DE_NULL // const VkSubpassDependency* pDependencies;
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkRenderPassCreateFlags flags;
+ (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
+ &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
+ (deUint32)subpassDescriptions.size(), // deUint32 subpassCount;
+ &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses;
+ (deUint32)subpassDependencies.size(), // deUint32 dependencyCount;
+ subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
};
m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
// Create framebuffer
{
- const VkImageView attachments[3] =
+ std::vector<VkImageView> attachments;
+ attachments.push_back(*m_colorAttachmentView);
+ if (m_renderType == RENDER_TYPE_RESOLVE)
{
- *m_colorAttachmentView,
- *m_resolveAttachmentView,
- *m_depthStencilAttachmentView
- };
+ attachments.push_back(*m_resolveAttachmentView);
+ }
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
+ }
+ }
+
+ if (m_useDepth || m_useStencil)
+ {
+ attachments.push_back(*m_depthStencilAttachmentView);
+ }
const VkFramebufferCreateInfo framebufferParams =
{
- VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- 0u, // VkFramebufferCreateFlags flags;
- *m_renderPass, // VkRenderPass renderPass;
- numUsedAttachments, // deUint32 attachmentCount;
- attachments, // const VkImageView* pAttachments;
- (deUint32)m_renderSize.x(), // deUint32 width;
- (deUint32)m_renderSize.y(), // deUint32 height;
- 1u // deUint32 layers;
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkFramebufferCreateFlags flags;
+ *m_renderPass, // VkRenderPass renderPass;
+ (deUint32)attachments.size(), // deUint32 attachmentCount;
+ &attachments[0], // const VkImageView* pAttachments;
+ (deUint32)m_renderSize.x(), // deUint32 width;
+ (deUint32)m_renderSize.y(), // deUint32 height;
+ 1u // deUint32 layers;
};
m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
};
m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+
+ // Create descriptor set layout
+ const VkDescriptorSetLayoutBinding layoutBinding =
+ {
+ 0u, // deUint32 binding;
+ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
+ 1u, // deUint32 descriptorCount;
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
+ DE_NULL, // const VkSampler* pImmutableSamplers;
+ };
+
+ const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
+ {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ 0u, // VkDescriptorSetLayoutCreateFlags flags
+ 1u, // deUint32 bindingCount
+ &layoutBinding // const VkDescriptorSetLayoutBinding* pBindings
+ };
+ m_copySampleDesciptorLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
+
+ // Create pipeline layout
+
+ const VkPushConstantRange pushConstantRange =
+ {
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
+ 0u, // deUint32 offset;
+ sizeof(deInt32) // deUint32 size;
+ };
+ const VkPipelineLayoutCreateInfo copySamplePipelineLayoutParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineLayoutCreateFlags flags;
+ 1u, // deUint32 setLayoutCount;
+ &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
+ 1u, // deUint32 pushConstantRangeCount;
+ &pushConstantRange // const VkPushConstantRange* pPushConstantRanges;
+ };
+ m_copySamplePipelineLayout = createPipelineLayout(vk, vkDevice, ©SamplePipelineLayoutParams);
+ }
}
m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ m_copySampleVertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
+ m_copySampleFragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
+ }
+
// Create pipeline
{
- const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
+ const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
{
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
}
};
- const VkVertexInputBindingDescription vertexInputBindingDescription =
+ const VkVertexInputBindingDescription vertexInputBindingDescription =
{
0u, // deUint32 binding;
sizeof(Vertex4RGBA), // deUint32 stride;
}
}
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ // Create pipelines for copying samples to single sampled images
+ {
+ const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
+ {
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
+ *m_copySampleVertexShaderModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
+ },
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
+ *m_copySampleFragmentShaderModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
+ }
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineVertexInputStateCreateFlags flags;
+ 0u, // deUint32 vertexBindingDescriptionCount;
+ DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ 0u, // deUint32 vertexAttributeDescriptionCount;
+ DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ // Topology is set before the pipeline creation.
+ VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
+ false // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkViewport viewport =
+ {
+ 0.0f, // float x;
+ 0.0f, // float y;
+ (float)m_renderSize.x(), // float width;
+ (float)m_renderSize.y(), // float height;
+ 0.0f, // float minDepth;
+ 1.0f // float maxDepth;
+ };
+
+ const VkRect2D scissor =
+ {
+ { 0, 0 }, // VkOffset2D offset;
+ { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } // VkExtent2D extent;
+ };
+
+ const VkPipelineViewportStateCreateInfo viewportStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineViewportStateCreateFlags flags;
+ 1u, // deUint32 viewportCount;
+ &viewport, // const VkViewport* pViewports;
+ 1u, // deUint32 scissorCount;
+ &scissor // const VkRect2D* pScissors;
+ };
+
+ const VkPipelineRasterizationStateCreateInfo rasterStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineRasterizationStateCreateFlags flags;
+ false, // VkBool32 depthClampEnable;
+ false, // VkBool32 rasterizerDiscardEnable;
+ VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
+ VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
+ VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
+ VK_FALSE, // VkBool32 depthBiasEnable;
+ 0.0f, // float depthBiasConstantFactor;
+ 0.0f, // float depthBiasClamp;
+ 0.0f, // float depthBiasSlopeFactor;
+ 1.0f // float lineWidth;
+ };
+
+ const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineColorBlendStateCreateFlags flags;
+ false, // VkBool32 logicOpEnable;
+ VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
+ 1u, // deUint32 attachmentCount;
+ &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments;
+ { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
+ };
+
+ const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ 0u, // VkPipelineMultisampleStateCreateFlags flags
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
+ VK_FALSE, // VkBool32 sampleShadingEnable
+ 0.0f, // float minSampleShading
+ DE_NULL, // const VkSampleMask* pSampleMask
+ VK_FALSE, // VkBool32 alphaToCoverageEnable
+ VK_FALSE, // VkBool32 alphaToOneEnable
+ };
+
+ const VkGraphicsPipelineCreateInfo graphicsPipelineTemplate =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineCreateFlags flags;
+ 2u, // deUint32 stageCount;
+ shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ *m_copySamplePipelineLayout, // VkPipelineLayout layout;
+ *m_renderPass, // VkRenderPass renderPass;
+ 0u, // deUint32 subpass;
+ 0u, // VkPipeline basePipelineHandle;
+ 0u // deInt32 basePipelineIndex;
+ };
+
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ VkGraphicsPipelineCreateInfo graphicsPipelineParams = graphicsPipelineTemplate;
+
+ // Pipeline is to be used in subpasses subsequent to sample-shading subpass
+ graphicsPipelineParams.subpass = 1u + (deUint32)i;
+
+ m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams))));
+ }
+ }
+
+
+ const VkDescriptorPoolSize descriptorPoolSize =
+ {
+ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type;
+ 1u // deUint32 descriptorCount;
+ };
+
+ const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
+ 1u, // deUint32 maxSets
+ 1u, // deUint32 poolSizeCount
+ &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes
+ };
+
+ m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
+
+ const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
+ {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ *m_copySampleDesciptorPool, // VkDescriptorPool descriptorPool
+ 1u, // deUint32 descriptorSetCount
+ &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts
+ };
+
+ m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
+
+ const VkDescriptorImageInfo imageInfo =
+ {
+ DE_NULL,
+ *m_colorAttachmentView,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
+ };
+ const VkWriteDescriptorSet descriptorWrite =
+ {
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *m_copySampleDesciptorSet, // VkDescriptorSet dstSet;
+ 0u, // deUint32 dstBinding;
+ 0u, // deUint32 dstArrayElement;
+ 1u, // deUint32 descriptorCount;
+ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
+ &imageInfo, // const VkDescriptorImageInfo* pImageInfo;
+ DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo;
+ DE_NULL, // const VkBufferView* pTexelBufferView;
+ };
+ vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
+ }
+
// Create vertex buffer
{
const VkBufferCreateInfo vertexBufferParams =
depthStencilClearValue.depthStencil.depth = 1.0f;
depthStencilClearValue.depthStencil.stencil = 0u;
- const VkClearValue clearValues[3] =
+ std::vector<VkClearValue> clearValues;
+ clearValues.push_back(colorClearValue);
+ if (m_renderType == RENDER_TYPE_RESOLVE)
{
- colorClearValue,
- colorClearValue,
- depthStencilClearValue
- };
+ clearValues.push_back(colorClearValue);
+ }
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ clearValues.push_back(colorClearValue);
+ }
+ }
+ if (m_useDepth || m_useStencil)
+ {
+ clearValues.push_back(depthStencilClearValue);
+ }
const VkRenderPassBeginInfo renderPassBeginInfo =
{
{ 0, 0 },
{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
}, // VkRect2D renderArea;
- numUsedAttachments, // deUint32 clearValueCount;
- clearValues // const VkClearValue* pClearValues;
+ (deUint32)clearValues.size(), // deUint32 clearValueCount;
+ &clearValues[0] // const VkClearValue* pClearValues;
};
- const VkImageMemoryBarrier imageLayoutBarriers[] =
+ std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
+
{
- // color attachment image
+ const VkImageMemoryBarrier colorImageBarrier =
+ // color attachment image
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
*m_colorImage, // VkImage image;
{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
- },
+ };
+ imageLayoutBarriers.push_back(colorImageBarrier);
+ }
+ if (m_renderType == RENDER_TYPE_RESOLVE)
+ {
+ const VkImageMemoryBarrier resolveImageBarrier =
// resolve attachment image
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
*m_resolveImage, // VkImage image;
{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
- },
+ };
+ imageLayoutBarriers.push_back(resolveImageBarrier);
+ }
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ for (size_t i = 0; i < m_perSampleImages.size(); ++i)
+ {
+ const VkImageMemoryBarrier perSampleImageBarrier =
+ // resolve attachment image
+ {
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkAccessFlags srcAccessMask;
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
+ VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
+ VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
+ *m_perSampleImages[i]->m_image, // VkImage image;
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
+ };
+ imageLayoutBarriers.push_back(perSampleImageBarrier);
+ }
+ }
+ if (m_useDepth || m_useStencil)
+ {
+ const VkImageMemoryBarrier depthStencilImageBarrier =
// depth/stencil attachment image
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
*m_depthStencilImage, // VkImage image;
{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
- },
+ };
+ imageLayoutBarriers.push_back(depthStencilImageBarrier);
};
m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
- 0u, DE_NULL, 0u, DE_NULL, numUsedAttachments, imageLayoutBarriers);
+ 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
}
+ if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
+ {
+ // Copy each sample id to single sampled image
+ for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
+ {
+ vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
+ vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
+ vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
+ vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
+ vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+ }
+ }
+
vk.cmdEndRenderPass(*m_cmdBuffer);
VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
- return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
+ if (m_renderType == RENDER_TYPE_RESOLVE)
+ {
+ return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
+ }
+ else
+ {
+ return de::MovePtr<tcu::TextureLevel>();
+ }
+}
+
+de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+ const VkQueue queue = m_context.getUniversalQueue();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+
+ return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
}
} // anonymous