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"
40 #include "vkBarrierUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuTextureUtil.hpp"
48 #include "deUniquePtr.hpp"
49 #include "deStringUtil.hpp"
56 namespace FragmentOperations
64 inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
66 const VkImageCreateInfo imageParams =
68 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
69 DE_NULL, // const void* pNext;
70 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
71 VK_IMAGE_TYPE_2D, // VkImageType imageType;
72 format, // VkFormat format;
73 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
74 1u, // deUint32 mipLevels;
75 1u, // deUint32 arrayLayers;
76 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
77 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
78 usage, // VkImageUsageFlags usage;
79 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
80 0u, // deUint32 queueFamilyIndexCount;
81 DE_NULL, // const deUint32* pQueueFamilyIndices;
82 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
87 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
88 const VkDevice device,
89 const VkFormat colorFormat,
90 const bool useDepthStencilAttachment,
91 const VkFormat depthStencilFormat)
93 return makeRenderPass(vk, device, colorFormat, useDepthStencilAttachment ? depthStencilFormat : VK_FORMAT_UNDEFINED);
96 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
97 const VkDevice device,
98 const VkPipelineLayout pipelineLayout,
99 const VkRenderPass renderPass,
100 const VkShaderModule vertexModule,
101 const VkShaderModule fragmentModule,
102 const tcu::IVec2& renderSize,
103 const bool enableDepthTest,
104 const bool enableStencilTest,
105 const VkStencilOp stencilFailOp = VK_STENCIL_OP_KEEP,
106 const VkStencilOp stencilPassOp = VK_STENCIL_OP_KEEP)
108 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
109 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
111 const VkStencilOpState stencilOpState = makeStencilOpState(
112 stencilFailOp, // stencil fail
113 stencilPassOp, // depth & stencil pass
114 VK_STENCIL_OP_KEEP, // depth only fail
115 VK_COMPARE_OP_EQUAL, // compare op
120 VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
122 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
123 DE_NULL, // const void* pNext
124 0u, // VkPipelineDepthStencilStateCreateFlags flags
125 enableDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
126 enableDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
127 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
128 VK_FALSE, // VkBool32 depthBoundsTestEnable
129 enableStencilTest ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
130 stencilOpState, // VkStencilOpState front
131 stencilOpState, // VkStencilOpState back
132 0.0f, // float minDepthBounds
133 1.0f // float maxDepthBounds
136 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
137 device, // const VkDevice device
138 pipelineLayout, // const VkPipelineLayout pipelineLayout
139 vertexModule, // const VkShaderModule vertexShaderModule
140 DE_NULL, // const VkShaderModule tessellationControlModule
141 DE_NULL, // const VkShaderModule tessellationEvalModule
142 DE_NULL, // const VkShaderModule geometryShaderModule
143 fragmentModule, // const VkShaderModule fragmentShaderModule
144 renderPass, // const VkRenderPass renderPass
145 viewports, // const std::vector<VkViewport>& viewports
146 scissors, // const std::vector<VkRect2D>& scissors
147 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
148 0u, // const deUint32 subpass
149 0u, // const deUint32 patchControlPoints
150 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
151 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
152 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
153 &depthStencilStateCreateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
156 void commandClearStencilAttachment (const DeviceInterface& vk,
157 const VkCommandBuffer commandBuffer,
158 const VkOffset2D& offset,
159 const VkExtent2D& extent,
160 const deUint32 clearValue)
162 const VkClearAttachment stencilAttachment =
164 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
165 0u, // uint32_t colorAttachment;
166 makeClearValueDepthStencil(0.0f, clearValue), // VkClearValue clearValue;
169 const VkClearRect rect =
171 { offset, extent }, // VkRect2D rect;
172 0u, // uint32_t baseArrayLayer;
173 1u, // uint32_t layerCount;
176 vk.cmdClearAttachments(commandBuffer, 1u, &stencilAttachment, 1u, &rect);
179 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
181 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
183 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
184 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT;
185 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT;
191 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, const VkPhysicalDevice device, const VkFormat format)
193 VkFormatProperties formatProps;
194 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
195 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
198 VkFormat pickSupportedDepthStencilFormat (const InstanceInterface& instanceInterface,
199 const VkPhysicalDevice device,
200 const deUint32 numFormats,
201 const VkFormat* pFormats)
203 for (deUint32 i = 0; i < numFormats; ++i)
204 if (isSupportedDepthStencilFormat(instanceInterface, device, pFormats[i]))
206 return VK_FORMAT_UNDEFINED;
211 FLAG_TEST_DEPTH = 1u << 0,
212 FLAG_TEST_STENCIL = 1u << 1,
213 FLAG_DONT_USE_TEST_ATTACHMENT = 1u << 2,
214 FLAG_DONT_USE_EARLY_FRAGMENT_TESTS = 1u << 3,
217 class EarlyFragmentTest : public TestCase
220 EarlyFragmentTest (tcu::TestContext& testCtx,
221 const std::string name,
222 const deUint32 flags);
224 void initPrograms (SourceCollections& programCollection) const;
225 TestInstance* createInstance (Context& context) const;
226 virtual void checkSupport (Context& context) const;
229 const deUint32 m_flags;
232 EarlyFragmentTest::EarlyFragmentTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags)
233 : TestCase (testCtx, name, "")
238 void EarlyFragmentTest::initPrograms (SourceCollections& programCollection) const
242 std::ostringstream src;
243 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
245 << "layout(location = 0) in highp vec4 position;\n"
247 << "out gl_PerVertex {\n"
248 << " vec4 gl_Position;\n"
251 << "void main (void)\n"
253 << " gl_Position = position;\n"
256 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
261 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
262 std::ostringstream src;
263 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
265 << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
266 << "layout(location = 0) out highp vec4 fragColor;\n"
268 << "layout(binding = 0) coherent buffer Output {\n"
272 << "void main (void)\n"
274 << " atomicAdd(sb_out.result, 1u);\n"
275 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
278 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
282 class EarlyFragmentTestInstance : public TestInstance
285 EarlyFragmentTestInstance (Context& context, const deUint32 flags);
287 tcu::TestStatus iterate (void);
297 const TestMode m_testMode;
298 const bool m_useTestAttachment;
299 const bool m_useEarlyTests;
302 EarlyFragmentTestInstance::EarlyFragmentTestInstance (Context& context, const deUint32 flags)
303 : TestInstance (context)
304 , m_testMode (flags & FLAG_TEST_DEPTH ? MODE_DEPTH :
305 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
306 , m_useTestAttachment ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
307 , m_useEarlyTests ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
309 DE_ASSERT(m_testMode != MODE_INVALID);
312 tcu::TestStatus EarlyFragmentTestInstance::iterate (void)
314 const DeviceInterface& vk = m_context.getDeviceInterface();
315 const InstanceInterface& vki = m_context.getInstanceInterface();
316 const VkDevice device = m_context.getDevice();
317 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
318 const VkQueue queue = m_context.getUniversalQueue();
319 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
320 Allocator& allocator = m_context.getDefaultAllocator();
324 const tcu::IVec2 renderSize = tcu::IVec2(32, 32);
325 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
326 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
327 const Unique<VkImage> colorImage (makeImage(vk, device, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
328 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
329 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
331 // Test attachment (depth or stencil)
332 static const VkFormat stencilFormats[] =
334 // One of the following formats must be supported, as per spec requirement.
336 VK_FORMAT_D16_UNORM_S8_UINT,
337 VK_FORMAT_D24_UNORM_S8_UINT,
338 VK_FORMAT_D32_SFLOAT_S8_UINT,
341 const VkFormat testFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
342 : VK_FORMAT_D16_UNORM); // spec requires this format to be supported
343 if (testFormat == VK_FORMAT_UNDEFINED)
344 return tcu::TestStatus::fail("Required depth/stencil format not supported");
346 if (m_useTestAttachment)
347 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(testFormat) << tcu::TestLog::EndMessage;
349 const VkImageSubresourceRange testSubresourceRange = makeImageSubresourceRange(getImageAspectFlags(testFormat), 0u, 1u, 0u, 1u);
350 const Unique<VkImage> testImage (makeImage(vk, device, makeImageCreateInfo(renderSize, testFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
351 const UniquePtr<Allocation> testImageAlloc (bindImage(vk, device, allocator, *testImage, MemoryRequirement::Any));
352 const Unique<VkImageView> testImageView (makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, testFormat, testSubresourceRange));
353 const VkImageView attachmentImages[] = { *colorImageView, *testImageView };
354 const deUint32 numUsedAttachmentImages = (m_useTestAttachment ? 2u : 1u);
358 const deUint32 numVertices = 6;
359 const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices;
360 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
361 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
364 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr());
366 pVertices[0] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
367 pVertices[1] = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
368 pVertices[2] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
370 pVertices[3] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
371 pVertices[4] = tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f);
372 pVertices[5] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
374 flushAlloc(vk, device, *vertexBufferAlloc);
375 // No barrier needed, flushed memory is automatically visible
380 const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32);
381 const Unique<VkBuffer> resultBuffer (makeBuffer(vk, device, resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
382 const UniquePtr<Allocation> resultBufferAlloc (bindBuffer(vk, device, allocator, *resultBuffer, MemoryRequirement::HostVisible));
385 deUint32* const pData = static_cast<deUint32*>(resultBufferAlloc->getHostPtr());
388 flushAlloc(vk, device, *resultBufferAlloc);
391 // Render result buffer (to retrieve color attachment contents)
393 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
394 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
395 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
399 const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
400 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
403 const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
404 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
405 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
407 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
408 const VkDescriptorBufferInfo resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
410 DescriptorSetUpdateBuilder()
411 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
416 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
417 const Unique<VkShaderModule> fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
418 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, testFormat));
419 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize.x(), renderSize.y()));
420 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
421 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
422 (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL)));
423 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
424 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
429 const VkRect2D renderArea = {
431 makeExtent2D(renderSize.x(), renderSize.y()),
433 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
434 const VkDeviceSize vertexBufferOffset = 0ull;
436 beginCommandBuffer(vk, *cmdBuffer);
439 const VkImageMemoryBarrier barriers[] = {
440 makeImageMemoryBarrier(
441 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
442 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
443 *colorImage, colorSubresourceRange),
444 makeImageMemoryBarrier(
445 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
446 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
447 *testImage, testSubresourceRange),
450 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
451 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
454 // Will clear the attachments with specified depth and stencil values.
455 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 0u);
457 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
458 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
459 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
461 // Mask half of the attachment image with value that will pass the stencil test.
462 if (m_useTestAttachment && m_testMode == MODE_STENCIL)
463 commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
465 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
466 endRenderPass(vk, *cmdBuffer);
468 copyImageToBuffer(vk, *cmdBuffer, *colorImage, *colorBuffer, renderSize, VK_ACCESS_SHADER_WRITE_BIT);
470 endCommandBuffer(vk, *cmdBuffer);
471 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
476 invalidateAlloc(vk, device, *colorBufferAlloc);
478 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc->getHostPtr());
480 tcu::TestLog& log = m_context.getTestContext().getLog();
481 log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
486 invalidateAlloc(vk, device, *resultBufferAlloc);
488 const int actualCounter = *static_cast<deInt32*>(resultBufferAlloc->getHostPtr());
489 const bool expectPartialResult = (m_useEarlyTests && m_useTestAttachment);
490 const int expectedCounter = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
491 const int tolerance = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3 : 0;
492 const int expectedMin = de::max(0, expectedCounter - tolerance);
493 const int expectedMax = expectedCounter + tolerance;
495 tcu::TestLog& log = m_context.getTestContext().getLog();
496 log << tcu::TestLog::Message << "Expected value"
497 << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
498 << tcu::TestLog::EndMessage;
499 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
501 if (expectedMin <= actualCounter && actualCounter <= expectedMax)
502 return tcu::TestStatus::pass("Success");
504 return tcu::TestStatus::fail("Value out of range");
508 TestInstance* EarlyFragmentTest::createInstance (Context& context) const
510 return new EarlyFragmentTestInstance(context, m_flags);
513 void EarlyFragmentTest::checkSupport (Context& context) const
515 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS);
518 class EarlyFragmentDiscardTestInstance : public EarlyFragmentTestInstance
521 EarlyFragmentDiscardTestInstance (Context& context, const deUint32 flags);
523 tcu::TestStatus iterate (void);
526 tcu::TextureLevel generateReferenceColorImage (const tcu::TextureFormat format, const tcu::IVec2& renderSize);
534 const TestMode m_testMode;
535 const bool m_useTestAttachment;
536 const bool m_useEarlyTests;
539 EarlyFragmentDiscardTestInstance::EarlyFragmentDiscardTestInstance (Context& context, const deUint32 flags)
540 : EarlyFragmentTestInstance (context, flags)
541 , m_testMode (flags & FLAG_TEST_DEPTH ? MODE_DEPTH :
542 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
543 , m_useTestAttachment ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
544 , m_useEarlyTests ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
546 DE_ASSERT(m_testMode != MODE_INVALID);
549 tcu::TextureLevel EarlyFragmentDiscardTestInstance::generateReferenceColorImage(const tcu::TextureFormat format, const tcu::IVec2 &renderSize)
551 tcu::TextureLevel image(format, renderSize.x(), renderSize.y());
552 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
554 tcu::clear(image.getAccess(), clearColor);
559 tcu::TestStatus EarlyFragmentDiscardTestInstance::iterate (void)
561 const DeviceInterface& vk = m_context.getDeviceInterface();
562 const InstanceInterface& vki = m_context.getInstanceInterface();
563 const VkDevice device = m_context.getDevice();
564 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
565 const VkQueue queue = m_context.getUniversalQueue();
566 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
567 Allocator& allocator = m_context.getDefaultAllocator();
569 DE_ASSERT(m_useTestAttachment);
572 const tcu::IVec2 renderSize = tcu::IVec2(32, 32);
573 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
574 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
575 const Unique<VkImage> colorImage (makeImage(vk, device, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
576 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
577 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
579 // Test attachment (depth or stencil)
580 static const VkFormat stencilFormats[] =
582 // One of the following formats must be supported, as per spec requirement.
584 VK_FORMAT_D16_UNORM_S8_UINT,
585 VK_FORMAT_D24_UNORM_S8_UINT,
586 VK_FORMAT_D32_SFLOAT_S8_UINT,
589 const VkFormat depthStencilFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
590 : VK_FORMAT_D16_UNORM); // spec requires this format to be supported
592 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
593 return tcu::TestStatus::fail("Required depth/stencil format not supported");
595 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(depthStencilFormat) << tcu::TestLog::EndMessage;
597 const VkImageSubresourceRange testSubresourceRange = makeImageSubresourceRange(getImageAspectFlags(depthStencilFormat), 0u, 1u, 0u, 1u);
598 const Unique<VkImage> testImage (makeImage(vk, device, makeImageCreateInfo(renderSize, depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
599 const UniquePtr<Allocation> testImageAlloc (bindImage(vk, device, allocator, *testImage, MemoryRequirement::Any));
600 const Unique<VkImageView> testImageView (makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, depthStencilFormat, testSubresourceRange));
601 const VkImageView attachmentImages[] = { *colorImageView, *testImageView };
602 const deUint32 numUsedAttachmentImages = DE_LENGTH_OF_ARRAY(attachmentImages);
606 const deUint32 numVertices = 6;
607 const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices;
608 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
609 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
612 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr());
614 pVertices[0] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
615 pVertices[1] = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
616 pVertices[2] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
618 pVertices[3] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
619 pVertices[4] = tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f);
620 pVertices[5] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
622 flushAlloc(vk, device, *vertexBufferAlloc);
623 // No barrier needed, flushed memory is automatically visible
628 const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32);
629 const Unique<VkBuffer> resultBuffer (makeBuffer(vk, device, resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
630 const UniquePtr<Allocation> resultBufferAlloc (bindBuffer(vk, device, allocator, *resultBuffer, MemoryRequirement::HostVisible));
633 deUint32* const pData = static_cast<deUint32*>(resultBufferAlloc->getHostPtr());
636 flushAlloc(vk, device, *resultBufferAlloc);
639 // Render result buffer (to retrieve color attachment contents)
641 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
642 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
643 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
645 // Depth stencil result buffer (to retrieve depth-stencil attachment contents)
647 const VkDeviceSize dsBufferSizeBytes = tcu::getPixelSize(mapVkFormat(depthStencilFormat)) * renderSize.x() * renderSize.y();
648 const Unique<VkBuffer> dsBuffer (makeBuffer(vk, device, dsBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
649 const UniquePtr<Allocation> dsBufferAlloc (bindBuffer(vk, device, allocator, *dsBuffer, MemoryRequirement::HostVisible));
653 const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
654 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
657 const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
658 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
659 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
661 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
662 const VkDescriptorBufferInfo resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
664 DescriptorSetUpdateBuilder()
665 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
670 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
671 const Unique<VkShaderModule> fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
672 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, depthStencilFormat));
673 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize.x(), renderSize.y()));
674 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
675 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
676 (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL),
677 VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_INCREMENT_AND_CLAMP));
678 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
679 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
683 const VkRect2D renderArea = {
685 makeExtent2D(renderSize.x(), renderSize.y()),
687 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
688 const VkDeviceSize vertexBufferOffset = 0ull;
690 beginCommandBuffer(vk, *cmdBuffer);
693 const VkImageMemoryBarrier barriers[] = {
694 makeImageMemoryBarrier(
695 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
696 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
697 *colorImage, colorSubresourceRange),
698 makeImageMemoryBarrier(
699 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
700 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
701 *testImage, testSubresourceRange),
704 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
705 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
708 // Will clear the attachments with specified depth and stencil values.
709 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 3u);
711 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
712 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
713 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
715 // Mask half of the attachment image with value that will pass the stencil test.
716 if (m_testMode == MODE_STENCIL)
717 commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
719 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
720 endRenderPass(vk, *cmdBuffer);
722 copyImageToBuffer(vk, *cmdBuffer, *colorImage, *colorBuffer, renderSize, VK_ACCESS_SHADER_WRITE_BIT);
723 VkImageAspectFlags dsAspect = m_testMode == MODE_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
724 copyImageToBuffer(vk, *cmdBuffer, *testImage, *dsBuffer, renderSize, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, 1u, dsAspect, dsAspect);
726 endCommandBuffer(vk, *cmdBuffer);
727 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
730 // Verify color output
732 invalidateAlloc(vk, device, *colorBufferAlloc);
734 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc->getHostPtr());
735 const tcu::TextureLevel referenceImage = generateReferenceColorImage(mapVkFormat(colorFormat), renderSize);
736 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage.getAccess(), imagePixelAccess, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
737 printf("Rendered color image is not correct");
740 // Verify depth-stencil output
742 invalidateAlloc(vk, device, *dsBufferAlloc);
743 tcu::TextureFormat format = mapVkFormat(depthStencilFormat);
744 const tcu::ConstPixelBufferAccess dsPixelAccess (format, renderSize.x(), renderSize.y(), 1, dsBufferAlloc->getHostPtr());
746 for(int z = 0; z < dsPixelAccess.getDepth(); z++)
747 for(int y = 0; y < dsPixelAccess.getHeight(); y++)
748 for(int x = 0; x < dsPixelAccess.getWidth(); x++)
750 float depthValue = (m_testMode == MODE_DEPTH) ? dsPixelAccess.getPixDepth(x, y, z) : 0.0f;
751 int stencilValue = (m_testMode == MODE_STENCIL) ? dsPixelAccess.getPixStencil(x, y, z) : 0;
753 // Depth test should write to the depth buffer even when there is a discard in the fragment shader,
754 // when early fragment tests are enabled.
755 if (m_testMode == MODE_DEPTH)
757 if (m_useEarlyTests && ((x + y) < 31) && depthValue >= 0.5f)
759 std::ostringstream error;
760 error << "Rendered depth value [ "<< x << ", " << y << ", " << z << "] is not correct: " << depthValue << " >= 0.5f";
761 TCU_FAIL(error.str().c_str());
763 // When early fragment tests are disabled, the depth test happens after the fragment shader, but as we are discarding
764 // all fragments, the stored value in the depth buffer should be the clear one (0.5f).
765 if (!m_useEarlyTests && deAbs(depthValue - 0.5f) > 0.01f)
767 std::ostringstream error;
768 error << "Rendered depth value [ "<< x << ", " << y << ", " << z << "] is not correct: " << depthValue << " != 0.5f";
769 TCU_FAIL(error.str().c_str());
773 if (m_testMode == MODE_STENCIL)
775 if (m_useEarlyTests && ((x < 16 && stencilValue != 2u) || (x >= 16 && stencilValue != 4u)))
777 std::ostringstream error;
778 error << "Rendered stencil value [ "<< x << ", " << y << ", " << z << "] is not correct: " << stencilValue << " != ";
779 error << (x < 16 ? 2u : 4u);
780 TCU_FAIL(error.str().c_str());
783 if (!m_useEarlyTests && ((x < 16 && stencilValue != 1u) || (x >= 16 && stencilValue != 3u)))
785 std::ostringstream error;
786 error << "Rendered stencil value [ "<< x << ", " << y << ", " << z << "] is not correct: " << stencilValue << " != ";
787 error << (x < 16 ? 1u : 3u);
788 TCU_FAIL(error.str().c_str());
794 // Verify we process all the fragments
796 invalidateAlloc(vk, device, *resultBufferAlloc);
798 const int actualCounter = *static_cast<deInt32*>(resultBufferAlloc->getHostPtr());
799 const bool expectPartialResult = m_useEarlyTests;
800 const int expectedCounter = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
801 const int tolerance = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3 : 0;
802 const int expectedMin = de::max(0, expectedCounter - tolerance);
803 const int expectedMax = expectedCounter + tolerance;
805 tcu::TestLog& log = m_context.getTestContext().getLog();
806 log << tcu::TestLog::Message << "Expected value"
807 << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
808 << tcu::TestLog::EndMessage;
809 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
811 if (expectedMin <= actualCounter && actualCounter <= expectedMax)
812 return tcu::TestStatus::pass("Success");
814 return tcu::TestStatus::fail("Value out of range");
818 class EarlyFragmentDiscardTest : public EarlyFragmentTest
821 EarlyFragmentDiscardTest (tcu::TestContext& testCtx,
822 const std::string name,
823 const deUint32 flags);
825 void initPrograms (SourceCollections& programCollection) const;
826 TestInstance* createInstance (Context& context) const;
829 const deUint32 m_flags;
832 EarlyFragmentDiscardTest::EarlyFragmentDiscardTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags)
833 : EarlyFragmentTest (testCtx, name, flags)
838 TestInstance* EarlyFragmentDiscardTest::createInstance (Context& context) const
840 return new EarlyFragmentDiscardTestInstance(context, m_flags);
843 void EarlyFragmentDiscardTest::initPrograms(SourceCollections &programCollection) const
847 std::ostringstream src;
848 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
850 << "layout(location = 0) in highp vec4 position;\n"
852 << "out gl_PerVertex {\n"
853 << " vec4 gl_Position;\n"
856 << "void main (void)\n"
858 << " gl_Position = position;\n"
861 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
866 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
867 std::ostringstream src;
868 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
870 << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
871 << "layout(location = 0) out highp vec4 fragColor;\n"
873 << "layout(binding = 0) coherent buffer Output {\n"
877 << "void main (void)\n"
879 << " atomicAdd(sb_out.result, 1u);\n"
880 << " gl_FragDepth = 0.75f;\n"
881 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
885 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
889 class EarlyFragmentSampleMaskTestInstance : public EarlyFragmentTestInstance
892 EarlyFragmentSampleMaskTestInstance (Context& context, const deUint32 flags, const deUint32 sampleCount);
894 tcu::TestStatus iterate (void);
897 tcu::TextureLevel generateReferenceColorImage (const tcu::TextureFormat format, const tcu::IVec2& renderSize);
898 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
899 const VkDevice device,
900 const VkFormat colorFormat,
901 const VkFormat depthStencilFormat);
902 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
903 const VkDevice device,
904 const VkPipelineLayout pipelineLayout,
905 const VkRenderPass renderPass,
906 const VkShaderModule vertexModule,
907 const VkShaderModule fragmentModule,
908 const tcu::IVec2& renderSize,
909 const bool enableDepthTest,
910 const bool enableStencilTest,
911 const VkStencilOp stencilFailOp,
912 const VkStencilOp stencilPassOp);
920 const TestMode m_testMode;
921 const bool m_useTestAttachment;
922 const bool m_useEarlyTests;
923 const deUint32 m_sampleCount;
926 EarlyFragmentSampleMaskTestInstance::EarlyFragmentSampleMaskTestInstance (Context& context, const deUint32 flags, const deUint32 sampleCount)
927 : EarlyFragmentTestInstance (context, flags)
928 , m_testMode (flags & FLAG_TEST_DEPTH ? MODE_DEPTH :
929 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
930 , m_useTestAttachment ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
931 , m_useEarlyTests ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
932 , m_sampleCount (sampleCount)
934 DE_ASSERT(m_testMode != MODE_INVALID);
937 tcu::TextureLevel EarlyFragmentSampleMaskTestInstance::generateReferenceColorImage(const tcu::TextureFormat format, const tcu::IVec2 &renderSize)
939 tcu::TextureLevel image(format, renderSize.x(), renderSize.y());
940 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
942 tcu::clear(image.getAccess(), clearColor);
947 Move<VkPipeline> EarlyFragmentSampleMaskTestInstance::makeGraphicsPipeline (const DeviceInterface& vk,
948 const VkDevice device,
949 const VkPipelineLayout pipelineLayout,
950 const VkRenderPass renderPass,
951 const VkShaderModule vertexModule,
952 const VkShaderModule fragmentModule,
953 const tcu::IVec2& renderSize,
954 const bool enableDepthTest,
955 const bool enableStencilTest,
956 const VkStencilOp stencilFailOp,
957 const VkStencilOp stencilPassOp)
959 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
960 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
962 const VkStencilOpState stencilOpState = makeStencilOpState(
963 stencilFailOp, // stencil fail
964 stencilPassOp, // depth & stencil pass
965 VK_STENCIL_OP_KEEP, // depth only fail
966 VK_COMPARE_OP_EQUAL, // compare op
971 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
973 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
974 DE_NULL, // const void* pNext
975 0u, // VkPipelineDepthStencilStateCreateFlags flags
976 enableDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
977 enableDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
978 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
979 VK_FALSE, // VkBool32 depthBoundsTestEnable
980 enableStencilTest ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
981 stencilOpState, // VkStencilOpState front
982 stencilOpState, // VkStencilOpState back
983 0.0f, // float minDepthBounds
984 1.0f // float maxDepthBounds
987 // Only allow coverage on sample 0.
988 const VkSampleMask sampleMask = 0x1;
990 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
992 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
993 DE_NULL, // const void* pNext
994 0u, // VkPipelineMultisampleStateCreateFlags flags
995 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits rasterizationSamples
996 DE_TRUE, // VkBool32 sampleShadingEnable
997 0.0f, // float minSampleShading
998 &sampleMask, // const VkSampleMask* pSampleMask
999 DE_FALSE, // VkBool32 alphaToCoverageEnable
1000 DE_FALSE, // VkBool32 alphaToOneEnable
1003 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
1004 device, // const VkDevice device
1005 pipelineLayout, // const VkPipelineLayout pipelineLayout
1006 vertexModule, // const VkShaderModule vertexShaderModule
1007 DE_NULL, // const VkShaderModule tessellationControlModule
1008 DE_NULL, // const VkShaderModule tessellationEvalModule
1009 DE_NULL, // const VkShaderModule geometryShaderModule
1010 fragmentModule, // const VkShaderModule fragmentShaderModule
1011 renderPass, // const VkRenderPass renderPass
1012 viewports, // const std::vector<VkViewport>& viewports
1013 scissors, // const std::vector<VkRect2D>& scissors
1014 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1015 0u, // const deUint32 subpass
1016 0u, // const deUint32 patchControlPoints
1017 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1018 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1019 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1020 &depthStencilStateCreateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1023 Move<VkRenderPass> EarlyFragmentSampleMaskTestInstance::makeRenderPass (const DeviceInterface& vk,
1024 const VkDevice device,
1025 const VkFormat colorFormat,
1026 const VkFormat depthStencilFormat)
1028 const bool hasColor = colorFormat != VK_FORMAT_UNDEFINED;
1029 const bool hasDepthStencil = depthStencilFormat != VK_FORMAT_UNDEFINED;
1032 const VkAttachmentDescription2 colorAttachmentDescription =
1034 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1035 DE_NULL, // const void* pNext;
1036 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
1037 colorFormat, // VkFormat format
1038 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples
1039 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
1040 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
1041 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
1042 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
1043 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
1044 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
1047 const VkAttachmentDescription2 depthStencilAttachmentDescription =
1049 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1050 DE_NULL, // const void* pNext;
1051 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
1052 depthStencilFormat, // VkFormat format
1053 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples
1054 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
1055 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
1056 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp
1057 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
1058 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
1059 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
1062 const VkAttachmentDescription2 resolveAttachmentDescription =
1064 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1065 DE_NULL, // const void* pNext;
1066 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
1067 colorFormat, // VkFormat format
1068 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1069 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
1070 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
1071 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
1072 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
1073 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
1074 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
1077 const VkAttachmentDescription2 resolveDepthStencilAttachmentDescription =
1079 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1080 DE_NULL, // const void* pNext;
1081 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
1082 depthStencilFormat, // VkFormat format
1083 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1084 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
1085 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
1086 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp
1087 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
1088 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
1089 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
1092 std::vector<VkAttachmentDescription2> attachmentDescriptions;
1095 attachmentDescriptions.push_back(colorAttachmentDescription);
1096 if (hasDepthStencil)
1097 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
1099 attachmentDescriptions.push_back(resolveAttachmentDescription);
1100 if (hasDepthStencil)
1101 attachmentDescriptions.push_back(resolveDepthStencilAttachmentDescription);
1103 const VkAttachmentReference2 colorAttachmentRef =
1105 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType;
1106 DE_NULL, // const void* pNext;
1107 0u, // deUint32 attachment
1108 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
1109 VK_IMAGE_ASPECT_COLOR_BIT // VkImageAspectFlags aspectMask;
1112 const VkAttachmentReference2 depthStencilAttachmentRef =
1114 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType;
1115 DE_NULL, // const void* pNext;
1116 hasDepthStencil ? 1u : 0u, // deUint32 attachment
1117 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, // VkImageLayout layout
1118 m_testMode == MODE_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT // VkImageAspectFlags aspectMask;
1121 const VkAttachmentReference2 resolveAttachmentRef =
1123 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType;
1124 DE_NULL, // const void* pNext;
1125 hasColor ? 2u : 0u, // deUint32 attachment
1126 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
1127 VK_IMAGE_ASPECT_COLOR_BIT // VkImageAspectFlags aspectMask;
1130 const VkAttachmentReference2 depthStencilResolveAttachmentRef =
1132 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType;
1133 DE_NULL, // const void* pNext;
1134 hasDepthStencil ? 3u : 0u, // deUint32 attachment
1135 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, // VkImageLayout layout
1136 m_testMode == MODE_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT // VkImageAspectFlags aspectMask;
1139 // Using VK_RESOLVE_MODE_SAMPLE_ZERO_BIT as resolve mode, so no need to check its support as it is mandatory in the extension.
1140 const VkSubpassDescriptionDepthStencilResolve depthStencilResolveDescription =
1142 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, // VkStructureType sType;
1143 DE_NULL, // const void* pNext;
1144 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, // VkResolveModeFlagBits depthResolveMode;
1145 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, // VkResolveModeFlagBits stencilResolveMode;
1146 &depthStencilResolveAttachmentRef // const VkAttachmentReference2* pDepthStencilResolveAttachment;
1149 const VkSubpassDescription2 subpassDescription =
1151 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // VkStructureType sType;
1152 hasDepthStencil ? &depthStencilResolveDescription : DE_NULL, // const void* pNext;
1153 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
1154 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
1155 0u, // deUint32 viewMask;
1156 0u, // deUint32 inputAttachmentCount
1157 DE_NULL, // const VkAttachmentReference2* pInputAttachments
1158 hasColor ? 1u : 0u, // deUint32 colorAttachmentCount
1159 hasColor ? &colorAttachmentRef : DE_NULL, // const VkAttachmentReference2* pColorAttachments
1160 hasColor ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference2* pResolveAttachments
1161 hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL, // const VkAttachmentReference2* pDepthStencilAttachment
1162 0u, // deUint32 preserveAttachmentCount
1163 DE_NULL // const deUint32* pPreserveAttachments
1166 const VkRenderPassCreateInfo2 renderPassInfo =
1168 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // VkStructureType sType
1169 DE_NULL, // const void* pNext
1170 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
1171 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
1172 attachmentDescriptions.size() > 0 ? &attachmentDescriptions[0] : DE_NULL, // const VkAttachmentDescription2* pAttachments
1173 1u, // deUint32 subpassCount
1174 &subpassDescription, // const VkSubpassDescription2* pSubpasses
1175 0u, // deUint32 dependencyCount
1176 DE_NULL, // const VkSubpassDependency* pDependencies
1177 0u, // deUint32 correlatedViewMaskCount;
1178 DE_NULL, // const deUint32* pCorrelatedViewMasks;
1181 return createRenderPass2(vk, device, &renderPassInfo, DE_NULL);
1184 tcu::TestStatus EarlyFragmentSampleMaskTestInstance::iterate (void)
1186 const DeviceInterface& vk = m_context.getDeviceInterface();
1187 const InstanceInterface& vki = m_context.getInstanceInterface();
1188 const VkDevice device = m_context.getDevice();
1189 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1190 const VkQueue queue = m_context.getUniversalQueue();
1191 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1192 Allocator& allocator = m_context.getDefaultAllocator();
1193 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1195 DE_ASSERT(m_useTestAttachment);
1196 DE_UNREF(m_useTestAttachment);
1198 // Test attachment (depth or stencil)
1199 static const VkFormat stencilFormats[] =
1201 // One of the following formats must be supported, as per spec requirement.
1203 VK_FORMAT_D16_UNORM_S8_UINT,
1204 VK_FORMAT_D24_UNORM_S8_UINT,
1205 VK_FORMAT_D32_SFLOAT_S8_UINT,
1208 const VkFormat depthStencilFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
1209 : VK_FORMAT_D16_UNORM); // spec requires this format to be supported
1211 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
1212 return tcu::TestStatus::fail("Required depth/stencil format not supported");
1214 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(depthStencilFormat) << tcu::TestLog::EndMessage;
1216 // Check support for MSAA image formats used in the test.
1217 VkImageFormatProperties formatProperties;
1218 vki.getPhysicalDeviceImageFormatProperties(physDevice, colorFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0u, &formatProperties);
1219 if ((formatProperties.sampleCounts & m_sampleCount) == 0)
1220 TCU_THROW(NotSupportedError, "Format does not support this number of samples for color format");
1222 vki.getPhysicalDeviceImageFormatProperties(physDevice, depthStencilFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0u, &formatProperties);
1223 if ((formatProperties.sampleCounts & m_sampleCount) == 0)
1224 TCU_THROW(NotSupportedError, "Format does not support this number of samples for depth-stencil format");
1227 const tcu::IVec2 renderSize = tcu::IVec2(32, 32);
1228 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1230 const VkImageCreateInfo imageParams =
1232 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1233 DE_NULL, // const void* pNext;
1234 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
1235 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1236 colorFormat, // VkFormat format;
1237 makeExtent3D(renderSize.x(), renderSize.y(), 1), // VkExtent3D extent;
1238 1u, // deUint32 mipLevels;
1239 1u, // deUint32 arrayLayers;
1240 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples;
1241 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1242 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1243 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1244 0u, // deUint32 queueFamilyIndexCount;
1245 DE_NULL, // const deUint32* pQueueFamilyIndices;
1246 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1248 const Unique<VkImage> colorImage (makeImage(vk, device, imageParams));
1249 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1250 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
1252 const Unique<VkImage> resolveColorImage (makeImage(vk, device, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
1253 const UniquePtr<Allocation> resolveColorImageAlloc (bindImage(vk, device, allocator, *resolveColorImage, MemoryRequirement::Any));
1254 const Unique<VkImageView> resolveColorImageView (makeImageView(vk, device, *resolveColorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
1256 // Depth-Stencil attachment
1257 const VkImageSubresourceRange depthStencilSubresourceRange = makeImageSubresourceRange(getImageAspectFlags(depthStencilFormat), 0u, 1u, 0u, 1u);
1259 const VkImageCreateInfo depthStencilImageParams =
1261 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1262 DE_NULL, // const void* pNext;
1263 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
1264 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1265 depthStencilFormat, // VkFormat format;
1266 makeExtent3D(renderSize.x(), renderSize.y(), 1), // VkExtent3D extent;
1267 1u, // deUint32 mipLevels;
1268 1u, // deUint32 arrayLayers;
1269 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples;
1270 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1271 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1272 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1273 0u, // deUint32 queueFamilyIndexCount;
1274 DE_NULL, // const deUint32* pQueueFamilyIndices;
1275 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1277 const Unique<VkImage> depthStencilImage (makeImage(vk, device, depthStencilImageParams));
1278 const UniquePtr<Allocation> depthStencilImageAlloc (bindImage(vk, device, allocator, *depthStencilImage, MemoryRequirement::Any));
1279 const Unique<VkImageView> depthStencilImageView (makeImageView(vk, device, *depthStencilImage, VK_IMAGE_VIEW_TYPE_2D, depthStencilFormat, depthStencilSubresourceRange));
1281 const Unique<VkImage> resolveDepthStencilImage (makeImage(vk, device, makeImageCreateInfo(renderSize, depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
1282 const UniquePtr<Allocation> resolveDepthStencilImageAlloc (bindImage(vk, device, allocator, *resolveDepthStencilImage, MemoryRequirement::Any));
1283 const Unique<VkImageView> resolveDepthStencilImageView (makeImageView(vk, device, *resolveDepthStencilImage, VK_IMAGE_VIEW_TYPE_2D, depthStencilFormat, depthStencilSubresourceRange));
1285 const VkImageView attachmentImages[] = { *colorImageView, *depthStencilImageView, *resolveColorImageView, *resolveDepthStencilImageView };
1286 const deUint32 numUsedAttachmentImages = DE_LENGTH_OF_ARRAY(attachmentImages);
1290 const deUint32 numVertices = 6u;
1291 const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices;
1292 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1293 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1296 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr());
1298 pVertices[0] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
1299 pVertices[1] = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
1300 pVertices[2] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
1302 pVertices[3] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f);
1303 pVertices[4] = tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f);
1304 pVertices[5] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f);
1306 flushAlloc(vk, device, *vertexBufferAlloc);
1307 // No barrier needed, flushed memory is automatically visible
1312 const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32);
1313 const Unique<VkBuffer> resultBuffer (makeBuffer(vk, device, resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
1314 const UniquePtr<Allocation> resultBufferAlloc (bindBuffer(vk, device, allocator, *resultBuffer, MemoryRequirement::HostVisible));
1317 deUint32* const pData = static_cast<deUint32*>(resultBufferAlloc->getHostPtr());
1320 flushAlloc(vk, device, *resultBufferAlloc);
1323 // Render result buffer (to retrieve color attachment contents)
1325 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
1326 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1327 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1329 // Depth stencil result buffer (to retrieve depth-stencil attachment contents)
1331 const VkDeviceSize dsBufferSizeBytes = tcu::getPixelSize(mapVkFormat(depthStencilFormat)) * renderSize.x() * renderSize.y();
1332 const Unique<VkBuffer> dsBuffer (makeBuffer(vk, device, dsBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1333 const UniquePtr<Allocation> dsBufferAlloc (bindBuffer(vk, device, allocator, *dsBuffer, MemoryRequirement::HostVisible));
1337 const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
1338 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
1339 .build(vk, device));
1341 const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
1342 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1343 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1345 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1346 const VkDescriptorBufferInfo resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
1348 DescriptorSetUpdateBuilder()
1349 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
1350 .update(vk, device);
1354 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1355 const Unique<VkShaderModule> fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1357 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat, depthStencilFormat));
1358 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize.x(), renderSize.y()));
1359 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
1360 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
1361 (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL),
1362 VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_INCREMENT_AND_CLAMP));
1363 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1364 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1369 const VkRect2D renderArea = {
1371 makeExtent2D(renderSize.x(), renderSize.y()),
1373 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1374 const VkDeviceSize vertexBufferOffset = 0ull;
1376 beginCommandBuffer(vk, *cmdBuffer);
1379 const VkImageMemoryBarrier barriers[] = {
1380 makeImageMemoryBarrier(
1381 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1382 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1383 *colorImage, colorSubresourceRange),
1384 makeImageMemoryBarrier(
1385 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1386 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1387 *depthStencilImage, depthStencilSubresourceRange),
1388 makeImageMemoryBarrier(
1389 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1390 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1391 *resolveColorImage, colorSubresourceRange),
1392 makeImageMemoryBarrier(
1393 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1394 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1395 *resolveDepthStencilImage, depthStencilSubresourceRange),
1398 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
1399 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
1402 // Will clear the attachments with specified depth and stencil values.
1404 const VkClearValue clearValues[] =
1406 makeClearValueColor(clearColor), // attachment 0
1407 makeClearValueDepthStencil(0.5f, 3u), // attachment 1
1408 makeClearValueColor(clearColor), // attachment 2
1409 makeClearValueDepthStencil(0.5f, 3u), // attachment 3
1412 const VkRenderPassBeginInfo renderPassBeginInfo =
1414 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1415 DE_NULL, // const void* pNext;
1416 *renderPass, // VkRenderPass renderPass;
1417 *framebuffer, // VkFramebuffer framebuffer;
1418 renderArea, // VkRect2D renderArea;
1419 DE_LENGTH_OF_ARRAY(clearValues), // deUint32 clearValueCount;
1420 clearValues, // const VkClearValue* pClearValues;
1423 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1426 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1427 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
1428 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
1430 // Mask half of the attachment image with value that will pass the stencil test.
1431 if (m_testMode == MODE_STENCIL)
1432 commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
1434 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
1435 endRenderPass(vk, *cmdBuffer);
1437 copyImageToBuffer(vk, *cmdBuffer, *resolveColorImage, *colorBuffer, renderSize, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1438 VkImageAspectFlags dsAspect = m_testMode == MODE_DEPTH ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
1439 copyImageToBuffer(vk, *cmdBuffer, *resolveDepthStencilImage, *dsBuffer, renderSize, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1u, dsAspect, dsAspect);
1441 endCommandBuffer(vk, *cmdBuffer);
1442 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1445 // Verify color output
1447 invalidateAlloc(vk, device, *colorBufferAlloc);
1449 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc->getHostPtr());
1450 const tcu::TextureLevel referenceImage = generateReferenceColorImage(mapVkFormat(colorFormat), renderSize);
1451 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage.getAccess(), imagePixelAccess, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
1452 printf("Rendered color image is not correct");
1455 // Verify depth-stencil output
1457 invalidateAlloc(vk, device, *dsBufferAlloc);
1458 tcu::TextureFormat format = mapVkFormat(depthStencilFormat);
1459 const tcu::ConstPixelBufferAccess dsPixelAccess (format, renderSize.x(), renderSize.y(), 1, dsBufferAlloc->getHostPtr());
1461 for(int z = 0; z < dsPixelAccess.getDepth(); z++)
1462 for(int y = 0; y < dsPixelAccess.getHeight(); y++)
1463 for(int x = 0; x < dsPixelAccess.getWidth(); x++)
1465 float depthValue = (m_testMode == MODE_DEPTH) ? dsPixelAccess.getPixDepth(x, y, z) : 0.0f;
1466 int stencilValue = (m_testMode == MODE_STENCIL) ? dsPixelAccess.getPixStencil(x, y, z) : 0;
1468 // Depth test should write to the depth buffer even when there is a discard in the fragment shader,
1469 // when early fragment tests are enabled.
1470 if (m_testMode == MODE_DEPTH)
1472 if (m_useEarlyTests && ((x + y) < 31) && depthValue >= 0.5f)
1474 std::ostringstream error;
1475 error << "Rendered depth value [ "<< x << ", " << y << ", " << z << "] is not correct: " << depthValue << " >= 0.5f";
1476 TCU_FAIL(error.str().c_str());
1478 // When early fragment tests are disabled, the depth test happens after the fragment shader, but as we are discarding
1479 // all fragments, the stored value in the depth buffer should be the clear one (0.5f).
1480 if (!m_useEarlyTests && deAbs(depthValue - 0.5f) > 0.01f)
1482 std::ostringstream error;
1483 error << "Rendered depth value [ "<< x << ", " << y << ", " << z << "] is not correct: " << depthValue << " != 0.5f";
1484 TCU_FAIL(error.str().c_str());
1488 if (m_testMode == MODE_STENCIL)
1490 if (m_useEarlyTests && ((x < 16 && stencilValue != 2u) || (x >= 16 && stencilValue != 4u)))
1492 std::ostringstream error;
1493 error << "Rendered stencil value [ "<< x << ", " << y << ", " << z << "] is not correct: " << stencilValue << " != ";
1494 error << (x < 16 ? 2u : 4u);
1495 TCU_FAIL(error.str().c_str());
1498 if (!m_useEarlyTests && ((x < 16 && stencilValue != 1u) || (x >= 16 && stencilValue != 3u)))
1500 std::ostringstream error;
1501 error << "Rendered stencil value [ "<< x << ", " << y << ", " << z << "] is not correct: " << stencilValue << " != ";
1502 error << (x < 16 ? 1u : 3u);
1503 TCU_FAIL(error.str().c_str());
1509 // Verify we process all the fragments
1511 invalidateAlloc(vk, device, *resultBufferAlloc);
1513 const int actualCounter = *static_cast<deInt32*>(resultBufferAlloc->getHostPtr());
1514 const bool expectPartialResult = m_useEarlyTests;
1515 const int expectedCounter = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
1516 const int tolerance = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3 : 0;
1517 const int expectedMin = de::max(0, expectedCounter - tolerance);
1518 const int expectedMax = expectedCounter + tolerance;
1520 tcu::TestLog& log = m_context.getTestContext().getLog();
1521 log << tcu::TestLog::Message << "Expected value"
1522 << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
1523 << tcu::TestLog::EndMessage;
1524 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
1526 if (expectedMin <= actualCounter && actualCounter <= expectedMax)
1527 return tcu::TestStatus::pass("Success");
1529 return tcu::TestStatus::fail("Value out of range");
1533 class EarlyFragmentSampleMaskTest : public EarlyFragmentTest
1536 EarlyFragmentSampleMaskTest (tcu::TestContext& testCtx,
1537 const std::string name,
1538 const deUint32 flags,
1539 const deUint32 sampleCount);
1541 void initPrograms (SourceCollections& programCollection) const override;
1542 TestInstance* createInstance (Context& context) const override;
1543 void checkSupport (Context& context) const override;
1546 const deUint32 m_flags;
1547 const deUint32 m_sampleCount;
1550 EarlyFragmentSampleMaskTest::EarlyFragmentSampleMaskTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags, const deUint32 sampleCount)
1551 : EarlyFragmentTest (testCtx, name, flags)
1553 , m_sampleCount (sampleCount)
1557 TestInstance* EarlyFragmentSampleMaskTest::createInstance (Context& context) const
1559 return new EarlyFragmentSampleMaskTestInstance(context, m_flags, m_sampleCount);
1562 void EarlyFragmentSampleMaskTest::initPrograms(SourceCollections &programCollection) const
1566 std::ostringstream src;
1567 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1569 << "layout(location = 0) in highp vec4 position;\n"
1571 << "out gl_PerVertex {\n"
1572 << " vec4 gl_Position;\n"
1575 << "void main (void)\n"
1577 << " gl_Position = position;\n"
1580 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1585 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
1586 std::ostringstream src;
1587 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1589 << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
1590 << "layout(location = 0) out highp vec4 fragColor;\n"
1592 << "layout(binding = 0) coherent buffer Output {\n"
1593 << " uint result;\n"
1596 << "void main (void)\n"
1598 << " atomicAdd(sb_out.result, 1u);\n"
1599 << " gl_SampleMask[0] = 0x0;\n"
1600 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
1604 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1608 void EarlyFragmentSampleMaskTest::checkSupport(Context& context) const
1610 EarlyFragmentTest::checkSupport(context);
1612 context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1617 tcu::TestCaseGroup* createEarlyFragmentTests (tcu::TestContext& testCtx)
1619 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "early_fragment", "early fragment test cases"));
1624 std::string caseName;
1628 { "no_early_fragment_tests_depth", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
1629 { "no_early_fragment_tests_stencil", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
1630 { "early_fragment_tests_depth", FLAG_TEST_DEPTH },
1631 { "early_fragment_tests_stencil", FLAG_TEST_STENCIL },
1632 { "no_early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT },
1633 { "no_early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT },
1634 { "early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_TEST_ATTACHMENT },
1635 { "early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_TEST_ATTACHMENT },
1638 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
1639 testGroup->addChild(new EarlyFragmentTest(testCtx, cases[i].caseName, cases[i].flags));
1642 // Check that discard does not affect depth test writes.
1646 std::string caseName;
1650 { "discard_no_early_fragment_tests_depth", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
1651 { "discard_no_early_fragment_tests_stencil", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS },
1652 { "discard_early_fragment_tests_depth", FLAG_TEST_DEPTH },
1653 { "discard_early_fragment_tests_stencil", FLAG_TEST_STENCIL },
1656 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
1657 testGroup->addChild(new EarlyFragmentDiscardTest(testCtx, cases[i].caseName, cases[i].flags));
1660 // Check that writing to gl_SampleMask does not affect depth test writes.
1664 std::string caseName;
1668 { "samplemask_no_early_fragment_tests_depth", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS, },
1669 { "samplemask_early_fragment_tests_depth", FLAG_TEST_DEPTH, },
1672 const VkSampleCountFlags sampleCounts[] = { VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, VK_SAMPLE_COUNT_16_BIT };
1673 const std::string sampleCountsStr[] = { "samples_2", "samples_4", "samples_8", "samples_16" };
1675 for (deUint32 sampleCountsNdx = 0; sampleCountsNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountsNdx++)
1677 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
1678 testGroup->addChild(new EarlyFragmentSampleMaskTest(testCtx, cases[i].caseName + "_" + sampleCountsStr[sampleCountsNdx], cases[i].flags, sampleCounts[sampleCountsNdx]));
1682 return testGroup.release();
1685 } // FragmentOperations