1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 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 8 * 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 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 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. 20 * 21 *//*! 22 * \file 23 * \brief Shader builtin variable tests. 24 *//*--------------------------------------------------------------------*/ 25 26#include "vktShaderRenderBuiltinVarTests.hpp" 27 28#include "tcuFloat.hpp" 29#include "deUniquePtr.hpp" 30#include "vkDefs.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" 42 43#include "deMath.h" 44#include "deRandom.hpp" 45 46#include <map> 47 48using namespace std; 49using namespace tcu; 50using namespace vk; 51using namespace de; 52 53namespace vkt 54{ 55using namespace drawutil; 56 57namespace sr 58{ 59 60namespace 61{ 62 63enum 64{ 65 FRONTFACE_RENDERWIDTH = 16, 66 FRONTFACE_RENDERHEIGHT = 16 67}; 68 69class FrontFacingVertexShader : public rr::VertexShader 70{ 71public: 72 FrontFacingVertexShader (void) 73 : rr::VertexShader(1, 0) 74 { 75 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 76 } 77 78 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 79 { 80 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 81 { 82 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0], 83 packets[packetNdx]->instanceNdx, 84 packets[packetNdx]->vertexNdx); 85 } 86 } 87}; 88 89class FrontFacingFragmentShader : public rr::FragmentShader 90{ 91public: 92 FrontFacingFragmentShader (void) 93 : rr::FragmentShader(0, 1) 94 { 95 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 96 } 97 98 void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const 99 { 100 tcu::Vec4 color; 101 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 102 { 103 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx) 104 { 105 if (context.visibleFace == rr::FACETYPE_FRONT) 106 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 107 else 108 color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); 109 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 110 } 111 } 112 } 113}; 114 115class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance 116{ 117public: 118 BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology); 119 120 TestStatus iterate (void); 121private: 122 const VkPrimitiveTopology m_topology; 123}; 124 125BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology) 126 : ShaderRenderCaseInstance (context) 127 , m_topology (topology) 128{ 129} 130 131 132TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void) 133{ 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; 140 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)); 147 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"))); 150 151 testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " "; 152 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); 159 dc.draw(); 160 161 ReferenceDrawContext refDrawContext(frameBufferState); 162 refDrawContext.registerDrawObject(pipelineState, vertexShader, fragmentShader, drawCallData); 163 refDrawContext.draw(); 164 165 log << TestLog::Image( "reference", 166 "reference", 167 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 168 refDrawContext.getColorPixels().getFormat()), 169 refDrawContext.getColorPixels().getWidth(), 170 refDrawContext.getColorPixels().getHeight(), 171 1, 172 refDrawContext.getColorPixels().getDataPtr())); 173 174 log << TestLog::Image( "result", 175 "result", 176 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 177 dc.getColorPixels().getFormat()), 178 dc.getColorPixels().getWidth(), 179 dc.getColorPixels().getHeight(), 180 1, 181 dc.getColorPixels().getDataPtr())); 182 183 if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 184 "ComparisonResult", 185 "Image comparison result", 186 refDrawContext.getColorPixels(), 187 dc.getColorPixels(), 188 UVec4(0u), 189 IVec3(1,1,0), 190 false, 191 tcu::COMPARE_LOG_RESULT)) 192 { 193 testDesc += "passed"; 194 return tcu::TestStatus::pass(testDesc.c_str()); 195 } 196 else 197 { 198 testDesc += "failed"; 199 return tcu::TestStatus::fail(testDesc.c_str()); 200 } 201} 202 203class BuiltinGlFrontFacingCase : public TestCase 204{ 205public: 206 BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name); 207 virtual ~BuiltinGlFrontFacingCase (void); 208 209 void initPrograms (SourceCollections& dst) const; 210 void checkSupport (Context& context) const; 211 TestInstance* createInstance (Context& context) const; 212 213private: 214 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed! 215 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed! 216 217 const VkPrimitiveTopology m_topology; 218}; 219 220BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name) 221 : TestCase (testCtx, name) 222 , m_topology (topology) 223{ 224} 225 226BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void) 227{ 228} 229 230void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const 231{ 232 { 233 std::ostringstream vertexSource; 234 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 235 << "\n" 236 << "layout(location = 0) in highp vec4 position;\n" 237 << "void main()\n" 238 << "{\n" 239 << "gl_Position = position;\n" 240 << "gl_PointSize = 1.0;\n" 241 << "}\n"; 242 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str()); 243 } 244 245 { 246 std::ostringstream fragmentSource; 247 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 248 << "\n" 249 << "layout(location = 0) out mediump vec4 color;\n" 250 << "void main()\n" 251 << "{\n" 252 << "if (gl_FrontFacing)\n" 253 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 254 << "else\n" 255 << " color = vec4(0.0, 1.0, 0.0, 1.0);\n" 256 << "}\n"; 257 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str()); 258 } 259} 260 261void BuiltinGlFrontFacingCase::checkSupport (Context& context) const 262{ 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) 267 { 268 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation"); 269 } 270#else 271 DE_UNREF(context); 272#endif // CTS_USES_VULKANSC 273} 274 275TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const 276{ 277 return new BuiltinGlFrontFacingCaseInstance(context, m_topology); 278} 279 280class BuiltinFragDepthCaseInstance : public TestInstance 281{ 282public: 283 enum 284 { 285 RENDERWIDTH = 16, 286 RENDERHEIGHT = 16 287 }; 288 BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples); 289 TestStatus iterate (void); 290 291 bool validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const; 292private: 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; 301}; 302 303BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples) 304 : TestInstance (context) 305 , m_topology (topology) 306 , m_format (format) 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) 313{ 314 const InstanceInterface& vki = m_context.getInstanceInterface(); 315 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 316 317 try 318 { 319 VkImageFormatProperties imageFormatProperties; 320 VkFormatProperties formatProperties; 321 322 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE) 323 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported"); 324 325 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE) 326 throw tcu::NotSupportedError("sampleRateShading not supported"); 327 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); 330 331 if ((imageFormatProperties.sampleCounts & m_samples) == 0) 332 throw tcu::NotSupportedError("Image format and sample count not supported"); 333 334 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT); 335 336 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0) 337 throw tcu::NotSupportedError("MarkerImage format not supported as storage image"); 338 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"); 341 342 if (m_context.getDeviceFeatures().depthClamp == VK_FALSE && m_depthClampEnable) 343 throw tcu::NotSupportedError("Depthclamp is not supported."); 344 } 345 catch (const vk::Error& e) 346 { 347 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED) 348 throw tcu::NotSupportedError("Image format not supported"); 349 else 350 throw; 351 352 } 353} 354 355TestStatus BuiltinFragDepthCaseInstance::iterate (void) 356{ 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; 385 386 // Create Buffer/Image for validation 387 { 388 VkFormat resolvedBufferFormat = VK_FORMAT_R32_SFLOAT; 389 const VkBufferCreateInfo validationBufferCreateInfo = 390 { 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 399 }; 400 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())); 404 405 const VkImageCreateInfo depthResolveImageCreateInfo = 406 { 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 424 }; 425 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())); 429 430 const VkImageViewCreateInfo depthResolveImageViewCreateInfo = 431 { 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 440 }; 441 442 depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL); 443 } 444 445 // Marker Buffer 446 { 447 const VkDeviceSize size = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT)); 448 449 const VkBufferCreateInfo markerBufferCreateInfo = 450 { 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 459 }; 460 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())); 464 465 const VkImageCreateInfo markerImageCreateInfo = 466 { 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 484 }; 485 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())); 489 490 const VkImageViewCreateInfo markerViewCreateInfo = 491 { 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) 500 }; 501 502 markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL); 503 } 504 505 // Control Buffer 506 { 507 const VkBufferCreateInfo controlBufferCreateInfo = 508 { 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 516 517 DE_NULL // pQueueFamilyIndices 518 }; 519 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())); 523 524 { 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++) 528 { 529 bufferData[ndx * scale] = (float)ndx / 256.0f * sign; 530 if (m_largeDepthEnable) 531 bufferData[ndx * scale] += m_largeDepthBase; 532 } 533 534 const VkMappedMemoryRange range = 535 { 536 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 537 DE_NULL, 538 controlBufferAllocation->getMemory(), 539 0u, 540 VK_WHOLE_SIZE 541 }; 542 543 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range)); 544 } 545 } 546 547 // Depth Buffer 548 { 549 VkImageSubresourceRange depthSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u); 550 const VkImageCreateInfo depthImageCreateInfo = 551 { 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 570 }; 571 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())); 575 576 const VkImageViewCreateInfo imageViewParams = 577 { 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; 586 }; 587 depthImageView = createImageView(vk, device, &imageViewParams); 588 589 const VkSamplerCreateInfo depthSamplerCreateInfo = 590 { 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 609 }; 610 611 depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL); 612 } 613 614 // Command Pool 615 { 616 const VkCommandPoolCreateInfo cmdPoolCreateInfo = 617 { 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 622 }; 623 624 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo); 625 } 626 627 // Command buffer for data transfers 628 { 629 const VkCommandBufferAllocateInfo cmdBufferAllocInfo = 630 { 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 636 }; 637 638 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo); 639 } 640 641 // Initialize Marker Buffer 642 { 643 const VkImageMemoryBarrier imageBarrier[] = 644 { 645 { 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 655 { 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 661 } 662 }, 663 }; 664 665 const VkImageMemoryBarrier imagePostBarrier[] = 666 { 667 { 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 677 { 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 683 } 684 }, 685 }; 686 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); 693 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); 696 697 vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange); 698 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); 704 705 endCommandBuffer(vk, *transferCmdBuffer); 706 707 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 708 m_context.resetCommandPoolForVKSC(device, *cmdPool); 709 } 710 711 712 // Perform Draw 713 { 714 std::vector<Vec4> vertices; 715 std::vector<VulkanShader> shaders; 716 Move<VkDescriptorSetLayout> descriptorSetLayout; 717 Move<VkDescriptorPool> descriptorPool; 718 Move<VkDescriptorSet> descriptorSet; 719 720 // Descriptors 721 { 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); 730 731 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 732 { 733 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 734 DE_NULL, 735 *descriptorPool, 736 1u, 737 &descriptorSetLayout.get() 738 }; 739 740 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 741 742 const VkDescriptorBufferInfo bufferInfo = 743 { 744 *controlBuffer, 745 0u, 746 VK_WHOLE_SIZE 747 }; 748 749 const VkDescriptorImageInfo imageInfo = 750 { 751 (VkSampler)DE_NULL, 752 *markerImageView, 753 VK_IMAGE_LAYOUT_GENERAL 754 }; 755 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) 759 .update(vk, device); 760 } 761 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)); 766 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"))); 769 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); 774 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; 785 786 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState); 787 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData); 788 vulkanDrawContext.draw(); 789 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(), 796 1, 797 vulkanDrawContext.getColorPixels().getDataPtr())); 798 } 799 800 // Barrier to transition between first and second pass 801 { 802 const VkImageMemoryBarrier imageBarrier[] = 803 { 804 { 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 814 { 815 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask 816 0u, // deUint32 baseMipLevel 817 1u, // deUint32 levelCount 818 0u, // deUint32 baseArrayLayer 819 1u // deUint32 layerCount 820 } 821 }, 822 { 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 832 { 833 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 834 0u, // deUint32 baseMipLevel 835 1u, // deUint32 levelCount 836 0u, // deUint32 baseArrayLayer 837 1u, // deUint32 layerCount 838 839 } 840 } 841 }; 842 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); 850 851 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 852 m_context.resetCommandPoolForVKSC(device, *cmdPool); 853 } 854 855 // Resolve Depth Buffer 856 { 857 std::vector<Vec4> vertices; 858 std::vector<VulkanShader> shaders; 859 Move<VkDescriptorSetLayout> descriptorSetLayout; 860 Move<VkDescriptorPool> descriptorPool; 861 Move<VkDescriptorSet> descriptorSet; 862 863 // Descriptors 864 { 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); 873 874 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 875 { 876 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 877 DE_NULL, 878 *descriptorPool, 879 1u, 880 &descriptorSetLayout.get() 881 }; 882 883 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 884 885 const VkDescriptorImageInfo depthImageInfo = 886 { 887 *depthSampler, 888 *depthImageView, 889 VK_IMAGE_LAYOUT_GENERAL 890 }; 891 892 const VkDescriptorImageInfo imageInfo = 893 { 894 (VkSampler)DE_NULL, 895 *depthResolveImageView, 896 VK_IMAGE_LAYOUT_GENERAL 897 }; 898 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) 902 .update(vk, device); 903 } 904 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)); 909 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"))); 912 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); 917 918 frameBufferState.numSamples = m_samples; 919 pipelineState.sampleShadingEnable = true; 920 vulkanProgram.descriptorSetLayout = *descriptorSetLayout; 921 vulkanProgram.descriptorSet = *descriptorSet; 922 923 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState); 924 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData); 925 vulkanDrawContext.draw(); 926 } 927 928 // Transfer marker buffer 929 { 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); 933 934 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 935 m_context.resetCommandPoolForVKSC(device, *cmdPool); 936 } 937 938 // Verify depth buffer 939 { 940 bool status; 941 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); 945 946 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 947 m_context.resetCommandPoolForVKSC(device, *cmdPool); 948 949 invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE); 950 invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE); 951 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) + " "; 956 if (status) 957 { 958 testDesc += "passed"; 959 return tcu::TestStatus::pass(testDesc.c_str()); 960 } 961 else 962 { 963 log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer); 964 testDesc += "failed"; 965 return tcu::TestStatus::fail(testDesc.c_str()); 966 } 967 } 968} 969 970bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const 971{ 972 TestLog& log = m_context.getTestContext().getLog(); 973 974 for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++) 975 { 976 for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++) 977 { 978 const float multiplier = m_depthClampEnable ? 0.0f : 1.0f; 979 float expectedValue = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier; 980 981 if (m_largeDepthEnable) 982 expectedValue += m_largeDepthBase; 983 984 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++) 985 { 986 const float actualValue = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x(); 987 const float markerValue = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x(); 988 989 if (markerValue != 0) 990 { 991 if (de::abs(expectedValue - actualValue) > tolerance) 992 { 993 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage; 994 return false; 995 } 996 } 997 else 998 { 999 if (de::abs(actualValue - m_defaultDepthValue) > tolerance) 1000 { 1001 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage; 1002 return false; 1003 } 1004 } 1005 } 1006 } 1007 } 1008 1009 return true; 1010} 1011 1012class BuiltinFragCoordMsaaCaseInstance : public TestInstance 1013{ 1014public: 1015 enum 1016 { 1017 RENDERWIDTH = 16, 1018 RENDERHEIGHT = 16 1019 }; 1020 BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable); 1021 TestStatus iterate (void); 1022private: 1023 bool validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const; 1024 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; 1030}; 1031 1032BuiltinFragCoordMsaaCaseInstance::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) 1039{ 1040 const InstanceInterface& vki = m_context.getInstanceInterface(); 1041 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 1042 1043 if (!context.getDeviceFeatures().sampleRateShading) 1044 TCU_THROW(NotSupportedError, "sampleRateShading not supported"); 1045 1046 try 1047 { 1048 VkImageFormatProperties imageFormatProperties; 1049 VkFormatProperties formatProperties; 1050 1051 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE) 1052 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported"); 1053 1054 if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE) 1055 throw tcu::NotSupportedError("sampleRateShading not supported"); 1056 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); 1059 1060 if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0) 1061 throw tcu::NotSupportedError("Image format and sample count not supported"); 1062 1063 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT); 1064 1065 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0) 1066 throw tcu::NotSupportedError("Output format not supported as storage image"); 1067 } 1068 catch (const vk::Error& e) 1069 { 1070 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED) 1071 throw tcu::NotSupportedError("Image format not supported"); 1072 else 1073 throw; 1074 1075 } 1076} 1077 1078TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void) 1079{ 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; 1096 1097 // Coordinate result image 1098 { 1099 const VkImageCreateInfo outputImageCreateInfo = 1100 { 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 1117 }; 1118 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()); 1122 1123 VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 1124 const VkImageViewCreateInfo outputImageViewCreateInfo = 1125 { 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 1134 }; 1135 1136 outputImageView = createImageView(vk, device, &outputImageViewCreateInfo); 1137 } 1138 1139 // Validation buffer 1140 { 1141 VkDeviceSize pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT)); 1142 const VkBufferCreateInfo sampleLocationBufferCreateInfo = 1143 { 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 1152 }; 1153 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()); 1157 } 1158 1159 // Descriptors 1160 { 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); 1167 1168 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 1169 { 1170 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1171 DE_NULL, 1172 *descriptorPool, 1173 1u, 1174 &*descriptorSetLayout 1175 }; 1176 1177 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 1178 1179 const VkDescriptorImageInfo imageInfo = 1180 { 1181 (VkSampler)DE_NULL, 1182 *outputImageView, 1183 VK_IMAGE_LAYOUT_GENERAL 1184 }; 1185 1186 DescriptorSetUpdateBuilder() 1187 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo) 1188 .update(vk, device); 1189 } 1190 1191 // Command Pool 1192 { 1193 const VkCommandPoolCreateInfo cmdPoolCreateInfo = 1194 { 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 1199 }; 1200 1201 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo); 1202 } 1203 1204 // Command buffer for data transfers 1205 { 1206 const VkCommandBufferAllocateInfo cmdBufferAllocInfo = 1207 { 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 1213 }; 1214 1215 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo); 1216 } 1217 1218 // Transition the output image to LAYOUT_GENERAL 1219 { 1220 const VkImageMemoryBarrier barrier = 1221 { 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 1231 { 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 1237 } 1238 }; 1239 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, 1245 1, &barrier); 1246 1247 endCommandBuffer(vk, *transferCmdBuffer); 1248 1249 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 1250 m_context.resetCommandPoolForVKSC(device, *cmdPool); 1251 } 1252 1253 // Perform draw 1254 { 1255 std::vector<Vec4> vertices; 1256 std::vector<VulkanShader> shaders; 1257 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)); 1262 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"))); 1265 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); 1270 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; 1276 1277 VulkanDrawContext vulkanDrawContext(m_context, frameBufferState); 1278 vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData); 1279 vulkanDrawContext.draw(); 1280 1281 log << TestLog::Image( "result", 1282 "result", 1283 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1284 vulkanDrawContext.getColorPixels().getFormat()), 1285 vulkanDrawContext.getColorPixels().getWidth(), 1286 vulkanDrawContext.getColorPixels().getHeight(), 1287 1, 1288 vulkanDrawContext.getColorPixels().getDataPtr())); 1289 } 1290 1291 // Transfer location image to buffer 1292 { 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); 1296 1297 submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get()); 1298 m_context.resetCommandPoolForVKSC(device, *cmdPool); 1299 1300 invalidateAlloc(vk, device, *sampleLocationBufferAllocation); 1301 } 1302 1303 // Validate result 1304 { 1305 bool status; 1306 1307 ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(), 1308 m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr()); 1309 1310 status = validateSampleLocations(sampleLocationPixelBuffer); 1311 if (status) 1312 return TestStatus::pass("FragCoordMsaa passed"); 1313 else 1314 return TestStatus::fail("FragCoordMsaa failed"); 1315 } 1316} 1317 1318static bool pixelOffsetCompare (const Vec2& a, const Vec2& b) 1319{ 1320 return a.x() < b.x(); 1321} 1322 1323bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const 1324{ 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; 1330 1331 static const Vec2 sampleCount1Bit[] = 1332 { 1333 Vec2(0.5f, 0.5f) 1334 }; 1335 1336 static const Vec2 sampleCount2Bit[] = 1337 { 1338 Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f) 1339 }; 1340 1341 static const Vec2 sampleCount4Bit[] = 1342 { 1343 Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f) 1344 }; 1345 1346 static const Vec2 sampleCount8Bit[] = 1347 { 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) 1350 }; 1351 1352 static const Vec2 sampleCount16Bit[] = 1353 { 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) 1358 }; 1359 1360 static const Vec2* standardSampleLocationTable[] = 1361 { 1362 sampleCount1Bit, 1363 sampleCount2Bit, 1364 sampleCount4Bit, 1365 sampleCount8Bit, 1366 sampleCount16Bit 1367 }; 1368 1369 vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties); 1370 1371 for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++) 1372 { 1373 for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++) 1374 { 1375 // Check standard sample locations 1376 if (m_sampleShading == true) 1377 { 1378 std::vector<Vec2> locations; 1379 1380 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++) 1381 { 1382 const UVec2 pixelAddress = UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx); 1383 const Vec4 pixelData = sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y()); 1384 1385 if (pixelData.z() != 0.0f) 1386 { 1387 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage; 1388 return false; 1389 } 1390 1391 if (pixelData.w() != 1.0f) 1392 { 1393 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage; 1394 return false; 1395 } 1396 1397 locations.push_back(Vec2(pixelData.x(), pixelData.y())); 1398 } 1399 std::sort(locations.begin(), locations.end(), pixelOffsetCompare); 1400 for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++) 1401 { 1402 IVec2 sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y())); 1403 IVec2 sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y())); 1404 1405 if ((sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1)) 1406 { 1407 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage; 1408 return false; 1409 } 1410 } 1411 1412 std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end()); 1413 if (last != locations.end()) 1414 { 1415 log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage; 1416 return false; 1417 } 1418 1419 if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable)) 1420 { 1421 if (physicalDeviceProperties.limits.standardSampleLocations) 1422 { 1423 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++) 1424 { 1425 if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx)))) 1426 { 1427 log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage; 1428 return false; 1429 } 1430 } 1431 } 1432 } 1433 } 1434 else 1435 { 1436 // Check the sample location is at the pixel center when sample shading is disabled. 1437 const Vec4 pixelData = sampleLocationBuffer.getPixel(colNdx, rowNdx); 1438 1439 if (pixelData.z() != 0.0f) 1440 { 1441 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage; 1442 return false; 1443 } 1444 1445 if (pixelData.w() != 1.0f) 1446 { 1447 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage; 1448 return false; 1449 } 1450 1451 if (!(deFloatFrac(pixelData.x()) == 0.5f && deFloatFrac(pixelData.y()) == 0.5f)) 1452 { 1453 log << TestLog::Message << "Didn't match sample locations (" << pixelData.x() << ", " << pixelData.y() << "): " << Vec2(float(colNdx) + 0.5f, float(rowNdx) + 0.5f) << TestLog::EndMessage; 1454 return false; 1455 } 1456 } 1457 } 1458 } 1459 1460 return true; 1461} 1462 1463class BuiltinFragCoordMsaaTestCase : public TestCase 1464{ 1465public: 1466 BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, 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; 1470private: 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; 1476}; 1477 1478BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable) 1479 : TestCase (testCtx, name) 1480 , m_sampleCount (sampleCount) 1481 , m_sampleShading (sampleShading) 1482 , m_sampleMaskArray (sampleMaskArray) 1483 , m_useCentroid (useCentroid) 1484 , m_useEnable (useEnable) 1485{ 1486} 1487 1488BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void) 1489{ 1490} 1491 1492void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const 1493{ 1494 { 1495 std::ostringstream vertexSource; 1496 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1497 << "\n" 1498 << "layout (location = 0) in vec4 position;\n" 1499 << "void main()\n" 1500 << "{\n" 1501 << " gl_Position = position;\n" 1502 << "}\n"; 1503 programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str()); 1504 } 1505 1506 if(m_sampleShading == true) 1507 { 1508 std::ostringstream fragmentSource; 1509 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1510 << "\n" 1511 << "layout(location = 0) out mediump vec4 color;\n" 1512 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n" 1513 << "void main()\n" 1514 << "{\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" 1519 << "}\n"; 1520 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str()); 1521 } 1522 else 1523 { 1524 if (m_useCentroid == false) 1525 { 1526 std::ostringstream src; 1527 1528 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1529 << "\n" 1530 << "layout (location = 0) out mediump vec4 color;\n" 1531 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n" 1532 << "void main()\n" 1533 << "{\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" 1537 << "}\n"; 1538 1539 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(src.str()); 1540 } 1541 else 1542 { 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" 1548 << "; Bound: 36\n" 1549 << "; Schema: 0\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" 1590 << "%5 = OpLabel\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" 1605 << "OpReturn\n" 1606 << "OpFunctionEnd\n"; 1607 1608 programCollection.spirvAsmSources.add("FragCoordMsaaFrag") << src.str(); 1609 } 1610 } 1611} 1612 1613TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const 1614{ 1615 return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount, m_sampleShading, m_sampleMaskArray, m_useEnable); 1616} 1617 1618class BuiltinFragDepthCase : public TestCase 1619{ 1620public: 1621 BuiltinFragDepthCase (TestContext& testCtx, const char* name, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples); 1622 virtual ~BuiltinFragDepthCase (void); 1623 1624 void initPrograms (SourceCollections& dst) const; 1625 TestInstance* createInstance (Context& context) const; 1626 1627private: 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; 1634}; 1635 1636BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples) 1637 : TestCase (testCtx, name) 1638 , m_topology (topology) 1639 , m_format (format) 1640 , m_largeDepthEnable (largeDepthEnable) 1641 , m_defaultDepth (0.0f) 1642 , m_depthClampEnable (depthClampEnable) 1643 , m_samples (samples) 1644{ 1645} 1646 1647BuiltinFragDepthCase::~BuiltinFragDepthCase(void) 1648{ 1649} 1650 1651void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const 1652{ 1653 // Vertex 1654 { 1655 // Pass 1 1656 { 1657 std::ostringstream vertexSource; 1658 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1659 << "\n" 1660 << "layout (location = 0) in vec4 position;\n" 1661 << "void main()\n" 1662 << "{\n" 1663 << " gl_Position = position;\n" 1664 << " gl_PointSize = 1.0;\n" 1665 << "}\n"; 1666 programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str()); 1667 } 1668 1669 // Pass 2 1670 { 1671 std::ostringstream vertexSource; 1672 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1673 << "\n" 1674 << "layout (location = 0) in vec4 position;\n" 1675 << "layout (location = 1) out vec2 texCoord;\n" 1676 << "void main()\n" 1677 << "{\n" 1678 << " gl_Position = position;\n" 1679 << " gl_PointSize = 1.0;\n" 1680 << " texCoord = position.xy/2 + vec2(0.5);\n" 1681 << "}\n"; 1682 programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str()); 1683 } 1684 } 1685 1686 // Fragment 1687 { 1688 // Pass 1 1689 { 1690 std::ostringstream fragmentSource; 1691 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1692 << "\n" 1693 << "layout(location = 0) out mediump vec4 color;\n" 1694 << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n" 1695 << "{\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" 1701 << "{\n" 1702 << " if (gl_FragDepth != controlDepthValue)\n" 1703 << " gl_FragDepth = 1.0;\n" 1704 << "}\n" 1705 << "void main()\n" 1706 << "{\n" 1707 << " const int numSamples = " << m_samples << ";\n" 1708 << " if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n" 1709 << " discard;\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" 1718 << "}\n"; 1719 programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str()); 1720 } 1721 1722 // Pass 2 1723 { 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" 1727 << "\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" 1733 << "{\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" 1741 << "}\n"; 1742 programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str()); 1743 } 1744 } 1745} 1746 1747TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const 1748{ 1749 return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples); 1750} 1751 1752class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance 1753{ 1754public: 1755 BuiltinGlFragCoordXYZCaseInstance (Context& context); 1756 1757 TestStatus iterate (void); 1758 virtual void setupDefaultInputs (void); 1759}; 1760 1761BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context) 1762 : ShaderRenderCaseInstance (context) 1763{ 1764 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM; 1765} 1766 1767TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void) 1768{ 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] = 1775 { 1776 2, 1, 3, 1777 0, 1, 2, 1778 }; 1779 1780 setup(); 1781 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale); 1782 1783 render(4, 2, indices); 1784 1785 // Reference image 1786 for (int y = 0; y < height; y++) 1787 { 1788 for (int x = 0; x < width; x++) 1789 { 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); 1797 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"); 1802 } 1803 } 1804 1805 return TestStatus::pass("Result image matches reference"); 1806} 1807 1808void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void) 1809{ 1810 const float vertices[] = 1811 { 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, 1816 }; 1817 1818 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices); 1819} 1820 1821class BuiltinGlFragCoordXYZCase : public TestCase 1822{ 1823public: 1824 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name); 1825 virtual ~BuiltinGlFragCoordXYZCase (void); 1826 1827 void initPrograms (SourceCollections& dst) const; 1828 TestInstance* createInstance (Context& context) const; 1829 1830private: 1831 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed! 1832 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed! 1833}; 1834 1835BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name) 1836 : TestCase(testCtx, name) 1837{ 1838} 1839 1840BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void) 1841{ 1842} 1843 1844void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const 1845{ 1846 dst.glslSources.add("vert") << glu::VertexSource( 1847 "#version 310 es\n" 1848 "layout(location = 0) in highp vec4 a_position;\n" 1849 "void main (void)\n" 1850 "{\n" 1851 " gl_Position = a_position;\n" 1852 "}\n"); 1853 1854 dst.glslSources.add("frag") << glu::FragmentSource( 1855 "#version 310 es\n" 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" 1859 "{\n" 1860 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n" 1861 "}\n"); 1862} 1863 1864TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const 1865{ 1866 return new BuiltinGlFragCoordXYZCaseInstance(context); 1867} 1868 1869inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny) 1870{ 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]); 1872} 1873 1874class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance 1875{ 1876public: 1877 BuiltinGlFragCoordWCaseInstance (Context& context); 1878 1879 TestStatus iterate (void); 1880 virtual void setupDefaultInputs (void); 1881 1882private: 1883 1884 const Vec4 m_w; 1885 1886}; 1887 1888BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context) 1889 : ShaderRenderCaseInstance (context) 1890 , m_w (1.7f, 2.0f, 1.2f, 1.0f) 1891{ 1892 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM; 1893} 1894 1895TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void) 1896{ 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] = 1902 { 1903 2, 1, 3, 1904 0, 1, 2, 1905 }; 1906 1907 setup(); 1908 render(4, 2, indices); 1909 1910 // Reference image 1911 for (int y = 0; y < height; y++) 1912 { 1913 for (int x = 0; x < width; x++) 1914 { 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); 1922 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"); 1927 } 1928 } 1929 1930 return TestStatus::pass("Result image matches reference"); 1931} 1932 1933void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void) 1934{ 1935 const float vertices[] = 1936 { 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] 1941 }; 1942 1943 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices); 1944} 1945 1946class BuiltinGlFragCoordWCase : public TestCase 1947{ 1948public: 1949 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name); 1950 virtual ~BuiltinGlFragCoordWCase (void); 1951 1952 void initPrograms (SourceCollections& dst) const; 1953 TestInstance* createInstance (Context& context) const; 1954 1955private: 1956 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed! 1957 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed! 1958}; 1959 1960BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name) 1961 : TestCase(testCtx, name) 1962{ 1963} 1964 1965BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void) 1966{ 1967} 1968 1969void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const 1970{ 1971 dst.glslSources.add("vert") << glu::VertexSource( 1972 "#version 310 es\n" 1973 "layout(location = 0) in highp vec4 a_position;\n" 1974 "void main (void)\n" 1975 "{\n" 1976 " gl_Position = a_position;\n" 1977 "}\n"); 1978 1979 dst.glslSources.add("frag") << glu::FragmentSource( 1980 "#version 310 es\n" 1981 "layout(location = 0) out highp vec4 o_color;\n" 1982 "void main (void)\n" 1983 "{\n" 1984 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n" 1985 "}\n"); 1986} 1987 1988TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const 1989{ 1990 return new BuiltinGlFragCoordWCaseInstance(context); 1991} 1992 1993enum 1994{ 1995 POINTCOORD_VARIANT_DEFAULT, 1996 POINTCOORD_VARIANT_UNIFORM_VERTEX, 1997 POINTCOORD_VARIANT_UNIFORM_FRAGMENT 1998}; 1999 2000 2001class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance 2002{ 2003public: 2004 BuiltinGlPointCoordCaseInstance (Context& context, int testVariant); 2005 2006 TestStatus iterate (void); 2007 virtual void setupDefaultInputs (void); 2008private: 2009 int variant; 2010}; 2011 2012BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context, int testVariant) 2013 : ShaderRenderCaseInstance (context), 2014 variant(testVariant) 2015{ 2016} 2017 2018TestStatus BuiltinGlPointCoordCaseInstance::iterate (void) 2019{ 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); 2031 2032 // Compute coordinates. 2033 { 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)); 2038 2039 TCU_CHECK(minPointSize <= maxPointSize); 2040 2041 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord) 2042 { 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); 2046 } 2047 } 2048 2049 setup(); 2050 2051 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX || variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT) 2052 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale); 2053 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()); 2057 2058 // Draw reference 2059 clear(refImage.getAccess(), m_clearColor); 2060 2061 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter) 2062 { 2063 float x = pointIter->x(); 2064 float y = pointIter->y(); 2065 if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX) 2066 { 2067 x *= scale.m_data[0]; 2068 y *= scale.m_data[1]; 2069 } 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; 2079 2080 for (int yo = 0; yo < h; yo++) 2081 { 2082 for (int xo = 0; xo < w; xo++) 2083 { 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); 2091 2092 if (variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT) 2093 { 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]; 2097 } 2098 2099 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight())) 2100 refImage.setPixel(dx, dy, RGBA(color)); 2101 } 2102 } 2103 } 2104 2105 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT); 2106 2107 if (compareOk) 2108 return TestStatus::pass("Result image matches reference"); 2109 else 2110 return TestStatus::fail("Image mismatch"); 2111} 2112 2113void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void) 2114{ 2115} 2116 2117class BuiltinGlPointCoordCase : public TestCase 2118{ 2119public: 2120 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, int testVariant); 2121 virtual ~BuiltinGlPointCoordCase (void); 2122 2123 void initPrograms (SourceCollections& dst) const; 2124 TestInstance* createInstance (Context& context) const; 2125 2126private: 2127 int variant; 2128 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed! 2129 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed! 2130}; 2131 2132BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, int testVariant) 2133 : TestCase(testCtx, name), 2134 variant(testVariant) 2135{ 2136} 2137 2138BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void) 2139{ 2140} 2141 2142void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const 2143{ 2144 switch (variant) 2145 { 2146 case POINTCOORD_VARIANT_UNIFORM_FRAGMENT: 2147 dst.glslSources.add("vert") << glu::VertexSource( 2148 "#version 310 es\n" 2149 "layout(location = 0) in highp vec3 a_position;\n" 2150 "void main (void)\n" 2151 "{\n" 2152 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" 2153 " gl_PointSize = a_position.z;\n" 2154 "}\n"); 2155 2156 dst.glslSources.add("frag") << glu::FragmentSource( 2157 "#version 310 es\n" 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" 2161 "{\n" 2162 " o_color = vec4(gl_PointCoord, 0.0, 1.0) * vec4(u_scale, 1.0);\n" 2163 "}\n"); 2164 break; 2165 case POINTCOORD_VARIANT_UNIFORM_VERTEX: 2166 dst.glslSources.add("vert") << glu::VertexSource( 2167 "#version 310 es\n" 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" 2171 "{\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" 2174 "}\n"); 2175 2176 dst.glslSources.add("frag") << glu::FragmentSource( 2177 "#version 310 es\n" 2178 "layout(location = 0) out lowp vec4 o_color;\n" 2179 "void main (void)\n" 2180 "{\n" 2181 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n" 2182 "}\n"); 2183 break; 2184 default: // POINTCOORD_VARIANT_DEFAULT 2185 dst.glslSources.add("vert") << glu::VertexSource( 2186 "#version 310 es\n" 2187 "layout(location = 0) in highp vec3 a_position;\n" 2188 "void main (void)\n" 2189 "{\n" 2190 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" 2191 " gl_PointSize = a_position.z;\n" 2192 "}\n"); 2193 2194 dst.glslSources.add("frag") << glu::FragmentSource( 2195 "#version 310 es\n" 2196 "layout(location = 0) out lowp vec4 o_color;\n" 2197 "void main (void)\n" 2198 "{\n" 2199 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n" 2200 "}\n"); 2201 } 2202} 2203 2204TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const 2205{ 2206 return new BuiltinGlPointCoordCaseInstance(context, variant); 2207} 2208 2209enum ShaderInputTypeBits 2210{ 2211 SHADER_INPUT_BUILTIN_BIT = 0x01, 2212 SHADER_INPUT_VARYING_BIT = 0x02, 2213 SHADER_INPUT_CONSTANT_BIT = 0x04 2214}; 2215 2216typedef deUint16 ShaderInputTypes; 2217 2218string shaderInputTypeToString (ShaderInputTypes type) 2219{ 2220 string typeString = "input"; 2221 2222 if (type == 0) 2223 return "input_none"; 2224 2225 if (type & SHADER_INPUT_BUILTIN_BIT) 2226 typeString += "_builtin"; 2227 2228 if (type & SHADER_INPUT_VARYING_BIT) 2229 typeString += "_varying"; 2230 2231 if (type & SHADER_INPUT_CONSTANT_BIT) 2232 typeString += "_constant"; 2233 2234 return typeString; 2235} 2236 2237class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance 2238{ 2239public: 2240 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes); 2241 2242 TestStatus iterate (void); 2243 virtual void setupDefaultInputs (void); 2244 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout); 2245 2246private: 2247 const ShaderInputTypes m_shaderInputTypes; 2248 const Vec4 m_constantColor; 2249}; 2250 2251BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes) 2252 : ShaderRenderCaseInstance (context) 2253 , m_shaderInputTypes (shaderInputTypes) 2254 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f) 2255{ 2256} 2257 2258TestStatus BuiltinInputVariationsCaseInstance::iterate (void) 2259{ 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 = 2268 { 2269 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 2270 0u, // deUint32 offset; 2271 sizeof(Vec4) // deUint32 size; 2272 }; 2273 const deUint16 indices[12] = 2274 { 2275 0, 4, 1, 2276 0, 5, 4, 2277 1, 2, 3, 2278 1, 3, 4 2279 }; 2280 2281 setup(); 2282 2283 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2284 setPushConstantRanges(1, &pcRanges); 2285 2286 render(6, 4, indices); 2287 copy(resImage.getAccess(), getResultImage().getAccess()); 2288 2289 // Reference image 2290 for (int y = 0; y < refImage.getHeight(); y++) 2291 { 2292 for (int x = 0; x < refImage.getWidth(); x++) 2293 { 2294 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f); 2295 2296 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) || 2297 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT)) 2298 { 2299 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT) 2300 { 2301 const float xf = (float(x)+.5f) / float(refImage.getWidth()); 2302 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f); 2303 } 2304 else 2305 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f); 2306 } 2307 2308 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2309 color += m_constantColor; 2310 2311 refImage.setPixel(x, y, RGBA(color)); 2312 } 2313 } 2314 2315 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT); 2316 2317 if (compareOk) 2318 return TestStatus::pass("Result image matches reference"); 2319 else 2320 return TestStatus::fail("Image mismatch"); 2321} 2322 2323void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void) 2324{ 2325 const float vertices[] = 2326 { 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 2333 }; 2334 2335 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices); 2336 2337 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT) 2338 { 2339 const float colors[] = 2340 { 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 2347 }; 2348 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors); 2349 } 2350} 2351 2352void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout) 2353{ 2354 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2355 { 2356 const DeviceInterface& vk = m_context.getDeviceInterface(); 2357 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor); 2358 } 2359} 2360 2361class BuiltinInputVariationsCase : public TestCase 2362{ 2363public: 2364 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const ShaderInputTypes shaderInputTypes); 2365 virtual ~BuiltinInputVariationsCase (void); 2366 2367 void initPrograms (SourceCollections& dst) const; 2368 TestInstance* createInstance (Context& context) const; 2369 2370private: 2371 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed! 2372 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed! 2373 const ShaderInputTypes m_shaderInputTypes; 2374}; 2375 2376BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, ShaderInputTypes shaderInputTypes) 2377 : TestCase (testCtx, name) 2378 , m_shaderInputTypes (shaderInputTypes) 2379{ 2380} 2381 2382BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void) 2383{ 2384} 2385 2386void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const 2387{ 2388 map<string, string> vertexParams; 2389 map<string, string> fragmentParams; 2390 const tcu::StringTemplate vertexCodeTemplate ( 2391 "#version 450\n" 2392 "layout(location = 0) in highp vec4 a_position;\n" 2393 "out gl_PerVertex {\n" 2394 " vec4 gl_Position;\n" 2395 "};\n" 2396 "${VARYING_DECL}" 2397 "void main (void)\n" 2398 "{\n" 2399 " gl_Position = a_position;\n" 2400 " ${VARYING_USAGE}" 2401 "}\n"); 2402 2403 const tcu::StringTemplate fragmentCodeTemplate ( 2404 "#version 450\n" 2405 "${VARYING_DECL}" 2406 "${CONSTANT_DECL}" 2407 "layout(location = 0) out highp vec4 o_color;\n" 2408 "void main (void)\n" 2409 "{\n" 2410 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n" 2411 " ${BUILTIN_USAGE}" 2412 " ${VARYING_USAGE}" 2413 " ${CONSTANT_USAGE}" 2414 "}\n"); 2415 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" 2419 : ""; 2420 2421 vertexParams["VARYING_USAGE"] = 2422 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n" 2423 : ""; 2424 2425 fragmentParams["VARYING_DECL"] = 2426 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n" 2427 : ""; 2428 2429 fragmentParams["CONSTANT_DECL"] = 2430 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n" 2431 " vec4 color;\n" 2432 "} pc;\n" 2433 : ""; 2434 2435 fragmentParams["BUILTIN_USAGE"] = 2436 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n" 2437 : ""; 2438 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"; 2442 2443 2444 fragmentParams["CONSTANT_USAGE"] = 2445 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n" 2446 : ""; 2447 2448 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams)); 2449 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams)); 2450} 2451 2452TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const 2453{ 2454 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes); 2455} 2456 2457} // anonymous 2458 2459TestCaseGroup* createBuiltinVarTests (TestContext& testCtx) 2460{ 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")); 2468 2469 // FragCoord xyz test 2470 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz")); 2471 // FragCoord w test 2472 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w")); 2473 // PointCoord test 2474 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", POINTCOORD_VARIANT_DEFAULT)); 2475 // PointCoord test with fragment uniform 2476 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_frag", POINTCOORD_VARIANT_UNIFORM_FRAGMENT)); 2477 // PointCoord test with vertex uniform 2478 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_vert", POINTCOORD_VARIANT_UNIFORM_VERTEX)); 2479 2480 // FragCoord_msaa 2481 { 2482 static const struct FragCoordMsaaCaseList 2483 { 2484 const char* name; 2485 VkSampleCountFlagBits sampleCount; 2486 } fragCoordMsaaCaseList[] = 2487 { 2488 { "1_bit", VK_SAMPLE_COUNT_1_BIT }, 2489 { "2_bit", VK_SAMPLE_COUNT_2_BIT }, 2490 { "4_bit", VK_SAMPLE_COUNT_4_BIT }, 2491 { "8_bit", VK_SAMPLE_COUNT_8_BIT }, 2492 { "16_bit", VK_SAMPLE_COUNT_16_BIT }, 2493 { "32_bit", VK_SAMPLE_COUNT_32_BIT }, 2494 { "64_bit", VK_SAMPLE_COUNT_64_BIT }, 2495 }; 2496 2497 // Standard sample tests 2498 std::vector<uint32_t> sampleMaskArray; 2499 2500 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++) 2501 { 2502 fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, true)); 2503 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, false)); 2504 } 2505 2506 sampleMaskArray.push_back(1u); 2507 2508 // No sample shading tests 2509 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++) 2510 { 2511 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading").c_str(), fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, false, false)); 2512 } 2513 2514 // No sample shading tests with centroid interpolation decoration 2515 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++) 2516 { 2517 fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading_centroid_interpolation").c_str(), fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, true, false)); 2518 } 2519 } 2520 2521 // gl_FrontFacing tests 2522 { 2523 static const struct PrimitiveTable 2524 { 2525 const char* name; 2526 VkPrimitiveTopology primitive; 2527 } frontfacingCases[] = 2528 { 2529 // Test that points are frontfacing 2530 { "point_list", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 2531 // Test that lines are frontfacing 2532 { "line_list", VK_PRIMITIVE_TOPOLOGY_LINE_LIST }, 2533 // Test that triangles can be frontfacing or backfacing 2534 { "triangle_list", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST }, 2535 // Test that traiangle strips can be front or back facing 2536 { "triangle_strip", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 2537 // Test that triangle fans can be front or back facing 2538 { "triangle_fan", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN }, 2539 }; 2540 2541 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++) 2542 frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name)); 2543 } 2544 2545 // gl_FragDepth 2546 { 2547 static const struct PrimitiveTopologyTable 2548 { 2549 std::string name; 2550 VkPrimitiveTopology prim; 2551 } primitiveTopologyTable[] = 2552 { 2553 // test that points respect gl_fragdepth 2554 { "point_list", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 2555 // test taht lines respect gl_fragdepth 2556 { "line_list", VK_PRIMITIVE_TOPOLOGY_LINE_LIST }, 2557 // test that triangles respect gl_fragdepth 2558 { "triangle_list", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 2559 }; 2560 2561 static const struct TestCaseTable 2562 { 2563 VkFormat format; 2564 std::string name; 2565 bool largeDepthEnable; 2566 bool depthClampEnable; 2567 VkSampleCountFlagBits samples; 2568 } testCaseTable[] = 2569 { 2570 { VK_FORMAT_D16_UNORM, "d16_unorm_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2571 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2572 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2573 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2574 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2575 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2576 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_large_depth", true, false, VK_SAMPLE_COUNT_1_BIT }, 2577 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", false, true, VK_SAMPLE_COUNT_1_BIT }, 2578 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", false, true, VK_SAMPLE_COUNT_1_BIT }, 2579 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_2", false, false, VK_SAMPLE_COUNT_2_BIT }, 2580 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_4", false, false, VK_SAMPLE_COUNT_4_BIT }, 2581 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_8", false, false, VK_SAMPLE_COUNT_8_BIT }, 2582 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_16", false, false, VK_SAMPLE_COUNT_16_BIT }, 2583 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_32", false, false, VK_SAMPLE_COUNT_32_BIT }, 2584 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_64", false, false, VK_SAMPLE_COUNT_64_BIT }, 2585 }; 2586 2587 for (deUint32 primNdx = 0; primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++) 2588 { 2589 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++) 2590 fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), 2591 primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples)); 2592 2593 } 2594 } 2595 2596 builtinGroup->addChild(frontFacingGroup.release()); 2597 builtinGroup->addChild(fragDepthGroup.release()); 2598 builtinGroup->addChild(fragCoordMsaaGroup.release()); 2599 builtinGroup->addChild(fragCoordMsaaInputGroup.release()); 2600 builtinGroup->addChild(simpleGroup.release()); 2601 2602 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType) 2603 { 2604 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), shaderType)); 2605 } 2606 2607 builtinGroup->addChild(inputVariationsGroup.release()); 2608 return builtinGroup.release(); 2609} 2610 2611} // sr 2612} // vkt 2613