1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright 2014 The Android Open Source Project
6 * Copyright (c) 2015 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 Early fragment tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktFragmentOperationsEarlyFragmentTests.hpp"
26 #include "vktFragmentOperationsMakeUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkStrUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkImageUtil.hpp"
41 #include "tcuTestLog.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deStringUtil.hpp"
50 namespace FragmentOperations
58 inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
60 const VkImageCreateInfo imageParams =
62 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
63 DE_NULL, // const void* pNext;
64 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
65 VK_IMAGE_TYPE_2D, // VkImageType imageType;
66 format, // VkFormat format;
67 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
68 1u, // deUint32 mipLevels;
69 1u, // deUint32 arrayLayers;
70 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
71 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
72 usage, // VkImageUsageFlags usage;
73 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
74 0u, // deUint32 queueFamilyIndexCount;
75 DE_NULL, // const deUint32* pQueueFamilyIndices;
76 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
81 void beginRenderPass (const DeviceInterface& vk,
82 const VkCommandBuffer commandBuffer,
83 const VkRenderPass renderPass,
84 const VkFramebuffer framebuffer,
85 const VkRect2D& renderArea,
86 const tcu::Vec4& clearColor,
87 const float clearDepth,
88 const deUint32 clearStencil)
90 const VkClearValue clearValues[] =
92 makeClearValueColor(clearColor), // attachment 0
93 makeClearValueDepthStencil(clearDepth, clearStencil), // attachment 1
96 const VkRenderPassBeginInfo renderPassBeginInfo = {
97 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
98 DE_NULL, // const void* pNext;
99 renderPass, // VkRenderPass renderPass;
100 framebuffer, // VkFramebuffer framebuffer;
101 renderArea, // VkRect2D renderArea;
102 DE_LENGTH_OF_ARRAY(clearValues), // uint32_t clearValueCount;
103 clearValues, // const VkClearValue* pClearValues;
106 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
109 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
110 const VkDevice device,
111 const VkFormat colorFormat,
112 const bool useDepthStencilAttachment,
113 const VkFormat depthStencilFormat)
115 const VkAttachmentDescription attachments[] =
119 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
120 colorFormat, // VkFormat format;
121 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
122 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
123 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
124 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
125 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
126 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
127 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
131 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
132 depthStencilFormat, // VkFormat format;
133 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
134 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
135 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
136 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
137 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
138 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
139 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
143 const VkAttachmentReference unusedAttachmentReference =
145 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
146 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
149 const VkAttachmentReference colorAttachmentReference =
151 0u, // deUint32 attachment;
152 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
155 const VkAttachmentReference depthStencilAttachmentReference =
157 1u, // deUint32 attachment;
158 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
161 const VkAttachmentReference* pDepthStencilAttachment = (useDepthStencilAttachment ? &depthStencilAttachmentReference : &unusedAttachmentReference);
163 const VkSubpassDescription subpassDescription =
165 0u, // VkSubpassDescriptionFlags flags;
166 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
167 0u, // deUint32 inputAttachmentCount;
168 DE_NULL, // const VkAttachmentReference* pInputAttachments;
169 1u, // deUint32 colorAttachmentCount;
170 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
171 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
172 pDepthStencilAttachment, // const VkAttachmentReference* pDepthStencilAttachment;
173 0u, // deUint32 preserveAttachmentCount;
174 DE_NULL // const deUint32* pPreserveAttachments;
177 const VkRenderPassCreateInfo renderPassInfo =
179 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
180 DE_NULL, // const void* pNext;
181 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
182 (useDepthStencilAttachment ? 2u : 1u), // deUint32 attachmentCount;
183 attachments, // const VkAttachmentDescription* pAttachments;
184 1u, // deUint32 subpassCount;
185 &subpassDescription, // const VkSubpassDescription* pSubpasses;
186 0u, // deUint32 dependencyCount;
187 DE_NULL // const VkSubpassDependency* pDependencies;
190 return createRenderPass(vk, device, &renderPassInfo);
193 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
194 const VkDevice device,
195 const VkRenderPass renderPass,
196 const deUint32 attachmentCount,
197 const VkImageView* pAttachments,
198 const tcu::IVec2 size)
200 const VkFramebufferCreateInfo framebufferInfo = {
201 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
202 DE_NULL, // const void* pNext;
203 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
204 renderPass, // VkRenderPass renderPass;
205 attachmentCount, // uint32_t attachmentCount;
206 pAttachments, // const VkImageView* pAttachments;
207 static_cast<deUint32>(size.x()), // uint32_t width;
208 static_cast<deUint32>(size.y()), // uint32_t height;
209 1u, // uint32_t layers;
212 return createFramebuffer(vk, device, &framebufferInfo);
215 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
216 const VkDevice device,
217 const VkPipelineLayout pipelineLayout,
218 const VkRenderPass renderPass,
219 const VkShaderModule vertexModule,
220 const VkShaderModule fragmentModule,
221 const tcu::IVec2& renderSize,
222 const bool enableDepthTest,
223 const bool enableStencilTest)
225 const VkVertexInputBindingDescription vertexInputBindingDescription =
227 0u, // uint32_t binding;
228 sizeof(tcu::Vec4), // uint32_t stride; // Vertex is a 4-element vector XYZW, position only
229 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
232 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
234 0u, // uint32_t location;
235 0u, // uint32_t binding;
236 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
237 0u, // uint32_t offset;
240 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
242 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
243 DE_NULL, // const void* pNext;
244 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
245 1u, // uint32_t vertexBindingDescriptionCount;
246 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
247 1u, // uint32_t vertexAttributeDescriptionCount;
248 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
251 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
253 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
254 DE_NULL, // const void* pNext;
255 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
256 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
257 VK_FALSE, // VkBool32 primitiveRestartEnable;
260 const VkViewport viewport = makeViewport(
262 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
265 const VkRect2D scissor = {
267 makeExtent2D(renderSize.x(), renderSize.y()),
270 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
272 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
273 DE_NULL, // const void* pNext;
274 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
275 1u, // uint32_t viewportCount;
276 &viewport, // const VkViewport* pViewports;
277 1u, // uint32_t scissorCount;
278 &scissor, // const VkRect2D* pScissors;
281 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
283 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
286 VK_FALSE, // VkBool32 depthClampEnable;
287 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
288 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
289 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
290 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
291 VK_FALSE, // VkBool32 depthBiasEnable;
292 0.0f, // float depthBiasConstantFactor;
293 0.0f, // float depthBiasClamp;
294 0.0f, // float depthBiasSlopeFactor;
295 1.0f, // float lineWidth;
298 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
300 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
301 DE_NULL, // const void* pNext;
302 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
303 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
304 VK_FALSE, // VkBool32 sampleShadingEnable;
305 0.0f, // float minSampleShading;
306 DE_NULL, // const VkSampleMask* pSampleMask;
307 VK_FALSE, // VkBool32 alphaToCoverageEnable;
308 VK_FALSE // VkBool32 alphaToOneEnable;
311 const VkStencilOpState stencilOpState = makeStencilOpState(
312 VK_STENCIL_OP_KEEP, // stencil fail
313 VK_STENCIL_OP_KEEP, // depth & stencil pass
314 VK_STENCIL_OP_KEEP, // depth only fail
315 VK_COMPARE_OP_EQUAL, // compare op
320 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
322 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
323 DE_NULL, // const void* pNext;
324 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
325 enableDepthTest, // VkBool32 depthTestEnable;
326 VK_TRUE, // VkBool32 depthWriteEnable;
327 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
328 VK_FALSE, // VkBool32 depthBoundsTestEnable;
329 enableStencilTest, // VkBool32 stencilTestEnable;
330 stencilOpState, // VkStencilOpState front;
331 stencilOpState, // VkStencilOpState back;
332 0.0f, // float minDepthBounds;
333 1.0f, // float maxDepthBounds;
336 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
337 // Number of blend attachments must equal the number of color attachments.
338 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
340 VK_FALSE, // VkBool32 blendEnable;
341 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
342 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
343 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
344 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
345 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
346 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
347 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
350 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
352 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
353 DE_NULL, // const void* pNext;
354 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
355 VK_FALSE, // VkBool32 logicOpEnable;
356 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
357 1u, // deUint32 attachmentCount;
358 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
359 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
362 const VkPipelineShaderStageCreateInfo pShaderStages[] =
365 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
366 DE_NULL, // const void* pNext;
367 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
368 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
369 vertexModule, // VkShaderModule module;
370 "main", // const char* pName;
371 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
374 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
375 DE_NULL, // const void* pNext;
376 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
377 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
378 fragmentModule, // VkShaderModule module;
379 "main", // const char* pName;
380 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
384 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
386 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
387 DE_NULL, // const void* pNext;
388 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
389 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
390 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
391 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
392 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
393 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
394 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
395 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
396 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
397 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
398 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
399 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
400 pipelineLayout, // VkPipelineLayout layout;
401 renderPass, // VkRenderPass renderPass;
402 0u, // deUint32 subpass;
403 DE_NULL, // VkPipeline basePipelineHandle;
404 0, // deInt32 basePipelineIndex;
407 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
410 VkBufferImageCopy makeBufferImageCopy (const VkImageAspectFlags aspectFlags, const tcu::IVec2& renderSize)
412 const VkBufferImageCopy copyParams =
414 0ull, // VkDeviceSize bufferOffset;
415 0u, // deUint32 bufferRowLength;
416 0u, // deUint32 bufferImageHeight;
417 makeImageSubresourceLayers(aspectFlags, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
418 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
419 makeExtent3D(renderSize.x(), renderSize.y(), 1u), // VkExtent3D imageExtent;
424 void commandClearStencilAttachment (const DeviceInterface& vk,
425 const VkCommandBuffer commandBuffer,
426 const VkOffset2D& offset,
427 const VkExtent2D& extent,
428 const deUint32 clearValue)
430 const VkClearAttachment stencilAttachment =
432 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
433 0u, // uint32_t colorAttachment;
434 makeClearValueDepthStencil(0.0f, clearValue), // VkClearValue clearValue;
437 const VkClearRect rect =
439 { offset, extent }, // VkRect2D rect;
440 0u, // uint32_t baseArrayLayer;
441 1u, // uint32_t layerCount;
444 vk.cmdClearAttachments(commandBuffer, 1u, &stencilAttachment, 1u, &rect);
447 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
449 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
451 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
452 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT;
453 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT;
459 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, const VkPhysicalDevice device, const VkFormat format)
461 VkFormatProperties formatProps;
462 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
463 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
466 VkFormat pickSupportedDepthStencilFormat (const InstanceInterface& instanceInterface,
467 const VkPhysicalDevice device,
468 const deUint32 numFormats,
469 const VkFormat* pFormats)
471 for (deUint32 i = 0; i < numFormats; ++i)
472 if (isSupportedDepthStencilFormat(instanceInterface, device, pFormats[i]))
474 return VK_FORMAT_UNDEFINED;
479 FLAG_TEST_DEPTH = 1u << 0,
480 FLAG_TEST_STENCIL = 1u << 1,
481 FLAG_DONT_USE_TEST_ATTACHMENT = 1u << 2,
482 FLAG_DONT_USE_EARLY_FRAGMENT_TESTS = 1u << 3,
485 class EarlyFragmentTest : public TestCase
488 EarlyFragmentTest (tcu::TestContext& testCtx,
489 const std::string name,
490 const deUint32 flags);
492 void initPrograms (SourceCollections& programCollection) const;
493 TestInstance* createInstance (Context& context) const;
496 const deUint32 m_flags;
499 EarlyFragmentTest::EarlyFragmentTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags)
500 : TestCase (testCtx, name, "")
505 void EarlyFragmentTest::initPrograms (SourceCollections& programCollection) const
509 std::ostringstream src;
510 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
512 << "layout(location = 0) in highp vec4 position;\n"
514 << "out gl_PerVertex {\n"
515 << " vec4 gl_Position;\n"
518 << "void main (void)\n"
520 << " gl_Position = position;\n"
523 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
528 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
529 std::ostringstream src;
530 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
532 << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
533 << "layout(location = 0) out highp vec4 fragColor;\n"
535 << "layout(binding = 0) coherent buffer Output {\n"
539 << "void main (void)\n"
541 << " atomicAdd(sb_out.result, 1u);\n"
542 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
545 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
549 class EarlyFragmentTestInstance : public TestInstance
552 EarlyFragmentTestInstance (Context& context, const deUint32 flags);
554 tcu::TestStatus iterate (void);
564 const TestMode m_testMode;
565 const bool m_useTestAttachment;
566 const bool m_useEarlyTests;
569 EarlyFragmentTestInstance::EarlyFragmentTestInstance (Context& context, const deUint32 flags)
570 : TestInstance (context)
571 , m_testMode (flags & FLAG_TEST_DEPTH ? MODE_DEPTH :
572 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
573 , m_useTestAttachment ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
574 , m_useEarlyTests ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
576 DE_ASSERT(m_testMode != MODE_INVALID);
579 tcu::TestStatus EarlyFragmentTestInstance::iterate (void)
581 const DeviceInterface& vk = m_context.getDeviceInterface();
582 const InstanceInterface& vki = m_context.getInstanceInterface();
583 const VkDevice device = m_context.getDevice();
584 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
585 const VkQueue queue = m_context.getUniversalQueue();
586 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
587 Allocator& allocator = m_context.getDefaultAllocator();
591 const tcu::IVec2 renderSize = tcu::IVec2(32, 32);
592 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
593 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
594 const Unique<VkImage> colorImage (makeImage(vk, device, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
595 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
596 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
598 // Test attachment (depth or stencil)
599 static const VkFormat stencilFormats[] =
601 // One of the following formats must be supported, as per spec requirement.
603 VK_FORMAT_D16_UNORM_S8_UINT,
604 VK_FORMAT_D24_UNORM_S8_UINT,
605 VK_FORMAT_D32_SFLOAT_S8_UINT,
608 const VkFormat testFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
609 : VK_FORMAT_D16_UNORM); // spec requires this format to be supported
610 if (testFormat == VK_FORMAT_UNDEFINED)
611 return tcu::TestStatus::fail("Required depth/stencil format not supported");
613 if (m_useTestAttachment)
614 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(testFormat) << tcu::TestLog::EndMessage;
616 const VkImageSubresourceRange testSubresourceRange = makeImageSubresourceRange(getImageAspectFlags(testFormat), 0u, 1u, 0u, 1u);
617 const Unique<VkImage> testImage (makeImage(vk, device, makeImageCreateInfo(renderSize, testFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
618 const UniquePtr<Allocation> testImageAlloc (bindImage(vk, device, allocator, *testImage, MemoryRequirement::Any));
619 const Unique<VkImageView> testImageView (makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, testFormat, testSubresourceRange));
620 const VkImageView attachmentImages[] = { *colorImageView, *testImageView };
621 const deUint32 numUsedAttachmentImages = (m_useTestAttachment ? 2u : 1u);
625 const deUint32 numVertices = 6;
626 const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices;
627 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, makeBufferCreateInfo(vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
628 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
631 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr());
633 pVertices[0] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
634 pVertices[1] = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
635 pVertices[2] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
637 pVertices[3] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
638 pVertices[4] = tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f);
639 pVertices[5] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
641 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSizeBytes);
642 // No barrier needed, flushed memory is automatically visible
647 const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32);
648 const Unique<VkBuffer> resultBuffer (makeBuffer(vk, device, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)));
649 const UniquePtr<Allocation> resultBufferAlloc (bindBuffer(vk, device, allocator, *resultBuffer, MemoryRequirement::HostVisible));
652 deUint32* const pData = static_cast<deUint32*>(resultBufferAlloc->getHostPtr());
655 flushMappedMemoryRange(vk, device, resultBufferAlloc->getMemory(), resultBufferAlloc->getOffset(), resultBufferSizeBytes);
658 // Render result buffer (to retrieve color attachment contents)
660 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
661 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
662 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
666 const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
667 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
670 const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
671 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
672 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
674 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
675 const VkDescriptorBufferInfo resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
677 DescriptorSetUpdateBuilder()
678 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
683 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
684 const Unique<VkShaderModule> fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
685 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, testFormat));
686 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize));
687 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
688 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
689 (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL)));
690 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
691 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
696 const VkRect2D renderArea = {
698 makeExtent2D(renderSize.x(), renderSize.y()),
700 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
701 const VkDeviceSize vertexBufferOffset = 0ull;
703 beginCommandBuffer(vk, *cmdBuffer);
706 const VkImageMemoryBarrier barriers[] = {
707 makeImageMemoryBarrier(
708 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
709 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
710 *colorImage, colorSubresourceRange),
711 makeImageMemoryBarrier(
712 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
713 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
714 *testImage, testSubresourceRange),
717 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
718 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
721 // Will clear the attachments with specified depth and stencil values.
722 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 0u);
724 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
725 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
726 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
728 // Mask half of the attachment image with value that will pass the stencil test.
729 if (m_useTestAttachment && m_testMode == MODE_STENCIL)
730 commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
732 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
733 vk.cmdEndRenderPass(*cmdBuffer);
736 const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
737 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes);
739 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
740 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL);
742 const VkImageMemoryBarrier preCopyColorImageBarrier = makeImageMemoryBarrier(
743 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
744 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
745 *colorImage, colorSubresourceRange);
747 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
748 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyColorImageBarrier);
750 const VkBufferImageCopy copyRegion = makeBufferImageCopy(VK_IMAGE_ASPECT_COLOR_BIT, renderSize);
751 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ©Region);
753 const VkBufferMemoryBarrier postCopyColorBufferBarrier = makeBufferMemoryBarrier(
754 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
756 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
757 0u, DE_NULL, 1u, &postCopyColorBufferBarrier, 0u, DE_NULL);
760 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
761 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
766 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSizeBytes);
768 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc->getHostPtr());
770 tcu::TestLog& log = m_context.getTestContext().getLog();
771 log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
776 invalidateMappedMemoryRange(vk, device, resultBufferAlloc->getMemory(), resultBufferAlloc->getOffset(), resultBufferSizeBytes);
778 const int actualCounter = *static_cast<deInt32*>(resultBufferAlloc->getHostPtr());
779 const bool expectPartialResult = (m_useEarlyTests && m_useTestAttachment);
780 const int expectedCounter = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
781 const int tolerance = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3 : 0;
782 const int expectedMin = de::max(0, expectedCounter - tolerance);
783 const int expectedMax = expectedCounter + tolerance;
785 tcu::TestLog& log = m_context.getTestContext().getLog();
786 log << tcu::TestLog::Message << "Expected value"
787 << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
788 << tcu::TestLog::EndMessage;
789 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
791 if (expectedMin <= actualCounter && actualCounter <= expectedMax)
792 return tcu::TestStatus::pass("Success");
794 return tcu::TestStatus::fail("Value out of range");
798 TestInstance* EarlyFragmentTest::createInstance (Context& context) const
800 // Check required features
802 VkPhysicalDeviceFeatures features;
803 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
805 // SSBO writes in fragment shader
806 if (!features.fragmentStoresAndAtomics)
807 throw tcu::NotSupportedError("Missing required feature: fragmentStoresAndAtomics");
810 return new EarlyFragmentTestInstance(context, m_flags);
815 tcu::TestCaseGroup* createEarlyFragmentTests (tcu::TestContext& testCtx)
817 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "early_fragment", "early fragment test cases"));
821 std::string caseName;
825 { "no_early_fragment_tests_depth", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
826 { "no_early_fragment_tests_stencil", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
827 { "early_fragment_tests_depth", FLAG_TEST_DEPTH },
828 { "early_fragment_tests_stencil", FLAG_TEST_STENCIL },
829 { "no_early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT },
830 { "no_early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT },
831 { "early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_TEST_ATTACHMENT },
832 { "early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_TEST_ATTACHMENT },
835 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
836 testGroup->addChild(new EarlyFragmentTest(testCtx, cases[i].caseName, cases[i].flags));
838 return testGroup.release();
841 } // FragmentOperations