dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_16
dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_32
dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_32
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_vertex
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_instance
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_snorm_rate_vertex
vktPipelineMultisampleTestsUtil.hpp
vktPipelineMultisampleTests.cpp
vktPipelineMultisampleTests.hpp
+ vktPipelineMultisampleBase.cpp
+ vktPipelineMultisampleBase.hpp
+ vktPipelineMultisampleBaseResolve.cpp
+ vktPipelineMultisampleBaseResolve.hpp
+ vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp
+ vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp
vktPipelineMultisampleInterpolationTests.cpp
vktPipelineMultisampleInterpolationTests.hpp
+ vktPipelineMultisampleShaderBuiltInTests.cpp
+ vktPipelineMultisampleShaderBuiltInTests.hpp
vktPipelineMultisampleImageTests.cpp
vktPipelineMultisampleImageTests.hpp
vktPipelineInputAssemblyTests.cpp
--- /dev/null
+/*------------------------------------------------------------------------
+* Vulkan Conformance Tests
+* ------------------------
+*
+* Copyright (c) 2016 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 vktPipelineMultisampleBase.cpp
+* \brief Multisample Tests Base Classes
+*//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleBase.hpp"
+#include "vkQueryUtil.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+using namespace vk;
+
+void MultisampleInstanceBase::validateImageSize (const InstanceInterface& instance,
+ const VkPhysicalDevice physicalDevice,
+ const ImageType imageType,
+ const tcu::UVec3& imageSize) const
+{
+ const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
+
+ bool isImageSizeValid = true;
+
+ switch (imageType)
+ {
+ case IMAGE_TYPE_1D:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
+ break;
+ case IMAGE_TYPE_1D_ARRAY:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
+ imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+ break;
+ case IMAGE_TYPE_2D:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
+ imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
+ break;
+ case IMAGE_TYPE_2D_ARRAY:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
+ imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
+ imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+ break;
+ case IMAGE_TYPE_CUBE:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
+ imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
+ break;
+ case IMAGE_TYPE_CUBE_ARRAY:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
+ imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
+ imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+ break;
+ case IMAGE_TYPE_3D:
+ isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
+ imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
+ imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
+ break;
+ default:
+ DE_FATAL("Unknown image type");
+ }
+
+ if (!isImageSizeValid)
+ {
+ std::ostringstream notSupportedStream;
+
+ notSupportedStream << "Image type (" << getImageTypeName(imageType) << ") with size (" << imageSize.x() << ", " << imageSize.y() << ", " << imageSize.z() << ") not supported by device" << std::endl;
+
+ const std::string notSupportedString = notSupportedStream.str();
+
+ TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ }
+}
+
+void MultisampleInstanceBase::validateImageFeatureFlags (const InstanceInterface& instance,
+ const VkPhysicalDevice physicalDevice,
+ const VkFormat format,
+ const VkFormatFeatureFlags featureFlags) const
+{
+ const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
+
+ if ((formatProperties.optimalTilingFeatures & featureFlags) != featureFlags)
+ {
+ std::ostringstream notSupportedStream;
+
+ notSupportedStream << "Device does not support image format " << format << " for feature flags " << featureFlags << std::endl;
+
+ const std::string notSupportedString = notSupportedStream.str();
+
+ TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ }
+}
+
+void MultisampleInstanceBase::validateImageInfo (const InstanceInterface& instance,
+ const VkPhysicalDevice physicalDevice,
+ const VkImageCreateInfo& imageInfo) const
+{
+ VkImageFormatProperties imageFormatProps;
+ instance.getPhysicalDeviceImageFormatProperties(physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProps);
+
+ if (imageFormatProps.maxExtent.width < imageInfo.extent.width ||
+ imageFormatProps.maxExtent.height < imageInfo.extent.height ||
+ imageFormatProps.maxExtent.depth < imageInfo.extent.depth)
+ {
+ std::ostringstream notSupportedStream;
+
+ notSupportedStream << "Image extent ("
+ << imageInfo.extent.width << ", "
+ << imageInfo.extent.height << ", "
+ << imageInfo.extent.depth
+ << ") exceeds allowed maximum ("
+ << imageFormatProps.maxExtent.width << ", "
+ << imageFormatProps.maxExtent.height << ", "
+ << imageFormatProps.maxExtent.depth
+ << ")"
+ << std::endl;
+
+ const std::string notSupportedString = notSupportedStream.str();
+
+ TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ }
+
+ if (imageFormatProps.maxArrayLayers < imageInfo.arrayLayers)
+ {
+ std::ostringstream notSupportedStream;
+
+ notSupportedStream << "Image layers count of " << imageInfo.arrayLayers << " exceeds allowed maximum which is " << imageFormatProps.maxArrayLayers << std::endl;
+
+ const std::string notSupportedString = notSupportedStream.str();
+
+ TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ }
+
+ if (!(imageFormatProps.sampleCounts & imageInfo.samples))
+ {
+ std::ostringstream notSupportedStream;
+
+ notSupportedStream << "Samples count of " << imageInfo.samples << " not supported for image" << std::endl;
+
+ const std::string notSupportedString = notSupportedStream.str();
+
+ TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ }
+}
+
+} // multisample
+} // pipeline
+} // vkt
--- /dev/null
+#ifndef _VKTPIPELINEMULTISAMPLEBASE_HPP
+#define _VKTPIPELINEMULTISAMPLEBASE_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 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 vktPipelineMultisampleBase.hpp
+ * \brief Multisample Tests Base Classes
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleTestsUtil.hpp"
+#include "vktTestCase.hpp"
+#include "tcuVector.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+struct ImageMSParams
+{
+ ImageMSParams(const vk::VkSampleCountFlagBits samples, const tcu::UVec3& size) : numSamples(samples), imageSize(size) {}
+
+ vk::VkSampleCountFlagBits numSamples;
+ tcu::UVec3 imageSize;
+};
+
+class MultisampleCaseBase : public TestCase
+{
+public:
+ MultisampleCaseBase (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams)
+ : TestCase(testCtx, name, "")
+ , m_imageMSParams(imageMSParams)
+ {}
+
+protected:
+ const ImageMSParams m_imageMSParams;
+};
+
+typedef MultisampleCaseBase* (*MultisampleCaseFuncPtr)(tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams);
+
+class MultisampleInstanceBase : public TestInstance
+{
+public:
+ MultisampleInstanceBase (Context& context,
+ const ImageMSParams& imageMSParams)
+ : TestInstance (context)
+ , m_imageMSParams (imageMSParams)
+ , m_imageType (IMAGE_TYPE_2D)
+ , m_imageFormat (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
+ {}
+
+ typedef std::vector<vk::VkVertexInputAttributeDescription> VertexAttribDescVec;
+
+ struct VertexDataDesc
+ {
+ vk::VkPrimitiveTopology primitiveTopology;
+ deUint32 verticesCount;
+ deUint32 dataStride;
+ vk::VkDeviceSize dataSize;
+ VertexAttribDescVec vertexAttribDescVec;
+ };
+
+protected:
+
+ void validateImageSize (const vk::InstanceInterface& instance,
+ const vk::VkPhysicalDevice physicalDevice,
+ const ImageType imageType,
+ const tcu::UVec3& imageSize) const;
+
+ void validateImageFeatureFlags (const vk::InstanceInterface& instance,
+ const vk::VkPhysicalDevice physicalDevice,
+ const vk::VkFormat format,
+ const vk::VkFormatFeatureFlags featureFlags) const;
+
+ void validateImageInfo (const vk::InstanceInterface& instance,
+ const vk::VkPhysicalDevice physicalDevice,
+ const vk::VkImageCreateInfo& imageInfo) const;
+
+ virtual VertexDataDesc getVertexDataDescripton (void) const = 0;
+
+ virtual void uploadVertexData (const vk::Allocation& vertexBufferAllocation,
+ const VertexDataDesc& vertexDataDescripton) const = 0;
+protected:
+ const ImageMSParams m_imageMSParams;
+ const ImageType m_imageType;
+ const tcu::TextureFormat m_imageFormat;
+};
+
+} // multisample
+
+template <class CaseClass>
+tcu::TestCaseGroup* makeMSGroup (tcu::TestContext& testCtx,
+ const std::string groupName,
+ const tcu::UVec3 imageSizes[],
+ const deUint32 imageSizesElemCount,
+ const vk::VkSampleCountFlagBits imageSamples[],
+ const deUint32 imageSamplesElemCount)
+{
+ de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
+
+ for (deUint32 imageSizeNdx = 0u; imageSizeNdx < imageSizesElemCount; ++imageSizeNdx)
+ {
+ const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
+ std::ostringstream imageSizeStream;
+
+ imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
+
+ de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
+
+ for (deUint32 imageSamplesNdx = 0u; imageSamplesNdx < imageSamplesElemCount; ++imageSamplesNdx)
+ {
+ const vk::VkSampleCountFlagBits samples = imageSamples[imageSamplesNdx];
+ const multisample::ImageMSParams imageMSParams = multisample::ImageMSParams(samples, imageSize);
+
+ sizeGroup->addChild(CaseClass::createCase(testCtx, "samples_" + de::toString(samples), imageMSParams));
+ }
+
+ caseGroup->addChild(sizeGroup.release());
+ }
+ return caseGroup.release();
+}
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLEBASE_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+* Vulkan Conformance Tests
+* ------------------------
+*
+* Copyright (c) 2016 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 vktPipelineMultisampleBaseResolve.cpp
+* \brief Base class for tests that check results of multisample resolve
+*//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleBaseResolve.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+using namespace vk;
+
+tcu::TestStatus MSInstanceBaseResolve::iterate (void)
+{
+ const InstanceInterface& instance = m_context.getInstanceInterface();
+ const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+ const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
+ Allocator& allocator = m_context.getDefaultAllocator();
+ const VkQueue queue = m_context.getUniversalQueue();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+
+ VkImageCreateInfo imageMSInfo;
+ VkImageCreateInfo imageRSInfo;
+
+ // Check if image size does not exceed device limits
+ validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
+
+ // Check if device supports image format as color attachment
+ validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
+
+ imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ imageMSInfo.pNext = DE_NULL;
+ imageMSInfo.flags = 0u;
+ imageMSInfo.imageType = mapImageType(m_imageType);
+ imageMSInfo.format = mapTextureFormat(m_imageFormat);
+ imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
+ imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
+ imageMSInfo.mipLevels = 1u;
+ imageMSInfo.samples = m_imageMSParams.numSamples;
+ imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ imageMSInfo.queueFamilyIndexCount = 0u;
+ imageMSInfo.pQueueFamilyIndices = DE_NULL;
+
+ if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
+ {
+ imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+ }
+
+ validateImageInfo(instance, physicalDevice, imageMSInfo);
+
+ const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
+
+ imageRSInfo = imageMSInfo;
+ imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+
+ validateImageInfo(instance, physicalDevice, imageRSInfo);
+
+ const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
+
+ // Create render pass
+ const VkAttachmentDescription attachmentMSDesc =
+ {
+ (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
+ imageMSInfo.format, // VkFormat format;
+ imageMSInfo.samples, // 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;
+ };
+
+ const VkAttachmentDescription attachmentRSDesc =
+ {
+ (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
+ imageRSInfo.format, // VkFormat format;
+ imageRSInfo.samples, // 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;
+ };
+
+ const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
+
+ const VkAttachmentReference attachmentMSRef =
+ {
+ 0u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkAttachmentReference attachmentRSRef =
+ {
+ 1u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
+
+ const VkSubpassDescription subpassDescription =
+ {
+ (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 0u, // deUint32 inputAttachmentCount;
+ DE_NULL, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &attachmentMSRef, // const VkAttachmentReference* pColorAttachments;
+ resolveAttachment, // const VkAttachmentReference* pResolveAttachments;
+ 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)0u, // VkRenderPassCreateFlags flags;
+ 2u, // deUint32 attachmentCount;
+ attachments, // const VkAttachmentDescription* pAttachments;
+ 1u, // deUint32 subpassCount;
+ &subpassDescription, // const VkSubpassDescription* pSubpasses;
+ 0u, // deUint32 dependencyCount;
+ DE_NULL // const VkSubpassDependency* pDependencies;
+ };
+
+ const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
+
+ const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
+
+ // Create color attachments image views
+ const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
+ const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
+
+ const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
+
+ // Create framebuffer
+ const VkFramebufferCreateInfo framebufferInfo =
+ {
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
+ *renderPass, // VkRenderPass renderPass;
+ 2u, // uint32_t attachmentCount;
+ attachmentsViews, // const VkImageView* pAttachments;
+ imageMSInfo.extent.width, // uint32_t width;
+ imageMSInfo.extent.height, // uint32_t height;
+ imageMSInfo.arrayLayers, // uint32_t layers;
+ };
+
+ const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
+
+ // Create pipeline layout
+ const VkPipelineLayoutCreateInfo pipelineLayoutParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
+ 0u, // deUint32 setLayoutCount;
+ DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
+ 0u, // deUint32 pushConstantRangeCount;
+ DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
+ };
+
+ const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
+
+ // Create vertex attributes data
+ const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
+
+ de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+ const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
+
+ uploadVertexData(vertexBufferAllocation, vertexDataDesc);
+
+ flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), VK_WHOLE_SIZE);
+
+ const VkVertexInputBindingDescription vertexBinding =
+ {
+ 0u, // deUint32 binding;
+ vertexDataDesc.dataStride, // deUint32 stride;
+ VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
+ 1u, // uint32_t vertexBindingDescriptionCount;
+ &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
+ dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
+ vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
+ VK_FALSE, // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkViewport viewport =
+ {
+ 0.0f, 0.0f,
+ static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
+ 0.0f, 1.0f
+ };
+
+ const VkRect2D scissor =
+ {
+ makeOffset2D(0, 0),
+ makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+ };
+
+ const VkPipelineViewportStateCreateInfo viewportStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
+ 1u, // uint32_t viewportCount;
+ &viewport, // const VkViewport* pViewports;
+ 1u, // uint32_t scissorCount;
+ &scissor, // const VkRect2D* pScissors;
+ };
+
+ const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
+ VK_FALSE, // VkBool32 depthClampEnable;
+ VK_FALSE, // VkBool32 rasterizerDiscardEnable;
+ VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
+ VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
+ VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
+ VK_FALSE, // VkBool32 depthBiasEnable;
+ 0.0f, // float depthBiasConstantFactor;
+ 0.0f, // float depthBiasClamp;
+ 0.0f, // float depthBiasSlopeFactor;
+ 1.0f, // float lineWidth;
+ };
+
+ const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
+ imageMSInfo.samples, // VkSampleCountFlagBits rasterizationSamples;
+ VK_TRUE, // VkBool32 sampleShadingEnable;
+ 1.0f, // float minSampleShading;
+ DE_NULL, // const VkSampleMask* pSampleMask;
+ VK_FALSE, // VkBool32 alphaToCoverageEnable;
+ VK_FALSE, // VkBool32 alphaToOneEnable;
+ };
+
+ const VkStencilOpState stencilOpState = makeStencilOpState
+ (
+ VK_STENCIL_OP_KEEP, // stencil fail
+ VK_STENCIL_OP_KEEP, // depth & stencil pass
+ VK_STENCIL_OP_KEEP, // depth only fail
+ VK_COMPARE_OP_ALWAYS, // compare op
+ 0u, // compare mask
+ 0u, // write mask
+ 0u // reference
+ );
+
+ const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
+ VK_FALSE, // VkBool32 depthTestEnable;
+ VK_FALSE, // VkBool32 depthWriteEnable;
+ VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
+ VK_FALSE, // VkBool32 depthBoundsTestEnable;
+ VK_FALSE, // VkBool32 stencilTestEnable;
+ stencilOpState, // VkStencilOpState front;
+ stencilOpState, // VkStencilOpState back;
+ 0.0f, // float minDepthBounds;
+ 1.0f, // float maxDepthBounds;
+ };
+
+ const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+
+ const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+ {
+ VK_FALSE, // VkBool32 blendEnable;
+ VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
+ VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
+ colorComponentsAll, // VkColorComponentFlags colorWriteMask;
+ };
+
+ const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
+ VK_FALSE, // VkBool32 logicOpEnable;
+ VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
+ 1u, // deUint32 attachmentCount;
+ &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
+ { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
+ };
+
+ const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
+
+ const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
+ *vsModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
+
+ const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
+ *fsModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
+
+ const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
+ 2u, // deUint32 stageCount;
+ shaderStageInfos, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ *pipelineLayout, // VkPipelineLayout layout;
+ *renderPass, // VkRenderPass renderPass;
+ 0u, // deUint32 subpass;
+ DE_NULL, // VkPipeline basePipelineHandle;
+ 0u, // deInt32 basePipelineIndex;
+ };
+
+ // Create graphics pipeline
+ const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
+
+ // Create command buffer for compute and transfer oparations
+ const Unique<VkCommandPool> commandPool(makeCommandPool(deviceInterface, device, queueFamilyIndex));
+ const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
+
+ // Start recording commands
+ beginCommandBuffer(deviceInterface, *commandBuffer);
+
+ {
+ VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
+
+ imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
+ (
+ 0u,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ **imageMS,
+ fullImageRange
+ );
+
+ imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
+ (
+ 0u,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ **imageRS,
+ fullImageRange
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers);
+ }
+
+ {
+ const VkDeviceSize vertexStartOffset = 0u;
+
+ std::vector<VkClearValue> clearValues;
+ clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+ clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+
+ const vk::VkRect2D renderArea =
+ {
+ makeOffset2D(0u, 0u),
+ makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+ };
+
+ // Begin render pass
+ const VkRenderPassBeginInfo renderPassBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *renderPass, // VkRenderPass renderPass;
+ *framebuffer, // VkFramebuffer framebuffer;
+ renderArea, // VkRect2D renderArea;
+ static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
+ &clearValues[0], // const VkClearValue* pClearValues;
+ };
+
+ deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+ // Bind graphics pipeline
+ deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
+
+ // Bind vertex buffer
+ deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
+
+ // Draw full screen quad
+ deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
+
+ // End render pass
+ deviceInterface.cmdEndRenderPass(*commandBuffer);
+ }
+
+ const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
+
+ {
+ const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
+ (
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_TRANSFER_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ sourceImage,
+ fullImageRange
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
+ }
+
+ // Copy data from resolve image to buffer
+ const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
+
+ const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+ const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
+
+ {
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // deUint32 bufferRowLength;
+ 0u, // deUint32 bufferImageHeight;
+ makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
+ makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
+ imageRSInfo.extent, // VkExtent3D imageExtent;
+ };
+
+ deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
+ }
+
+ {
+ const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
+ (
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_ACCESS_HOST_READ_BIT,
+ bufferRS->get(),
+ 0u,
+ imageRSSizeInBytes
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
+ }
+
+ // End recording commands
+ VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
+
+ // Submit commands for execution and wait for completion
+ submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
+
+ // Retrieve data from buffer to host memory
+ const Allocation& bufferRSAllocation = bufferRS->getAllocation();
+
+ invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), VK_WHOLE_SIZE);
+
+ const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
+ imageRSInfo.extent.width,
+ imageRSInfo.extent.height,
+ imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
+ bufferRSAllocation.getHostPtr());
+
+ std::stringstream imageName;
+ imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
+
+ m_context.getTestContext().getLog()
+ << tcu::TestLog::Section(imageName.str(), imageName.str())
+ << tcu::LogImage("image", "", bufferRSData)
+ << tcu::TestLog::EndSection;
+
+ return verifyImageData(imageRSInfo, bufferRSData);
+}
+
+} // multisample
+} // pipeline
+} // vkt
--- /dev/null
+#ifndef _VKTPIPELINEMULTISAMPLEBASERESOLVE_HPP
+#define _VKTPIPELINEMULTISAMPLEBASERESOLVE_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 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 vktPipelineMultisampleBaseResolve.hpp
+ * \brief Base class for tests that check results of multisample resolve
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleBase.hpp"
+#include "vktTestCase.hpp"
+#include "tcuVector.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+class MSCaseBaseResolve : public MultisampleCaseBase
+{
+public:
+ MSCaseBaseResolve (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams)
+ : MultisampleCaseBase(testCtx, name, imageMSParams)
+ {}
+};
+
+class MSInstanceBaseResolve : public MultisampleInstanceBase
+{
+public:
+ MSInstanceBaseResolve (Context& context,
+ const ImageMSParams& imageMSParams)
+ : MultisampleInstanceBase(context, imageMSParams)
+ {}
+
+protected:
+
+ tcu::TestStatus iterate (void);
+
+ virtual tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageRSInfo,
+ const tcu::ConstPixelBufferAccess& dataRS) const = 0;
+};
+
+} // multisample
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLEBASERESOLVE_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+* Vulkan Conformance Tests
+* ------------------------
+*
+* Copyright (c) 2016 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 vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp
+* \brief Base class for tests that check results of multisample resolve
+* and/or values of individual samples
+*//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+using namespace vk;
+
+void MSCaseBaseResolveAndPerSampleFetch::initPrograms (vk::SourceCollections& programCollection) const
+{
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("per_sample_fetch_vs") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
+ << "\n"
+ << "layout(set = 0, binding = 1, std140) uniform SampleBlock {\n"
+ << " int sampleNdx;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " fs_out_color = subpassLoad(imageMS, sampleNdx);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("per_sample_fetch_fs") << glu::FragmentSource(fs.str());
+}
+
+VkPipelineMultisampleStateCreateInfo MSInstanceBaseResolveAndPerSampleFetch::getMSStateCreateInfo (const ImageMSParams& imageMSParams) const
+{
+ const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
+ imageMSParams.numSamples, // VkSampleCountFlagBits rasterizationSamples;
+ VK_TRUE, // VkBool32 sampleShadingEnable;
+ 1.0f, // float minSampleShading;
+ DE_NULL, // const VkSampleMask* pSampleMask;
+ VK_FALSE, // VkBool32 alphaToCoverageEnable;
+ VK_FALSE, // VkBool32 alphaToOneEnable;
+ };
+
+ return multisampleStateInfo;
+}
+
+const VkDescriptorSetLayout* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSetLayout(const ImageMSParams& imageMSParams)
+{
+ DE_UNREF(imageMSParams);
+
+ return DE_NULL;
+}
+
+const VkDescriptorSet* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSet(const ImageMSParams& imageMSParams, const VkDescriptorSetLayout* descSetLayout)
+{
+ DE_UNREF(imageMSParams);
+ DE_UNREF(descSetLayout);
+
+ return DE_NULL;
+}
+
+tcu::TestStatus MSInstanceBaseResolveAndPerSampleFetch::iterate (void)
+{
+ const InstanceInterface& instance = m_context.getInstanceInterface();
+ const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+ const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
+ Allocator& allocator = m_context.getDefaultAllocator();
+ const VkQueue queue = m_context.getUniversalQueue();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+
+ VkImageCreateInfo imageMSInfo;
+ VkImageCreateInfo imageRSInfo;
+ const deUint32 firstSubpassAttachmentsCount = 2u;
+
+ // Check if image size does not exceed device limits
+ validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
+
+ // Check if device supports image format as color attachment
+ validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
+
+ imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ imageMSInfo.pNext = DE_NULL;
+ imageMSInfo.flags = 0u;
+ imageMSInfo.imageType = mapImageType(m_imageType);
+ imageMSInfo.format = mapTextureFormat(m_imageFormat);
+ imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
+ imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
+ imageMSInfo.mipLevels = 1u;
+ imageMSInfo.samples = m_imageMSParams.numSamples;
+ imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+ imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ imageMSInfo.queueFamilyIndexCount = 0u;
+ imageMSInfo.pQueueFamilyIndices = DE_NULL;
+
+ if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
+ {
+ imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+ }
+
+ validateImageInfo(instance, physicalDevice, imageMSInfo);
+
+ const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
+
+ imageRSInfo = imageMSInfo;
+ imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ imageRSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+
+ validateImageInfo(instance, physicalDevice, imageRSInfo);
+
+ const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
+
+ const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
+
+ std::vector<de::SharedPtr<Image> > imagesPerSampleVec(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ imagesPerSampleVec[sampleNdx] = de::SharedPtr<Image>(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
+ }
+
+ // Create render pass
+ std::vector<VkAttachmentDescription> attachments(firstSubpassAttachmentsCount + numSamples);
+
+ {
+ const VkAttachmentDescription attachmentMSDesc =
+ {
+ (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
+ imageMSInfo.format, // VkFormat format;
+ imageMSInfo.samples, // 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_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout;
+ };
+
+ attachments[0] = attachmentMSDesc;
+
+ const VkAttachmentDescription attachmentRSDesc =
+ {
+ (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
+ imageRSInfo.format, // VkFormat format;
+ imageRSInfo.samples, // 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;
+ };
+
+ attachments[1] = attachmentRSDesc;
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ attachments[firstSubpassAttachmentsCount + sampleNdx] = attachmentRSDesc;
+ }
+ }
+
+ const VkAttachmentReference attachmentMSColorRef =
+ {
+ 0u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkAttachmentReference attachmentMSInputRef =
+ {
+ 0u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkAttachmentReference attachmentRSColorRef =
+ {
+ 1u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ std::vector<VkAttachmentReference> perSampleAttachmentRef(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const VkAttachmentReference attachmentRef =
+ {
+ firstSubpassAttachmentsCount + sampleNdx, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ perSampleAttachmentRef[sampleNdx] = attachmentRef;
+ }
+
+ std::vector<deUint32> preserveAttachments(1u + numSamples);
+
+ for (deUint32 attachNdx = 0u; attachNdx < 1u + numSamples; ++attachNdx)
+ {
+ preserveAttachments[attachNdx] = 1u + attachNdx;
+ }
+
+ std::vector<VkSubpassDescription> subpasses(1u + numSamples);
+ std::vector<VkSubpassDependency> subpassDependencies(numSamples);
+
+ const VkSubpassDescription firstSubpassDesc =
+ {
+ (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 0u, // deUint32 inputAttachmentCount;
+ DE_NULL, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &attachmentMSColorRef, // const VkAttachmentReference* pColorAttachments;
+ &attachmentRSColorRef, // const VkAttachmentReference* pResolveAttachments;
+ DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
+ 0u, // deUint32 preserveAttachmentCount;
+ DE_NULL // const deUint32* pPreserveAttachments;
+ };
+
+ subpasses[0] = firstSubpassDesc;
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const VkSubpassDescription subpassDesc =
+ {
+ (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 1u, // deUint32 inputAttachmentCount;
+ &attachmentMSInputRef, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &perSampleAttachmentRef[sampleNdx], // const VkAttachmentReference* pColorAttachments;
+ DE_NULL, // const VkAttachmentReference* pResolveAttachments;
+ DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
+ 1u + sampleNdx, // deUint32 preserveAttachmentCount;
+ dataPointer(preserveAttachments) // const deUint32* pPreserveAttachments;
+ };
+
+ subpasses[1u + sampleNdx] = subpassDesc;
+
+ const VkSubpassDependency subpassDependency =
+ {
+ 0u, // uint32_t srcSubpass;
+ 1u + sampleNdx, // uint32_t dstSubpass;
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask;
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask;
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
+ VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask;
+ 0u, // VkDependencyFlags dependencyFlags;
+ };
+
+ subpassDependencies[sampleNdx] = subpassDependency;
+ }
+
+ const VkRenderPassCreateInfo renderPassInfo =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
+ static_cast<deUint32>(attachments.size()), // deUint32 attachmentCount;
+ dataPointer(attachments), // const VkAttachmentDescription* pAttachments;
+ static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
+ dataPointer(subpasses), // const VkSubpassDescription* pSubpasses;
+ static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount;
+ dataPointer(subpassDependencies) // const VkSubpassDependency* pDependencies;
+ };
+
+ const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
+
+ const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
+
+ // Create color attachments image views
+ typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
+ std::vector<VkImageViewSp> imageViewsShPtrs(firstSubpassAttachmentsCount + numSamples);
+ std::vector<VkImageView> imageViews(firstSubpassAttachmentsCount + numSamples);
+
+ imageViewsShPtrs[0] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
+ imageViewsShPtrs[1] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
+
+ imageViews[0] = **imageViewsShPtrs[0];
+ imageViews[1] = **imageViewsShPtrs[1];
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imagesPerSampleVec[sampleNdx], mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
+ imageViews[firstSubpassAttachmentsCount + sampleNdx] = **imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx];
+ }
+
+ // Create framebuffer
+ const VkFramebufferCreateInfo framebufferInfo =
+ {
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
+ *renderPass, // VkRenderPass renderPass;
+ static_cast<deUint32>(imageViews.size()), // uint32_t attachmentCount;
+ dataPointer(imageViews), // const VkImageView* pAttachments;
+ imageMSInfo.extent.width, // uint32_t width;
+ imageMSInfo.extent.height, // uint32_t height;
+ imageMSInfo.arrayLayers, // uint32_t layers;
+ };
+
+ const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
+
+ const VkDescriptorSetLayout* descriptorSetLayoutMSPass = createMSPassDescSetLayout(m_imageMSParams);
+
+ // Create pipeline layout
+ const VkPipelineLayoutCreateInfo pipelineLayoutMSPassParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
+ descriptorSetLayoutMSPass ? 1u : 0u, // deUint32 setLayoutCount;
+ descriptorSetLayoutMSPass, // const VkDescriptorSetLayout* pSetLayouts;
+ 0u, // deUint32 pushConstantRangeCount;
+ DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
+ };
+
+ const Unique<VkPipelineLayout> pipelineLayoutMSPass(createPipelineLayout(deviceInterface, device, &pipelineLayoutMSPassParams));
+
+ // Create vertex attributes data
+ const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
+
+ de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+ const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
+
+ uploadVertexData(vertexBufferAllocation, vertexDataDesc);
+
+ flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), VK_WHOLE_SIZE);
+
+ const VkVertexInputBindingDescription vertexBinding =
+ {
+ 0u, // deUint32 binding;
+ vertexDataDesc.dataStride, // deUint32 stride;
+ VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
+ 1u, // uint32_t vertexBindingDescriptionCount;
+ &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
+ dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
+ vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
+ VK_FALSE, // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkViewport viewport =
+ {
+ 0.0f, 0.0f,
+ static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
+ 0.0f, 1.0f
+ };
+
+ const VkRect2D scissor =
+ {
+ makeOffset2D(0, 0),
+ makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+ };
+
+ const VkPipelineViewportStateCreateInfo viewportStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
+ 1u, // uint32_t viewportCount;
+ &viewport, // const VkViewport* pViewports;
+ 1u, // uint32_t scissorCount;
+ &scissor, // const VkRect2D* pScissors;
+ };
+
+ const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
+ VK_FALSE, // VkBool32 depthClampEnable;
+ VK_FALSE, // VkBool32 rasterizerDiscardEnable;
+ VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
+ VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
+ VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
+ VK_FALSE, // VkBool32 depthBiasEnable;
+ 0.0f, // float depthBiasConstantFactor;
+ 0.0f, // float depthBiasClamp;
+ 0.0f, // float depthBiasSlopeFactor;
+ 1.0f, // float lineWidth;
+ };
+
+ const VkPipelineMultisampleStateCreateInfo multisampleStateInfo = getMSStateCreateInfo(m_imageMSParams);
+
+ const VkStencilOpState stencilOpState = makeStencilOpState
+ (
+ VK_STENCIL_OP_KEEP, // stencil fail
+ VK_STENCIL_OP_KEEP, // depth & stencil pass
+ VK_STENCIL_OP_KEEP, // depth only fail
+ VK_COMPARE_OP_ALWAYS, // compare op
+ 0u, // compare mask
+ 0u, // write mask
+ 0u // reference
+ );
+
+ const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
+ VK_FALSE, // VkBool32 depthTestEnable;
+ VK_FALSE, // VkBool32 depthWriteEnable;
+ VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
+ VK_FALSE, // VkBool32 depthBoundsTestEnable;
+ VK_FALSE, // VkBool32 stencilTestEnable;
+ stencilOpState, // VkStencilOpState front;
+ stencilOpState, // VkStencilOpState back;
+ 0.0f, // float minDepthBounds;
+ 1.0f, // float maxDepthBounds;
+ };
+
+ const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+
+ const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+ {
+ VK_FALSE, // VkBool32 blendEnable;
+ VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
+ VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
+ colorComponentsAll, // VkColorComponentFlags colorWriteMask;
+ };
+
+ const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
+ VK_FALSE, // VkBool32 logicOpEnable;
+ VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
+ 1u, // deUint32 attachmentCount;
+ &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
+ { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
+ };
+
+ // Create graphics pipeline for multisample pass
+ const Unique<VkShaderModule> vsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0u));
+
+ const VkPipelineShaderStageCreateInfo vsMSPassShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
+ *vsMSPassModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const Unique<VkShaderModule> fsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0u));
+
+ const VkPipelineShaderStageCreateInfo fsMSPassShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
+ *fsMSPassModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const VkPipelineShaderStageCreateInfo shaderStageInfosMSPass[] = { vsMSPassShaderStageInfo, fsMSPassShaderStageInfo };
+
+ const VkGraphicsPipelineCreateInfo graphicsPipelineInfoMSPass =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags;
+ 2u, // deUint32 stageCount;
+ shaderStageInfosMSPass, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ *pipelineLayoutMSPass, // VkPipelineLayout layout;
+ *renderPass, // VkRenderPass renderPass;
+ 0u, // deUint32 subpass;
+ DE_NULL, // VkPipeline basePipelineHandle;
+ 0u, // deInt32 basePipelineIndex;
+ };
+
+ const Unique<VkPipeline> graphicsPipelineMSPass(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfoMSPass));
+
+ typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
+ std::vector<VkPipelineSp> graphicsPipelinesPerSampleFetch(numSamples);
+
+ // Create descriptor set layout
+ const Unique<VkDescriptorSetLayout> descriptorSetLayout(
+ DescriptorSetLayoutBuilder()
+ .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
+ .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_FRAGMENT_BIT)
+ .build(deviceInterface, device));
+
+ const Unique<VkPipelineLayout> pipelineLayoutPerSampleFetchPass(makePipelineLayout(deviceInterface, device, *descriptorSetLayout));
+
+ const deUint32 bufferPerSampleFetchPassSize = 4u * (deUint32)sizeof(tcu::Vec4);
+
+ de::SharedPtr<Buffer> vertexBufferPerSampleFetchPass = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(bufferPerSampleFetchPassSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+
+ // Create graphics pipelines for per sample texel fetch passes
+ {
+ const Unique<VkShaderModule> vsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_vs"), (VkShaderModuleCreateFlags)0u));
+
+ const VkPipelineShaderStageCreateInfo vsPerSampleFetchPassShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
+ *vsPerSampleFetchPassModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const Unique<VkShaderModule> fsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_fs"), (VkShaderModuleCreateFlags)0u));
+
+ const VkPipelineShaderStageCreateInfo fsPerSampleFetchPassShaderStageInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
+ *fsPerSampleFetchPassModule, // VkShaderModule module;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const VkPipelineShaderStageCreateInfo shaderStageInfosPerSampleFetchPass[] = { vsPerSampleFetchPassShaderStageInfo, fsPerSampleFetchPassShaderStageInfo };
+
+ std::vector<tcu::Vec4> vertices;
+
+ vertices.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
+ vertices.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
+ vertices.push_back(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
+ vertices.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
+
+ const Allocation& vertexAllocPerSampleFetchPass = vertexBufferPerSampleFetchPass->getAllocation();
+
+ deMemcpy(vertexAllocPerSampleFetchPass.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(bufferPerSampleFetchPassSize));
+
+ flushMappedMemoryRange(deviceInterface, device, vertexAllocPerSampleFetchPass.getMemory(), vertexAllocPerSampleFetchPass.getOffset(), VK_WHOLE_SIZE);
+
+ const VkVertexInputBindingDescription vertexBindingPerSampleFetchPass =
+ {
+ 0u, // deUint32 binding;
+ sizeof(tcu::Vec4), // deUint32 stride;
+ VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
+ };
+
+ const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+ {
+ 0u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
+ 0u, // deUint32 offset;
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStatePerSampleFetchPass =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
+ 1u, // uint32_t vertexBindingDescriptionCount;
+ &vertexBindingPerSampleFetchPass, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ 1u, // uint32_t vertexAttributeDescriptionCount;
+ &vertexAttribPositionNdc, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStatePerSampleFetchPass =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
+ VK_FALSE, // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkPipelineMultisampleStateCreateInfo multisampleStatePerSampleFetchPass =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineMultisampleStateCreateFlags)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;
+ };
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags;
+ 2u, // deUint32 stageCount;
+ shaderStageInfosPerSampleFetchPass, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStatePerSampleFetchPass, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStatePerSampleFetchPass, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ &multisampleStatePerSampleFetchPass, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ *pipelineLayoutPerSampleFetchPass, // VkPipelineLayout layout;
+ *renderPass, // VkRenderPass renderPass;
+ 1u + sampleNdx, // deUint32 subpass;
+ DE_NULL, // VkPipeline basePipelineHandle;
+ 0u, // deInt32 basePipelineIndex;
+ };
+
+ graphicsPipelinesPerSampleFetch[sampleNdx] = makeVkSharedPtr(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
+ }
+ }
+
+ // Create descriptor pool
+ const Unique<VkDescriptorPool> descriptorPool(
+ DescriptorPoolBuilder()
+ .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
+ .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1u)
+ .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
+
+ // Create descriptor set
+ const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(deviceInterface, device, *descriptorPool, *descriptorSetLayout));
+
+ const VkPhysicalDeviceLimits deviceLimits = getPhysicalDeviceProperties(instance, physicalDevice).limits;
+
+ VkDeviceSize uboOffsetAlignment = sizeof(deInt32) < deviceLimits.minUniformBufferOffsetAlignment ? deviceLimits.minUniformBufferOffsetAlignment : sizeof(deInt32);
+
+ uboOffsetAlignment += (deviceLimits.minUniformBufferOffsetAlignment - uboOffsetAlignment % deviceLimits.minUniformBufferOffsetAlignment) % deviceLimits.minUniformBufferOffsetAlignment;
+
+ const VkBufferCreateInfo bufferSampleIDInfo = makeBufferCreateInfo(uboOffsetAlignment * numSamples, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+ const de::UniquePtr<Buffer> bufferSampleID(new Buffer(deviceInterface, device, allocator, bufferSampleIDInfo, MemoryRequirement::HostVisible));
+
+ std::vector<deUint32> sampleIDsOffsets(numSamples);
+
+ {
+ deInt8* sampleIDs = new deInt8[uboOffsetAlignment * numSamples];
+
+ for (deInt32 sampleNdx = 0u; sampleNdx < static_cast<deInt32>(numSamples); ++sampleNdx)
+ {
+ sampleIDsOffsets[sampleNdx] = static_cast<deUint32>(sampleNdx * uboOffsetAlignment);
+ deInt8* samplePtr = sampleIDs + sampleIDsOffsets[sampleNdx];
+
+ deMemcpy(samplePtr, &sampleNdx, sizeof(deInt32));
+ }
+
+ deMemcpy(bufferSampleID->getAllocation().getHostPtr(), sampleIDs, static_cast<deUint32>(uboOffsetAlignment * numSamples));
+
+ flushMappedMemoryRange(deviceInterface, device, bufferSampleID->getAllocation().getMemory(), bufferSampleID->getAllocation().getOffset(), VK_WHOLE_SIZE);
+
+ delete[] sampleIDs;
+ }
+
+ {
+ const VkDescriptorImageInfo descImageInfo = makeDescriptorImageInfo(DE_NULL, imageViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ const VkDescriptorBufferInfo descBufferInfo = makeDescriptorBufferInfo(**bufferSampleID, 0u, sizeof(deInt32));
+
+ DescriptorSetUpdateBuilder()
+ .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descImageInfo)
+ .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &descBufferInfo)
+ .update(deviceInterface, device);
+ }
+
+ // Create command buffer for compute and transfer oparations
+ const Unique<VkCommandPool> commandPool(makeCommandPool(deviceInterface, device, queueFamilyIndex));
+ const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
+
+ // Start recording commands
+ beginCommandBuffer(deviceInterface, *commandBuffer);
+
+ {
+ std::vector<VkImageMemoryBarrier> imageOutputAttachmentBarriers(firstSubpassAttachmentsCount + numSamples);
+
+ imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
+ (
+ 0u,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ **imageMS,
+ fullImageRange
+ );
+
+ imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
+ (
+ 0u,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ **imageRS,
+ fullImageRange
+ );
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ imageOutputAttachmentBarriers[firstSubpassAttachmentsCount + sampleNdx] = makeImageMemoryBarrier
+ (
+ 0u,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ **imagesPerSampleVec[sampleNdx],
+ fullImageRange
+ );
+ }
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
+ static_cast<deUint32>(imageOutputAttachmentBarriers.size()), dataPointer(imageOutputAttachmentBarriers));
+ }
+
+ {
+ const VkDeviceSize vertexStartOffset = 0u;
+
+ std::vector<VkClearValue> clearValues(firstSubpassAttachmentsCount + numSamples);
+ for (deUint32 attachmentNdx = 0u; attachmentNdx < firstSubpassAttachmentsCount + numSamples; ++attachmentNdx)
+ {
+ clearValues[attachmentNdx] = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+ }
+
+ const vk::VkRect2D renderArea =
+ {
+ makeOffset2D(0u, 0u),
+ makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+ };
+
+ // Begin render pass
+ const VkRenderPassBeginInfo renderPassBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *renderPass, // VkRenderPass renderPass;
+ *framebuffer, // VkFramebuffer framebuffer;
+ renderArea, // VkRect2D renderArea;
+ static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
+ dataPointer(clearValues), // const VkClearValue* pClearValues;
+ };
+
+ deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+ // Bind graphics pipeline
+ deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelineMSPass);
+
+ const VkDescriptorSet* descriptorSetMSPass = createMSPassDescSet(m_imageMSParams, descriptorSetLayoutMSPass);
+
+ if (descriptorSetMSPass)
+ {
+ // Bind descriptor set
+ deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutMSPass, 0u, 1u, descriptorSetMSPass, 0u, DE_NULL);
+ }
+
+ // Bind vertex buffer
+ deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
+
+ // Perform a draw
+ deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
+
+ // Change imageMS layout for input attachment compatibility
+ const VkImageMemoryBarrier imageMSInputAttachmentBarrier = makeImageMemoryBarrier
+ (
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ **imageMS,
+ fullImageRange
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMSInputAttachmentBarrier);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ deviceInterface.cmdNextSubpass(*commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
+
+ // Bind graphics pipeline
+ deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **graphicsPipelinesPerSampleFetch[sampleNdx]);
+
+ // Bind descriptor set
+ deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutPerSampleFetchPass, 0u, 1u, &descriptorSet.get(), 1u, &sampleIDsOffsets[sampleNdx]);
+
+ // Bind vertex buffer
+ deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBufferPerSampleFetchPass->get(), &vertexStartOffset);
+
+ // Perform a draw
+ deviceInterface.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
+ }
+
+ // End render pass
+ deviceInterface.cmdEndRenderPass(*commandBuffer);
+ }
+
+ {
+ const VkImageMemoryBarrier imageRSTransferBarrier = makeImageMemoryBarrier
+ (
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_TRANSFER_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ **imageRS,
+ fullImageRange
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageRSTransferBarrier);
+ }
+
+ // Copy data from imageRS to buffer
+ const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels, 1u);
+
+ const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+ const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
+
+ {
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // deUint32 bufferRowLength;
+ 0u, // deUint32 bufferImageHeight;
+ makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
+ makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
+ imageRSInfo.extent, // VkExtent3D imageExtent;
+ };
+
+ deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imageRS, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
+ }
+
+ {
+ const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
+ (
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_ACCESS_HOST_READ_BIT,
+ bufferRS->get(),
+ 0u,
+ imageRSSizeInBytes
+ );
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
+ }
+
+ // Copy data from per sample images to buffers
+ std::vector<VkImageMemoryBarrier> imagesPerSampleTransferBarriers(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ imagesPerSampleTransferBarriers[sampleNdx] = makeImageMemoryBarrier
+ (
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_TRANSFER_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ **imagesPerSampleVec[sampleNdx],
+ fullImageRange
+ );
+ }
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
+ static_cast<deUint32>(imagesPerSampleTransferBarriers.size()), dataPointer(imagesPerSampleTransferBarriers));
+
+ std::vector<de::SharedPtr<Buffer> > buffersPerSample(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ buffersPerSample[sampleNdx] = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
+
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // deUint32 bufferRowLength;
+ 0u, // deUint32 bufferImageHeight;
+ makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
+ makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
+ imageRSInfo.extent, // VkExtent3D imageExtent;
+ };
+
+ deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imagesPerSampleVec[sampleNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **buffersPerSample[sampleNdx], 1u, &bufferImageCopy);
+ }
+
+ std::vector<VkBufferMemoryBarrier> buffersPerSampleHostReadBarriers(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ buffersPerSampleHostReadBarriers[sampleNdx] = makeBufferMemoryBarrier
+ (
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_ACCESS_HOST_READ_BIT,
+ **buffersPerSample[sampleNdx],
+ 0u,
+ imageRSSizeInBytes
+ );
+ }
+
+ deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL,
+ static_cast<deUint32>(buffersPerSampleHostReadBarriers.size()), dataPointer(buffersPerSampleHostReadBarriers), 0u, DE_NULL);
+
+ // End recording commands
+ VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
+
+ // Submit commands for execution and wait for completion
+ submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
+
+ // Retrieve data from bufferRS to host memory
+ const Allocation& bufferRSAlloc = bufferRS->getAllocation();
+
+ invalidateMappedMemoryRange(deviceInterface, device, bufferRSAlloc.getMemory(), bufferRSAlloc.getOffset(), VK_WHOLE_SIZE);
+
+ const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
+ imageRSInfo.extent.width,
+ imageRSInfo.extent.height,
+ imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
+ bufferRSAlloc.getHostPtr());
+
+ std::stringstream resolveName;
+ resolveName << "Resolve image " << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
+
+ m_context.getTestContext().getLog()
+ << tcu::TestLog::Section(resolveName.str(), resolveName.str())
+ << tcu::LogImage("resolve", "", bufferRSData)
+ << tcu::TestLog::EndSection;
+
+ std::vector<tcu::ConstPixelBufferAccess> buffersPerSampleData(numSamples);
+
+ // Retrieve data from per sample buffers to host memory
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const Allocation& bufferAlloc = buffersPerSample[sampleNdx]->getAllocation();
+
+ invalidateMappedMemoryRange(deviceInterface, device, bufferAlloc.getMemory(), bufferAlloc.getOffset(), VK_WHOLE_SIZE);
+
+ buffersPerSampleData[sampleNdx] = tcu::ConstPixelBufferAccess
+ (
+ m_imageFormat,
+ imageRSInfo.extent.width,
+ imageRSInfo.extent.height,
+ imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
+ bufferAlloc.getHostPtr()
+ );
+
+ std::stringstream sampleName;
+ sampleName << "Sample " << sampleNdx << " image" << std::endl;
+
+ m_context.getTestContext().getLog()
+ << tcu::TestLog::Section(sampleName.str(), sampleName.str())
+ << tcu::LogImage("sample", "", buffersPerSampleData[sampleNdx])
+ << tcu::TestLog::EndSection;
+ }
+
+ return verifyImageData(imageMSInfo, imageRSInfo, buffersPerSampleData, bufferRSData);
+}
+
+} // multisample
+} // pipeline
+} // vkt
--- /dev/null
+#ifndef _VKTPIPELINEMULTISAMPLEBASERESOLVEANDPERSAMPLEFETCH_HPP
+#define _VKTPIPELINEMULTISAMPLEBASERESOLVEANDPERSAMPLEFETCH_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 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 vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp
+ * \brief Base class for tests that check results of multisample resolve
+ * and/or values of individual samples
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleBase.hpp"
+#include "vktTestCase.hpp"
+#include "tcuVector.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+class MSCaseBaseResolveAndPerSampleFetch : public MultisampleCaseBase
+{
+public:
+ MSCaseBaseResolveAndPerSampleFetch (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams)
+ : MultisampleCaseBase(testCtx, name, imageMSParams) {}
+
+ void initPrograms (vk::SourceCollections& programCollection) const;
+};
+
+class MSInstanceBaseResolveAndPerSampleFetch : public MultisampleInstanceBase
+{
+public:
+ MSInstanceBaseResolveAndPerSampleFetch (Context& context,
+ const ImageMSParams& imageMSParams)
+ : MultisampleInstanceBase(context, imageMSParams) {}
+
+protected:
+
+ tcu::TestStatus iterate (void);
+
+ virtual vk::VkPipelineMultisampleStateCreateInfo getMSStateCreateInfo (const ImageMSParams& imageMSParams) const;
+
+ virtual const vk::VkDescriptorSetLayout* createMSPassDescSetLayout (const ImageMSParams& imageMSParams);
+
+ virtual const vk::VkDescriptorSet* createMSPassDescSet (const ImageMSParams& imageMSParams,
+ const vk::VkDescriptorSetLayout* descSetLayout);
+
+ virtual tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const = 0;
+};
+
+} // multisample
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLEBASERESOLVEANDPERSAMPLEFETCH_HPP
*//*--------------------------------------------------------------------*/
#include "vktPipelineMultisampleInterpolationTests.hpp"
+#include "vktPipelineMultisampleBaseResolve.hpp"
#include "vktPipelineMultisampleTestsUtil.hpp"
#include "vktPipelineMakeUtil.hpp"
#include "vkQueryUtil.hpp"
-
-#include <set>
+#include <vector>
namespace vkt
{
using namespace vk;
-struct ImageMSParams
+struct VertexDataNdc
{
- ImageMSParams(const VkSampleCountFlagBits samples, const tcu::UVec3& size) : numSamples(samples), imageSize(size) {}
+ VertexDataNdc (const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
- VkSampleCountFlagBits numSamples;
- tcu::UVec3 imageSize;
+ tcu::Vec4 positionNdc;
};
-class MSInterpolationCaseBase : public TestCase
+struct VertexDataNdcScreen
{
-public:
- MSInterpolationCaseBase (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : TestCase(testCtx, name, "")
- , m_imageMSParams(imageMSParams)
- {}
-
-protected:
- const ImageMSParams m_imageMSParams;
-};
+ VertexDataNdcScreen (const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
-typedef MSInterpolationCaseBase* (*MSInterpolationCaseFuncPtr)(tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams);
+ tcu::Vec4 positionNdc;
+ tcu::Vec2 positionScreen;
+};
-class MSInterpolationInstanceBase : public TestInstance
+struct VertexDataNdcBarycentric
{
-public:
- MSInterpolationInstanceBase (Context& context,
- const ImageMSParams& imageMSParams)
- : TestInstance (context)
- , m_imageMSParams (imageMSParams)
- , m_imageType (IMAGE_TYPE_2D)
- , m_imageFormat (tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::UNORM_INT8))
- {}
+ VertexDataNdcBarycentric (const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {}
- tcu::TestStatus iterate (void);
-
-protected:
-
- typedef std::vector<VkVertexInputAttributeDescription> VertexAttribDescVec;
-
- struct VertexDataDesc
- {
- VkPrimitiveTopology primitiveTopology;
- deUint32 verticesCount;
- deUint32 dataStride;
- VkDeviceSize dataSize;
- VertexAttribDescVec vertexAttribDescVec;
- };
-
- void validateImageSize (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const ImageType imageType,
- const tcu::UVec3& imageSize) const;
-
- void validateImageFeatureFlags (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const VkFormat format,
- const VkFormatFeatureFlags featureFlags) const;
-
- void validateImageInfo (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const VkImageCreateInfo& imageInfo) const;
-
- virtual VertexDataDesc getVertexDataDescripton (void) const = 0;
-
- virtual void uploadVertexData (const Allocation& vertexBufferAllocation,
- const VertexDataDesc& vertexDataDescripton) const = 0;
-
- virtual tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const = 0;
-protected:
- const ImageMSParams m_imageMSParams;
- const ImageType m_imageType;
- const tcu::TextureFormat m_imageFormat;
+ tcu::Vec4 positionNdc;
+ tcu::Vec3 barycentricCoord;
};
-void MSInterpolationInstanceBase::validateImageSize (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const ImageType imageType,
- const tcu::UVec3& imageSize) const
+bool checkForError (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS, const deUint32 errorCompNdx)
{
- const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
-
- bool isImageSizeValid = true;
-
- switch (imageType)
+ for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x)
{
- case IMAGE_TYPE_1D:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
- break;
- case IMAGE_TYPE_1D_ARRAY:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
- imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
- break;
- case IMAGE_TYPE_2D:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
- imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
- break;
- case IMAGE_TYPE_2D_ARRAY:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
- imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
- imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
- break;
- case IMAGE_TYPE_CUBE:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
- imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
- break;
- case IMAGE_TYPE_CUBE_ARRAY:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
- imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
- imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
- break;
- case IMAGE_TYPE_3D:
- isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
- imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
- imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
- break;
- default:
- DE_FATAL("Unknown image type");
- }
-
- if (!isImageSizeValid)
- {
- std::ostringstream notSupportedStream;
-
- notSupportedStream << "Image type (" << getImageTypeName(imageType) << ") with size (" << imageSize.x() << ", " << imageSize.y() << ", " << imageSize.z() << ") not supported by device" << std::endl;
+ const deUint32 errorComponent = dataRS.getPixelUint(x, y, z)[errorCompNdx];
- const std::string notSupportedString = notSupportedStream.str();
-
- TCU_THROW(NotSupportedError, notSupportedString.c_str());
+ if (errorComponent > 0)
+ return true;
}
-}
-
-void MSInterpolationInstanceBase::validateImageFeatureFlags (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const VkFormat format,
- const VkFormatFeatureFlags featureFlags) const
-{
- const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
- if ((formatProperties.optimalTilingFeatures & featureFlags) != featureFlags)
- {
- std::ostringstream notSupportedStream;
-
- notSupportedStream << "Device does not support image format " << format << " for feature flags " << featureFlags << std::endl;
-
- const std::string notSupportedString = notSupportedStream.str();
-
- TCU_THROW(NotSupportedError, notSupportedString.c_str());
- }
+ return false;
}
-void MSInterpolationInstanceBase::validateImageInfo (const InstanceInterface& instance,
- const VkPhysicalDevice physicalDevice,
- const VkImageCreateInfo& imageInfo) const
+template <typename CaseClassName>
+class MSCase : public MultisampleCaseBase
{
- VkImageFormatProperties imageFormatProps;
- instance.getPhysicalDeviceImageFormatProperties(physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProps);
-
- if (imageFormatProps.maxExtent.width < imageInfo.extent.width ||
- imageFormatProps.maxExtent.height < imageInfo.extent.height ||
- imageFormatProps.maxExtent.depth < imageInfo.extent.depth)
- {
- std::ostringstream notSupportedStream;
-
- notSupportedStream << "Image extent ("
- << imageInfo.extent.width << ", "
- << imageInfo.extent.height << ", "
- << imageInfo.extent.depth
- << ") exceeds allowed maximum ("
- << imageFormatProps.maxExtent.width << ", "
- << imageFormatProps.maxExtent.height << ", "
- << imageFormatProps.maxExtent.depth
- << ")"
- << std::endl;
-
- const std::string notSupportedString = notSupportedStream.str();
-
- TCU_THROW(NotSupportedError, notSupportedString.c_str());
- }
-
- if (imageFormatProps.maxArrayLayers < imageInfo.arrayLayers)
- {
- std::ostringstream notSupportedStream;
-
- notSupportedStream << "Image layers count of " << imageInfo.arrayLayers << " exceeds allowed maximum which is " << imageFormatProps.maxArrayLayers << std::endl;
-
- const std::string notSupportedString = notSupportedStream.str();
-
- TCU_THROW(NotSupportedError, notSupportedString.c_str());
- }
-
- if (!(imageFormatProps.sampleCounts & imageInfo.samples))
- {
- std::ostringstream notSupportedStream;
-
- notSupportedStream << "Samples count of " << imageInfo.samples << " not supported for image" << std::endl;
-
- const std::string notSupportedString = notSupportedStream.str();
-
- TCU_THROW(NotSupportedError, notSupportedString.c_str());
- }
-}
+public:
+ MSCase (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams)
+ : MultisampleCaseBase(testCtx, name, imageMSParams) {}
+
+ void init (void);
+ void initPrograms (vk::SourceCollections& programCollection) const;
+ TestInstance* createInstance (Context& context) const;
+ static MultisampleCaseBase* createCase (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams);
+};
-tcu::TestStatus MSInterpolationInstanceBase::iterate (void)
+template <typename CaseClassName>
+MultisampleCaseBase* MSCase<CaseClassName>::createCase (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
{
- const InstanceInterface& instance = m_context.getInstanceInterface();
- const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
- const VkDevice device = m_context.getDevice();
- const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
- Allocator& allocator = m_context.getDefaultAllocator();
- const VkQueue queue = m_context.getUniversalQueue();
- const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
-
- VkImageCreateInfo imageMSInfo;
- VkImageCreateInfo imageRSInfo;
-
- // Check if image size does not exceed device limits
- validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
-
- // Check if device supports image format as color attachment
- validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
-
- imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- imageMSInfo.pNext = DE_NULL;
- imageMSInfo.flags = 0u;
- imageMSInfo.imageType = mapImageType(m_imageType);
- imageMSInfo.format = mapTextureFormat(m_imageFormat);
- imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
- imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
- imageMSInfo.mipLevels = 1u;
- imageMSInfo.samples = m_imageMSParams.numSamples;
- imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
- imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- imageMSInfo.queueFamilyIndexCount = 0u;
- imageMSInfo.pQueueFamilyIndices = DE_NULL;
-
- if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
- {
- imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
- }
-
- validateImageInfo(instance, physicalDevice, imageMSInfo);
-
- const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
-
- imageRSInfo = imageMSInfo;
- imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-
- validateImageInfo(instance, physicalDevice, imageRSInfo);
-
- const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
-
- // Create render pass
- const VkAttachmentDescription attachmentMSDesc =
- {
- (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
- imageMSInfo.format, // VkFormat format;
- imageMSInfo.samples, // 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;
- };
-
- const VkAttachmentDescription attachmentRSDesc =
- {
- (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
- imageRSInfo.format, // VkFormat format;
- imageRSInfo.samples, // 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;
- };
-
- const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
-
- const VkAttachmentReference attachmentMSRef =
- {
- 0u, // deUint32 attachment;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
- };
-
- const VkAttachmentReference attachmentRSRef =
- {
- 1u, // deUint32 attachment;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
- };
-
- const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
-
- const VkSubpassDescription subpassDescription =
- {
- (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
- VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
- 0u, // deUint32 inputAttachmentCount;
- DE_NULL, // const VkAttachmentReference* pInputAttachments;
- 1u, // deUint32 colorAttachmentCount;
- &attachmentMSRef, // const VkAttachmentReference* pColorAttachments;
- resolveAttachment, // const VkAttachmentReference* pResolveAttachments;
- 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)0u, // VkRenderPassCreateFlags flags;
- 2u, // deUint32 attachmentCount;
- attachments, // const VkAttachmentDescription* pAttachments;
- 1u, // deUint32 subpassCount;
- &subpassDescription, // const VkSubpassDescription* pSubpasses;
- 0u, // deUint32 dependencyCount;
- DE_NULL // const VkSubpassDependency* pDependencies;
- };
-
- const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
-
- const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
-
- // Create color attachments image views
- const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
- const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
-
- const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
-
- // Create framebuffer
- const VkFramebufferCreateInfo framebufferInfo =
- {
- VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
- *renderPass, // VkRenderPass renderPass;
- 2u, // uint32_t attachmentCount;
- attachmentsViews, // const VkImageView* pAttachments;
- imageMSInfo.extent.width, // uint32_t width;
- imageMSInfo.extent.height, // uint32_t height;
- imageMSInfo.arrayLayers, // uint32_t layers;
- };
-
- const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
-
- // Create pipeline layout
- const VkPipelineLayoutCreateInfo pipelineLayoutParams =
- {
- VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
- 0u, // deUint32 setLayoutCount;
- DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
- 0u, // deUint32 pushConstantRangeCount;
- DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
- };
-
- const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
-
- // Create vertex attributes data
- const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
-
- de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
- const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
-
- uploadVertexData(vertexBufferAllocation, vertexDataDesc);
-
- flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), vertexDataDesc.dataSize);
-
- const VkVertexInputBindingDescription vertexBinding =
- {
- 0u, // deUint32 binding;
- vertexDataDesc.dataStride, // deUint32 stride;
- VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
- };
-
- const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
- 1u, // uint32_t vertexBindingDescriptionCount;
- &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
- static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
- dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
- };
-
- const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
- vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
- VK_FALSE, // VkBool32 primitiveRestartEnable;
- };
-
- const VkViewport viewport =
- {
- 0.0f, 0.0f,
- static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
- 0.0f, 1.0f
- };
-
- const VkRect2D scissor =
- {
- makeOffset2D(0, 0),
- makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
- };
-
- const VkPipelineViewportStateCreateInfo viewportStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
- 1u, // uint32_t viewportCount;
- &viewport, // const VkViewport* pViewports;
- 1u, // uint32_t scissorCount;
- &scissor, // const VkRect2D* pScissors;
- };
-
- const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
- VK_FALSE, // VkBool32 depthClampEnable;
- VK_FALSE, // VkBool32 rasterizerDiscardEnable;
- VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
- VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
- VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
- VK_FALSE, // VkBool32 depthBiasEnable;
- 0.0f, // float depthBiasConstantFactor;
- 0.0f, // float depthBiasClamp;
- 0.0f, // float depthBiasSlopeFactor;
- 1.0f, // float lineWidth;
- };
-
- const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
- imageMSInfo.samples, // VkSampleCountFlagBits rasterizationSamples;
- VK_TRUE, // VkBool32 sampleShadingEnable;
- 1.0f, // float minSampleShading;
- DE_NULL, // const VkSampleMask* pSampleMask;
- VK_FALSE, // VkBool32 alphaToCoverageEnable;
- VK_FALSE, // VkBool32 alphaToOneEnable;
- };
-
- const VkStencilOpState stencilOpState = makeStencilOpState
- (
- VK_STENCIL_OP_KEEP, // stencil fail
- VK_STENCIL_OP_KEEP, // depth & stencil pass
- VK_STENCIL_OP_KEEP, // depth only fail
- VK_COMPARE_OP_ALWAYS, // compare op
- 0u, // compare mask
- 0u, // write mask
- 0u // reference
- );
-
- const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
- VK_FALSE, // VkBool32 depthTestEnable;
- VK_FALSE, // VkBool32 depthWriteEnable;
- VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
- VK_FALSE, // VkBool32 depthBoundsTestEnable;
- VK_FALSE, // VkBool32 stencilTestEnable;
- stencilOpState, // VkStencilOpState front;
- stencilOpState, // VkStencilOpState back;
- 0.0f, // float minDepthBounds;
- 1.0f, // float maxDepthBounds;
- };
-
- const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
-
- const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
- {
- VK_FALSE, // VkBool32 blendEnable;
- VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
- VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
- VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
- VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
- VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
- VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
- colorComponentsAll, // VkColorComponentFlags colorWriteMask;
- };
-
- const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
- VK_FALSE, // VkBool32 logicOpEnable;
- VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
- 1u, // deUint32 attachmentCount;
- &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
- { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
- };
-
- const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
-
- const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
- VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
- *vsModule, // VkShaderModule module;
- "main", // const char* pName;
- DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
- };
-
- const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
-
- const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
- {
- VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
- VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
- *fsModule, // VkShaderModule module;
- "main", // const char* pName;
- DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
- };
-
- const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
-
- const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
- {
- VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
- 2u, // deUint32 stageCount;
- shaderStageInfos, // const VkPipelineShaderStageCreateInfo* pStages;
- &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
- &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
- DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
- &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
- &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
- &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
- &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
- &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
- DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
- *pipelineLayout, // VkPipelineLayout layout;
- *renderPass, // VkRenderPass renderPass;
- 0u, // deUint32 subpass;
- DE_NULL, // VkPipeline basePipelineHandle;
- 0u, // deInt32 basePipelineIndex;
- };
-
- // Create graphics pipeline
- const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
-
- // Create command buffer for compute and transfer oparations
- const Unique<VkCommandPool> commandPool(makeCommandPool(deviceInterface, device, queueFamilyIndex));
- const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
-
- // Start recording commands
- beginCommandBuffer(deviceInterface, *commandBuffer);
-
- {
- VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
-
- imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
- (
- 0u,
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- **imageMS,
- fullImageRange
- );
-
- imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
- (
- 0u,
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- **imageRS,
- fullImageRange
- );
-
- deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers);
- }
-
- {
- const VkDeviceSize vertexStartOffset = 0u;
-
- std::vector<VkClearValue> clearValues;
- clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
- clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
-
- const vk::VkRect2D renderArea =
- {
- makeOffset2D(0u, 0u),
- makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
- };
-
- // Begin render pass
- const VkRenderPassBeginInfo renderPassBeginInfo =
- {
- VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- *renderPass, // VkRenderPass renderPass;
- *framebuffer, // VkFramebuffer framebuffer;
- renderArea, // VkRect2D renderArea;
- static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
- &clearValues[0], // const VkClearValue* pClearValues;
- };
-
- deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-
- // Bind graphics pipeline
- deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
-
- // Bind vertex buffer
- deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
-
- // Draw full screen quad
- deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
-
- // End render pass
- deviceInterface.cmdEndRenderPass(*commandBuffer);
- }
-
- const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
-
- {
- const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
- (
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- VK_ACCESS_TRANSFER_READ_BIT,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- sourceImage,
- fullImageRange
- );
-
- deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
- }
-
- // Copy data from resolve image to buffer
- const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
-
- const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
- const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
-
- {
- const VkBufferImageCopy bufferImageCopy =
- {
- 0u, // VkDeviceSize bufferOffset;
- 0u, // deUint32 bufferRowLength;
- 0u, // deUint32 bufferImageHeight;
- makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
- makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
- imageRSInfo.extent, // VkExtent3D imageExtent;
- };
-
- deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
- }
-
- {
- const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
- (
- VK_ACCESS_TRANSFER_WRITE_BIT,
- VK_ACCESS_HOST_READ_BIT,
- bufferRS->get(),
- 0u,
- imageRSSizeInBytes
- );
-
- deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
- }
-
- // End recording commands
- VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
-
- // Submit commands for execution and wait for completion
- submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
-
- // Retrieve data from buffer to host memory
- const Allocation& bufferRSAllocation = bufferRS->getAllocation();
-
- invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), imageRSSizeInBytes);
-
- const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
- imageRSInfo.extent.width,
- imageRSInfo.extent.height,
- imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
- bufferRSAllocation.getHostPtr());
-
- std::stringstream imageName;
- imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
-
- m_context.getTestContext().getLog()
- << tcu::TestLog::Section(imageName.str(), imageName.str())
- << tcu::LogImage("image", "", bufferRSData)
- << tcu::TestLog::EndSection;
-
- return verifyResolvedImage(bufferRSData);
+ return new MSCase<CaseClassName>(testCtx, name, imageMSParams);
}
-class MSInstanceDistinctValues : public MSInterpolationInstanceBase
+template <typename InstanceClassName>
+class MSInstance : public MSInstanceBaseResolve
{
public:
- MSInstanceDistinctValues(Context& context,
- const ImageMSParams& imageMSParams)
- : MSInterpolationInstanceBase(context, imageMSParams) {}
+ MSInstance (Context& context,
+ const ImageMSParams& imageMSParams)
+ : MSInstanceBaseResolve(context, imageMSParams) {}
VertexDataDesc getVertexDataDescripton (void) const;
- void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
- tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
-
-protected:
- struct VertexData
- {
- VertexData(const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
-
- tcu::Vec4 positionNdc;
- };
+ void uploadVertexData (const Allocation& vertexBufferAllocation,
+ const VertexDataDesc& vertexDataDescripton) const;
+ tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageRSInfo,
+ const tcu::ConstPixelBufferAccess& dataRS) const;
};
-MSInterpolationInstanceBase::VertexDataDesc MSInstanceDistinctValues::getVertexDataDescripton (void) const
+class MSInstanceDistinctValues;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceDistinctValues>::getVertexDataDescripton (void) const
{
VertexDataDesc vertexDataDesc;
vertexDataDesc.verticesCount = 3u;
- vertexDataDesc.dataStride = sizeof(VertexData);
+ vertexDataDesc.dataStride = sizeof(VertexDataNdc);
vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
0u, // deUint32 location;
0u, // deUint32 binding;
VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
- DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
+ DE_OFFSET_OF(VertexDataNdc, positionNdc), // deUint32 offset;
};
vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
return vertexDataDesc;
}
-void MSInstanceDistinctValues::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+template<> void MSInstance<MSInstanceDistinctValues>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
{
- std::vector<VertexData> vertices;
+ std::vector<VertexDataNdc> vertices;
- vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f)));
- vertices.push_back(VertexData(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)));
- vertices.push_back(VertexData(tcu::Vec4( 4.0f,-1.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4( 4.0f, -1.0f, 0.0f, 1.0f)));
deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
}
-tcu::TestStatus MSInstanceDistinctValues::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+template<> tcu::TestStatus MSInstance<MSInstanceDistinctValues>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const
{
const deUint32 distinctValuesExpected = static_cast<deUint32>(m_imageMSParams.numSamples) + 1u;
std::vector<tcu::IVec4> distinctValues;
- for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
- for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
- for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
+ for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x)
{
- const tcu::IVec4 pixel = imageData.getPixelInt(x, y, z);
+ const tcu::IVec4 pixel = dataRS.getPixelInt(x, y, z);
if (std::find(distinctValues.begin(), distinctValues.end(), pixel) == distinctValues.end())
distinctValues.push_back(pixel);
if (distinctValues.size() >= distinctValuesExpected)
return tcu::TestStatus::pass("Passed");
else
- return tcu::TestStatus::fail("Failed");
+ return tcu::TestStatus::fail("Expected numSamples+1 different colors in the output image");
}
-class MSCaseSampleQualifierDistinctValues : public MSInterpolationCaseBase
-{
-public:
- MSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
+class MSCaseSampleQualifierDistinctValues;
-MSInterpolationCaseBase* createMSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseSampleQualifierDistinctValues(testCtx, name, imageMSParams);
-}
-
-void MSCaseSampleQualifierDistinctValues::init (void)
+template<> void MSCase<MSCaseSampleQualifierDistinctValues>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => Resulting image should contain n+1 different colors, where n = sample count.\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseSampleQualifierDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseSampleQualifierDistinctValues>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
fs << "#version 440\n"
<< "layout(location = 0) sample in vec4 fs_in_position_ndc;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " if(fs_in_position_ndc.y < -2.0*pow(0.5*(fs_in_position_ndc.x + 1.0), 2.0) + 1.0)\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseSampleQualifierDistinctValues::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseSampleQualifierDistinctValues>::createInstance (Context& context) const
{
- return new MSInstanceDistinctValues(context, m_imageMSParams);
+ return new MSInstance<MSInstanceDistinctValues>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtSampleDistinctValues : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtSampleDistinctValues(testCtx, name, imageMSParams);
-}
+class MSCaseInterpolateAtSampleDistinctValues;
-void MSCaseInterpolateAtSampleDistinctValues::init (void)
+template<> void MSCase<MSCaseInterpolateAtSampleDistinctValues>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => Resulting image should contain n+1 different colors, where n = sample count.\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtSampleDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtSampleDistinctValues>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
fs << "#version 440\n"
<< "layout(location = 0) in vec4 fs_in_position_ndc;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const vec4 position_ndc_at_sample = interpolateAtSample(fs_in_position_ndc, gl_SampleID);\n"
<< " if(position_ndc_at_sample.y < -2.0*pow(0.5*(position_ndc_at_sample.x + 1.0), 2.0) + 1.0)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtSampleDistinctValues::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtSampleDistinctValues>::createInstance (Context& context) const
{
- return new MSInstanceDistinctValues(context, m_imageMSParams);
+ return new MSInstance<MSInstanceDistinctValues>(context, m_imageMSParams);
}
-class MSInstanceInterpolateScreenPosition : public MSInterpolationInstanceBase
-{
-public:
- MSInstanceInterpolateScreenPosition (Context& context,
- const ImageMSParams& imageMSParams)
- : MSInterpolationInstanceBase(context, imageMSParams) {}
-
- VertexDataDesc getVertexDataDescripton (void) const;
- void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
- tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
-
-protected:
- struct VertexData
- {
- VertexData(const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
-
- tcu::Vec4 positionNdc;
- tcu::Vec2 positionScreen;
- };
-};
+class MSInstanceInterpolateScreenPosition;
-MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateScreenPosition::getVertexDataDescripton (void) const
+template<> MSInstanceBaseResolve::VertexDataDesc MSInstance<MSInstanceInterpolateScreenPosition>::getVertexDataDescripton (void) const
{
VertexDataDesc vertexDataDesc;
vertexDataDesc.verticesCount = 4u;
- vertexDataDesc.dataStride = sizeof(VertexData);
+ vertexDataDesc.dataStride = sizeof(VertexDataNdcScreen);
vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
const VkVertexInputAttributeDescription vertexAttribPositionNdc =
{
- 0u, // deUint32 location;
- 0u, // deUint32 binding;
- VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
- DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
+ 0u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdcScreen, positionNdc), // deUint32 offset;
};
vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
1u, // deUint32 location;
0u, // deUint32 binding;
VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
- DE_OFFSET_OF(VertexData, positionScreen), // deUint32 offset;
+ DE_OFFSET_OF(VertexDataNdcScreen, positionScreen), // deUint32 offset;
};
vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen);
return vertexDataDesc;
}
-void MSInstanceInterpolateScreenPosition::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+template<> void MSInstance<MSInstanceInterpolateScreenPosition>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
{
const tcu::UVec3 layerSize = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize);
const float screenSizeX = static_cast<float>(layerSize.x());
const float screenSizeY = static_cast<float>(layerSize.y());
- std::vector<VertexData> vertices;
+ std::vector<VertexDataNdcScreen> vertices;
- vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f)));
- vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f)));
- vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSizeY)));
- vertices.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSizeY)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY)));
deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
}
-tcu::TestStatus MSInstanceInterpolateScreenPosition::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+template<> tcu::TestStatus MSInstance<MSInstanceInterpolateScreenPosition>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const
{
- for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
- for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
- for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
- {
- const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
+ if (checkForError(imageRSInfo, dataRS, 0))
+ return tcu::TestStatus::fail("Failed");
- if (firstComponent > 0)
- return tcu::TestStatus::fail("Failed");
- }
return tcu::TestStatus::pass("Passed");
}
-class MSCaseInterpolateAtSampleSingleSample : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtSampleSingleSample (tcu::TestContext& testCtx,
- const std::string& name,
- tcu::UVec3 imageSize)
- : MSInterpolationCaseBase(testCtx, name, ImageMSParams(VK_SAMPLE_COUNT_1_BIT, imageSize)) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
+class MSCaseInterpolateAtSampleSingleSample;
-void MSCaseInterpolateAtSampleSingleSample::init (void)
+template<> void MSCase<MSCaseInterpolateAtSampleSingleSample>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => fract(screen space location) should be (about) (0.5, 0.5)\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtSampleSingleSample::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtSampleSingleSample>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
fs << "#version 440\n"
<< "layout(location = 0) in vec2 fs_in_position_screen;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const vec2 position_inside_pixel = fract(position_screen_at_sample);\n"
<< "\n"
<< " if (abs(position_inside_pixel.x - 0.5) <= threshold && abs(position_inside_pixel.y - 0.5) <= threshold)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtSampleSingleSample::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtSampleSingleSample>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtSampleIgnoresCentroid : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtSampleIgnoresCentroid(tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseInterpolateAtSampleIgnoresCentroid (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtSampleIgnoresCentroid(testCtx, name, imageMSParams);
-}
+class MSCaseInterpolateAtSampleIgnoresCentroid;
-void MSCaseInterpolateAtSampleIgnoresCentroid::init (void)
+template<> void MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => interpolateAtSample(screenSample, n) ~= interpolateAtSample(screenCentroid, n)\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtSampleIgnoresCentroid::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
<< "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
<< "layout(location = 1) in vec2 fs_in_pos_screen_fragment;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const bool valuesEqual = all(lessThan(abs(position_a - position_b), vec2(threshold)));\n"
<< "\n"
<< " if (valuesEqual)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtSampleIgnoresCentroid::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtSampleConsistency : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
+class MSCaseInterpolateAtSampleConsistency;
-MSInterpolationCaseBase* createMSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtSampleConsistency(testCtx, name, imageMSParams);
-}
-
-void MSCaseInterpolateAtSampleConsistency::init (void)
+template<> void MSCase<MSCaseInterpolateAtSampleConsistency>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => interpolateAtSample(screenCentroid, sampleID) = screenSample\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtSampleConsistency::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtSampleConsistency>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
<< "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
<< "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_sample - fs_in_pos_screen_sample), vec2(threshold)));\n"
<< "\n"
<< " if (valuesEqual)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtSampleConsistency::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtSampleConsistency>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtCentroidConsistency : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtCentroidConsistency(testCtx, name, imageMSParams);
-}
+class MSCaseInterpolateAtCentroidConsistency;
-void MSCaseInterpolateAtCentroidConsistency::init (void)
+template<> void MSCase<MSCaseInterpolateAtCentroidConsistency>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => interpolateAtCentroid(screenSample) = screenCentroid\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtCentroidConsistency::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtCentroidConsistency>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
<< "layout(location = 0) sample in vec2 fs_in_pos_screen_sample;\n"
<< "layout(location = 1) centroid in vec2 fs_in_pos_screen_centroid;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid), vec2(threshold)));\n"
<< "\n"
<< " if (valuesEqual)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtCentroidConsistency::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtCentroidConsistency>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtOffsetPixelCenter : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtOffsetPixelCenter(tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetPixelCenter (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtOffsetPixelCenter(testCtx, name, imageMSParams);
-}
+class MSCaseInterpolateAtOffsetPixelCenter;
-void MSCaseInterpolateAtOffsetPixelCenter::init (void)
+template<> void MSCase<MSCaseInterpolateAtOffsetPixelCenter>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => interpolateAtOffset(screen, offset) should be \"varying value at the pixel center\" + offset"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtOffsetPixelCenter::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtOffsetPixelCenter>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
<< "layout(location = 0) in vec2 fs_in_pos_screen;\n"
<< "layout(location = 1) in vec2 fs_in_offset;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " }\n"
<< "\n"
<< " if (valuesEqual)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtOffsetPixelCenter::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtOffsetPixelCenter>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSCaseInterpolateAtOffsetSamplePosition : public MSInterpolationCaseBase
-{
-public:
- MSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseInterpolateAtOffsetSamplePosition(testCtx, name, imageMSParams);
-}
+class MSCaseInterpolateAtOffsetSamplePosition;
-void MSCaseInterpolateAtOffsetSamplePosition::init (void)
+template<> void MSCase<MSCaseInterpolateAtOffsetSamplePosition>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => interpolateAtOffset(screenFragment, samplePosition - (0.5,0.5)) = screenSample"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseInterpolateAtOffsetSamplePosition::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseInterpolateAtOffsetSamplePosition>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
<< "layout(location = 0) in vec2 fs_in_pos_screen_fragment;\n"
<< "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - fs_in_pos_screen_sample), vec2(threshold)));\n"
<< "\n"
<< " if (valuesEqual)\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseInterpolateAtOffsetSamplePosition::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseInterpolateAtOffsetSamplePosition>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams);
}
-class MSInstanceInterpolateBarycentricCoordinates : public MSInterpolationInstanceBase
-{
-public:
- MSInstanceInterpolateBarycentricCoordinates (Context& context,
- const ImageMSParams& imageMSParams)
- : MSInterpolationInstanceBase(context, imageMSParams) {}
-
- VertexDataDesc getVertexDataDescripton (void) const;
- void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
- tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
-
-protected:
- struct VertexData
- {
- VertexData(const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {}
+class MSInstanceInterpolateBarycentricCoordinates;
- tcu::Vec4 positionNdc;
- tcu::Vec3 barycentricCoord;
- };
-};
-
-MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateBarycentricCoordinates::getVertexDataDescripton (void) const
+template<> MSInstanceBaseResolve::VertexDataDesc MSInstance<MSInstanceInterpolateBarycentricCoordinates>::getVertexDataDescripton (void) const
{
VertexDataDesc vertexDataDesc;
vertexDataDesc.verticesCount = 3u;
- vertexDataDesc.dataStride = sizeof(VertexData);
+ vertexDataDesc.dataStride = sizeof(VertexDataNdcBarycentric);
vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
const VkVertexInputAttributeDescription vertexAttribPositionNdc =
{
- 0u, // deUint32 location;
- 0u, // deUint32 binding;
- VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
- DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
+ 0u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdcBarycentric, positionNdc), // deUint32 offset;
};
vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
const VkVertexInputAttributeDescription vertexAttrBarCoord =
{
- 1u, // deUint32 location;
- 0u, // deUint32 binding;
- VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
- DE_OFFSET_OF(VertexData, barycentricCoord), // deUint32 offset;
+ 1u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdcBarycentric, barycentricCoord), // deUint32 offset;
};
vertexDataDesc.vertexAttribDescVec.push_back(vertexAttrBarCoord);
return vertexDataDesc;
}
-void MSInstanceInterpolateBarycentricCoordinates::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+template<> void MSInstance<MSInstanceInterpolateBarycentricCoordinates>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
{
// Create buffer storing vertex data
- std::vector<VertexData> vertices;
+ std::vector<VertexDataNdcBarycentric> vertices;
- vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f)));
- vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f)));
- vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f)));
+ vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f)));
+ vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f)));
deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
}
-tcu::TestStatus MSInstanceInterpolateBarycentricCoordinates::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+template<> tcu::TestStatus MSInstance<MSInstanceInterpolateBarycentricCoordinates>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const
{
- for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
- for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
- for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
- {
- const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
-
- if (firstComponent > 0)
- return tcu::TestStatus::fail("Failed");
- }
+ if (checkForError(imageRSInfo, dataRS, 0))
+ return tcu::TestStatus::fail("Failed");
return tcu::TestStatus::pass("Passed");
}
-class MSCaseCentroidQualifierInsidePrimitive : public MSInterpolationCaseBase
-{
-public:
- MSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx,
- const std::string& name,
- const ImageMSParams& imageMSParams)
- : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
-
- void init (void);
- void initPrograms (vk::SourceCollections& programCollection) const;
- TestInstance* createInstance (Context& context) const;
-};
-
-MSInterpolationCaseBase* createMSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
-{
- return new MSCaseCentroidQualifierInsidePrimitive(testCtx, name, imageMSParams);
-}
+class MSCaseCentroidQualifierInsidePrimitive;
-void MSCaseCentroidQualifierInsidePrimitive::init (void)
+template<> void MSCase<MSCaseCentroidQualifierInsidePrimitive>::init (void)
{
m_testCtx.getLog()
<< tcu::TestLog::Message
<< " => After interpolation we expect barycentric.xyz >= 0.0 && barycentric.xyz <= 1.0\n"
<< tcu::TestLog::EndMessage;
- MSInterpolationCaseBase::init();
+ MultisampleCaseBase::init();
}
-void MSCaseCentroidQualifierInsidePrimitive::initPrograms (vk::SourceCollections& programCollection) const
+template<> void MSCase<MSCaseCentroidQualifierInsidePrimitive>::initPrograms (vk::SourceCollections& programCollection) const
{
// Create vertex shader
std::ostringstream vs;
fs << "#version 440\n"
<< "layout(location = 0) centroid in vec3 fs_in_barCoord;\n"
<< "\n"
- << "layout(location = 0) out vec2 fs_out_color;\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
<< "\n"
<< "void main (void)\n"
<< "{\n"
<< " if( all(greaterThanEqual(fs_in_barCoord, vec3(0.0))) && all(lessThanEqual(fs_in_barCoord, vec3(1.0))) )\n"
- << " fs_out_color = vec2(0.0, 1.0);\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
<< " else\n"
- << " fs_out_color = vec2(1.0, 0.0);\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
<< "}\n";
programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
}
-TestInstance* MSCaseCentroidQualifierInsidePrimitive::createInstance (Context& context) const
+template<> TestInstance* MSCase<MSCaseCentroidQualifierInsidePrimitive>::createInstance (Context& context) const
{
- return new MSInstanceInterpolateBarycentricCoordinates(context, m_imageMSParams);
+ return new MSInstance<MSInstanceInterpolateBarycentricCoordinates>(context, m_imageMSParams);
}
} // multisample
-tcu::TestCaseGroup* makeGroup( multisample::MSInterpolationCaseFuncPtr createCaseFuncPtr,
- tcu::TestContext& testCtx,
- const std::string groupName,
- const tcu::UVec3 imageSizes[],
- const deUint32 imageSizesElemCount,
- const vk::VkSampleCountFlagBits imageSamples[],
- const deUint32 imageSamplesElemCount)
-{
- de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
-
- for (deUint32 imageSizeNdx = 0u; imageSizeNdx < imageSizesElemCount; ++imageSizeNdx)
- {
- const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
- std::ostringstream imageSizeStream;
-
- imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
-
- de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
-
- for (deUint32 imageSamplesNdx = 0u; imageSamplesNdx < imageSamplesElemCount; ++imageSamplesNdx)
- {
- const vk::VkSampleCountFlagBits samples = imageSamples[imageSamplesNdx];
- const multisample::ImageMSParams imageMSParams = multisample::ImageMSParams(samples, imageSize);
-
- sizeGroup->addChild(createCaseFuncPtr(testCtx, "samples_" + de::toString(samples), imageMSParams));
- }
-
- caseGroup->addChild(sizeGroup.release());
- }
- return caseGroup.release();
-}
-
tcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_interpolation", "Multisample Interpolation"));
de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
- sizeGroup->addChild(new multisample::MSCaseInterpolateAtSampleSingleSample(testCtx, "samples_" + de::toString(1), imageSize));
+ sizeGroup->addChild(multisample::MSCase<multisample::MSCaseInterpolateAtSampleSingleSample>::createCase(testCtx, "samples_" + de::toString(1), multisample::ImageMSParams(vk::VK_SAMPLE_COUNT_1_BIT, imageSize)));
caseGroup->addChild(sizeGroup.release());
}
testGroup->addChild(caseGroup.release());
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleDistinctValues, testCtx, "sample_interpolate_at_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleIgnoresCentroid, testCtx, "sample_interpolate_at_ignores_centroid", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleConsistency, testCtx, "sample_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseSampleQualifierDistinctValues, testCtx, "sample_qualifier_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtCentroidConsistency, testCtx, "centroid_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseCentroidQualifierInsidePrimitive, testCtx, "centroid_qualifier_inside_primitive", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetPixelCenter, testCtx, "offset_interpolate_at_pixel_center", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
- testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetSamplePosition, testCtx, "offset_interpolate_at_sample_position", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleDistinctValues> > (testCtx, "sample_interpolate_at_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleIgnoresCentroid> >(testCtx, "sample_interpolate_at_ignores_centroid", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "sample_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleQualifierDistinctValues> > (testCtx, "sample_qualifier_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "centroid_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseCentroidQualifierInsidePrimitive> > (testCtx, "centroid_qualifier_inside_primitive", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetPixelCenter> > (testCtx, "offset_interpolate_at_pixel_center", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "offset_interpolate_at_sample_position", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
return testGroup.release();
}
* Vulkan Conformance Tests
* ------------------------
*
- * Copyright (c) 2015 The Khronos Group Inc.
- * Copyright (c) 2015 Imagination Technologies Ltd.
+ * Copyright (c) 2016 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.
--- /dev/null
+/*------------------------------------------------------------------------
+* Vulkan Conformance Tests
+* ------------------------
+*
+* Copyright (c) 2016 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 vktPipelineMultisampleShaderBuiltInTests.cpp
+* \brief Multisample Shader BuiltIn Tests
+*//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleShaderBuiltInTests.hpp"
+#include "vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "tcuVectorUtil.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+using namespace vk;
+
+struct VertexDataNdc
+{
+ VertexDataNdc (const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
+
+ tcu::Vec4 positionNdc;
+};
+
+MultisampleInstanceBase::VertexDataDesc getVertexDataDescriptonNdc (void)
+{
+ MultisampleInstanceBase::VertexDataDesc vertexDataDesc;
+
+ vertexDataDesc.verticesCount = 4u;
+ vertexDataDesc.dataStride = sizeof(VertexDataNdc);
+ vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
+ vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+ {
+ 0u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdc, positionNdc), // deUint32 offset;
+ };
+
+ vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
+
+ return vertexDataDesc;
+}
+
+void uploadVertexDataNdc (const Allocation& vertexBufferAllocation, const MultisampleInstanceBase::VertexDataDesc& vertexDataDescripton)
+{
+ std::vector<VertexDataNdc> vertices;
+
+ vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f)));
+ vertices.push_back(VertexDataNdc(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f)));
+
+ deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
+}
+
+struct VertexDataNdcScreen
+{
+ VertexDataNdcScreen (const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
+
+ tcu::Vec4 positionNdc;
+ tcu::Vec2 positionScreen;
+};
+
+MultisampleInstanceBase::VertexDataDesc getVertexDataDescriptonNdcScreen (void)
+{
+ MultisampleInstanceBase::VertexDataDesc vertexDataDesc;
+
+ vertexDataDesc.verticesCount = 4u;
+ vertexDataDesc.dataStride = sizeof(VertexDataNdcScreen);
+ vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
+ vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+ {
+ 0u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdcScreen, positionNdc), // deUint32 offset;
+ };
+
+ vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
+
+ const VkVertexInputAttributeDescription vertexAttribPositionScreen =
+ {
+ 1u, // deUint32 location;
+ 0u, // deUint32 binding;
+ VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
+ DE_OFFSET_OF(VertexDataNdcScreen, positionScreen), // deUint32 offset;
+ };
+
+ vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen);
+
+ return vertexDataDesc;
+}
+
+void uploadVertexDataNdcScreen (const Allocation& vertexBufferAllocation, const MultisampleInstanceBase::VertexDataDesc& vertexDataDescripton, const tcu::Vec2& screenSize)
+{
+ std::vector<VertexDataNdcScreen> vertices;
+
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(screenSize.x(), 0.0f)));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSize.y())));
+ vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSize.x(), screenSize.y())));
+
+ deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
+}
+
+bool checkForErrorMS (const vk::VkImageCreateInfo& imageMSInfo, const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample, const deUint32 errorCompNdx)
+{
+ const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
+
+ for (deUint32 z = 0u; z < imageMSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageMSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageMSInfo.extent.width; ++x)
+ {
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const deUint32 errorComponent = dataPerSample[sampleNdx].getPixelUint(x, y, z)[errorCompNdx];
+
+ if (errorComponent > 0)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool checkForErrorRS (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS, const deUint32 errorCompNdx)
+{
+ for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x)
+ {
+ const deUint32 errorComponent = dataRS.getPixelUint(x, y, z)[errorCompNdx];
+
+ if (errorComponent > 0)
+ return true;
+ }
+
+ return false;
+}
+
+template <typename CaseClassName>
+class MSCase : public MSCaseBaseResolveAndPerSampleFetch
+{
+public:
+ MSCase (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams)
+ : MSCaseBaseResolveAndPerSampleFetch(testCtx, name, imageMSParams) {}
+
+ void init (void);
+ void initPrograms (vk::SourceCollections& programCollection) const;
+ TestInstance* createInstance (Context& context) const;
+ static MultisampleCaseBase* createCase (tcu::TestContext& testCtx,
+ const std::string& name,
+ const ImageMSParams& imageMSParams);
+};
+
+template <typename CaseClassName>
+MultisampleCaseBase* MSCase<CaseClassName>::createCase (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+ return new MSCase<CaseClassName>(testCtx, name, imageMSParams);
+}
+
+template <typename InstanceClassName>
+class MSInstance : public MSInstanceBaseResolveAndPerSampleFetch
+{
+public:
+ MSInstance (Context& context,
+ const ImageMSParams& imageMSParams)
+ : MSInstanceBaseResolveAndPerSampleFetch(context, imageMSParams) {}
+
+ VertexDataDesc getVertexDataDescripton (void) const;
+ void uploadVertexData (const Allocation& vertexBufferAllocation,
+ const VertexDataDesc& vertexDataDescripton) const;
+
+ tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const;
+};
+
+class MSInstanceSampleID;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSampleID>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+template<> void MSInstance<MSInstanceSampleID>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSampleID>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ DE_UNREF(imageRSInfo);
+ DE_UNREF(dataRS);
+
+ const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ for (deUint32 z = 0u; z < imageMSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageMSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageMSInfo.extent.width; ++x)
+ {
+ const deUint32 sampleID = dataPerSample[sampleNdx].getPixelUint(x, y, z).x();
+
+ if (sampleID != sampleNdx)
+ return tcu::TestStatus::fail("gl_SampleID does not have correct value");
+ }
+ }
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSampleID;
+
+template<> void MSCase<MSCaseSampleID>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Writing gl_SampleID to the red channel of the texture and verifying texture values.\n"
+ << "Expecting value N at sample index N of a multisample texture.\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSampleID>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " fs_out_color = vec4(float(gl_SampleID) / float(255), 0.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSampleID>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSampleID>(context, m_imageMSParams);
+}
+
+class MSInstanceSamplePosDistribution;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSamplePosDistribution>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+template<> void MSInstance<MSInstanceSamplePosDistribution>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSamplePosDistribution>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
+
+ // approximate Bates distribution as normal
+ const float variance = (1.0f / (12.0f * (float)numSamples));
+ const float standardDeviation = deFloatSqrt(variance);
+
+ // 95% of means of sample positions are within 2 standard deviations if
+ // they were randomly assigned. Sample patterns are expected to be more
+ // uniform than a random pattern.
+ const float distanceThreshold = 2.0f * standardDeviation;
+
+ for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x)
+ {
+ const deUint32 errorComponent = dataRS.getPixelUint(x, y, z).z();
+
+ if (errorComponent > 0)
+ return tcu::TestStatus::fail("gl_SamplePosition is not within interval [0,1]");
+
+ if (numSamples >= VK_SAMPLE_COUNT_4_BIT)
+ {
+ const tcu::Vec2 averageSamplePos = tcu::Vec2((float)dataRS.getPixelUint(x, y, z).x() / 255.0f, (float)dataRS.getPixelUint(x, y, z).y() / 255.0f);
+ const tcu::Vec2 distanceFromCenter = tcu::abs(averageSamplePos - tcu::Vec2(0.5f, 0.5f));
+
+ if (distanceFromCenter.x() > distanceThreshold || distanceFromCenter.y() > distanceThreshold)
+ return tcu::TestStatus::fail("Sample positions are not uniformly distributed within the pixel");
+ }
+ }
+
+ for (deUint32 z = 0u; z < imageMSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageMSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageMSInfo.extent.width; ++x)
+ {
+ std::vector<tcu::Vec2> samplePositions(numSamples);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const deUint32 errorComponent = dataPerSample[sampleNdx].getPixelUint(x, y, z).z();
+
+ if (errorComponent > 0)
+ return tcu::TestStatus::fail("gl_SamplePosition is not within interval [0,1]");
+
+ samplePositions[sampleNdx] = tcu::Vec2( (float)dataPerSample[sampleNdx].getPixelUint(x, y, z).x() / 255.0f,
+ (float)dataPerSample[sampleNdx].getPixelUint(x, y, z).y() / 255.0f);
+ }
+
+ for (deUint32 sampleNdxA = 0u; sampleNdxA < numSamples; ++sampleNdxA)
+ for (deUint32 sampleNdxB = sampleNdxA + 1u; sampleNdxB < numSamples; ++sampleNdxB)
+ {
+ if (samplePositions[sampleNdxA] == samplePositions[sampleNdxB])
+ return tcu::TestStatus::fail("Two samples have the same position");
+ }
+
+ if (numSamples >= VK_SAMPLE_COUNT_4_BIT)
+ {
+ tcu::Vec2 averageSamplePos(0.0f, 0.0f);
+
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ averageSamplePos.x() += samplePositions[sampleNdx].x();
+ averageSamplePos.y() += samplePositions[sampleNdx].y();
+ }
+
+ averageSamplePos.x() /= (float)numSamples;
+ averageSamplePos.y() /= (float)numSamples;
+
+ const tcu::Vec2 distanceFromCenter = tcu::abs(averageSamplePos - tcu::Vec2(0.5f, 0.5f));
+
+ if (distanceFromCenter.x() > distanceThreshold || distanceFromCenter.y() > distanceThreshold)
+ return tcu::TestStatus::fail("Sample positions are not uniformly distributed within the pixel");
+ }
+ }
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSamplePosDistribution;
+
+template<> void MSCase<MSCaseSamplePosDistribution>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Verifying gl_SamplePosition value with multisample targets:\n"
+ << " a) Expect legal sample position.\n"
+ << " b) Sample position is unique within the set of all sample positions of a pixel.\n"
+ << " c) Sample position distribution is uniform or almost uniform.\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSamplePosDistribution>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " if (gl_SamplePosition.x < 0.0 || gl_SamplePosition.x > 1.0 || gl_SamplePosition.y < 0.0 || gl_SamplePosition.y > 1.0)\n"
+ " fs_out_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
+ " else\n"
+ " fs_out_color = vec4(gl_SamplePosition.x, gl_SamplePosition.y, 0.0, 1.0);\n"
+ "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSamplePosDistribution>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSamplePosDistribution>(context, m_imageMSParams);
+}
+
+class MSInstanceSamplePosCorrectness;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSamplePosCorrectness>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdcScreen();
+}
+
+template<> void MSInstance<MSInstanceSamplePosCorrectness>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ const tcu::UVec3 layerSize = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize);
+
+ uploadVertexDataNdcScreen(vertexBufferAllocation, vertexDataDescripton, tcu::Vec2(static_cast<float>(layerSize.x()), static_cast<float>(layerSize.y())));
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSamplePosCorrectness>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ if (checkForErrorMS(imageMSInfo, dataPerSample, 0))
+ return tcu::TestStatus::fail("Varying values are not sampled at gl_SamplePosition");
+
+ if (checkForErrorRS(imageRSInfo, dataRS, 0))
+ return tcu::TestStatus::fail("Varying values are not sampled at gl_SamplePosition");
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSamplePosCorrectness;
+
+template<> void MSCase<MSCaseSamplePosCorrectness>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Verifying gl_SamplePosition correctness:\n"
+ << " 1) Varying values should be sampled at the sample position.\n"
+ << " => fract(position_screen) == gl_SamplePosition\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSamplePosCorrectness>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shaders
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+ << "\n"
+ << "layout(location = 0) sample out vec2 vs_out_position_screen;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << " vs_out_position_screen = vs_in_position_screen;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "layout(location = 0) sample in vec2 fs_in_position_screen;\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " const float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for other errors\n"
+ << " const ivec2 nearby_pixel = ivec2(floor(fs_in_position_screen));\n"
+ << " bool ok = false;\n"
+ << "\n"
+ << " // sample at edge + inaccuaries may cause us to round to any neighboring pixel\n"
+ << " // check all neighbors for any match\n"
+ << " for (int dy = -1; dy <= 1; ++dy)\n"
+ << " for (int dx = -1; dx <= 1; ++dx)\n"
+ << " {\n"
+ << " ivec2 current_pixel = nearby_pixel + ivec2(dx, dy);\n"
+ << " vec2 position_inside_pixel = vec2(current_pixel) + gl_SamplePosition;\n"
+ << " vec2 position_diff = abs(position_inside_pixel - fs_in_position_screen);\n"
+ << "\n"
+ << " if (all(lessThan(position_diff, vec2(threshold))))\n"
+ << " ok = true;\n"
+ << " }\n"
+ << "\n"
+ << " if (ok)\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ << " else\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSamplePosCorrectness>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSamplePosCorrectness>(context, m_imageMSParams);
+}
+
+class MSInstanceSampleMaskPattern : public MSInstanceBaseResolveAndPerSampleFetch
+{
+public:
+ MSInstanceSampleMaskPattern (Context& context,
+ const ImageMSParams& imageMSParams);
+
+ VkPipelineMultisampleStateCreateInfo getMSStateCreateInfo (const ImageMSParams& imageMSParams) const;
+
+ const VkDescriptorSetLayout* createMSPassDescSetLayout (const ImageMSParams& imageMSParams);
+
+ const VkDescriptorSet* createMSPassDescSet (const ImageMSParams& imageMSParams,
+ const VkDescriptorSetLayout* descSetLayout);
+
+ VertexDataDesc getVertexDataDescripton (void) const;
+
+ void uploadVertexData (const Allocation& vertexBufferAllocation,
+ const VertexDataDesc& vertexDataDescripton) const;
+
+ tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const;
+protected:
+
+ VkSampleMask m_sampleMask;
+ Move<VkDescriptorSetLayout> m_descriptorSetLayout;
+ Move<VkDescriptorPool> m_descriptorPool;
+ Move<VkDescriptorSet> m_descriptorSet;
+ de::MovePtr<Buffer> m_buffer;
+};
+
+MSInstanceSampleMaskPattern::MSInstanceSampleMaskPattern (Context& context, const ImageMSParams& imageMSParams) : MSInstanceBaseResolveAndPerSampleFetch(context, imageMSParams)
+{
+ m_sampleMask = 0xAAAAAAAAu & ((1u << imageMSParams.numSamples) - 1u);
+}
+
+VkPipelineMultisampleStateCreateInfo MSInstanceSampleMaskPattern::getMSStateCreateInfo (const ImageMSParams& imageMSParams) const
+{
+ const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
+ imageMSParams.numSamples, // VkSampleCountFlagBits rasterizationSamples;
+ VK_TRUE, // VkBool32 sampleShadingEnable;
+ 1.0f, // float minSampleShading;
+ &m_sampleMask, // const VkSampleMask* pSampleMask;
+ VK_FALSE, // VkBool32 alphaToCoverageEnable;
+ VK_FALSE, // VkBool32 alphaToOneEnable;
+ };
+
+ return multisampleStateInfo;
+}
+
+const VkDescriptorSetLayout* MSInstanceSampleMaskPattern::createMSPassDescSetLayout (const ImageMSParams& imageMSParams)
+{
+ DE_UNREF(imageMSParams);
+
+ const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+
+ // Create descriptor set layout
+ m_descriptorSetLayout = DescriptorSetLayoutBuilder()
+ .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
+ .build(deviceInterface, device);
+
+ return &m_descriptorSetLayout.get();
+}
+
+const VkDescriptorSet* MSInstanceSampleMaskPattern::createMSPassDescSet (const ImageMSParams& imageMSParams, const VkDescriptorSetLayout* descSetLayout)
+{
+ DE_UNREF(imageMSParams);
+
+ const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+ Allocator& allocator = m_context.getDefaultAllocator();
+
+ // Create descriptor pool
+ m_descriptorPool = DescriptorPoolBuilder()
+ .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)
+ .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+ // Create descriptor set
+ m_descriptorSet = makeDescriptorSet(deviceInterface, device, *m_descriptorPool, *descSetLayout);
+
+ const VkBufferCreateInfo bufferSampleMaskInfo = makeBufferCreateInfo(sizeof(VkSampleMask), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+
+ m_buffer = de::MovePtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferSampleMaskInfo, MemoryRequirement::HostVisible));
+
+ deMemcpy(m_buffer->getAllocation().getHostPtr(), &m_sampleMask, sizeof(VkSampleMask));
+
+ flushMappedMemoryRange(deviceInterface, device, m_buffer->getAllocation().getMemory(), m_buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
+
+ const VkDescriptorBufferInfo descBufferInfo = makeDescriptorBufferInfo(**m_buffer, 0u, sizeof(VkSampleMask));
+
+ DescriptorSetUpdateBuilder()
+ .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descBufferInfo)
+ .update(deviceInterface, device);
+
+ return &m_descriptorSet.get();
+}
+
+MultisampleInstanceBase::VertexDataDesc MSInstanceSampleMaskPattern::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+void MSInstanceSampleMaskPattern::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+tcu::TestStatus MSInstanceSampleMaskPattern::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ DE_UNREF(imageRSInfo);
+ DE_UNREF(dataRS);
+
+ if (checkForErrorMS(imageMSInfo, dataPerSample, 0))
+ return tcu::TestStatus::fail("gl_SampleMaskIn bits have not been killed by pSampleMask state");
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSampleMaskPattern;
+
+template<> void MSCase<MSCaseSampleMaskPattern>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Verifying gl_SampleMaskIn value with pSampleMask state. gl_SampleMaskIn does not contain any bits set that are have been killed by pSampleMask state. Expecting:\n"
+ << "Expected result: gl_SampleMaskIn AND ~(pSampleMask) should be zero.\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSampleMaskPattern>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "layout(set = 0, binding = 0, std140) uniform SampleMaskBlock\n"
+ << "{\n"
+ << " int sampleMaskPattern;\n"
+ << "};"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " if ((gl_SampleMaskIn[0] & ~sampleMaskPattern) != 0)\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ << " else\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSampleMaskPattern>::createInstance (Context& context) const
+{
+ return new MSInstanceSampleMaskPattern(context, m_imageMSParams);
+}
+
+class MSInstanceSampleMaskBitCount;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSampleMaskBitCount>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+template<> void MSInstance<MSInstanceSampleMaskBitCount>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSampleMaskBitCount>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ DE_UNREF(imageRSInfo);
+ DE_UNREF(dataRS);
+
+ if (checkForErrorMS(imageMSInfo, dataPerSample, 0))
+ return tcu::TestStatus::fail("gl_SampleMaskIn has more than one bit set for some shader invocations");
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSampleMaskBitCount;
+
+template<> void MSCase<MSCaseSampleMaskBitCount>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Verifying gl_SampleMaskIn.\n"
+ << " Fragment shader will be invoked numSamples times.\n"
+ << " => gl_SampleMaskIn should have only one bit set for each shader invocation.\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSampleMaskBitCount>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " uint maskBitCount = 0u;\n"
+ << "\n"
+ << " for (int i = 0; i < 32; ++i)\n"
+ << " if (((gl_SampleMaskIn[0] >> i) & 0x01) == 0x01)\n"
+ << " ++maskBitCount;\n"
+ << "\n"
+ << " if (maskBitCount != 1u)\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ << " else\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSampleMaskBitCount>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSampleMaskBitCount>(context, m_imageMSParams);
+}
+
+class MSInstanceSampleMaskCorrectBit;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSampleMaskCorrectBit>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+template<> void MSInstance<MSInstanceSampleMaskCorrectBit>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSampleMaskCorrectBit>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ DE_UNREF(imageRSInfo);
+ DE_UNREF(dataRS);
+
+ if (checkForErrorMS(imageMSInfo, dataPerSample, 0))
+ return tcu::TestStatus::fail("The bit corresponsing to current gl_SampleID is not set in gl_SampleMaskIn");
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSampleMaskCorrectBit;
+
+template<> void MSCase<MSCaseSampleMaskCorrectBit>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Verifying gl_SampleMaskIn.\n"
+ << " Fragment shader will be invoked numSamples times.\n"
+ << " => In each invocation gl_SampleMaskIn should have the bit set that corresponds to gl_SampleID.\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSampleMaskCorrectBit>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " if (((gl_SampleMaskIn[0] >> gl_SampleID) & 0x01) == 0x01)\n"
+ << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ << " else\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSampleMaskCorrectBit>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSampleMaskCorrectBit>(context, m_imageMSParams);
+}
+
+class MSInstanceSampleMaskWrite;
+
+template<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceSampleMaskWrite>::getVertexDataDescripton (void) const
+{
+ return getVertexDataDescriptonNdc();
+}
+
+template<> void MSInstance<MSInstanceSampleMaskWrite>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+ uploadVertexDataNdc(vertexBufferAllocation, vertexDataDescripton);
+}
+
+template<> tcu::TestStatus MSInstance<MSInstanceSampleMaskWrite>::verifyImageData (const vk::VkImageCreateInfo& imageMSInfo,
+ const vk::VkImageCreateInfo& imageRSInfo,
+ const std::vector<tcu::ConstPixelBufferAccess>& dataPerSample,
+ const tcu::ConstPixelBufferAccess& dataRS) const
+{
+ const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
+
+ for (deUint32 z = 0u; z < imageMSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageMSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageMSInfo.extent.width; ++x)
+ {
+ for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
+ {
+ const deUint32 firstComponent = dataPerSample[sampleNdx].getPixelUint(x, y, z)[0];
+
+ if (firstComponent != 0u && firstComponent != 255u)
+ return tcu::TestStatus::fail("Expected color to be zero or saturated on the first channel");
+ }
+ }
+
+ for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z)
+ for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y)
+ for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x)
+ {
+ const float firstComponent = dataRS.getPixel(x, y, z)[0];
+
+ if (deFloatAbs(firstComponent - 0.5f) > 0.02f)
+ return tcu::TestStatus::fail("Expected resolve color to be half intensity on the first channel");
+ }
+
+ return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseSampleMaskWrite;
+
+template<> void MSCase<MSCaseSampleMaskWrite>::init (void)
+{
+ m_testCtx.getLog()
+ << tcu::TestLog::Message
+ << "Discarding half of the samples using gl_SampleMask."
+ << "Expecting half intensity on multisample targets (numSamples > 1)\n"
+ << tcu::TestLog::EndMessage;
+
+ MultisampleCaseBase::init();
+}
+
+template<> void MSCase<MSCaseSampleMaskWrite>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ MSCaseBaseResolveAndPerSampleFetch::initPrograms(programCollection);
+
+ // Create vertex shader
+ std::ostringstream vs;
+
+ vs << "#version 440\n"
+ << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+ << "\n"
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_Position = vs_in_position_ndc;\n"
+ << "}\n";
+
+ programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+ // Create fragment shader
+ std::ostringstream fs;
+
+ fs << "#version 440\n"
+ << "\n"
+ << "layout(location = 0) out vec4 fs_out_color;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_SampleMask[0] = 0xAAAAAAAA;\n"
+ << "\n"
+ << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ << "}\n";
+
+ programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+template<> TestInstance* MSCase<MSCaseSampleMaskWrite>::createInstance (Context& context) const
+{
+ return new MSInstance<MSInstanceSampleMaskWrite>(context, m_imageMSParams);
+}
+
+} // multisample
+
+tcu::TestCaseGroup* createMultisampleShaderBuiltInTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_shader_builtin", "Multisample Shader BuiltIn Tests"));
+
+ const tcu::UVec3 imageSizes[] =
+ {
+ tcu::UVec3(128u, 128u, 1u),
+ tcu::UVec3(137u, 191u, 1u),
+ };
+
+ const deUint32 sizesElemCount = static_cast<deUint32>(sizeof(imageSizes) / sizeof(tcu::UVec3));
+
+ const vk::VkSampleCountFlagBits samplesSetFull[] =
+ {
+ vk::VK_SAMPLE_COUNT_2_BIT,
+ vk::VK_SAMPLE_COUNT_4_BIT,
+ vk::VK_SAMPLE_COUNT_8_BIT,
+ vk::VK_SAMPLE_COUNT_16_BIT,
+ vk::VK_SAMPLE_COUNT_32_BIT,
+ vk::VK_SAMPLE_COUNT_64_BIT,
+ };
+
+ const deUint32 samplesSetFullCount = static_cast<deUint32>(sizeof(samplesSetFull) / sizeof(vk::VkSampleCountFlagBits));
+
+ testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleID> >(testCtx, "sample_id", imageSizes, sizesElemCount, samplesSetFull, samplesSetFullCount));
+
+ de::MovePtr<tcu::TestCaseGroup> samplePositionGroup(new tcu::TestCaseGroup(testCtx, "sample_position", "Sample Position Tests"));
+
+ samplePositionGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSamplePosDistribution> >(testCtx, "distribution", imageSizes, sizesElemCount, samplesSetFull, samplesSetFullCount));
+ samplePositionGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSamplePosCorrectness> > (testCtx, "correctness", imageSizes, sizesElemCount, samplesSetFull, samplesSetFullCount));
+
+ testGroup->addChild(samplePositionGroup.release());
+
+ const vk::VkSampleCountFlagBits samplesSetReduced[] =
+ {
+ vk::VK_SAMPLE_COUNT_2_BIT,
+ vk::VK_SAMPLE_COUNT_4_BIT,
+ vk::VK_SAMPLE_COUNT_8_BIT,
+ vk::VK_SAMPLE_COUNT_16_BIT,
+ vk::VK_SAMPLE_COUNT_32_BIT,
+ };
+
+ const deUint32 samplesSetReducedCount = static_cast<deUint32>(sizeof(samplesSetReduced) / sizeof(vk::VkSampleCountFlagBits));
+
+ de::MovePtr<tcu::TestCaseGroup> sampleMaskGroup(new tcu::TestCaseGroup(testCtx, "sample_mask", "Sample Mask Tests"));
+
+ sampleMaskGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleMaskPattern> > (testCtx, "pattern", imageSizes, sizesElemCount, samplesSetReduced, samplesSetReducedCount));
+ sampleMaskGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleMaskBitCount> > (testCtx, "bit_count", imageSizes, sizesElemCount, samplesSetReduced, samplesSetReducedCount));
+ sampleMaskGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleMaskCorrectBit> >(testCtx, "correct_bit",imageSizes, sizesElemCount, samplesSetReduced, samplesSetReducedCount));
+ sampleMaskGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleMaskWrite> > (testCtx, "write", imageSizes, sizesElemCount, samplesSetReduced, samplesSetReducedCount));
+
+ testGroup->addChild(sampleMaskGroup.release());
+
+ return testGroup.release();
+}
+
+} // pipeline
+} // vkt
--- /dev/null
+#ifndef _VKTPIPELINEMULTISAMPLESHADERBUILTINTESTS_HPP
+#define _VKTPIPELINEMULTISAMPLESHADERBUILTINTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 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 vktPipelineMultisampleShaderBuiltInTests.hpp
+ * \brief Multisample Shader BuiltIn Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+tcu::TestCaseGroup* createMultisampleShaderBuiltInTests (tcu::TestContext& testCtx);
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLESHADERBUILTINTESTS_HPP
return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
}
-deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel)
+deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 numSamples)
{
const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
- return extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format);
+ return extents.width * extents.height * extents.depth * layersCount * numSamples * tcu::getPixelSize(format);
}
-deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount)
+deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 numSamples)
{
deUint32 imageSizeInBytes = 0;
for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
{
- imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel);
+ imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, numSamples);
}
return imageSizeInBytes;
deUint32 getLayerDimensions (const ImageType imageType);
vk::VkExtent3D mipLevelExtents (const vk::VkExtent3D& baseExtents, const deUint32 mipLevel);
tcu::UVec3 mipLevelExtents (const tcu::UVec3& baseExtents, const deUint32 mipLevel);
-deUint32 getImageMipLevelSizeInBytes (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel);
-deUint32 getImageSizeInBytes (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount = 1u);
+deUint32 getImageMipLevelSizeInBytes (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 numSamples = 1u);
+deUint32 getImageSizeInBytes (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount = 1u, const deUint32 numSamples = 1u);
deUint32 getImageMaxMipLevels (const vk::VkImageFormatProperties& imageFormatProperties, const vk::VkExtent3D& extent);
enum FeatureFlagBits
#include "vktPipelineSpecConstantTests.hpp"
#include "vktPipelineMultisampleTests.hpp"
#include "vktPipelineMultisampleInterpolationTests.hpp"
+#include "vktPipelineMultisampleShaderBuiltInTests.hpp"
#include "vktPipelineVertexInputTests.hpp"
#include "vktPipelineTimestampTests.hpp"
#include "vktPipelineCacheTests.hpp"
pipelineTests->addChild(createSpecConstantTests (testCtx));
pipelineTests->addChild(createMultisampleTests (testCtx));
pipelineTests->addChild(createMultisampleInterpolationTests (testCtx));
+ pipelineTests->addChild(createMultisampleShaderBuiltInTests (testCtx));
pipelineTests->addChild(createVertexInputTests (testCtx));
pipelineTests->addChild(createInputAssemblyTests (testCtx));
pipelineTests->addChild(createTimestampTests (testCtx));
dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_16
dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_32
dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_id.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.distribution.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_position.correctness.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_count.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.correct_bit.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.write.137_191_1.samples_32
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_vertex
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_instance
dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_snorm_rate_vertex