From: Maciej Jesionowski Date: Wed, 20 Jul 2016 10:51:49 +0000 (+0200) Subject: Add multisampled image texel fetch test X-Git-Tag: upstream/0.1.0~731^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c344d62e50c91fe847b4904682978e492eaf1fc4;p=platform%2Fupstream%2FVK-GL-CTS.git Add multisampled image texel fetch test New test: - dEQP-VK.pipeline.multisample.sampled_image.* Fixes #428 Change-Id: I947053c5fc48f7d479fab80a6fc31823da3e5c1a --- diff --git a/android/cts/master/com.drawelements.deqp.vk.xml b/android/cts/master/com.drawelements.deqp.vk.xml index 3f8308f..4782495 100644 --- a/android/cts/master/com.drawelements.deqp.vk.xml +++ b/android/cts/master/com.drawelements.deqp.vk.xml @@ -229092,6 +229092,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index c2426b0..783cd21 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -71409,6 +71409,102 @@ dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_32.alpha_invisible dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_opaque dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_translucent dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_invisible +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_64 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.128_128_1.samples_1 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.137_191_1.samples_1 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_2 diff --git a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt index e9e7307..5cd9f48 100644 --- a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt @@ -31,6 +31,8 @@ set(DEQP_VK_PIPELINE_SRCS vktPipelineMultisampleTests.hpp vktPipelineMultisampleInterpolationTests.cpp vktPipelineMultisampleInterpolationTests.hpp + vktPipelineMultisampleImageTests.cpp + vktPipelineMultisampleImageTests.hpp vktPipelineInputAssemblyTests.cpp vktPipelineInputAssemblyTests.hpp vktPipelineReferenceRenderer.cpp diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.cpp new file mode 100644 index 0000000..5101421 --- /dev/null +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.cpp @@ -0,0 +1,1091 @@ +/*------------------------------------------------------------------------ + * 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 + * \brief Multisample image Tests + *//*--------------------------------------------------------------------*/ + +#include "vktPipelineMultisampleImageTests.hpp" +#include "vktPipelineMakeUtil.hpp" +#include "vktTestCase.hpp" +#include "vktTestCaseUtil.hpp" +#include "vktPipelineVertexUtil.hpp" +#include "vktTestGroupUtil.hpp" + +#include "vkMemUtil.hpp" +#include "vkQueryUtil.hpp" +#include "vkTypeUtil.hpp" +#include "vkRefUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkPrograms.hpp" +#include "vkImageUtil.hpp" + +#include "tcuTextureUtil.hpp" + +#include "deUniquePtr.hpp" +#include "deSharedPtr.hpp" + +#include + +namespace vkt +{ +namespace pipeline +{ +namespace +{ +using namespace vk; +using de::UniquePtr; +using de::MovePtr; +using de::SharedPtr; +using tcu::IVec2; +using tcu::Vec4; + +typedef SharedPtr > SharedPtrVkImageView; + +//! Test case parameters +struct CaseDef +{ + IVec2 renderSize; + int numLayers; + VkFormat colorFormat; + VkSampleCountFlagBits numSamples; +}; + +template +inline SharedPtr > makeSharedPtr (Move move) +{ + return SharedPtr >(new Unique(move)); +} + +template +inline VkDeviceSize sizeInBytes(const std::vector& vec) +{ + return vec.size() * sizeof(vec[0]); +} + +Move makeGraphicsPipeline (const DeviceInterface& vk, + const VkDevice device, + const VkPipelineLayout pipelineLayout, + const VkRenderPass renderPass, + const VkShaderModule vertexModule, + const VkShaderModule fragmentModule, + const IVec2 renderSize, + const VkSampleCountFlagBits numSamples, + const VkPrimitiveTopology topology) +{ + const VkVertexInputBindingDescription vertexInputBindingDescription = + { + 0u, // uint32_t binding; + sizeof(Vertex4RGBA), // uint32_t stride; + VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; + }; + + const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = + { + { + 0u, // uint32_t location; + 0u, // uint32_t binding; + VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; + 0u, // uint32_t offset; + }, + { + 1u, // uint32_t location; + 0u, // uint32_t binding; + VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; + sizeof(Vec4), // uint32_t offset; + }, + }; + + const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; + 1u, // uint32_t vertexBindingDescriptionCount; + &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; + DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // uint32_t vertexAttributeDescriptionCount; + vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; + }; + + const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; + topology, // VkPrimitiveTopology topology; + VK_FALSE, // VkBool32 primitiveRestartEnable; + }; + + const VkViewport viewport = makeViewport( + 0.0f, 0.0f, + static_cast(renderSize.x()), static_cast(renderSize.y()), + 0.0f, 1.0f); + + const VkRect2D scissor = { + makeOffset2D(0, 0), + makeExtent2D(renderSize.x(), renderSize.y()), + }; + + const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; + 1u, // uint32_t viewportCount; + &viewport, // const VkViewport* pViewports; + 1u, // uint32_t scissorCount; + &scissor, // const VkRect2D* pScissors; + }; + + const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineRasterizationStateCreateFlags)0, // 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 pipelineMultisampleStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; + numSamples, // VkSampleCountFlagBits rasterizationSamples; + VK_FALSE, // VkBool32 sampleShadingEnable; + 0.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 + + VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineDepthStencilStateCreateFlags)0, // 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; + // Number of blend attachments must equal the number of color attachments during any subpass. + const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = + { + 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 pipelineColorBlendStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; + VK_FALSE, // VkBool32 logicOpEnable; + VK_LOGIC_OP_COPY, // VkLogicOp logicOp; + 1u, // deUint32 attachmentCount; + &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; + { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; + }; + + const VkPipelineShaderStageCreateInfo pShaderStages[] = + { + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; + VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; + vertexModule, // VkShaderModule module; + "main", // const char* pName; + DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; + }, + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; + VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; + fragmentModule, // VkShaderModule module; + "main", // const char* pName; + DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; + } + }; + + const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = + { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; + DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount; + pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages; + &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; + &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; + &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; + pipelineLayout, // VkPipelineLayout layout; + renderPass, // VkRenderPass renderPass; + 0u, // deUint32 subpass; + DE_NULL, // VkPipeline basePipelineHandle; + 0, // deInt32 basePipelineIndex; + }; + + return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); +} + +//! Make a render pass with one subpass per color attachment and one attachment per image layer. +Move makeMultisampleRenderPass (const DeviceInterface& vk, + const VkDevice device, + const VkFormat colorFormat, + const VkSampleCountFlagBits numSamples, + const deUint32 numLayers) +{ + const VkAttachmentDescription colorAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + numSamples, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; + }; + const std::vector attachmentDescriptions(numLayers, colorAttachmentDescription); + + // Create a subpass for each attachment (each attachement is a layer of an arrayed image). + + std::vector colorAttachmentReferences(numLayers); + std::vector subpasses; + + for (deUint32 i = 0; i < numLayers; ++i) + { + const VkAttachmentReference attachmentRef = + { + i, // deUint32 attachment; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; + }; + colorAttachmentReferences[i] = attachmentRef; + + const VkSubpassDescription subpassDescription = + { + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference* pInputAttachments; + 1u, // deUint32 colorAttachmentCount; + &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments; + DE_NULL, // const VkAttachmentReference* pResolveAttachments; + DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; + 0u, // deUint32 preserveAttachmentCount; + DE_NULL // const deUint32* pPreserveAttachments; + }; + subpasses.push_back(subpassDescription); + } + + const VkRenderPassCreateInfo renderPassInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; + static_cast(attachmentDescriptions.size()), // deUint32 attachmentCount; + &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; + static_cast(subpasses.size()), // deUint32 subpassCount; + &subpasses[0], // const VkSubpassDescription* pSubpasses; + 0u, // deUint32 dependencyCount; + DE_NULL // const VkSubpassDependency* pDependencies; + }; + + return createRenderPass(vk, device, &renderPassInfo); +} + +//! A single-attachment, single-subpass render pass. +Move makeSimpleRenderPass (const DeviceInterface& vk, + const VkDevice device, + const VkFormat colorFormat) +{ + const VkAttachmentDescription colorAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; + }; + + const VkAttachmentReference colorAttachmentRef = + { + 0u, // deUint32 attachment; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; + }; + + const VkSubpassDescription subpassDescription = + { + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference* pInputAttachments; + 1u, // deUint32 colorAttachmentCount; + &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments; + DE_NULL, // 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)0, // VkRenderPassCreateFlags flags; + 1u, // deUint32 attachmentCount; + &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; + 1u, // deUint32 subpassCount; + &subpassDescription, // const VkSubpassDescription* pSubpasses; + 0u, // deUint32 dependencyCount; + DE_NULL // const VkSubpassDependency* pDependencies; + }; + + return createRenderPass(vk, device, &renderPassInfo); +} + +Move makeImage (const DeviceInterface& vk, const VkDevice device, const VkFormat format, const IVec2& size, const deUint32 numLayers, const VkSampleCountFlagBits samples, const VkImageUsageFlags usage) +{ + const VkImageCreateInfo imageParams = + { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0, // VkImageCreateFlags flags; + VK_IMAGE_TYPE_2D, // VkImageType imageType; + format, // VkFormat format; + makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; + 1u, // deUint32 mipLevels; + numLayers, // deUint32 arrayLayers; + samples, // VkSampleCountFlagBits samples; + VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; + usage, // VkImageUsageFlags usage; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 0u, // deUint32 queueFamilyIndexCount; + DE_NULL, // const deUint32* pQueueFamilyIndices; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + }; + return createImage(vk, device, &imageParams); +} + +//! Make a simplest sampler. +Move makeSampler (const DeviceInterface& vk, const VkDevice device) +{ + const VkSamplerCreateInfo samplerParams = + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags; + VK_FILTER_NEAREST, // VkFilter magFilter; + VK_FILTER_NEAREST, // VkFilter minFilter; + VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; + 0.0f, // float mipLodBias; + VK_FALSE, // VkBool32 anisotropyEnable; + 1.0f, // float maxAnisotropy; + VK_FALSE, // VkBool32 compareEnable; + VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; + 0.0f, // float minLod; + 0.0f, // float maxLod; + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor; + VK_FALSE, // VkBool32 unnormalizedCoordinates; + }; + return createSampler(vk, device, &samplerParams); +} + +inline Move makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage) +{ + const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage); + return createBuffer(vk, device, &bufferCreateInfo); +} + +inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount) +{ + return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast(baseArrayLayer), static_cast(layerCount)); +} + +void checkImageFormatRequirements (const InstanceInterface& vki, + const VkPhysicalDevice physDevice, + const VkSampleCountFlagBits sampleCount, + const VkFormat format, + const VkImageUsageFlags usage) +{ + VkImageFormatProperties imageFormatProperties; + const VkResult imageFormatResult = vki.getPhysicalDeviceImageFormatProperties( + physDevice, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, (VkImageCreateFlags)0, &imageFormatProperties); + + if (imageFormatResult == VK_ERROR_FORMAT_NOT_SUPPORTED) + TCU_THROW(NotSupportedError, "Image format is not supported"); + + if ((imageFormatProperties.sampleCounts & sampleCount) != sampleCount) + TCU_THROW(NotSupportedError, "Requested sample count is not supported"); +} + +//! The default foreground color. +inline Vec4 getPrimitiveColor (void) +{ + return Vec4(1.0f, 0.0f, 0.0f, 1.0f); +} + +//! Get a reference clear value based on color format. +VkClearValue getClearValue (const VkFormat format) +{ + if (isUintFormat(format) || isIntFormat(format)) + return makeClearValueColorU32(16, 32, 64, 96); + else + return makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f); +} + +std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint) +{ + std::ostringstream str; + if (numComponents == 1) + str << (isUint ? "uint" : isSint ? "int" : "float"); + else + str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents; + + return str.str(); +} + +std::string getSamplerTypeStr (const int numLayers, const bool isUint, const bool isSint) +{ + std::ostringstream str; + str << (isUint ? "u" : isSint ? "i" : "") << "sampler2DMS" << (numLayers > 1 ? "Array" : ""); + return str.str(); +} + +//! Generate a gvec4 color literal. +template +std::string getColorStr (const T* data, int numComponents, const bool isUint, const bool isSint) +{ + const int maxIndex = 3; // 4 components max + + std::ostringstream str; + str << (isUint ? "u" : isSint ? "i" : "") << "vec4("; + + for (int i = 0; i < numComponents; ++i) + { + str << data[i] + << (i < maxIndex ? ", " : ""); + } + + for (int i = numComponents; i < maxIndex + 1; ++i) + { + str << (i == maxIndex ? 1 : 0) + << (i < maxIndex ? ", " : ""); + } + + str << ")"; + return str.str(); +} + +//! Clear color literal value used by the sampling shader. +std::string getReferenceClearColorStr (const VkFormat format, const int numComponents, const bool isUint, const bool isSint) +{ + const VkClearColorValue clearColor = getClearValue(format).color; + if (isUint) + return getColorStr(clearColor.uint32, numComponents, isUint, isSint); + else if (isSint) + return getColorStr(clearColor.int32, numComponents, isUint, isSint); + else + return getColorStr(clearColor.float32, numComponents, isUint, isSint); +} + +//! Primitive color literal value used by the sampling shader. +std::string getReferencePrimitiveColorStr (int numComponents, const bool isUint, const bool isSint) +{ + const Vec4 color = getPrimitiveColor(); + return getColorStr(color.getPtr(), numComponents, isUint, isSint); +} + +inline int getNumSamples (const VkSampleCountFlagBits samples) +{ + return static_cast(samples); // enum bitmask actually matches the number of samples +} + +void initPrograms (SourceCollections& programCollection, const CaseDef caseDef) +{ + const int numComponents = tcu::getNumUsedChannels(mapVkFormat(caseDef.colorFormat).order); + const bool isUint = isUintFormat(caseDef.colorFormat); + const bool isSint = isIntFormat(caseDef.colorFormat); + + // Pass 1: Render to texture + + // Vertex shader + { + std::ostringstream src; + src << "#version 450\n" + << "\n" + << "layout(location = 0) in vec4 in_position;\n" + << "layout(location = 1) in vec4 in_color;\n" + << "layout(location = 0) out vec4 o_color;\n" + << "\n" + << "out gl_PerVertex {\n" + << " vec4 gl_Position;\n" + << "};\n" + << "\n" + << "void main(void)\n" + << "{\n" + << " gl_Position = in_position;\n" + << " o_color = in_color;\n" + << "}\n"; + + programCollection.glslSources.add("render_vert") << glu::VertexSource(src.str()); + } + + // Fragment shader + { + const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint); + + std::ostringstream src; + src << "#version 450\n" + << "\n" + << "layout(location = 0) in vec4 in_color;\n" + << "layout(location = 0) out " << colorFormat << " o_color;\n" + << "\n" + << "void main(void)\n" + << "{\n" + << " o_color = " << colorFormat << "(" // float color will be converted to int/uint here if needed + << (numComponents == 1 ? "in_color.r" : + numComponents == 2 ? "in_color.rg" : + numComponents == 3 ? "in_color.rgb" : "in_color") << ");\n" + << "}\n"; + + programCollection.glslSources.add("render_frag") << glu::FragmentSource(src.str()); + } + + // Pass 2: Sample texture + + // Vertex shader + { + std::ostringstream src; + src << "#version 450\n" + << "\n" + << "layout(location = 0) in vec4 in_position;\n" + << "\n" + << "out gl_PerVertex {\n" + << " vec4 gl_Position;\n" + << "};\n" + << "\n" + << "void main(void)\n" + << "{\n" + << " gl_Position = in_position;\n" + << "}\n"; + + programCollection.glslSources.add("sample_vert") << glu::VertexSource(src.str()); + } + + // Fragment shader + { + const std::string texelFormatStr = (isUint ? "uvec4" : isSint ? "ivec4" : "vec4"); + const std::string refClearColor = getReferenceClearColorStr(caseDef.colorFormat, numComponents, isUint, isSint); + const std::string refPrimitiveColor = getReferencePrimitiveColorStr(numComponents, isUint, isSint); + const std::string samplerTypeStr = getSamplerTypeStr(caseDef.numLayers, isUint, isSint); + + std::ostringstream src; + src << "#version 450\n" + << "\n" + << "layout(location = 0) out int o_status;\n" + << "\n" + << "layout(set = 0, binding = 0) uniform " << samplerTypeStr << " colorTexture;\n" + << "\n" + << "void main(void)\n" + << "{\n" + << " int checksum = 0;\n" + << "\n"; + + if (caseDef.numLayers == 1) + src << " for (int sampleNdx = 0; sampleNdx < " << caseDef.numSamples << "; ++sampleNdx) {\n" + << " " << texelFormatStr << " color = texelFetch(colorTexture, ivec2(gl_FragCoord.xy), sampleNdx);\n" + << " if (color == " << refClearColor << " || color == " << refPrimitiveColor << ")\n" + << " ++checksum;\n" + << " }\n"; + else + src << " for (int layerNdx = 0; layerNdx < " << caseDef.numLayers << "; ++layerNdx)\n" + << " for (int sampleNdx = 0; sampleNdx < " << caseDef.numSamples << "; ++sampleNdx) {\n" + << " " << texelFormatStr << " color = texelFetch(colorTexture, ivec3(gl_FragCoord.xy, layerNdx), sampleNdx);\n" + << " if (color == " << refClearColor << " || color == " << refPrimitiveColor << ")\n" + << " ++checksum;\n" + << " }\n"; + + src << "\n" + << " o_status = checksum;\n" + << "}\n"; + + programCollection.glslSources.add("sample_frag") << glu::FragmentSource(src.str()); + } +} + +//! A flat-colored shape with sharp angles to make antialiasing visible. +std::vector genTriangleVertices (void) +{ + static const Vertex4RGBA data[] = + { + { + Vec4(-1.0f, 0.0f, 0.0f, 1.0f), + getPrimitiveColor(), + }, + { + Vec4(0.8f, 0.2f, 0.0f, 1.0f), + getPrimitiveColor(), + }, + { + Vec4(0.8f, -0.2f, 0.0f, 1.0f), + getPrimitiveColor(), + }, + }; + return std::vector(data, data + DE_LENGTH_OF_ARRAY(data)); +} + +//! A full-viewport quad. Use with TRIANGLE_STRIP topology. +std::vector genFullQuadVertices (void) +{ + static const Vertex4RGBA data[] = + { + { + Vec4(-1.0f, -1.0f, 0.0f, 1.0f), + Vec4(), // unused + }, + { + Vec4(-1.0f, 1.0f, 0.0f, 1.0f), + Vec4(), // unused + }, + { + Vec4(1.0f, -1.0f, 0.0f, 1.0f), + Vec4(), // unused + }, + { + Vec4(1.0f, 1.0f, 0.0f, 1.0f), + Vec4(), // unused + }, + }; + return std::vector(data, data + DE_LENGTH_OF_ARRAY(data)); +} + +tcu::TestStatus test (Context& context, const CaseDef caseDef) +{ + const DeviceInterface& vk = context.getDeviceInterface(); + const InstanceInterface& vki = context.getInstanceInterface(); + const VkDevice device = context.getDevice(); + const VkPhysicalDevice physDevice = context.getPhysicalDevice(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + Allocator& allocator = context.getDefaultAllocator(); + + const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + checkImageFormatRequirements(vki, physDevice, caseDef.numSamples, caseDef.colorFormat, colorImageUsage); + + { + tcu::TestLog& log = context.getTestContext().getLog(); + log << tcu::LogSection("Description", "") + << tcu::TestLog::Message << "Rendering to a multisampled image. Expecting all samples to be either a clear color or a primitive color." << tcu::TestLog::EndMessage + << tcu::TestLog::Message << "Sampling from the texture with texelFetch (OpImageFetch)." << tcu::TestLog::EndMessage + << tcu::TestLog::EndSection; + } + + // Multisampled color image + const Unique colorImage (makeImage(vk, device, caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, caseDef.numSamples, colorImageUsage)); + const UniquePtr colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any)); + + const Unique cmdPool (makeCommandPool (vk, device, queueFamilyIndex)); + const Unique cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); + + const VkRect2D renderArea = { + makeOffset2D(0, 0), + makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()), + }; + + // Step 1: Render to texture + { + // Create an image view (attachment) for each layer of the image + std::vector colorAttachments; + std::vector attachmentHandles; + for (int i = 0; i < caseDef.numLayers; ++i) + { + colorAttachments.push_back(makeSharedPtr(makeImageView( + vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, caseDef.colorFormat, makeColorSubresourceRange(i, 1)))); + attachmentHandles.push_back(**colorAttachments.back()); + } + + // Vertex buffer + const std::vector vertices = genTriangleVertices(); + const VkDeviceSize vertexBufferSize = sizeInBytes(vertices); + const Unique vertexBuffer (makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); + const UniquePtr vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + + { + deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast(vertexBufferSize)); + flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize); + } + + const Unique vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("render_vert"), 0u)); + const Unique fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("render_frag"), 0u)); + const Unique renderPass (makeMultisampleRenderPass (vk, device, caseDef.colorFormat, caseDef.numSamples, caseDef.numLayers)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, caseDef.numLayers, &attachmentHandles[0], + static_cast(caseDef.renderSize.x()), static_cast(caseDef.renderSize.y()))); + const Unique pipelineLayout (makePipelineLayout (vk, device)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, + caseDef.renderSize, caseDef.numSamples, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)); + + beginCommandBuffer(vk, *cmdBuffer); + + const std::vector clearValues(caseDef.numLayers, getClearValue(caseDef.colorFormat)); + + 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(clearValues.size()), // uint32_t clearValueCount; + &clearValues[0], // const VkClearValue* pClearValues; + }; + vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + { + const VkDeviceSize vertexBufferOffset = 0ull; + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); + } + + for (int layerNdx = 0; layerNdx < caseDef.numLayers; ++layerNdx) + { + if (layerNdx != 0) + vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); + + vk.cmdDraw(*cmdBuffer, static_cast(vertices.size()), 1u, 0u, 0u); + } + + vk.cmdEndRenderPass(*cmdBuffer); + + VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + } + + // Step 2: Sample texture + { + // Color image view + const VkImageViewType colorImageViewType = (caseDef.numLayers == 1 ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY); + const Unique colorImageView (makeImageView(vk, device, *colorImage, colorImageViewType, caseDef.colorFormat, makeColorSubresourceRange(0, caseDef.numLayers))); + const Unique colorSampler (makeSampler(vk, device)); + + // Checksum image + const VkFormat checksumFormat = VK_FORMAT_R32_SINT; + const Unique checksumImage (makeImage(vk, device, checksumFormat, caseDef.renderSize, 1u, VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)); + const UniquePtr checksumImageAlloc (bindImage(vk, device, allocator, *checksumImage, MemoryRequirement::Any)); + const Unique checksumImageView (makeImageView(vk, device, *checksumImage, VK_IMAGE_VIEW_TYPE_2D, checksumFormat, makeColorSubresourceRange(0, 1))); + + // Checksum buffer (for host reading) + const VkDeviceSize checksumBufferSize = caseDef.renderSize.x() * caseDef.renderSize.y() * tcu::getPixelSize(mapVkFormat(checksumFormat)); + const Unique checksumBuffer (makeBuffer(vk, device, checksumBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); + const UniquePtr checksumBufferAlloc (bindBuffer(vk, device, allocator, *checksumBuffer, MemoryRequirement::HostVisible)); + + { + deMemset(checksumBufferAlloc->getHostPtr(), 0, static_cast(checksumBufferSize)); + flushMappedMemoryRange(vk, device, checksumBufferAlloc->getMemory(), checksumBufferAlloc->getOffset(), checksumBufferSize); + } + + // Vertex buffer + const std::vector vertices = genFullQuadVertices(); + const VkDeviceSize vertexBufferSize = sizeInBytes(vertices); + const Unique vertexBuffer (makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); + const UniquePtr vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + + { + deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast(vertexBufferSize)); + flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize); + } + + // Descriptors + // \note OpImageFetch doesn't use a sampler, but in GLSL texelFetch needs a sampler2D which translates to a combined image sampler in Vulkan. + + const Unique descriptorSetLayout(DescriptorSetLayoutBuilder() + .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &colorSampler.get()) + .build(vk, device)); + + const Unique descriptorPool(DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + + const Unique descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + const VkDescriptorImageInfo imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageDescriptorInfo) + .update(vk, device); + + const Unique vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("sample_vert"), 0u)); + const Unique fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("sample_frag"), 0u)); + const Unique renderPass (makeSimpleRenderPass (vk, device, checksumFormat)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, 1u, &checksumImageView.get(), + static_cast(caseDef.renderSize.x()), static_cast(caseDef.renderSize.y()))); + const Unique pipelineLayout (makePipelineLayout (vk, device, *descriptorSetLayout)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, + caseDef.renderSize, VK_SAMPLE_COUNT_1_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)); + + beginCommandBuffer(vk, *cmdBuffer); + + // Prepare for sampling in the fragment shader + { + const VkImageMemoryBarrier barriers[] = + { + { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask; + VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags inputMask; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; + *colorImage, // VkImage image; + makeColorSubresourceRange(0, caseDef.numLayers), // VkImageSubresourceRange subresourceRange; + }, + }; + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, + 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); + } + + const VkClearValue clearValue = makeClearValueColorU32(0u, 0u, 0u, 0u); + + const VkRenderPassBeginInfo renderPassBeginInfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *renderPass, // VkRenderPass renderPass; + *framebuffer, // VkFramebuffer framebuffer; + renderArea, // VkRect2D renderArea; + 1u, // uint32_t clearValueCount; + &clearValue, // const VkClearValue* pClearValues; + }; + vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + { + const VkDeviceSize vertexBufferOffset = 0ull; + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); + } + + vk.cmdDraw(*cmdBuffer, static_cast(vertices.size()), 1u, 0u, 0u); + vk.cmdEndRenderPass(*cmdBuffer); + + // Prepare checksum image for copy + { + const VkImageMemoryBarrier barriers[] = + { + { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask; + VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; + *checksumImage, // VkImage image; + makeColorSubresourceRange(0, 1), // VkImageSubresourceRange subresourceRange; + }, + }; + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, + 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); + } + // Checksum image -> host buffer + { + const VkBufferImageCopy region = + { + 0ull, // VkDeviceSize bufferOffset; + 0u, // uint32_t bufferRowLength; + 0u, // uint32_t bufferImageHeight; + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource; + makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; + makeExtent3D(caseDef.renderSize.x(), caseDef.renderSize.y(), 1u), // VkExtent3D imageExtent; + }; + + vk.cmdCopyImageToBuffer(*cmdBuffer, *checksumImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *checksumBuffer, 1u, ®ion); + } + // Buffer write barrier + { + const VkBufferMemoryBarrier barriers[] = + { + { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; + VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; + VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; + *checksumBuffer, // VkBuffer buffer; + 0ull, // VkDeviceSize offset; + checksumBufferSize, // VkDeviceSize size; + }, + }; + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, + 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u); + } + + VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + // Verify result + + { + invalidateMappedMemoryRange(vk, device, checksumBufferAlloc->getMemory(), 0ull, checksumBufferSize); + + const tcu::ConstPixelBufferAccess access(mapVkFormat(checksumFormat), caseDef.renderSize.x(), caseDef.renderSize.y(), 1, checksumBufferAlloc->getHostPtr()); + const int numExpectedChecksum = getNumSamples(caseDef.numSamples) * caseDef.numLayers; + + for (int y = 0; y < caseDef.renderSize.y(); ++y) + for (int x = 0; x < caseDef.renderSize.x(); ++x) + { + if (access.getPixelInt(x, y).x() != numExpectedChecksum) + return tcu::TestStatus::fail("Some samples have incorrect color"); + } + } + } + + return tcu::TestStatus::pass("OK"); +} + +std::string getSizeLayerString (const IVec2& size, const int numLayers) +{ + std::ostringstream str; + str << size.x() << "x" << size.y() << "_" << numLayers; + return str.str(); +} + +std::string getFormatString (const VkFormat format) +{ + std::string name(getFormatName(format)); + return de::toLower(name.substr(10)); +} + +void createTestsInGroup (tcu::TestCaseGroup* group) +{ + const IVec2 size[] = + { + IVec2(64, 64), + IVec2(79, 31), + }; + const int numLayers[] = + { + 1, 4 + }; + const VkSampleCountFlagBits samples[] = + { + VK_SAMPLE_COUNT_2_BIT, + VK_SAMPLE_COUNT_4_BIT, + VK_SAMPLE_COUNT_8_BIT, + VK_SAMPLE_COUNT_16_BIT, + VK_SAMPLE_COUNT_32_BIT, + VK_SAMPLE_COUNT_64_BIT, + }; + const VkFormat format[] = + { + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R32_UINT, + VK_FORMAT_R16G16_SINT, + VK_FORMAT_R32G32B32A32_SFLOAT, + }; + + for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(size); ++sizeNdx) + for (int layerNdx = 0; layerNdx < DE_LENGTH_OF_ARRAY(numLayers); ++layerNdx) + { + MovePtr sizeLayerGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeLayerString(size[sizeNdx], numLayers[layerNdx]).c_str(), "")); + for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx) + { + MovePtr formatGroup(new tcu::TestCaseGroup(group->getTestContext(), getFormatString(format[formatNdx]).c_str(), "")); + for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx) + { + std::ostringstream caseName; + caseName << "samples_" << getNumSamples(samples[samplesNdx]); + + const CaseDef caseDef = + { + size[sizeNdx], // IVec2 renderSize; + numLayers[layerNdx], // int numLayers; + format[formatNdx], // VkFormat colorFormat; + samples[samplesNdx], // VkSampleCountFlagBits numSamples; + }; + + addFunctionCaseWithPrograms(formatGroup.get(), caseName.str(), "", initPrograms, test, caseDef); + } + sizeLayerGroup->addChild(formatGroup.release()); + } + group->addChild(sizeLayerGroup.release()); + } +} + +} // anonymous ns + +tcu::TestCaseGroup* createMultisampleImageTests (tcu::TestContext& testCtx) +{ + return createTestGroup(testCtx, "sampled_image", "Multisampled image direct sample access", createTestsInGroup); +} + +} // pipeline +} // vkt diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.hpp new file mode 100644 index 0000000..e6a8d80 --- /dev/null +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleImageTests.hpp @@ -0,0 +1,38 @@ +#ifndef _VKTPIPELINEMULTISAMPLEIMAGETESTS_HPP +#define _VKTPIPELINEMULTISAMPLEIMAGETESTS_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 + * \brief Multisample image Tests + *//*--------------------------------------------------------------------*/ + +#include "vktTestCase.hpp" + +namespace vkt +{ +namespace pipeline +{ + +tcu::TestCaseGroup* createMultisampleImageTests (tcu::TestContext& testCtx); + +} // pipeline +} // vkt + +#endif // _VKTPIPELINEMULTISAMPLEIMAGETESTS_HPP diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp index aadec96..94a9081 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTests.cpp @@ -23,6 +23,7 @@ *//*--------------------------------------------------------------------*/ #include "vktPipelineMultisampleTests.hpp" +#include "vktPipelineMultisampleImageTests.hpp" #include "vktPipelineClearUtil.hpp" #include "vktPipelineImageUtil.hpp" #include "vktPipelineVertexUtil.hpp" @@ -2030,6 +2031,11 @@ tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx) multisampleTests->addChild(alphaToCoverageTests.release()); } + // Sampling from a multisampled image texture (texelFetch) + { + multisampleTests->addChild(createMultisampleImageTests(testCtx)); + } + return multisampleTests.release(); } diff --git a/external/vulkancts/mustpass/1.0.1/vk-default.txt b/external/vulkancts/mustpass/1.0.1/vk-default.txt index 32be6f4..1441d7d 100644 --- a/external/vulkancts/mustpass/1.0.1/vk-default.txt +++ b/external/vulkancts/mustpass/1.0.1/vk-default.txt @@ -65229,6 +65229,102 @@ dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_32.alpha_invisible dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_opaque dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_translucent dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_invisible +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_1.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.64x64_4.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_1.r32g32b32a32_sfloat.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r8g8b8a8_unorm.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32_uint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r16g16_sint.samples_64 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_2 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_4 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_8 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_16 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_32 +dEQP-VK.pipeline.multisample.sampled_image.79x31_4.r32g32b32a32_sfloat.samples_64 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.128_128_1.samples_1 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.137_191_1.samples_1 dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_2