1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Shader builtin variable tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktShaderRenderBuiltinVarTests.hpp"
28 #include "tcuFloat.hpp"
29 #include "deUniquePtr.hpp"
31 #include "vktShaderRender.hpp"
32 #include "gluShaderUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuStringTemplate.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuTestLog.hpp"
37 #include "vktDrawUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "vkCmdUtil.hpp"
44 #include "deRandom.hpp"
55 using namespace drawutil;
65 FRONTFACE_RENDERWIDTH = 16,
66 FRONTFACE_RENDERHEIGHT = 16
69 class FrontFacingVertexShader : public rr::VertexShader
72 FrontFacingVertexShader (void)
73 : rr::VertexShader(1, 0)
75 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
78 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
80 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
82 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
83 packets[packetNdx]->instanceNdx,
84 packets[packetNdx]->vertexNdx);
89 class FrontFacingFragmentShader : public rr::FragmentShader
92 FrontFacingFragmentShader (void)
93 : rr::FragmentShader(0, 1)
95 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
98 void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const
101 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
103 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
105 if (context.visibleFace == rr::FACETYPE_FRONT)
106 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
108 color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
109 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
115 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
118 BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology);
120 TestStatus iterate (void);
122 const VkPrimitiveTopology m_topology;
125 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology)
126 : ShaderRenderCaseInstance (context)
127 , m_topology (topology)
132 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
134 TestLog& log = m_context.getTestContext().getLog();
135 std::vector<Vec4> vertices;
136 std::vector<VulkanShader> shaders;
137 std::shared_ptr<rr::VertexShader> vertexShader = std::make_shared<FrontFacingVertexShader>();
138 std::shared_ptr<rr::FragmentShader> fragmentShader = std::make_shared<FrontFacingFragmentShader>();
139 std::string testDesc;
141 vertices.push_back(Vec4( -0.75f, -0.75f, 0.0f, 1.0f));
142 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f));
143 vertices.push_back(Vec4( -0.37f, 0.75f, 0.0f, 1.0f));
144 vertices.push_back(Vec4( 0.37f, 0.75f, 0.0f, 1.0f));
145 vertices.push_back(Vec4( 0.75f, -0.75f, 0.0f, 1.0f));
146 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f));
148 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert")));
149 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("frag")));
151 testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " ";
153 FrameBufferState frameBufferState (FRONTFACE_RENDERWIDTH, FRONTFACE_RENDERHEIGHT);
154 PipelineState pipelineState (m_context.getDeviceProperties().limits.subPixelPrecisionBits);
155 DrawCallData drawCallData (m_topology, vertices);
156 VulkanProgram vulkanProgram (shaders);
157 VulkanDrawContext dc (m_context, frameBufferState);
158 dc.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
161 ReferenceDrawContext refDrawContext(frameBufferState);
162 refDrawContext.registerDrawObject(pipelineState, vertexShader, fragmentShader, drawCallData);
163 refDrawContext.draw();
165 log << TestLog::Image( "reference",
167 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
168 refDrawContext.getColorPixels().getFormat()),
169 refDrawContext.getColorPixels().getWidth(),
170 refDrawContext.getColorPixels().getHeight(),
172 refDrawContext.getColorPixels().getDataPtr()));
174 log << TestLog::Image( "result",
176 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
177 dc.getColorPixels().getFormat()),
178 dc.getColorPixels().getWidth(),
179 dc.getColorPixels().getHeight(),
181 dc.getColorPixels().getDataPtr()));
183 if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
185 "Image comparison result",
186 refDrawContext.getColorPixels(),
191 tcu::COMPARE_LOG_RESULT))
193 testDesc += "passed";
194 return tcu::TestStatus::pass(testDesc.c_str());
198 testDesc += "failed";
199 return tcu::TestStatus::fail(testDesc.c_str());
203 class BuiltinGlFrontFacingCase : public TestCase
206 BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description);
207 virtual ~BuiltinGlFrontFacingCase (void);
209 void initPrograms (SourceCollections& dst) const;
210 void checkSupport (Context& context) const;
211 TestInstance* createInstance (Context& context) const;
214 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed!
215 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed!
217 const VkPrimitiveTopology m_topology;
220 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description)
221 : TestCase (testCtx, name, description)
222 , m_topology (topology)
226 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
230 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const
233 std::ostringstream vertexSource;
234 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
236 << "layout(location = 0) in highp vec4 position;\n"
239 << "gl_Position = position;\n"
240 << "gl_PointSize = 1.0;\n"
242 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str());
246 std::ostringstream fragmentSource;
247 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
249 << "layout(location = 0) out mediump vec4 color;\n"
252 << "if (gl_FrontFacing)\n"
253 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
255 << " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
257 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str());
261 void BuiltinGlFrontFacingCase::checkSupport (Context& context) const
263 #ifndef CTS_USES_VULKANSC
264 if (m_topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
265 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
266 !context.getPortabilitySubsetFeatures().triangleFans)
268 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
272 #endif // CTS_USES_VULKANSC
275 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
277 return new BuiltinGlFrontFacingCaseInstance(context, m_topology);
280 class BuiltinFragDepthCaseInstance : public TestInstance
288 BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples);
289 TestStatus iterate (void);
291 bool validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const;
293 const VkPrimitiveTopology m_topology;
294 const VkFormat m_format;
295 const bool m_largeDepthEnable;
296 const float m_defaultDepthValue;
297 const bool m_depthClampEnable;
298 const VkSampleCountFlagBits m_samples;
299 const tcu::UVec2 m_renderSize;
300 const float m_largeDepthBase;
303 BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples)
304 : TestInstance (context)
305 , m_topology (topology)
307 , m_largeDepthEnable (largeDepthEnable)
308 , m_defaultDepthValue (defaultDepth)
309 , m_depthClampEnable (depthClampEnable)
310 , m_samples (samples)
311 , m_renderSize (RENDERWIDTH, RENDERHEIGHT)
312 , m_largeDepthBase (20.0f)
314 const InstanceInterface& vki = m_context.getInstanceInterface();
315 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
319 VkImageFormatProperties imageFormatProperties;
320 VkFormatProperties formatProperties;
322 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
323 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
325 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
326 throw tcu::NotSupportedError("sampleRateShading not supported");
328 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D,
329 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0);
331 if ((imageFormatProperties.sampleCounts & m_samples) == 0)
332 throw tcu::NotSupportedError("Image format and sample count not supported");
334 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT);
336 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
337 throw tcu::NotSupportedError("MarkerImage format not supported as storage image");
339 if (m_largeDepthEnable && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted"))
340 throw tcu::NotSupportedError("large_depth test variants require the VK_EXT_depth_range_unrestricted extension");
342 if (m_context.getDeviceFeatures().depthClamp == VK_FALSE && m_depthClampEnable)
343 throw tcu::NotSupportedError("Depthclamp is not supported.");
345 catch (const vk::Error& e)
347 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
348 throw tcu::NotSupportedError("Image format not supported");
355 TestStatus BuiltinFragDepthCaseInstance::iterate (void)
357 const VkDevice device = m_context.getDevice();
358 const DeviceInterface& vk = m_context.getDeviceInterface();
359 const VkQueue queue = m_context.getUniversalQueue();
360 Allocator& allocator = m_context.getDefaultAllocator();
361 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
362 TestLog& log = m_context.getTestContext().getLog();
363 const deUint32 scale = 4; // To account for std140 stride
364 const VkDeviceSize pixelCount = m_renderSize.x() * m_renderSize.y();
365 std::string testDesc;
366 Move<VkImage> depthResolveImage;
367 Move<VkImageView> depthResolveImageView;
368 MovePtr<Allocation> depthResolveAllocation;
369 Move<VkImage> depthImage;
370 Move<VkImageView> depthImageView;
371 MovePtr<Allocation> depthImageAllocation;
372 Move<VkBuffer> controlBuffer;
373 MovePtr<Allocation> controlBufferAllocation;
374 Move<VkImage> markerImage;
375 Move<VkImageView> markerImageView;
376 MovePtr<Allocation> markerImageAllocation;
377 Move<VkBuffer> markerBuffer;
378 MovePtr<Allocation> markerBufferAllocation;
379 Move<VkBuffer> validationBuffer;
380 MovePtr<Allocation> validationAlloc;
381 MovePtr<Allocation> depthInitAllocation;
382 Move<VkCommandPool> cmdPool;
383 Move<VkCommandBuffer> transferCmdBuffer;
384 Move<VkSampler> depthSampler;
386 // Create Buffer/Image for validation
388 VkFormat resolvedBufferFormat = VK_FORMAT_R32_SFLOAT;
389 const VkBufferCreateInfo validationBufferCreateInfo =
391 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
392 DE_NULL, // const void* pNext
393 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
394 m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)), // VkDeviceSize size
395 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
396 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
397 0u, // uint32_t queueFamilyIndexCount,
398 DE_NULL // const uint32_t* pQueueFamilyIndices
401 validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo);
402 validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible);
403 VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset()));
405 const VkImageCreateInfo depthResolveImageCreateInfo =
407 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
408 DE_NULL, // const void* pNext
409 (VkImageCreateFlags)0, // VkImageCreateFlags flags
410 VK_IMAGE_TYPE_2D, // VkIMageType imageType
411 resolvedBufferFormat, // VkFormat format
412 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent
413 1u, // uint32_t mipLevels
414 1u, // uint32_t arrayLayers
415 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBits samples
416 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
417 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage
418 VK_IMAGE_USAGE_STORAGE_BIT |
419 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
420 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
421 0u, // uint32_t queueFamilyIndexCount
422 DE_NULL, // const uint32_t pQueueFamilyIndices
423 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
426 depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL);
427 depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any);
428 VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset()));
430 const VkImageViewCreateInfo depthResolveImageViewCreateInfo =
432 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
433 DE_NULL, // const void* pNext
434 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
435 *depthResolveImage, // VkImage image
436 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType type
437 resolvedBufferFormat, // VkFormat format
438 makeComponentMappingRGBA(), // VkComponentMapping componentMapping
439 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u) // VkImageSUbresourceRange subresourceRange
442 depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL);
447 const VkDeviceSize size = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT));
449 const VkBufferCreateInfo markerBufferCreateInfo =
451 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
452 DE_NULL, // const void* pNext
453 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
454 size, // VkDeviceSize size
455 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
456 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
457 0u, // uint32_t queueFamilyIndexCount
458 DE_NULL // const uint32_t* pQueueFamilyIndices
461 markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL);
462 markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible);
463 VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset()));
465 const VkImageCreateInfo markerImageCreateInfo =
467 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
468 DE_NULL, // const void* pNext
469 (VkImageCreateFlags)0, // VkImageCreateFlags flags
470 VK_IMAGE_TYPE_2D, // VkImageType imageType
471 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format
472 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D extent
473 1u, // uint32_t mipLevels
474 1u, // uint32_t arrayLayers
475 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBit smaples
476 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
477 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage
478 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
479 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
480 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharing
481 0u, // uint32_t queueFamilyIndexCount
482 DE_NULL, // const uint32_t* pQueueFamilyIndices
483 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
486 markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL);
487 markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any);
488 VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset()));
490 const VkImageViewCreateInfo markerViewCreateInfo =
492 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
493 DE_NULL, // const void* pNext
494 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
495 *markerImage, // VkImage image
496 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
497 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format
498 makeComponentMappingRGBA(), // VkComponentMapping components
499 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)
502 markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL);
507 const VkBufferCreateInfo controlBufferCreateInfo =
509 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
510 DE_NULL, // const void* pNext
511 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
512 pixelCount * sizeof(float)* scale, // VkDeviceSize size
513 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage
514 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
515 0u, // deUint32 queueFamilyIndexCount
517 DE_NULL // pQueueFamilyIndices
520 controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL);
521 controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible);
522 VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset()));
525 float* bufferData = (float*)(controlBufferAllocation->getHostPtr());
526 float sign = m_depthClampEnable ? -1.0f : 1.0f;
527 for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++)
529 bufferData[ndx * scale] = (float)ndx / 256.0f * sign;
530 if (m_largeDepthEnable)
531 bufferData[ndx * scale] += m_largeDepthBase;
534 const VkMappedMemoryRange range =
536 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
538 controlBufferAllocation->getMemory(),
543 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
549 VkImageSubresourceRange depthSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
550 const VkImageCreateInfo depthImageCreateInfo =
552 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
553 DE_NULL, // const void* pNext
554 (VkImageCreateFlags)0, // VkImageCreateFlags flags
555 VK_IMAGE_TYPE_2D, // VkImageType imageType
556 m_format, // VkFormat format
557 makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent
558 1u, // uint32_t mipLevels
559 1u, // uint32_t arrayLayers
560 m_samples, // VkSampleCountFlagsBits samples
561 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
562 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
563 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
564 VK_IMAGE_USAGE_SAMPLED_BIT |
565 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage
566 VK_SHARING_MODE_EXCLUSIVE, // VkShaderingMode sharingMode
567 0u, // uint32_t queueFamilyIndexCount
568 DE_NULL, // const uint32_t* pQueueFamilyIndices
569 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
572 depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL);
573 depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any);
574 VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset()));
576 const VkImageViewCreateInfo imageViewParams =
578 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
579 DE_NULL, // const void* pNext;
580 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
581 *depthImage, // VkImage image;
582 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
583 m_format, // VkFormat format;
584 makeComponentMappingRGBA(), // VkComponentMapping components;
585 depthSubresourceRange, // VkImageSubresourceRange subresourceRange;
587 depthImageView = createImageView(vk, device, &imageViewParams);
589 const VkSamplerCreateInfo depthSamplerCreateInfo =
591 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
592 DE_NULL, // const void* pNext
593 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags
594 VK_FILTER_NEAREST, // VkFilter minFilter
595 VK_FILTER_NEAREST, // VkFilter magFilter
596 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipMapMode mipMapMode
597 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
598 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
599 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressmodeW
600 0.0f, // float mipLodBias
601 VK_FALSE, // VkBool32 anisotropyEnable
602 0.0f, // float maxAnisotropy
603 VK_FALSE, // VkBool32 compareEnable
604 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp
605 0.0f, // float minLod
606 0.0f, // float maxLod
607 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
608 VK_FALSE // VkBool32 unnormalizedCoordinates
611 depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL);
616 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
618 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType
619 DE_NULL, // const void* pNext
620 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags
621 queueFamilyIndex // uint32_t queueFamilyIndex
624 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
627 // Command buffer for data transfers
629 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
631 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType,
632 DE_NULL, // const void* pNext
633 *cmdPool, // VkCommandPool commandPool
634 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level
635 1u // uint32_t bufferCount
638 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
641 // Initialize Marker Buffer
643 const VkImageMemoryBarrier imageBarrier[] =
646 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
647 DE_NULL, // const void* pNext
648 0, // VkAccessMask srcAccessMask
649 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessMask dstAccessMask
650 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
651 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
652 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
653 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
654 *markerImage, // VkImage image
656 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
657 0u, // uint32_t baseMipLevel
658 1u, // uint32_t mipLevels
659 0u, // uint32_t baseArray
660 1u // uint32_t arraySize
665 const VkImageMemoryBarrier imagePostBarrier[] =
668 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
669 DE_NULL, // const void* pNext
670 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlagBits srcAccessMask
671 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlagBits dstAccessMask
672 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
673 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
674 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
675 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
676 *markerImage, // VkImage image
678 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
679 0u, // uint32_t baseMipLevel
680 1u, // uint32_t mipLevels
681 0u, // uint32_t baseArray
682 1u // uint32_t arraySize
687 beginCommandBuffer(vk, *transferCmdBuffer);
688 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
689 (VkDependencyFlags)0,
690 0, (const VkMemoryBarrier*)DE_NULL,
691 0, (const VkBufferMemoryBarrier*)DE_NULL,
692 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
694 const VkClearValue colorClearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
695 const VkImageSubresourceRange colorClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
697 vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange);
699 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
700 (VkDependencyFlags)0,
701 0, (const VkMemoryBarrier*)DE_NULL,
702 0, (const VkBufferMemoryBarrier*)DE_NULL,
703 DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier);
705 endCommandBuffer(vk, *transferCmdBuffer);
707 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
708 m_context.resetCommandPoolForVKSC(device, *cmdPool);
714 std::vector<Vec4> vertices;
715 std::vector<VulkanShader> shaders;
716 Move<VkDescriptorSetLayout> descriptorSetLayout;
717 Move<VkDescriptorPool> descriptorPool;
718 Move<VkDescriptorSet> descriptorSet;
722 DescriptorSetLayoutBuilder layoutBuilder;
723 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
724 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
725 descriptorSetLayout = layoutBuilder.build(vk, device);
726 descriptorPool = DescriptorPoolBuilder()
727 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
728 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
729 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
731 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
733 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
737 &descriptorSetLayout.get()
740 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
742 const VkDescriptorBufferInfo bufferInfo =
749 const VkDescriptorImageInfo imageInfo =
753 VK_IMAGE_LAYOUT_GENERAL
756 DescriptorSetUpdateBuilder()
757 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo)
758 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
762 vertices.push_back(Vec4( -0.70f, 0.5f, 0.0f, 1.0f));
763 vertices.push_back(Vec4( 0.45f, -0.75f, 0.0f, 1.0f));
764 vertices.push_back(Vec4( 0.78f, 0.0f, 0.0f, 1.0f));
765 vertices.push_back(Vec4( -0.1f, 0.6f, 0.0f, 1.0f));
767 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert")));
768 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag")));
770 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
771 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
772 DrawCallData drawCallData(m_topology, vertices);
773 VulkanProgram vulkanProgram(shaders);
775 frameBufferState.depthFormat = m_format;
776 frameBufferState.numSamples = m_samples;
777 frameBufferState.depthImageView = *depthImageView;
778 pipelineState.depthClampEnable = m_depthClampEnable;
779 pipelineState.compareOp = rr::TESTFUNC_ALWAYS;
780 pipelineState.depthTestEnable = true;
781 pipelineState.depthWriteEnable = true;
782 pipelineState.sampleShadingEnable = true;
783 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
784 vulkanProgram.descriptorSet = *descriptorSet;
786 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
787 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
788 vulkanDrawContext.draw();
790 log << TestLog::Image( "resultColor",
791 "Result Color Buffer",
792 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
793 vulkanDrawContext.getColorPixels().getFormat()),
794 vulkanDrawContext.getColorPixels().getWidth(),
795 vulkanDrawContext.getColorPixels().getHeight(),
797 vulkanDrawContext.getColorPixels().getDataPtr()));
800 // Barrier to transition between first and second pass
802 const VkImageMemoryBarrier imageBarrier[] =
805 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
806 DE_NULL, // const void* pNext
807 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
808 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask
809 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
810 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
811 0u, // deUint32 srcQueueFamilyIndex
812 0u, // deUint32 dstQueueFamilyIndex
813 *depthImage, // VkImage image
815 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
816 0u, // deUint32 baseMipLevel
817 1u, // deUint32 levelCount
818 0u, // deUint32 baseArrayLayer
819 1u // deUint32 layerCount
823 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
824 DE_NULL, // const void* pNext
825 0u, // VkAccessFlags srcAccessMask
826 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
827 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
828 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
829 0u, // deUint32 srcQueueFamilyIndex
830 0u, // deUint32 dstQueueFamilyIndex
831 *depthResolveImage, // VkImage image
833 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
834 0u, // deUint32 baseMipLevel
835 1u, // deUint32 levelCount
836 0u, // deUint32 baseArrayLayer
837 1u, // deUint32 layerCount
843 beginCommandBuffer(vk, *transferCmdBuffer);
844 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_HOST_BIT,
845 (VkDependencyFlags)0,
846 0, (const VkMemoryBarrier*)DE_NULL,
847 0, (const VkBufferMemoryBarrier*)DE_NULL,
848 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
849 endCommandBuffer(vk, *transferCmdBuffer);
851 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
852 m_context.resetCommandPoolForVKSC(device, *cmdPool);
855 // Resolve Depth Buffer
857 std::vector<Vec4> vertices;
858 std::vector<VulkanShader> shaders;
859 Move<VkDescriptorSetLayout> descriptorSetLayout;
860 Move<VkDescriptorPool> descriptorPool;
861 Move<VkDescriptorSet> descriptorSet;
865 DescriptorSetLayoutBuilder layoutBuilder;
866 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
867 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
868 descriptorSetLayout = layoutBuilder.build(vk, device);
869 descriptorPool = DescriptorPoolBuilder()
870 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
871 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
872 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
874 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
876 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
880 &descriptorSetLayout.get()
883 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
885 const VkDescriptorImageInfo depthImageInfo =
889 VK_IMAGE_LAYOUT_GENERAL
892 const VkDescriptorImageInfo imageInfo =
895 *depthResolveImageView,
896 VK_IMAGE_LAYOUT_GENERAL
899 DescriptorSetUpdateBuilder()
900 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo)
901 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
905 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f));
906 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f));
907 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
908 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
910 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2")));
911 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2")));
913 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
914 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
915 DrawCallData drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
916 VulkanProgram vulkanProgram(shaders);
918 frameBufferState.numSamples = m_samples;
919 pipelineState.sampleShadingEnable = true;
920 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
921 vulkanProgram.descriptorSet = *descriptorSet;
923 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
924 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
925 vulkanDrawContext.draw();
928 // Transfer marker buffer
930 beginCommandBuffer(vk, *transferCmdBuffer);
931 copyImageToBuffer(vk, *transferCmdBuffer, *markerImage, *markerBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
932 endCommandBuffer(vk, *transferCmdBuffer);
934 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
935 m_context.resetCommandPoolForVKSC(device, *cmdPool);
938 // Verify depth buffer
942 beginCommandBuffer(vk, *transferCmdBuffer, 0u);
943 copyImageToBuffer(vk, *transferCmdBuffer, *depthResolveImage, *validationBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
944 endCommandBuffer(vk, *transferCmdBuffer);
946 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
947 m_context.resetCommandPoolForVKSC(device, *cmdPool);
949 invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE);
950 invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE);
952 tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr());
953 tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr());
954 status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f);
955 testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " ";
958 testDesc += "passed";
959 return tcu::TestStatus::pass(testDesc.c_str());
963 log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer);
964 testDesc += "failed";
965 return tcu::TestStatus::fail(testDesc.c_str());
970 bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const
972 TestLog& log = m_context.getTestContext().getLog();
974 for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++)
976 for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++)
978 const float multiplier = m_depthClampEnable ? 0.0f : 1.0f;
979 float expectedValue = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier;
981 if (m_largeDepthEnable)
982 expectedValue += m_largeDepthBase;
984 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++)
986 const float actualValue = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
987 const float markerValue = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
989 if (markerValue != 0)
991 if (de::abs(expectedValue - actualValue) > tolerance)
993 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
999 if (de::abs(actualValue - m_defaultDepthValue) > tolerance)
1001 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
1012 class BuiltinFragCoordMsaaCaseInstance : public TestInstance
1020 BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable);
1021 TestStatus iterate (void);
1023 bool validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const;
1025 const tcu::UVec2 m_renderSize;
1026 const VkSampleCountFlagBits m_sampleCount;
1027 const bool m_sampleShading;
1028 const std::vector<uint32_t> m_sampleMaskArray;
1029 const bool m_useEnable;
1032 BuiltinFragCoordMsaaCaseInstance::BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable)
1033 : TestInstance (context)
1034 , m_renderSize (RENDERWIDTH, RENDERHEIGHT)
1035 , m_sampleCount (sampleCount)
1036 , m_sampleShading (sampleShading)
1037 , m_sampleMaskArray (sampleMaskArray)
1038 , m_useEnable (useEnable)
1040 const InstanceInterface& vki = m_context.getInstanceInterface();
1041 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1043 if (!context.getDeviceFeatures().sampleRateShading)
1044 TCU_THROW(NotSupportedError, "sampleRateShading not supported");
1048 VkImageFormatProperties imageFormatProperties;
1049 VkFormatProperties formatProperties;
1051 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
1052 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
1054 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
1055 throw tcu::NotSupportedError("sampleRateShading not supported");
1057 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_TYPE_2D,
1058 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, (VkImageCreateFlags)0);
1060 if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
1061 throw tcu::NotSupportedError("Image format and sample count not supported");
1063 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT);
1065 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
1066 throw tcu::NotSupportedError("Output format not supported as storage image");
1068 catch (const vk::Error& e)
1070 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
1071 throw tcu::NotSupportedError("Image format not supported");
1078 TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void)
1080 const VkDevice device = m_context.getDevice();
1081 const DeviceInterface& vk = m_context.getDeviceInterface();
1082 const VkQueue queue = m_context.getUniversalQueue();
1083 Allocator& allocator = m_context.getDefaultAllocator();
1084 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1085 TestLog& log = m_context.getTestContext().getLog();
1086 Move<VkImage> outputImage;
1087 Move<VkImageView> outputImageView;
1088 MovePtr<Allocation> outputImageAllocation;
1089 Move<VkDescriptorSetLayout> descriptorSetLayout;
1090 Move<VkDescriptorPool> descriptorPool;
1091 Move<VkDescriptorSet> descriptorSet;
1092 Move<VkBuffer> sampleLocationBuffer;
1093 MovePtr<Allocation> sampleLocationBufferAllocation;
1094 Move<VkCommandPool> cmdPool;
1095 Move<VkCommandBuffer> transferCmdBuffer;
1097 // Coordinate result image
1099 const VkImageCreateInfo outputImageCreateInfo =
1101 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1102 DE_NULL, // const void* pNext
1103 (VkImageCreateFlags)0, // VkImageCreateFlags flags
1104 VK_IMAGE_TYPE_2D, // VkImageType imageType
1105 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
1106 makeExtent3D(m_sampleCount * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent3d
1107 1u, // uint32_t mipLevels
1108 1u, // uint32_t arrayLayers
1109 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1110 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1111 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage
1112 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1113 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1114 0u, // uint32_t queueFamilyIndexCount
1115 DE_NULL, // const uint32_t* pQueueFamilyIndices
1116 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1119 outputImage = createImage(vk, device, &outputImageCreateInfo, DE_NULL);
1120 outputImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *outputImage), MemoryRequirement::Any);
1121 vk.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset());
1123 VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1124 const VkImageViewCreateInfo outputImageViewCreateInfo =
1126 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
1127 DE_NULL, // const void* pNext
1128 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags
1129 *outputImage, // VkImage image
1130 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
1131 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format,
1132 makeComponentMappingRGBA(), // VkComponentMapping components
1133 imageSubresourceRange // VkImageSubresourceRange imageSubresourceRange
1136 outputImageView = createImageView(vk, device, &outputImageViewCreateInfo);
1139 // Validation buffer
1141 VkDeviceSize pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT));
1142 const VkBufferCreateInfo sampleLocationBufferCreateInfo =
1144 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
1145 DE_NULL, // const void* pNext
1146 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags
1147 m_sampleCount * m_renderSize.x() * m_renderSize.y() * pixelSize, // VkDeviceSize size
1148 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
1149 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode mode
1150 0u, // uint32_t queueFamilyIndexCount
1151 DE_NULL // const uint32_t* pQueueFamilyIndices
1154 sampleLocationBuffer = createBuffer(vk, device, &sampleLocationBufferCreateInfo, DE_NULL);
1155 sampleLocationBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *sampleLocationBuffer), MemoryRequirement::HostVisible);
1156 vk.bindBufferMemory(device, *sampleLocationBuffer, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset());
1161 DescriptorSetLayoutBuilder layoutBuilder;
1162 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
1163 descriptorSetLayout = layoutBuilder.build(vk, device);
1164 descriptorPool = DescriptorPoolBuilder()
1165 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1166 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1168 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1170 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1174 &*descriptorSetLayout
1177 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
1179 const VkDescriptorImageInfo imageInfo =
1183 VK_IMAGE_LAYOUT_GENERAL
1186 DescriptorSetUpdateBuilder()
1187 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
1188 .update(vk, device);
1193 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
1195 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType
1196 DE_NULL, // const void* pNext
1197 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags
1198 queueFamilyIndex // uint32_t queueFamilyIndex
1201 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
1204 // Command buffer for data transfers
1206 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
1208 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType,
1209 DE_NULL, // const void* pNext
1210 *cmdPool, // VkCommandPool commandPool
1211 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level
1212 1u // uint32_t bufferCount
1215 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
1218 // Transition the output image to LAYOUT_GENERAL
1220 const VkImageMemoryBarrier barrier =
1222 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1223 DE_NULL, // const void* pNext
1224 0u, // VkAccessFlags srcAccessMask
1225 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
1226 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1227 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1228 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1229 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1230 *outputImage, // VkImage image
1232 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1233 0u, // uint32_t baseMipLevel
1234 1u, // uint32_t mipLevels
1235 0u, // uint32_t baseArray
1236 1u // uint32_t arraySize
1240 beginCommandBuffer(vk, *transferCmdBuffer);
1241 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1242 (VkDependencyFlags)0,
1243 0, (const VkMemoryBarrier*)DE_NULL,
1244 0, (const VkBufferMemoryBarrier*)DE_NULL,
1247 endCommandBuffer(vk, *transferCmdBuffer);
1249 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1250 m_context.resetCommandPoolForVKSC(device, *cmdPool);
1255 std::vector<Vec4> vertices;
1256 std::vector<VulkanShader> shaders;
1258 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f));
1259 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f));
1260 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
1261 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
1263 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragCoordMsaaVert")));
1264 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragCoordMsaaFrag")));
1266 FrameBufferState frameBufferState(m_renderSize.x(), m_renderSize.y());
1267 PipelineState pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1268 DrawCallData drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
1269 VulkanProgram vulkanProgram(shaders);
1271 frameBufferState.numSamples = m_sampleCount;
1272 pipelineState.sampleShadingEnable = m_useEnable; // When m_useEnable is false, we rely on the gl_SampleID input to enable sample shading
1273 pipelineState.sampleMasks = m_sampleMaskArray;
1274 vulkanProgram.descriptorSetLayout = *descriptorSetLayout;
1275 vulkanProgram.descriptorSet = *descriptorSet;
1277 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState);
1278 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
1279 vulkanDrawContext.draw();
1281 log << TestLog::Image( "result",
1283 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1284 vulkanDrawContext.getColorPixels().getFormat()),
1285 vulkanDrawContext.getColorPixels().getWidth(),
1286 vulkanDrawContext.getColorPixels().getHeight(),
1288 vulkanDrawContext.getColorPixels().getDataPtr()));
1291 // Transfer location image to buffer
1293 beginCommandBuffer(vk, *transferCmdBuffer);
1294 copyImageToBuffer(vk, *transferCmdBuffer, *outputImage, *sampleLocationBuffer, tcu::IVec2(m_renderSize.x() * m_sampleCount, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
1295 endCommandBuffer(vk, *transferCmdBuffer);
1297 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1298 m_context.resetCommandPoolForVKSC(device, *cmdPool);
1300 invalidateAlloc(vk, device, *sampleLocationBufferAllocation);
1307 ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(),
1308 m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr());
1310 status = validateSampleLocations(sampleLocationPixelBuffer);
1312 return TestStatus::pass("FragCoordMsaa passed");
1314 return TestStatus::fail("FragCoordMsaa failed");
1318 static bool pixelOffsetCompare (const Vec2& a, const Vec2& b)
1320 return a.x() < b.x();
1323 bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const
1325 const InstanceInterface& vki = m_context.getInstanceInterface();
1326 TestLog& log = m_context.getTestContext().getLog();
1327 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1328 deUint32 logSampleCount = deLog2Floor32(m_sampleCount);
1329 VkPhysicalDeviceProperties physicalDeviceProperties;
1331 static const Vec2 sampleCount1Bit[] =
1336 static const Vec2 sampleCount2Bit[] =
1338 Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f)
1341 static const Vec2 sampleCount4Bit[] =
1343 Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f)
1346 static const Vec2 sampleCount8Bit[] =
1348 Vec2(0.5625f, 0.3125f), Vec2(0.4375f, 0.6875f), Vec2(0.8125f,0.5625f), Vec2(0.3125f, 0.1875f),
1349 Vec2(0.1875f, 0.8125f), Vec2(0.0625f, 0.4375f), Vec2(0.6875f,0.9375f), Vec2(0.9375f, 0.0625f)
1352 static const Vec2 sampleCount16Bit[] =
1354 Vec2(0.5625f, 0.5625f), Vec2(0.4375f, 0.3125f), Vec2(0.3125f,0.6250f), Vec2(0.7500f, 0.4375f),
1355 Vec2(0.1875f, 0.3750f), Vec2(0.6250f, 0.8125f), Vec2(0.8125f,0.6875f), Vec2(0.6875f, 0.1875f),
1356 Vec2(0.3750f, 0.8750f), Vec2(0.5000f, 0.0625f), Vec2(0.2500f,0.1250f), Vec2(0.1250f, 0.7500f),
1357 Vec2(0.0000f, 0.5000f), Vec2(0.9375f, 0.2500f), Vec2(0.8750f,0.9375f), Vec2(0.0625f, 0.0000f)
1360 static const Vec2* standardSampleLocationTable[] =
1369 vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
1371 for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++)
1373 for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++)
1375 // Check standard sample locations
1376 if (m_sampleShading == true)
1378 std::vector<Vec2> locations;
1380 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1382 const UVec2 pixelAddress = UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx);
1383 const Vec4 pixelData = sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y());
1385 if (pixelData.z() != 0.0f)
1387 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1391 if (pixelData.w() != 1.0f)
1393 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1397 locations.push_back(Vec2(pixelData.x(), pixelData.y()));
1399 std::sort(locations.begin(), locations.end(), pixelOffsetCompare);
1400 for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++)
1402 IVec2 sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y()));
1403 IVec2 sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y()));
1405 if ((sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1))
1407 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage;
1412 std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end());
1413 if (last != locations.end())
1415 log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage;
1419 if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable))
1421 if (physicalDeviceProperties.limits.standardSampleLocations)
1423 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1425 if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx))))
1427 log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage;
1436 // Check the sample location is at the pixel center when sample shading is disabled.
1437 const Vec4 pixelData = sampleLocationBuffer.getPixel(colNdx, rowNdx);
1439 if (pixelData.z() != 0.0f)
1441 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1445 if (pixelData.w() != 1.0f)
1447 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1451 if (!(deFloatFrac(pixelData.x()) == 0.5f && deFloatFrac(pixelData.y()) == 0.5f))
1453 log << TestLog::Message << "Didn't match sample locations (" << pixelData.x() << ", " << pixelData.y() << "): " << Vec2(float(colNdx) + 0.5f, float(rowNdx) + 0.5f) << TestLog::EndMessage;
1463 class BuiltinFragCoordMsaaTestCase : public TestCase
1466 BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable);
1467 virtual ~BuiltinFragCoordMsaaTestCase (void);
1468 void initPrograms (SourceCollections& sourceCollections) const;
1469 TestInstance* createInstance (Context& context) const;
1471 const VkSampleCountFlagBits m_sampleCount;
1472 const bool m_sampleShading; // Enable or disable Sample Shading.
1473 const std::vector<uint32_t> m_sampleMaskArray;
1474 const bool m_useCentroid; // Use Centroid interpolation decoration.
1475 const bool m_useEnable;
1478 BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable)
1479 : TestCase (testCtx, name, description)
1480 , m_sampleCount (sampleCount)
1481 , m_sampleShading (sampleShading)
1482 , m_sampleMaskArray (sampleMaskArray)
1483 , m_useCentroid (useCentroid)
1484 , m_useEnable (useEnable)
1488 BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void)
1492 void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const
1495 std::ostringstream vertexSource;
1496 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1498 << "layout (location = 0) in vec4 position;\n"
1501 << " gl_Position = position;\n"
1503 programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str());
1506 if(m_sampleShading == true)
1508 std::ostringstream fragmentSource;
1509 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1511 << "layout(location = 0) out mediump vec4 color;\n"
1512 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1515 << " const int sampleNdx = int(gl_SampleID);\n"
1516 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_sampleCount << ", int(gl_FragCoord.y));\n"
1517 << " imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1518 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1520 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str());
1524 if (m_useCentroid == false)
1526 std::ostringstream src;
1528 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1530 << "layout (location = 0) out mediump vec4 color;\n"
1531 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1534 << " ivec2 imageCoord = ivec2(int(gl_FragCoord.x), int(gl_FragCoord.y));\n"
1535 << " imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1536 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1539 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(src.str());
1543 // This SPIR-V shader is identical to GLSL shader above but with the exception of that added cendroid decoration line.
1544 std::ostringstream src;
1545 src << "; SPIR - V\n"
1546 << "; Version: 1.0\n"
1547 << "; Generator: Khronos Glslang Reference Front End; 10\n"
1550 << "OpCapability Shader\n"
1551 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1552 << "OpMemoryModel Logical GLSL450\n"
1553 << "OpEntryPoint Fragment %main \"main\" %gl_FragCoord %color\n"
1554 << "OpExecutionMode %main OriginUpperLeft\n"
1555 << "OpSource GLSL 450\n"
1556 << "OpName %main \"main\"\n"
1557 << "OpName %imageCoord \"imageCoord\"\n"
1558 << "OpName %gl_FragCoord \"gl_FragCoord\"\n"
1559 << "OpName %storageImage \"storageImage\"\n"
1560 << "OpName %color \"color\"\n"
1561 << "OpDecorate %gl_FragCoord BuiltIn FragCoord\n"
1562 << "OpDecorate %gl_FragCoord Centroid\n"
1563 << "OpDecorate %storageImage DescriptorSet 0\n"
1564 << "OpDecorate %storageImage Binding 0\n"
1565 << "OpDecorate %storageImage NonReadable\n"
1566 << "OpDecorate %color RelaxedPrecision\n"
1567 << "OpDecorate %color Location 0\n"
1568 << "%void = OpTypeVoid\n"
1569 << "%3 = OpTypeFunction %void\n"
1570 << "%int = OpTypeInt 32 1\n"
1571 << "%v2int = OpTypeVector %int 2\n"
1572 << "%_ptr_Function_v2int = OpTypePointer Function %v2int\n"
1573 << "%float = OpTypeFloat 32\n"
1574 << "%v4float = OpTypeVector %float 4\n"
1575 << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n"
1576 << "%gl_FragCoord = OpVariable %_ptr_Input_v4float Input\n"
1577 << "%uint = OpTypeInt 32 0\n"
1578 << "%uint_0 = OpConstant %uint 0\n"
1579 << "%_ptr_Input_float = OpTypePointer Input %float\n"
1580 << "%uint_1 = OpConstant %uint 1\n"
1581 << "%25 = OpTypeImage %float 2D 0 0 0 2 Rgba32f\n"
1582 << "%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25\n"
1583 << "%storageImage = OpVariable %_ptr_UniformConstant_25 UniformConstant\n"
1584 << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
1585 << "%color = OpVariable %_ptr_Output_v4float Output\n"
1586 << "%float_1 = OpConstant %float 1\n"
1587 << "%float_0 = OpConstant %float 0\n"
1588 << "%35 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1\n"
1589 << "%main = OpFunction %void None %3\n"
1591 << "%imageCoord = OpVariable %_ptr_Function_v2int Function\n"
1592 << "%17 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0\n"
1593 << "%18 = OpLoad %float %17\n"
1594 << "%19 = OpConvertFToS %int %18\n"
1595 << "%21 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_1\n"
1596 << "%22 = OpLoad %float %21\n"
1597 << "%23 = OpConvertFToS %int %22\n"
1598 << "%24 = OpCompositeConstruct %v2int %19 %23\n"
1599 << "OpStore %imageCoord %24\n"
1600 << "%28 = OpLoad %25 %storageImage\n"
1601 << "%29 = OpLoad %v2int %imageCoord\n"
1602 << "%30 = OpLoad %v4float %gl_FragCoord\n"
1603 << "OpImageWrite %28 %29 %30\n"
1604 << "OpStore %color %35\n"
1606 << "OpFunctionEnd\n";
1608 programCollection.spirvAsmSources.add("FragCoordMsaaFrag") << src.str();
1613 TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const
1615 return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount, m_sampleShading, m_sampleMaskArray, m_useEnable);
1618 class BuiltinFragDepthCase : public TestCase
1621 BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples);
1622 virtual ~BuiltinFragDepthCase (void);
1624 void initPrograms (SourceCollections& dst) const;
1625 TestInstance* createInstance (Context& context) const;
1628 const VkPrimitiveTopology m_topology;
1629 const VkFormat m_format;
1630 const bool m_largeDepthEnable;
1631 const float m_defaultDepth;
1632 const bool m_depthClampEnable;
1633 const VkSampleCountFlagBits m_samples;
1636 BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples)
1637 : TestCase (testCtx, name, description)
1638 , m_topology (topology)
1640 , m_largeDepthEnable (largeDepthEnable)
1641 , m_defaultDepth (0.0f)
1642 , m_depthClampEnable (depthClampEnable)
1643 , m_samples (samples)
1647 BuiltinFragDepthCase::~BuiltinFragDepthCase(void)
1651 void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const
1657 std::ostringstream vertexSource;
1658 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1660 << "layout (location = 0) in vec4 position;\n"
1663 << " gl_Position = position;\n"
1664 << " gl_PointSize = 1.0;\n"
1666 programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str());
1671 std::ostringstream vertexSource;
1672 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1674 << "layout (location = 0) in vec4 position;\n"
1675 << "layout (location = 1) out vec2 texCoord;\n"
1678 << " gl_Position = position;\n"
1679 << " gl_PointSize = 1.0;\n"
1680 << " texCoord = position.xy/2 + vec2(0.5);\n"
1682 programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str());
1690 std::ostringstream fragmentSource;
1691 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1693 << "layout(location = 0) out mediump vec4 color;\n"
1694 << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n"
1696 << " float data[256];\n"
1697 << "} control_buffer;\n"
1698 << "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n"
1699 << "float controlDepthValue;\n"
1700 << "void recheck(float controlDepthValue)\n"
1702 << " if (gl_FragDepth != controlDepthValue)\n"
1703 << " gl_FragDepth = 1.0;\n"
1707 << " const int numSamples = " << m_samples << ";\n"
1708 << " if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n"
1710 << " highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n"
1711 << " controlDepthValue = control_buffer.data[index];\n"
1712 << " gl_FragDepth = controlDepthValue;\n"
1713 << " const int sampleNdx = int(gl_SampleID);\n"
1714 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n"
1715 << " imageStore(storageImage, imageCoord, uvec4(1));\n"
1716 << " recheck(controlDepthValue);\n"
1717 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1719 programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str());
1724 const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : "";
1725 std::ostringstream fragmentSource;
1726 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1728 << "layout (location = 0) out mediump vec4 color;\n"
1729 << "layout (location = 1) in vec2 texCoord;\n"
1730 << "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n"
1731 << "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n"
1732 << "void main (void)\n"
1734 << " const int numSamples = " << m_samples << ";\n"
1735 << " const int sampleNdx = int(gl_SampleID);\n"
1736 << " ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n"
1737 << " ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n"
1738 << " vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n"
1739 << " imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n"
1740 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1742 programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str());
1747 TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const
1749 return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples);
1752 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
1755 BuiltinGlFragCoordXYZCaseInstance (Context& context);
1757 TestStatus iterate (void);
1758 virtual void setupDefaultInputs (void);
1761 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
1762 : ShaderRenderCaseInstance (context)
1764 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1767 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
1769 const UVec2 viewportSize = getViewportSize();
1770 const int width = viewportSize.x();
1771 const int height = viewportSize.y();
1772 const tcu::Vec3 scale (1.0f / float(width), 1.0f / float(height), 1.0f);
1773 const float precision = 0.00001f;
1774 const deUint16 indices[6] =
1781 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
1783 render(4, 2, indices);
1786 for (int y = 0; y < height; y++)
1788 for (int x = 0; x < width; x++)
1790 const float xf = (float(x) + .5f) / float(width);
1791 const float yf = (float(height - y - 1) + .5f) / float(height);
1792 const float z = (xf + yf) / 2.0f;
1793 const Vec3 fragCoord (float(x) + .5f, float(y) + .5f, z);
1794 const Vec3 scaledFC = fragCoord*scale;
1795 const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
1796 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y);
1798 if (de::abs(color.x() - resultColor.x()) > precision ||
1799 de::abs(color.y() - resultColor.y()) > precision ||
1800 de::abs(color.z() - resultColor.z()) > precision)
1801 return TestStatus::fail("Image mismatch");
1805 return TestStatus::pass("Result image matches reference");
1808 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
1810 const float vertices[] =
1812 -1.0f, 1.0f, 0.0f, 1.0f,
1813 -1.0f, -1.0f, 0.5f, 1.0f,
1814 1.0f, 1.0f, 0.5f, 1.0f,
1815 1.0f, -1.0f, 1.0f, 1.0f,
1818 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1821 class BuiltinGlFragCoordXYZCase : public TestCase
1824 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description);
1825 virtual ~BuiltinGlFragCoordXYZCase (void);
1827 void initPrograms (SourceCollections& dst) const;
1828 TestInstance* createInstance (Context& context) const;
1831 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed!
1832 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed!
1835 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
1836 : TestCase(testCtx, name, description)
1840 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
1844 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
1846 dst.glslSources.add("vert") << glu::VertexSource(
1848 "layout(location = 0) in highp vec4 a_position;\n"
1849 "void main (void)\n"
1851 " gl_Position = a_position;\n"
1854 dst.glslSources.add("frag") << glu::FragmentSource(
1856 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
1857 "layout(location = 0) out highp vec4 o_color;\n"
1858 "void main (void)\n"
1860 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
1864 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
1866 return new BuiltinGlFragCoordXYZCaseInstance(context);
1869 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
1871 return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
1874 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
1877 BuiltinGlFragCoordWCaseInstance (Context& context);
1879 TestStatus iterate (void);
1880 virtual void setupDefaultInputs (void);
1888 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
1889 : ShaderRenderCaseInstance (context)
1890 , m_w (1.7f, 2.0f, 1.2f, 1.0f)
1892 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1895 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
1897 const UVec2 viewportSize = getViewportSize();
1898 const int width = viewportSize.x();
1899 const int height = viewportSize.y();
1900 const float precision = 0.00001f;
1901 const deUint16 indices[6] =
1908 render(4, 2, indices);
1911 for (int y = 0; y < height; y++)
1913 for (int x = 0; x < width; x++)
1915 const float xf = (float(x) + .5f) / float(width);
1916 const float yf = (float(height - y - 1) +.5f) / float(height);
1917 const float oow = ((xf + yf) < 1.0f)
1918 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
1919 : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f - xf, 1.0f - yf);
1920 const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f);
1921 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y);
1923 if (de::abs(color.x() - resultColor.x()) > precision ||
1924 de::abs(color.y() - resultColor.y()) > precision ||
1925 de::abs(color.z() - resultColor.z()) > precision)
1926 return TestStatus::fail("Image mismatch");
1930 return TestStatus::pass("Result image matches reference");
1933 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
1935 const float vertices[] =
1937 -m_w[0], m_w[0], 0.0f, m_w[0],
1938 -m_w[1], -m_w[1], 0.0f, m_w[1],
1939 m_w[2], m_w[2], 0.0f, m_w[2],
1940 m_w[3], -m_w[3], 0.0f, m_w[3]
1943 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1946 class BuiltinGlFragCoordWCase : public TestCase
1949 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description);
1950 virtual ~BuiltinGlFragCoordWCase (void);
1952 void initPrograms (SourceCollections& dst) const;
1953 TestInstance* createInstance (Context& context) const;
1956 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed!
1957 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed!
1960 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
1961 : TestCase(testCtx, name, description)
1965 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
1969 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
1971 dst.glslSources.add("vert") << glu::VertexSource(
1973 "layout(location = 0) in highp vec4 a_position;\n"
1974 "void main (void)\n"
1976 " gl_Position = a_position;\n"
1979 dst.glslSources.add("frag") << glu::FragmentSource(
1981 "layout(location = 0) out highp vec4 o_color;\n"
1982 "void main (void)\n"
1984 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
1988 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
1990 return new BuiltinGlFragCoordWCaseInstance(context);
1995 POINTCOORD_VARIANT_DEFAULT,
1996 POINTCOORD_VARIANT_UNIFORM_VERTEX,
1997 POINTCOORD_VARIANT_UNIFORM_FRAGMENT
2001 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
2004 BuiltinGlPointCoordCaseInstance (Context& context, int testVariant);
2006 TestStatus iterate (void);
2007 virtual void setupDefaultInputs (void);
2012 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context, int testVariant)
2013 : ShaderRenderCaseInstance (context),
2014 variant(testVariant)
2018 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
2020 const UVec2 viewportSize = getViewportSize();
2021 const int width = viewportSize.x();
2022 const int height = viewportSize.y();
2023 const float threshold = 0.02f;
2024 const int numPoints = 16;
2025 vector<Vec3> coords (numPoints);
2026 de::Random rnd (0x145fa);
2027 Surface resImage (width, height);
2028 Surface refImage (width, height);
2029 bool compareOk = false;
2030 const tcu::Vec3 scale(1.0f / float(width), 1.0f / float(height), 1.0f);
2032 // Compute coordinates.
2034 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits;
2035 const float minPointSize = limits.pointSizeRange[0];
2036 const float maxPointSize = limits.pointSizeRange[1];
2037 const int pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
2039 TCU_CHECK(minPointSize <= maxPointSize);
2041 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
2043 coord->x() = rnd.getFloat(-0.9f, 0.9f);
2044 coord->y() = rnd.getFloat(-0.9f, 0.9f);
2045 coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
2051 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX || variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2052 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
2054 addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
2055 render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2056 copy(resImage.getAccess(), getResultImage().getAccess());
2059 clear(refImage.getAccess(), m_clearColor);
2061 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
2063 float x = pointIter->x();
2064 float y = pointIter->y();
2065 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX)
2067 x *= scale.m_data[0];
2068 y *= scale.m_data[1];
2070 const float centerX = float(width) *(x*0.5f + 0.5f);
2071 const float centerY = float(height)*(y*0.5f + 0.5f);
2072 const float size = pointIter->z();
2073 const int x0 = deRoundFloatToInt32(centerX - size*0.5f);
2074 const int y0 = deRoundFloatToInt32(centerY - size*0.5f);
2075 const int x1 = deRoundFloatToInt32(centerX + size*0.5f);
2076 const int y1 = deRoundFloatToInt32(centerY + size*0.5f);
2077 const int w = x1-x0;
2078 const int h = y1-y0;
2080 for (int yo = 0; yo < h; yo++)
2082 for (int xo = 0; xo < w; xo++)
2084 const int dx = x0+xo;
2085 const int dy = y0+yo;
2086 const float fragX = float(dx) + 0.5f;
2087 const float fragY = float(dy) + 0.5f;
2088 const float s = 0.5f + (fragX - centerX) / size;
2089 const float t = 0.5f + (fragY - centerY) / size;
2090 Vec4 color (s, t, 0.0f, 1.0f);
2092 if (variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2094 color.m_data[0] *= scale.m_data[0];
2095 color.m_data[1] *= scale.m_data[1];
2096 color.m_data[2] *= scale.m_data[2];
2099 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
2100 refImage.setPixel(dx, dy, RGBA(color));
2105 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2108 return TestStatus::pass("Result image matches reference");
2110 return TestStatus::fail("Image mismatch");
2113 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
2117 class BuiltinGlPointCoordCase : public TestCase
2120 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description, int testVariant);
2121 virtual ~BuiltinGlPointCoordCase (void);
2123 void initPrograms (SourceCollections& dst) const;
2124 TestInstance* createInstance (Context& context) const;
2128 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed!
2129 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed!
2132 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description, int testVariant)
2133 : TestCase(testCtx, name, description),
2134 variant(testVariant)
2138 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
2142 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
2146 case POINTCOORD_VARIANT_UNIFORM_FRAGMENT:
2147 dst.glslSources.add("vert") << glu::VertexSource(
2149 "layout(location = 0) in highp vec3 a_position;\n"
2150 "void main (void)\n"
2152 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2153 " gl_PointSize = a_position.z;\n"
2156 dst.glslSources.add("frag") << glu::FragmentSource(
2158 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2159 "layout(location = 0) out lowp vec4 o_color;\n"
2160 "void main (void)\n"
2162 " o_color = vec4(gl_PointCoord, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2165 case POINTCOORD_VARIANT_UNIFORM_VERTEX:
2166 dst.glslSources.add("vert") << glu::VertexSource(
2168 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2169 "layout(location = 0) in highp vec3 a_position;\n"
2170 "void main (void)\n"
2172 " gl_Position = vec4(a_position.xy, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2173 " gl_PointSize = a_position.z;\n"
2176 dst.glslSources.add("frag") << glu::FragmentSource(
2178 "layout(location = 0) out lowp vec4 o_color;\n"
2179 "void main (void)\n"
2181 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2184 default: // POINTCOORD_VARIANT_DEFAULT
2185 dst.glslSources.add("vert") << glu::VertexSource(
2187 "layout(location = 0) in highp vec3 a_position;\n"
2188 "void main (void)\n"
2190 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2191 " gl_PointSize = a_position.z;\n"
2194 dst.glslSources.add("frag") << glu::FragmentSource(
2196 "layout(location = 0) out lowp vec4 o_color;\n"
2197 "void main (void)\n"
2199 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2204 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
2206 return new BuiltinGlPointCoordCaseInstance(context, variant);
2209 enum ShaderInputTypeBits
2211 SHADER_INPUT_BUILTIN_BIT = 0x01,
2212 SHADER_INPUT_VARYING_BIT = 0x02,
2213 SHADER_INPUT_CONSTANT_BIT = 0x04
2216 typedef deUint16 ShaderInputTypes;
2218 string shaderInputTypeToString (ShaderInputTypes type)
2220 string typeString = "input";
2223 return "input_none";
2225 if (type & SHADER_INPUT_BUILTIN_BIT)
2226 typeString += "_builtin";
2228 if (type & SHADER_INPUT_VARYING_BIT)
2229 typeString += "_varying";
2231 if (type & SHADER_INPUT_CONSTANT_BIT)
2232 typeString += "_constant";
2237 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
2240 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes);
2242 TestStatus iterate (void);
2243 virtual void setupDefaultInputs (void);
2244 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
2247 const ShaderInputTypes m_shaderInputTypes;
2248 const Vec4 m_constantColor;
2251 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
2252 : ShaderRenderCaseInstance (context)
2253 , m_shaderInputTypes (shaderInputTypes)
2254 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f)
2258 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
2260 const UVec2 viewportSize = getViewportSize();
2261 const int width = viewportSize.x();
2262 const int height = viewportSize.y();
2263 const tcu::RGBA threshold (2, 2, 2, 2);
2264 Surface resImage (width, height);
2265 Surface refImage (width, height);
2266 bool compareOk = false;
2267 const VkPushConstantRange pcRanges =
2269 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
2270 0u, // deUint32 offset;
2271 sizeof(Vec4) // deUint32 size;
2273 const deUint16 indices[12] =
2283 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2284 setPushConstantRanges(1, &pcRanges);
2286 render(6, 4, indices);
2287 copy(resImage.getAccess(), getResultImage().getAccess());
2290 for (int y = 0; y < refImage.getHeight(); y++)
2292 for (int x = 0; x < refImage.getWidth(); x++)
2294 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
2296 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
2297 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
2299 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2301 const float xf = (float(x)+.5f) / float(refImage.getWidth());
2302 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
2305 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
2308 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2309 color += m_constantColor;
2311 refImage.setPixel(x, y, RGBA(color));
2315 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2318 return TestStatus::pass("Result image matches reference");
2320 return TestStatus::fail("Image mismatch");
2323 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
2325 const float vertices[] =
2327 -1.0f, -1.0f, 0.0f, 1.0f,
2328 0.0f, -1.0f, 0.0f, 1.0f,
2329 1.0f, -1.0f, 0.0f, 1.0f,
2330 1.0f, 1.0f, 0.0f, 1.0f,
2331 0.0f, 1.0f, 0.0f, 1.0f,
2332 -1.0f, 1.0f, 0.0f, 1.0f
2335 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
2337 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2339 const float colors[] =
2341 0.6f, 0.0f, 0.0f, 1.0f,
2342 0.3f, 0.3f, 0.0f, 1.0f,
2343 0.0f, 0.6f, 0.0f, 1.0f,
2344 0.0f, 0.6f, 0.0f, 1.0f,
2345 0.3f, 0.3f, 0.0f, 1.0f,
2346 0.6f, 0.0f, 0.0f, 1.0f
2348 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
2352 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
2354 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2356 const DeviceInterface& vk = m_context.getDeviceInterface();
2357 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
2361 class BuiltinInputVariationsCase : public TestCase
2364 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
2365 virtual ~BuiltinInputVariationsCase (void);
2367 void initPrograms (SourceCollections& dst) const;
2368 TestInstance* createInstance (Context& context) const;
2371 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed!
2372 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed!
2373 const ShaderInputTypes m_shaderInputTypes;
2376 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
2377 : TestCase (testCtx, name, description)
2378 , m_shaderInputTypes (shaderInputTypes)
2382 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
2386 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
2388 map<string, string> vertexParams;
2389 map<string, string> fragmentParams;
2390 const tcu::StringTemplate vertexCodeTemplate (
2392 "layout(location = 0) in highp vec4 a_position;\n"
2393 "out gl_PerVertex {\n"
2394 " vec4 gl_Position;\n"
2397 "void main (void)\n"
2399 " gl_Position = a_position;\n"
2403 const tcu::StringTemplate fragmentCodeTemplate (
2407 "layout(location = 0) out highp vec4 o_color;\n"
2408 "void main (void)\n"
2410 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
2413 " ${CONSTANT_USAGE}"
2416 vertexParams["VARYING_DECL"] =
2417 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n"
2418 "layout(location = 0) out highp vec4 v_color;\n"
2421 vertexParams["VARYING_USAGE"] =
2422 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n"
2425 fragmentParams["VARYING_DECL"] =
2426 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n"
2429 fragmentParams["CONSTANT_DECL"] =
2430 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n"
2435 fragmentParams["BUILTIN_USAGE"] =
2436 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n"
2439 fragmentParams["VARYING_USAGE"] =
2440 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n"
2441 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
2444 fragmentParams["CONSTANT_USAGE"] =
2445 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n"
2448 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
2449 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
2452 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
2454 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
2459 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
2461 de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
2462 de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases."));
2463 de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
2464 de::MovePtr<TestCaseGroup> frontFacingGroup (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword."));
2465 de::MovePtr<TestCaseGroup> fragDepthGroup (new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword."));
2466 de::MovePtr<TestCaseGroup> fragCoordMsaaGroup (new TestCaseGroup(testCtx, "fragcoord_msaa", "Test interation between gl_FragCoord and msaa"));
2467 de::MovePtr<TestCaseGroup> fragCoordMsaaInputGroup (new TestCaseGroup(testCtx, "fragcoord_msaa_input", "Test interation between gl_FragCoord and msaa"));
2469 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
2470 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
2471 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test", POINTCOORD_VARIANT_DEFAULT));
2472 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_frag", "PointCoord test with fragment uniform", POINTCOORD_VARIANT_UNIFORM_FRAGMENT));
2473 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_vert", "PointCoord test with vertex uniform", POINTCOORD_VARIANT_UNIFORM_VERTEX));
2477 static const struct FragCoordMsaaCaseList
2480 const char* description;
2481 VkSampleCountFlagBits sampleCount;
2482 } fragCoordMsaaCaseList[] =
2484 { "1_bit", "Test FragCoord locations with 1 sample", VK_SAMPLE_COUNT_1_BIT },
2485 { "2_bit", "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_2_BIT },
2486 { "4_bit", "Test FragCoord locations with 4 samples", VK_SAMPLE_COUNT_4_BIT },
2487 { "8_bit", "Test FragCoord locations with 8 samples", VK_SAMPLE_COUNT_8_BIT },
2488 { "16_bit", "Test FragCoord locations with 16 samples", VK_SAMPLE_COUNT_16_BIT },
2489 { "32_bit", "Test FragCoord locations with 32 samples", VK_SAMPLE_COUNT_32_BIT },
2490 { "64_bit", "Test FragCoord locaitons with 64 samples", VK_SAMPLE_COUNT_64_BIT },
2493 // Standard sample tests
2494 std::vector<uint32_t> sampleMaskArray;
2496 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2498 fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, true));
2499 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, false));
2502 sampleMaskArray.push_back(1u);
2504 // No sample shading tests
2505 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2507 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, false, false));
2510 // No sample shading tests with centroid interpolation decoration
2511 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2513 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading_centroid_interpolation").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, true, false));
2517 // gl_FrontFacing tests
2519 static const struct PrimitiveTable
2523 VkPrimitiveTopology primitive;
2524 } frontfacingCases[] =
2526 { "point_list", "Test that points are frontfacing", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2527 { "line_list", "Test that lines are frontfacing", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2528 { "triangle_list", "Test that triangles can be frontfacing or backfacing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST },
2529 { "triangle_strip", "Test that traiangle strips can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2530 { "triangle_fan", "Test that triangle fans can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN },
2533 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++)
2534 frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc));
2539 static const struct PrimitiveTopologyTable
2543 VkPrimitiveTopology prim;
2544 } primitiveTopologyTable[] =
2546 { "point_list", "test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2547 { "line_list", "test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2548 { "triangle_list", "test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2551 static const struct TestCaseTable
2555 bool largeDepthEnable;
2556 bool depthClampEnable;
2557 VkSampleCountFlagBits samples;
2560 { VK_FORMAT_D16_UNORM, "d16_unorm_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2561 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2562 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2563 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2564 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2565 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT },
2566 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_large_depth", true, false, VK_SAMPLE_COUNT_1_BIT },
2567 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", false, true, VK_SAMPLE_COUNT_1_BIT },
2568 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", false, true, VK_SAMPLE_COUNT_1_BIT },
2569 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_2", false, false, VK_SAMPLE_COUNT_2_BIT },
2570 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_4", false, false, VK_SAMPLE_COUNT_4_BIT },
2571 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_8", false, false, VK_SAMPLE_COUNT_8_BIT },
2572 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_16", false, false, VK_SAMPLE_COUNT_16_BIT },
2573 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_32", false, false, VK_SAMPLE_COUNT_32_BIT },
2574 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_64", false, false, VK_SAMPLE_COUNT_64_BIT },
2577 for (deUint32 primNdx = 0; primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++)
2579 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++)
2580 fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(),
2581 primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples));
2586 builtinGroup->addChild(frontFacingGroup.release());
2587 builtinGroup->addChild(fragDepthGroup.release());
2588 builtinGroup->addChild(fragCoordMsaaGroup.release());
2589 builtinGroup->addChild(fragCoordMsaaInputGroup.release());
2590 builtinGroup->addChild(simpleGroup.release());
2592 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
2594 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
2597 builtinGroup->addChild(inputVariationsGroup.release());
2598 return builtinGroup.release();