1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2019 Advanced Micro Devices, Inc.
6 * Copyright (c) 2019 The Khronos Group Inc.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Tests for VK_AMD_shader_fragment_mask
23 *//*--------------------------------------------------------------------*/
25 #include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
26 #include "vktPipelineMakeUtil.hpp"
27 #include "vktTestCase.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkImageUtil.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deSharedPtr.hpp"
44 #include "deRandom.hpp"
46 #include "tcuVector.hpp"
47 #include "tcuTestLog.hpp"
48 #include "tcuImageCompare.hpp"
49 #include "tcuTestLog.hpp"
50 #include "tcuTextureUtil.hpp"
70 typedef SharedPtr<Unique<VkImageView> > ImageViewSp;
71 typedef SharedPtr<Unique<VkPipeline> > PipelineSp;
76 VkClearColorValue color;
78 PositionColor (const tcu::Vec4& pos, const tcu::UVec4& col) : position(pos)
80 deMemcpy(color.uint32, col.getPtr(), sizeof(color.uint32));
83 PositionColor (const tcu::Vec4& pos, const tcu::Vec4& col) : position(pos)
85 deMemcpy(color.float32, col.getPtr(), sizeof(color.float32));
88 PositionColor (const PositionColor& rhs)
89 : position (rhs.position)
95 //! Make a dummy sampler.
96 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
98 const VkSamplerCreateInfo samplerParams =
100 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
101 DE_NULL, // const void* pNext;
102 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
103 VK_FILTER_NEAREST, // VkFilter magFilter;
104 VK_FILTER_NEAREST, // VkFilter minFilter;
105 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
106 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
107 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
108 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
109 0.0f, // float mipLodBias;
110 VK_FALSE, // VkBool32 anisotropyEnable;
111 1.0f, // float maxAnisotropy;
112 VK_FALSE, // VkBool32 compareEnable;
113 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
114 0.0f, // float minLod;
115 0.0f, // float maxLod;
116 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
117 VK_FALSE, // VkBool32 unnormalizedCoordinates;
119 return createSampler(vk, device, &samplerParams);
122 Move<VkImage> makeImage (const DeviceInterface& vk,
123 const VkDevice device,
124 const VkFormat format,
126 const deUint32 layers,
127 const VkSampleCountFlagBits samples,
128 const VkImageUsageFlags usage)
130 const VkImageCreateInfo imageParams =
132 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
133 DE_NULL, // const void* pNext;
134 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
135 VK_IMAGE_TYPE_2D, // VkImageType imageType;
136 format, // VkFormat format;
137 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
138 1u, // deUint32 mipLevels;
139 layers, // deUint32 arrayLayers;
140 samples, // VkSampleCountFlagBits samples;
141 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
142 usage, // VkImageUsageFlags usage;
143 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
144 0u, // deUint32 queueFamilyIndexCount;
145 DE_NULL, // const deUint32* pQueueFamilyIndices;
146 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
148 return createImage(vk, device, &imageParams);
151 //! Create a test-specific MSAA pipeline
152 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
153 const VkDevice device,
154 const VkPipelineLayout pipelineLayout,
155 const VkRenderPass renderPass,
156 const VkShaderModule vertexModule,
157 const VkShaderModule fragmentModule,
158 const bool useVertexInput,
159 const VkFormat vertexAttribColorFormat,
160 const bool useColorAttachment,
161 const deUint32 subpassNdx,
162 const UVec2& renderSize,
163 const VkSampleCountFlagBits numSamples)
165 std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions;
166 std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
168 // Vertex attributes: position and color
171 vertexInputBindingDescriptions.push_back (makeVertexInputBindingDescription (0u, sizeof(PositionColor), VK_VERTEX_INPUT_RATE_VERTEX));
172 vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u));
173 vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(1u, 0u, vertexAttribColorFormat, sizeof(Vec4)));
176 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
178 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
179 DE_NULL, // const void* pNext;
180 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
181 static_cast<deUint32>(vertexInputBindingDescriptions.size()), // uint32_t vertexBindingDescriptionCount;
182 dataOrNullPtr(vertexInputBindingDescriptions), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
183 static_cast<deUint32>(vertexInputAttributeDescriptions.size()), // uint32_t vertexAttributeDescriptionCount;
184 dataOrNullPtr(vertexInputAttributeDescriptions), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
187 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
189 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
190 DE_NULL, // const void* pNext;
191 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
192 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
193 VK_FALSE, // VkBool32 primitiveRestartEnable;
196 const VkViewport viewport =
199 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), // widht, height
200 0.0f, 1.0f // minDepth, maxDepth
203 const VkRect2D scissor =
206 makeExtent2D(renderSize.x(), renderSize.y()),
209 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
211 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
212 DE_NULL, // const void* pNext;
213 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
214 1u, // uint32_t viewportCount;
215 &viewport, // const VkViewport* pViewports;
216 1u, // uint32_t scissorCount;
217 &scissor, // const VkRect2D* pScissors;
220 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
222 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
223 DE_NULL, // const void* pNext;
224 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
225 VK_FALSE, // VkBool32 depthClampEnable;
226 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
227 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
228 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
229 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
230 VK_FALSE, // VkBool32 depthBiasEnable;
231 0.0f, // float depthBiasConstantFactor;
232 0.0f, // float depthBiasClamp;
233 0.0f, // float depthBiasSlopeFactor;
234 1.0f, // float lineWidth;
237 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
239 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
240 DE_NULL, // const void* pNext;
241 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
242 numSamples, // VkSampleCountFlagBits rasterizationSamples;
243 VK_FALSE, // VkBool32 sampleShadingEnable;
244 1.0f, // float minSampleShading;
245 DE_NULL, // const VkSampleMask* pSampleMask;
246 VK_FALSE, // VkBool32 alphaToCoverageEnable;
247 VK_FALSE // VkBool32 alphaToOneEnable;
250 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
252 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
253 DE_NULL, // const void* pNext;
254 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
255 VK_FALSE, // VkBool32 depthTestEnable;
256 VK_TRUE, // VkBool32 depthWriteEnable;
257 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
258 VK_FALSE, // VkBool32 depthBoundsTestEnable;
259 VK_FALSE, // VkBool32 stencilTestEnable;
260 VkStencilOpState(), // VkStencilOpState front;
261 VkStencilOpState(), // VkStencilOpState back;
262 0.0f, // float minDepthBounds;
263 1.0f, // float maxDepthBounds;
266 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
267 const VkPipelineColorBlendAttachmentState defaultBlendAttachmentState =
269 VK_FALSE, // VkBool32 blendEnable;
270 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
271 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
272 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
273 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
274 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
275 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
276 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
279 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
281 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
282 DE_NULL, // const void* pNext;
283 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
284 VK_FALSE, // VkBool32 logicOpEnable;
285 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
286 (useColorAttachment ? 1u : 0u), // deUint32 attachmentCount;
287 &defaultBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
288 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
291 const VkPipelineShaderStageCreateInfo pShaderStages[] =
294 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
295 DE_NULL, // const void* pNext;
296 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
297 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
298 vertexModule, // VkShaderModule module;
299 "main", // const char* pName;
300 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
303 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
304 DE_NULL, // const void* pNext;
305 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
306 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
307 fragmentModule, // VkShaderModule module;
308 "main", // const char* pName;
309 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
313 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
315 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
316 DE_NULL, // const void* pNext;
317 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
318 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
319 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
320 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
321 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
322 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
323 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
324 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
325 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
326 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
327 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
328 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
329 pipelineLayout, // VkPipelineLayout layout;
330 renderPass, // VkRenderPass renderPass;
331 subpassNdx, // deUint32 subpass;
332 DE_NULL, // VkPipeline basePipelineHandle;
333 -1, // deInt32 basePipelineIndex;
336 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
339 std::vector<PositionColor> genShapes (const VkFormat colorFormat)
341 std::vector<PositionColor> vertices;
343 if (colorFormat == VK_FORMAT_R8G8B8A8_UNORM)
345 vertices.push_back(PositionColor(Vec4( 0.0f, -0.75f, 0.0f, 1.0f), Vec4(0.5f, 0.5f, 0.5f, 1.0f)));
346 vertices.push_back(PositionColor(Vec4(-0.75f, 0.75f, 0.0f, 1.0f), Vec4(1.0f, 0.5f, 0.5f, 1.0f)));
347 vertices.push_back(PositionColor(Vec4( 0.75f, 0.65f, 0.0f, 1.0f), Vec4(0.0f, 0.5f, 1.0f, 1.0f)));
351 vertices.push_back(PositionColor(Vec4( 0.0f, -0.75f, 0.0f, 1.0f), UVec4(0xabcdu, 0u, 0u, 0u)));
352 vertices.push_back(PositionColor(Vec4(-0.75f, 0.75f, 0.0f, 1.0f), UVec4(0xbcdeu, 0u, 0u, 0u)));
353 vertices.push_back(PositionColor(Vec4( 0.75f, 0.65f, 0.0f, 1.0f), UVec4(0xcdefu, 0u, 0u, 0u)));
359 //! Map color image format to a convenient format used in vertex attributes
360 VkFormat getVertexInputColorFormat (const VkFormat colorImageFormat)
362 switch (tcu::getTextureChannelClass(mapVkFormat(colorImageFormat).type))
364 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
365 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
366 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
367 return VK_FORMAT_R32G32B32A32_SFLOAT;
369 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
370 return VK_FORMAT_R32G32B32A32_SINT;
372 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
373 return VK_FORMAT_R32G32B32A32_UINT;
377 return VK_FORMAT_UNDEFINED;
383 SAMPLE_SOURCE_IMAGE, //!< texel fetch from an image
384 SAMPLE_SOURCE_SUBPASS_INPUT, //!< texel fetch from an input attachment
387 //! The parameters that define a test case
391 deUint32 numLayers; //!< 1 or N for layered image
392 SampleSource sampleSource; //!< source of texel fetch
393 VkSampleCountFlagBits numColorSamples;
394 VkFormat colorFormat; //!< Color attachment format
404 void checkRequirements (Context& context, TestParams params)
406 context.requireDeviceFunctionality("VK_AMD_shader_fragment_mask");
408 // In the subpass input case we have to store fetch results into a buffer for subsequent verification in a compute shader.
409 const bool requireFragmentStores = (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT);
411 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
413 if ((limits.framebufferColorSampleCounts & params.numColorSamples) == 0u)
414 TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
416 if ((isIntFormat(params.colorFormat) || isUintFormat(params.colorFormat)))
418 if ((limits.sampledImageIntegerSampleCounts & params.numColorSamples) == 0u)
419 TCU_THROW(NotSupportedError, "sampledImageIntegerSampleCounts: sample count not supported");
423 if ((limits.sampledImageColorSampleCounts & params.numColorSamples) == 0u)
424 TCU_THROW(NotSupportedError, "sampledImageColorSampleCounts: sample count not supported");
427 if (requireFragmentStores)
429 if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
430 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics: feature not supported");
434 //! Common data used by the test
437 deUint32 numVertices; //!< Number of vertices defined in the vertex buffer
438 Move<VkBuffer> vertexBuffer;
439 MovePtr<Allocation> vertexBufferAlloc;
440 Move<VkImage> colorImage; //!< Color image
441 MovePtr<Allocation> colorImageAlloc;
442 Move<VkImageView> colorImageView; //!< Color image view spanning all layers
443 Move<VkBuffer> colorBuffer; //!< Buffer used to copy image data
444 MovePtr<Allocation> colorBufferAlloc;
445 VkDeviceSize colorBufferSize;
446 Move<VkSampler> defaultSampler; //!< Dummy sampler, we are using texel fetches
455 void initPrograms (SourceCollections& programCollection, const TestParams params)
457 std::string colorType; //!< color pixel type used by image functions
458 std::string colorBufferType; //!< packed pixel type as stored in a ssbo
459 std::string colorBufferPack; //!< a cast or a function call when writing back color format to the ssbo
460 std::string colorFragInQualifier; //!< fragment shader color input qualifier
461 std::string samplerPrefix; //!< u, i, or empty
463 switch (params.colorFormat)
465 case VK_FORMAT_R8G8B8A8_UNORM:
467 colorBufferType = "uint";
468 colorBufferPack = "packUnorm4x8";
471 case VK_FORMAT_R32_UINT:
473 colorBufferType = "uint";
474 colorBufferPack = colorBufferType;
475 colorFragInQualifier = "flat";
479 case VK_FORMAT_R32_SINT:
481 colorBufferType = "int";
482 colorBufferPack = colorBufferType;
483 colorFragInQualifier = "flat";
488 DE_FATAL("initPrograms not handled for this color format");
492 // Vertex shader - position and color
494 std::ostringstream src;
495 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
497 << "layout(location = 0) in vec4 in_position;\n"
498 << "layout(location = 1) in " << colorType << " in_color;\n"
499 << "layout(location = 0) out " << colorType << " o_color;\n"
501 << "out gl_PerVertex {\n"
502 << " vec4 gl_Position;\n"
505 << "void main(void)\n"
507 // Introduce a variance in geometry per instance index which maps to the image layer
508 << " float a = 0.25 * float(gl_InstanceIndex);\n"
509 << " mat3 rm = mat3( cos(a), sin(a), 0.0,\n"
510 << " -sin(a), cos(a), 0.0,\n"
511 << " 0.0, 0.0, 1.0);\n"
512 << " vec2 rpos = (rm * vec3(in_position.xy, 1.0)).xy;\n"
514 << " gl_Position = vec4(rpos, in_position.zw);\n"
515 << " o_color = in_color;\n"
518 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
521 // Vertex shader - no vertex data, fill viewport with one primitive
523 std::ostringstream src;
524 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
526 << "out gl_PerVertex {\n"
527 << " vec4 gl_Position;\n"
530 << "void main(void)\n"
532 // Specify an oversized triangle covering the whole viewport.
533 << " switch (gl_VertexIndex)\n"
536 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
539 << " gl_Position = vec4(-1.0, 3.0, 0.0, 1.0);\n"
542 << " gl_Position = vec4( 3.0, -1.0, 0.0, 1.0);\n"
547 programCollection.glslSources.add("vert_full") << glu::VertexSource(src.str());
550 // Fragment shader - output color from VS
552 std::ostringstream src;
553 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
555 << "layout(location = 0) in " << colorFragInQualifier << " " << colorType << " in_color;\n"
556 << "layout(location = 0) out " << colorType << " o_color;\n"
558 << "void main(void)\n"
560 << " o_color = in_color;\n"
563 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
566 // Fragment shader - FMASK fetch from an input attachment
567 if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
569 std::ostringstream src;
570 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
571 << "#extension GL_AMD_shader_fragment_mask : enable\n"
573 << "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n"
574 << "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n"
575 << " " << colorBufferType << " color[];\n"
577 << "layout(input_attachment_index = " << params.numLayers << ", set = 0, binding = 2) uniform " << samplerPrefix << "subpassInputMS" << " input_attach;\n"
579 << "void main(void)\n"
581 << " ivec2 p = ivec2(gl_FragCoord.xy);\n"
582 << " int width = " << params.renderSize.x() << ";\n"
583 << " int numSamples = " << static_cast<deUint32>(params.numColorSamples) << ";\n"
584 << " int colorOutNdx = numSamples * (p.x + width * p.y);\n"
586 << " uint mask = fragmentMaskFetchAMD(input_attach);\n"
587 << " for (int sampleNdx = 0; sampleNdx < numSamples; ++sampleNdx)\n"
589 << " int fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n"
590 << " " << samplerPrefix << "vec4 color = fragmentFetchAMD(input_attach, fragNdx);\n"
591 << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n"
595 programCollection.glslSources.add("frag_fmask_fetch") << glu::FragmentSource(src.str());
598 // Generate compute shaders
599 const struct ComputeShaderParams
606 // name // FMASK? // enabled?
607 { "comp_fetch", false, true, },
608 { "comp_fmask_fetch", true, (params.sampleSource != SAMPLE_SOURCE_SUBPASS_INPUT) },
611 for (const ComputeShaderParams* pShaderParams = computeShaders; pShaderParams != DE_ARRAY_END(computeShaders); ++pShaderParams)
612 if (pShaderParams->enabled)
614 const std::string samplingPos = (params.numLayers == 1 ? "ivec2(gl_WorkGroupID.xy)"
615 : "ivec3(gl_WorkGroupID)");
616 std::ostringstream src;
617 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
618 << (pShaderParams->isFmaskFetch ? "#extension GL_AMD_shader_fragment_mask : enable\n" : "")
619 << "#define NUM_SAMPLES " << static_cast<deUint32>(params.numColorSamples) << "\n"
621 << "layout(local_size_x = NUM_SAMPLES) in;\n" // one work group per pixel, each sample gets a local invocation
623 << "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n"
624 << "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n"
625 << " " << colorBufferType << " color[];\n"
628 << "void main(void)\n"
630 << " int sampleNdx = int(gl_LocalInvocationID.x);\n"
631 << " int colorOutNdx = NUM_SAMPLES * int(gl_WorkGroupID.x +\n"
632 << " gl_WorkGroupID.y * gl_NumWorkGroups.x +\n"
633 << " gl_WorkGroupID.z * gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n"
635 if (pShaderParams->isFmaskFetch)
637 src << " uint mask = fragmentMaskFetchAMD(u_image, " << samplingPos << ");\n"
638 << " int fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n"
639 << " " << samplerPrefix << "vec4 color = fragmentFetchAMD(u_image, " << samplingPos << ", fragNdx);\n"
640 << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n";
644 src << " " << samplerPrefix << "vec4 color = texelFetch(u_image, " << samplingPos << ", sampleNdx);\n"
645 << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n";
649 programCollection.glslSources.add(pShaderParams->name) << glu::ComputeSource(src.str());
653 std::vector<VkClearValue> genClearValues (const VkFormat format, const deUint32 count)
655 std::vector<VkClearValue> clearValues;
656 de::Random rng (332);
660 case VK_FORMAT_R8G8B8A8_UNORM:
661 for (deUint32 i = 0u; i < count; ++i)
662 clearValues.push_back(makeClearValueColorF32(rng.getFloat(), rng.getFloat(), rng.getFloat(), 1.0f));
665 case VK_FORMAT_R32_UINT:
666 case VK_FORMAT_R32_SINT:
667 for (deUint32 i = 0u; i < count; ++i)
668 clearValues.push_back(makeClearValueColorU32(rng.getUint32(), 0u, 0u, 0u));
672 DE_FATAL("Clear color not defined for this format");
679 //! For subpass load case draw and fetch must happen within the same render pass.
680 void drawAndSampleInputAttachment (Context& context, const TestParams& params, WorkingData& wd)
682 DE_ASSERT(params.numLayers == 1u); // subpass load with single-layer image
684 const DeviceInterface& vk = context.getDeviceInterface();
685 const VkDevice device = context.getDevice();
687 Move<VkRenderPass> renderPass;
688 Move<VkFramebuffer> framebuffer;
690 // Create descriptor set
691 const Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
692 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &wd.defaultSampler.get())
693 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
694 .addSingleBinding (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
697 const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
698 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
699 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
700 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
701 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
703 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
706 const VkDescriptorImageInfo colorImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
707 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(*wd.colorBuffer, 0u, wd.colorBufferSize);
709 DescriptorSetUpdateBuilder builder;
711 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo);
712 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
714 if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
715 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &colorImageInfo);
717 builder.update(vk, device);
720 // Create a render pass and a framebuffer
722 std::vector<VkSubpassDescription> subpasses;
723 std::vector<VkSubpassDependency> subpassDependencies;
724 std::vector<VkImageView> attachments;
725 std::vector<VkAttachmentDescription> attachmentDescriptions;
726 std::vector<VkAttachmentReference> attachmentReferences;
728 // Reserve capacity to avoid invalidating pointers to elements
729 attachmentReferences.reserve(2); // color image + input attachment
731 // Create a MS draw subpass
733 attachments.push_back(*wd.colorImageView);
735 attachmentDescriptions.push_back(makeAttachmentDescription(
736 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
737 params.colorFormat, // VkFormat format;
738 params.numColorSamples, // VkSampleCountFlagBits samples;
739 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
740 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
741 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
742 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
743 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
744 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout;
747 attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
748 const VkAttachmentReference* colorRef = &attachmentReferences.back();
750 const VkSubpassDescription subpassDescription =
752 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
753 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
754 0u, // uint32_t inputAttachmentCount;
755 DE_NULL, // const VkAttachmentReference* pInputAttachments;
756 1u, // uint32_t colorAttachmentCount;
757 colorRef, // const VkAttachmentReference* pColorAttachments;
758 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
759 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
760 0u, // uint32_t preserveAttachmentCount;
761 DE_NULL, // const uint32_t* pPreserveAttachments;
764 subpasses.push_back(subpassDescription);
767 // Create a sampling subpass
769 attachmentReferences.push_back(makeAttachmentReference(0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
770 const VkAttachmentReference* inputRef = &attachmentReferences.back();
772 // No color attachment, side effects only
773 VkSubpassDescription subpassDescription =
775 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
776 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
777 1u, // uint32_t inputAttachmentCount;
778 inputRef, // const VkAttachmentReference* pInputAttachments;
779 0u, // uint32_t colorAttachmentCount;
780 DE_NULL, // const VkAttachmentReference* pColorAttachments;
781 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
782 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
783 0u, // uint32_t preserveAttachmentCount;
784 DE_NULL, // const uint32_t* pPreserveAttachments;
787 subpasses.push_back(subpassDescription);
790 // Serialize the subpasses
792 const VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
793 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
794 | VK_ACCESS_SHADER_WRITE_BIT;
795 const VkSubpassDependency dependency =
797 0u, // uint32_t srcSubpass;
798 1u, // uint32_t dstSubpass;
799 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask;
800 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask;
801 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
802 dstAccessMask, // VkAccessFlags dstAccessMask;
803 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags;
805 subpassDependencies.push_back(dependency);
808 VkRenderPassCreateInfo renderPassInfo =
810 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
811 DE_NULL, // const void* pNext;
812 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
813 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
814 dataOrNullPtr(attachmentDescriptions), // const VkAttachmentDescription* pAttachments;
815 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
816 dataOrNullPtr(subpasses), // const VkSubpassDescription* pSubpasses;
817 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount;
818 dataOrNullPtr(subpassDependencies), // const VkSubpassDependency* pDependencies;
821 renderPass = createRenderPass(vk, device, &renderPassInfo);
822 framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y());
825 const Unique<VkShaderModule> vertexModuleDraw (createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
826 const Unique<VkShaderModule> fragmentModuleDraw (createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
828 // Create pipelines for MS draw
829 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
830 const Unique<VkPipeline> pipelineDraw (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleDraw, *fragmentModuleDraw,
831 true/*use vertex attribs*/, getVertexInputColorFormat(params.colorFormat), true/*use color attach*/, 0u/*subpass*/,
832 params.renderSize, params.numColorSamples));
834 // Sampling pass is single-sampled, output to storage buffer
835 const Unique<VkShaderModule> vertexModuleSample (createShaderModule(vk, device, context.getBinaryCollection().get("vert_full"), 0u));
836 const Unique<VkShaderModule> fragmentModuleSample (createShaderModule(vk, device, context.getBinaryCollection().get("frag_fmask_fetch"), 0u));
839 const Unique<VkPipeline> pipelineSample (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleSample, *fragmentModuleSample,
840 false/*use vertex attribs*/, VK_FORMAT_UNDEFINED, false/*no color output*/, 1u/*subpass*/,
841 params.renderSize, VK_SAMPLE_COUNT_1_BIT));
843 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
844 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
846 beginCommandBuffer(vk, *cmdBuffer);
849 // Generate clear values
850 std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers);
852 const VkRect2D renderArea =
855 { params.renderSize.x(), params.renderSize.y() }
858 const VkRenderPassBeginInfo renderPassBeginInfo =
860 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
861 DE_NULL, // const void* pNext;
862 *renderPass, // VkRenderPass renderPass;
863 *framebuffer, // VkFramebuffer framebuffer;
864 renderArea, // VkRect2D renderArea;
865 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
866 dataOrNullPtr(clearValues), // const VkClearValue* pClearValues;
868 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
871 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
874 const VkDeviceSize vertexBufferOffset = 0ull;
875 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset);
878 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineDraw);
879 vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, 0u);
881 vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
883 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSample);
884 vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u); // fill the framebuffer, geometry defined in the VS
886 vk.cmdEndRenderPass(*cmdBuffer);
888 // Buffer write barrier
890 const VkBufferMemoryBarrier barrier =
892 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
893 DE_NULL, // const void* pNext;
894 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
895 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
896 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
897 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
898 *wd.colorBuffer, // VkBuffer buffer;
899 0ull, // VkDeviceSize offset;
900 VK_WHOLE_SIZE, // VkDeviceSize size;
903 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
906 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
907 submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
909 invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
912 //! Only draw a multisampled image
913 void draw (Context& context, const TestParams& params, WorkingData& wd)
915 const DeviceInterface& vk = context.getDeviceInterface();
916 const VkDevice device = context.getDevice();
918 std::vector<ImageViewSp> imageViews;
919 Move<VkRenderPass> renderPass;
920 Move<VkFramebuffer> framebuffer;
922 // Create color attachments
923 for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
925 imageViews.push_back(ImageViewSp(new Unique<VkImageView>(
926 makeImageView(vk, device, *wd.colorImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, layerNdx, 1u)))));
929 // Create a render pass and a framebuffer
931 std::vector<VkSubpassDescription> subpasses;
932 std::vector<VkImageView> attachments;
933 std::vector<VkAttachmentDescription> attachmentDescriptions;
934 std::vector<VkAttachmentReference> attachmentReferences;
936 // Reserve capacity to avoid invalidating pointers to elements
937 attachmentReferences.reserve(params.numLayers);
939 // Create MS draw subpasses
940 for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
942 attachments.push_back(**imageViews[layerNdx]);
944 attachmentDescriptions.push_back(makeAttachmentDescription(
945 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
946 params.colorFormat, // VkFormat format;
947 params.numColorSamples, // VkSampleCountFlagBits samples;
948 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
949 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
950 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
951 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
952 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
953 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout;
956 attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
957 const VkAttachmentReference* colorRef = &attachmentReferences.back();
959 const VkSubpassDescription subpassDescription =
961 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
962 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
963 0u, // uint32_t inputAttachmentCount;
964 DE_NULL, // const VkAttachmentReference* pInputAttachments;
965 1u, // uint32_t colorAttachmentCount;
966 colorRef, // const VkAttachmentReference* pColorAttachments;
967 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
968 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
969 0u, // uint32_t preserveAttachmentCount;
970 DE_NULL, // const uint32_t* pPreserveAttachments;
973 subpasses.push_back(subpassDescription);
976 // All MS image drawing subpasses are independent
977 VkRenderPassCreateInfo renderPassInfo =
979 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
980 DE_NULL, // const void* pNext;
981 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
982 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
983 dataOrNullPtr(attachmentDescriptions), // const VkAttachmentDescription* pAttachments;
984 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
985 dataOrNullPtr(subpasses), // const VkSubpassDescription* pSubpasses;
986 0u, // deUint32 dependencyCount;
987 DE_NULL, // const VkSubpassDependency* pDependencies;
990 renderPass = createRenderPass(vk, device, &renderPassInfo);
991 framebuffer = makeFramebuffer (vk, device, *renderPass, static_cast<deUint32>(attachments.size()), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y());
994 std::vector<PipelineSp> pipelines;
995 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device));
996 const Unique<VkShaderModule> vertexModuleDraw (createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
997 const Unique<VkShaderModule> fragmentModuleDraw (createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
999 // Create pipelines for MS draw
1000 for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
1002 pipelines.push_back(PipelineSp(new Unique<VkPipeline>(
1003 makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModuleDraw, *fragmentModuleDraw,
1004 true /*use vertex attribs*/, getVertexInputColorFormat(params.colorFormat), true/*use color attachment*/, layerNdx /*subpass*/,
1005 params.renderSize, params.numColorSamples))));
1008 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
1009 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
1011 beginCommandBuffer(vk, *cmdBuffer);
1014 // Generate clear values
1015 std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers);
1017 const VkRect2D renderArea =
1020 { params.renderSize.x(), params.renderSize.y() }
1023 const VkRenderPassBeginInfo renderPassBeginInfo =
1025 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1026 DE_NULL, // const void* pNext;
1027 *renderPass, // VkRenderPass renderPass;
1028 *framebuffer, // VkFramebuffer framebuffer;
1029 renderArea, // VkRect2D renderArea;
1030 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
1031 dataOrNullPtr(clearValues), // const VkClearValue* pClearValues;
1033 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1037 const VkDeviceSize vertexBufferOffset = 0ull;
1038 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset);
1041 for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
1044 vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1046 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[layerNdx]);
1047 vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, layerNdx); // pass instance index to slightly change geometry per layer
1050 vk.cmdEndRenderPass(*cmdBuffer);
1052 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1053 submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
1056 //! Sample from an image in a compute shader, storing the result in a color buffer
1057 void dispatchSampleImage (Context& context, const TestParams& params, WorkingData& wd, const std::string& shaderName)
1059 const DeviceInterface& vk = context.getDeviceInterface();
1060 const VkDevice device = context.getDevice();
1062 // Create descriptor set
1064 const Unique<VkDescriptorSetLayout> descriptorSetLayout(
1065 DescriptorSetLayoutBuilder()
1066 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &wd.defaultSampler.get())
1067 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1068 .build(vk, device));
1070 const Unique<VkDescriptorPool> descriptorPool(
1071 DescriptorPoolBuilder()
1072 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1073 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1074 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1076 const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1079 const VkDescriptorImageInfo colorImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1080 const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(*wd.colorBuffer, 0ull, wd.colorBufferSize);
1082 DescriptorSetUpdateBuilder builder;
1084 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo);
1085 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo);
1087 builder.update(vk, device);
1092 const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, context.getBinaryCollection().get(shaderName), 0u));
1093 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
1094 const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule, DE_NULL));
1096 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
1097 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
1099 beginCommandBuffer(vk, *cmdBuffer);
1101 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
1102 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
1104 vk.cmdDispatch(*cmdBuffer, params.renderSize.x(), params.renderSize.y(), params.numLayers);
1107 const VkBufferMemoryBarrier barrier =
1109 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1110 DE_NULL, // const void* pNext;
1111 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1112 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1113 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1114 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1115 *wd.colorBuffer, // VkBuffer buffer;
1116 0ull, // VkDeviceSize offset;
1117 VK_WHOLE_SIZE, // VkDeviceSize size;
1120 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0,
1121 (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
1124 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1125 submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer);
1127 invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1130 //! Get a single-sampled image access from a multisampled color buffer with samples packed per pixel
1131 tcu::ConstPixelBufferAccess getSingleSampledAccess (const void* const imageData, const TestParams& params, const deUint32 sampleNdx, const deUint32 layerNdx)
1133 const deUint32 numSamples = static_cast<deUint32>(params.numColorSamples);
1134 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(params.colorFormat));
1135 const deUint32 rowSize = pixelSize * params.renderSize.x();
1136 const deUint32 layerSize = rowSize * params.renderSize.y();
1137 const deUint8* src = static_cast<const deUint8*>(imageData)
1138 + (layerNdx * numSamples * layerSize)
1139 + (sampleNdx * pixelSize);
1140 const tcu::IVec3 size (params.renderSize.x(), params.renderSize.y(), 1);
1141 const tcu::IVec3 pitch (numSamples * pixelSize,
1142 numSamples * rowSize,
1143 numSamples * layerSize);
1144 return tcu::ConstPixelBufferAccess(mapVkFormat(params.colorFormat), size, pitch, src);
1147 tcu::TestStatus test (Context& context, const TestParams params)
1150 const DeviceInterface& vk = context.getDeviceInterface();
1151 const VkDevice device = context.getDevice();
1152 MovePtr<Allocator> allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())));
1154 // Initialize resources
1156 const VkImageUsageFlags msImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
1157 | VK_IMAGE_USAGE_SAMPLED_BIT
1158 | (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1159 wd.colorImage = makeImage(vk, device, params.colorFormat, params.renderSize, params.numLayers, params.numColorSamples, msImageUsage);
1160 wd.colorImageAlloc = bindImage(vk, device, *allocator, *wd.colorImage, MemoryRequirement::Any);
1161 wd.colorImageView = makeImageView(vk, device, *wd.colorImage, (params.numLayers == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY), params.colorFormat,
1162 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.numLayers));
1164 wd.defaultSampler = makeSampler(vk, device);
1166 // Color buffer is meant to hold data for all layers and all samples of the image.
1167 // Data is tightly packed layer by layer, for each pixel all samples are laid out together starting with sample 0.
1168 // E.g.: pixel(0,0)sample(0)sample(1), pixel(1,0)sample(0)sample(1), ...
1169 wd.colorBufferSize = static_cast<VkDeviceSize>(tcu::getPixelSize(mapVkFormat(params.colorFormat))
1170 * params.renderSize.x() * params.renderSize.y() * params.numLayers * static_cast<deUint32>(params.numColorSamples));
1171 wd.colorBuffer = makeBuffer(vk, device, wd.colorBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1172 wd.colorBufferAlloc = bindBuffer(vk, device, *allocator, *wd.colorBuffer, MemoryRequirement::HostVisible);
1174 deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize));
1175 flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1177 const std::vector<PositionColor> vertices = genShapes(params.colorFormat);
1178 const VkDeviceSize vertexBufferSize = static_cast<VkDeviceSize>(sizeof(vertices[0]) * vertices.size());
1180 wd.numVertices = static_cast<deUint32>(vertices.size());
1181 wd.vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1182 wd.vertexBufferAlloc = bindBuffer(vk, device, *allocator, *wd.vertexBuffer, MemoryRequirement::HostVisible);
1184 deMemcpy(wd.vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize));
1185 flushMappedMemoryRange(vk, device, wd.vertexBufferAlloc->getMemory(), wd.vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1188 if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT)
1190 // Create a multisample image and sample from it
1191 drawAndSampleInputAttachment (context, params, wd);
1195 // Draw the image, then sample from it in a CS
1196 draw (context, params, wd);
1197 dispatchSampleImage (context, params, wd, "comp_fmask_fetch");
1201 std::vector<deUint8> fmaskFetchColorBuffer (static_cast<deUint32>(wd.colorBufferSize));
1202 deMemcpy(&fmaskFetchColorBuffer[0], wd.colorBufferAlloc->getHostPtr(), static_cast<std::size_t>(wd.colorBufferSize));
1204 // Clear the color buffer, just to be sure we're getting the new data
1205 deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize));
1206 flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1208 // Sample image using the standard texel fetch
1209 dispatchSampleImage (context, params, wd, "comp_fetch");
1211 // Verify the images
1213 const void* const fmaskResult = dataOrNullPtr(fmaskFetchColorBuffer);
1214 const void* const expectedResult = wd.colorBufferAlloc->getHostPtr();
1216 DE_ASSERT(!isFloatFormat(params.colorFormat)); // we're using int compare
1218 // Mismatch, do image compare to pinpoint the failure
1219 for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx)
1220 for (deUint32 sampleNdx = 0u; sampleNdx < static_cast<deUint32>(params.numColorSamples); ++sampleNdx)
1222 const std::string imageName = "layer_" + de::toString(layerNdx) + "_sample_" + de::toString(sampleNdx);
1223 const std::string imageDesc = "Layer " + de::toString(layerNdx) + " Sample " + de::toString(sampleNdx);
1224 const tcu::ConstPixelBufferAccess expected = getSingleSampledAccess(expectedResult, params, sampleNdx, layerNdx);
1225 const tcu::ConstPixelBufferAccess actual = getSingleSampledAccess(fmaskResult, params, sampleNdx, layerNdx);
1226 const UVec4 threshold (0); // should match exactly
1228 const bool ok = tcu::intThresholdCompare(context.getTestContext().getLog(), imageName.c_str(), imageDesc.c_str(),
1229 expected, actual, threshold, tcu::COMPARE_LOG_RESULT);
1232 return tcu::TestStatus::fail("Some texels were incorrect");
1236 return tcu::TestStatus::pass("Pass");
1239 std::string getFormatShortString (const VkFormat format)
1241 std::string s(de::toLower(getFormatName(format)));
1242 return s.substr(10);
1245 void createShaderFragmentMaskTestsInGroup (tcu::TestCaseGroup* rootGroup)
1247 // Per spec, the following formats must support color attachment and sampled image
1248 const VkFormat colorFormats[] =
1250 VK_FORMAT_R8G8B8A8_UNORM,
1255 const VkSampleCountFlagBits sampleCounts[] =
1257 VK_SAMPLE_COUNT_2_BIT,
1258 VK_SAMPLE_COUNT_4_BIT,
1259 VK_SAMPLE_COUNT_8_BIT,
1260 VK_SAMPLE_COUNT_16_BIT,
1263 const struct SourceCase
1267 SampleSource sampleSource;
1270 { "image_2d", 1u, SAMPLE_SOURCE_IMAGE },
1271 { "image_2d_array", 3u, SAMPLE_SOURCE_IMAGE },
1272 { "subpass_input", 1u, SAMPLE_SOURCE_SUBPASS_INPUT },
1275 // Test 1: Compare fragments fetched via FMASK and an ordinary texel fetch
1277 for (const VkSampleCountFlagBits* pSampleCount = sampleCounts; pSampleCount != DE_ARRAY_END(sampleCounts); ++pSampleCount)
1279 MovePtr<tcu::TestCaseGroup> sampleCountGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), ("samples_" + de::toString(*pSampleCount)).c_str(), ""));
1280 for (const SourceCase* pSourceCase = sourceCases; pSourceCase != DE_ARRAY_END(sourceCases); ++pSourceCase)
1282 MovePtr<tcu::TestCaseGroup> sourceGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), pSourceCase->name, ""));
1283 for (const VkFormat* pColorFormat = colorFormats; pColorFormat != DE_ARRAY_END(colorFormats); ++pColorFormat)
1286 params.renderSize = UVec2(32, 32);
1287 params.colorFormat = *pColorFormat;
1288 params.numColorSamples = *pSampleCount;
1289 params.numLayers = pSourceCase->numLayers;
1290 params.sampleSource = pSourceCase->sampleSource;
1292 addFunctionCaseWithPrograms(sourceGroup.get(), getFormatShortString(*pColorFormat), "", checkRequirements, initPrograms, test, params);
1294 sampleCountGroup->addChild(sourceGroup.release());
1296 rootGroup->addChild(sampleCountGroup.release());
1303 tcu::TestCaseGroup* createMultisampleShaderFragmentMaskTests (tcu::TestContext& testCtx)
1305 return createTestGroup(testCtx, "shader_fragment_mask", "Access raw texel values in a compressed MSAA surface", createShaderFragmentMaskTestsInGroup);