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 42#include "deMath.h" 43#include "deRandom.hpp" 44 45#include <map> 46 47using namespace std; 48using namespace tcu; 49using namespace vk; 50using namespace de; 51 52namespace vkt 53{ 54using namespace drawutil; 55 56namespace sr 57{ 58 59namespace 60{ 61 62enum 63{ 64 FRONTFACE_RENDERWIDTH = 16, 65 FRONTFACE_RENDERHEIGHT = 16 66}; 67 68class FrontFacingVertexShader : public rr::VertexShader 69{ 70public: 71 FrontFacingVertexShader (void) 72 : rr::VertexShader(1, 0) 73 { 74 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 75 } 76 77 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 78 { 79 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 80 { 81 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0], 82 packets[packetNdx]->instanceNdx, 83 packets[packetNdx]->vertexNdx); 84 } 85 } 86}; 87 88class FrontFacingFragmentShader : public rr::FragmentShader 89{ 90public: 91 FrontFacingFragmentShader (void) 92 : rr::FragmentShader(0, 1) 93 { 94 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 95 } 96 97 void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const 98 { 99 tcu::Vec4 color; 100 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 101 { 102 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx) 103 { 104 if (context.visibleFace == rr::FACETYPE_FRONT) 105 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 106 else 107 color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); 108 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 109 } 110 } 111 } 112}; 113 114class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance 115{ 116public: 117 BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology); 118 119 TestStatus iterate (void); 120private: 121 const VkPrimitiveTopology m_topology; 122}; 123 124BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology) 125 : ShaderRenderCaseInstance (context) 126 , m_topology (topology) 127{ 128} 129 130 131TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void) 132{ 133 TestLog& log = m_context.getTestContext().getLog(); 134 std::vector<Vec4> vertices; 135 std::vector<VulkanShader> shaders; 136 FrontFacingVertexShader vertexShader; 137 FrontFacingFragmentShader fragmentShader; 138 std::string testDesc; 139 140 vertices.push_back(Vec4( -0.75f, -0.75f, 0.0f, 1.0f)); 141 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f)); 142 vertices.push_back(Vec4( -0.37f, 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.75f, -0.75f, 0.0f, 1.0f)); 145 vertices.push_back(Vec4( 0.0f, -0.75f, 0.0f, 1.0f)); 146 147 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert"))); 148 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("frag"))); 149 150 testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " "; 151 152 DrawState drawState (m_topology, FRONTFACE_RENDERWIDTH, FRONTFACE_RENDERHEIGHT); 153 DrawCallData drawCallData (vertices); 154 VulkanProgram vulkanProgram (shaders); 155 156 VulkanDrawContext dc(m_context, drawState, drawCallData, vulkanProgram); 157 dc.draw(); 158 159 ReferenceDrawContext refDrawContext(drawState, drawCallData, vertexShader, fragmentShader); 160 refDrawContext.draw(); 161 162 log << TestLog::Image( "reference", 163 "reference", 164 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 165 refDrawContext.getColorPixels().getFormat()), 166 refDrawContext.getColorPixels().getWidth(), 167 refDrawContext.getColorPixels().getHeight(), 168 1, 169 refDrawContext.getColorPixels().getDataPtr())); 170 171 log << TestLog::Image( "result", 172 "result", 173 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 174 dc.getColorPixels().getFormat()), 175 dc.getColorPixels().getWidth(), 176 dc.getColorPixels().getHeight(), 177 1, 178 dc.getColorPixels().getDataPtr())); 179 180 if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 181 "ComparisonResult", 182 "Image comparison result", 183 refDrawContext.getColorPixels(), 184 dc.getColorPixels(), 185 UVec4(0u), 186 IVec3(1,1,0), 187 false, 188 tcu::COMPARE_LOG_RESULT)) 189 { 190 testDesc += "passed"; 191 return tcu::TestStatus::pass(testDesc.c_str()); 192 } 193 else 194 { 195 testDesc += "failed"; 196 return tcu::TestStatus::fail(testDesc.c_str()); 197 } 198} 199 200class BuiltinGlFrontFacingCase : public TestCase 201{ 202public: 203 BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description); 204 virtual ~BuiltinGlFrontFacingCase (void); 205 206 void initPrograms (SourceCollections& dst) const; 207 TestInstance* createInstance (Context& context) const; 208 209private: 210 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed! 211 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed! 212 213 const VkPrimitiveTopology m_topology; 214}; 215 216BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description) 217 : TestCase (testCtx, name, description) 218 , m_topology (topology) 219{ 220} 221 222BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void) 223{ 224} 225 226void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const 227{ 228 { 229 std::ostringstream vertexSource; 230 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 231 << "\n" 232 << "layout(location = 0) in highp vec4 position;\n" 233 << "void main()\n" 234 << "{\n" 235 << "gl_Position = position;\n" 236 << "gl_PointSize = 1.0;\n" 237 << "}\n"; 238 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str()); 239 } 240 241 { 242 std::ostringstream fragmentSource; 243 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 244 << "\n" 245 << "layout(location = 0) out mediump vec4 color;\n" 246 << "void main()\n" 247 << "{\n" 248 << "if (gl_FrontFacing)\n" 249 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 250 << "else\n" 251 << " color = vec4(0.0, 1.0, 0.0, 1.0);\n" 252 << "}\n"; 253 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str()); 254 } 255} 256 257TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const 258{ 259 return new BuiltinGlFrontFacingCaseInstance(context, m_topology); 260} 261 262class BuiltinFragDepthCaseInstance : public TestInstance 263{ 264public: 265 enum 266 { 267 RENDERWIDTH = 16, 268 RENDERHEIGHT = 16 269 }; 270 BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples); 271 TestStatus iterate (void); 272 273 bool validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const; 274private: 275 const VkPrimitiveTopology m_topology; 276 const VkFormat m_format; 277 const bool m_largeDepthEnable; 278 const float m_defaultDepthValue; 279 const bool m_depthClampEnable; 280 const VkSampleCountFlagBits m_samples; 281 const tcu::UVec2 m_renderSize; 282 const float m_largeDepthBase; 283}; 284 285BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples) 286 : TestInstance (context) 287 , m_topology (topology) 288 , m_format (format) 289 , m_largeDepthEnable (largeDepthEnable) 290 , m_defaultDepthValue (defaultDepth) 291 , m_depthClampEnable (depthClampEnable) 292 , m_samples (samples) 293 , m_renderSize (RENDERWIDTH, RENDERHEIGHT) 294 , m_largeDepthBase (20.0f) 295{ 296 const InstanceInterface& vki = m_context.getInstanceInterface(); 297 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 298 299 try 300 { 301 VkImageFormatProperties imageFormatProperties; 302 VkFormatProperties formatProperties; 303 304 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE) 305 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported"); 306 307 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D, 308 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0); 309 310 if ((imageFormatProperties.sampleCounts & m_samples) == 0) 311 throw tcu::NotSupportedError("Image format and sample count not supported"); 312 313 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT); 314 315 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0) 316 throw tcu::NotSupportedError("MarkerImage format not supported as storage image"); 317 318 if (m_largeDepthEnable && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted")) 319 throw tcu::NotSupportedError("large_depth test variants require the VK_EXT_depth_range_unrestricted extension"); 320 } 321 catch (const vk::Error& e) 322 { 323 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED) 324 throw tcu::NotSupportedError("Image format not supported"); 325 else 326 throw; 327 328 } 329} 330 331TestStatus BuiltinFragDepthCaseInstance::iterate (void) 332{ 333 const VkDevice device = m_context.getDevice(); 334 const DeviceInterface& vk = m_context.getDeviceInterface(); 335 const VkQueue queue = m_context.getUniversalQueue(); 336 Allocator& allocator = m_context.getDefaultAllocator(); 337 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 338 TestLog& log = m_context.getTestContext().getLog(); 339 const deUint32 scale = 4; // To account for std140 stride 340 const VkDeviceSize pixelCount = m_renderSize.x() * m_renderSize.y(); 341 std::string testDesc; 342 Move<VkImage> depthResolveImage; 343 Move<VkImageView> depthResolveImageView; 344 MovePtr<Allocation> depthResolveAllocation; 345 Move<VkImage> depthImage; 346 Move<VkImageView> depthImageView; 347 MovePtr<Allocation> depthImageAllocation; 348 Move<VkBuffer> controlBuffer; 349 MovePtr<Allocation> controlBufferAllocation; 350 Move<VkImage> markerImage; 351 Move<VkImageView> markerImageView; 352 MovePtr<Allocation> markerImageAllocation; 353 Move<VkBuffer> markerBuffer; 354 MovePtr<Allocation> markerBufferAllocation; 355 Move<VkBuffer> validationBuffer; 356 MovePtr<Allocation> validationAlloc; 357 MovePtr<Allocation> depthInitAllocation; 358 Move<VkCommandPool> cmdPool; 359 Move<VkCommandBuffer> transferCmdBuffer; 360 Move<VkFence> fence; 361 Move<VkSampler> depthSampler; 362 363 // Create Buffer/Image for validation 364 { 365 VkFormat resolvedBufferFormat = VK_FORMAT_R32_SFLOAT; 366 const VkBufferCreateInfo validationBufferCreateInfo = 367 { 368 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType 369 DE_NULL, // const void* pNext 370 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags 371 m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)), // VkDeviceSize size 372 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage 373 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 374 0u, // uint32_t queueFamilyIndexCount, 375 DE_NULL // const uint32_t* pQueueFamilyIndices 376 }; 377 378 validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo); 379 validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible); 380 VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset())); 381 382 const VkImageCreateInfo depthResolveImageCreateInfo = 383 { 384 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 385 DE_NULL, // const void* pNext 386 (VkImageCreateFlags)0, // VkImageCreateFlags flags 387 VK_IMAGE_TYPE_2D, // VkIMageType imageType 388 resolvedBufferFormat, // VkFormat format 389 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent 390 1u, // uint32_t mipLevels 391 1u, // uint32_t arrayLayers 392 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBits samples 393 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 394 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage 395 VK_IMAGE_USAGE_STORAGE_BIT | 396 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 397 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 398 0u, // uint32_t queueFamilyIndexCount 399 DE_NULL, // const uint32_t pQueueFamilyIndices 400 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 401 }; 402 403 depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL); 404 depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any); 405 VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset())); 406 407 const VkImageViewCreateInfo depthResolveImageViewCreateInfo = 408 { 409 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType 410 DE_NULL, // const void* pNext 411 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags 412 *depthResolveImage, // VkImage image 413 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType type 414 resolvedBufferFormat, // VkFormat format 415 makeComponentMappingRGBA(), // VkComponentMapping componentMapping 416 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u) // VkImageSUbresourceRange subresourceRange 417 }; 418 419 depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL); 420 } 421 422 // Marker Buffer 423 { 424 const VkDeviceSize size = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT)); 425 426 const VkBufferCreateInfo markerBufferCreateInfo = 427 { 428 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType 429 DE_NULL, // const void* pNext 430 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags 431 size, // VkDeviceSize size 432 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage 433 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 434 0u, // uint32_t queueFamilyIndexCount 435 DE_NULL // const uint32_t* pQueueFamilyIndices 436 }; 437 438 markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL); 439 markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible); 440 VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset())); 441 442 const VkImageCreateInfo markerImageCreateInfo = 443 { 444 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 445 DE_NULL, // const void* pNext 446 (VkImageCreateFlags)0, // VkImageCreateFlags flags 447 VK_IMAGE_TYPE_2D, // VkImageType imageType 448 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format 449 makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D extent 450 1u, // uint32_t mipLevels 451 1u, // uint32_t arrayLayers 452 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagsBit smaples 453 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 454 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage 455 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 456 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 457 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharing 458 0u, // uint32_t queueFamilyIndexCount 459 DE_NULL, // const uint32_t* pQueueFamilyIndices 460 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 461 }; 462 463 markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL); 464 markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any); 465 VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset())); 466 467 const VkImageViewCreateInfo markerViewCreateInfo = 468 { 469 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType 470 DE_NULL, // const void* pNext 471 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags 472 *markerImage, // VkImage image 473 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType 474 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format 475 makeComponentMappingRGBA(), // VkComponentMapping components 476 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u) 477 }; 478 479 markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL); 480 } 481 482 // Control Buffer 483 { 484 const VkBufferCreateInfo controlBufferCreateInfo = 485 { 486 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType 487 DE_NULL, // const void* pNext 488 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags 489 pixelCount * sizeof(float)* scale, // VkDeviceSize size 490 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage 491 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 492 0u, // deUint32 queueFamilyIndexCount 493 494 DE_NULL // pQueueFamilyIndices 495 }; 496 497 controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL); 498 controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible); 499 VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset())); 500 501 { 502 float* bufferData = (float*)(controlBufferAllocation->getHostPtr()); 503 float sign = m_depthClampEnable ? -1.0f : 1.0f; 504 for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++) 505 { 506 bufferData[ndx * scale] = (float)ndx / 256.0f * sign; 507 if (m_largeDepthEnable) 508 bufferData[ndx * scale] += m_largeDepthBase; 509 } 510 511 const VkMappedMemoryRange range = 512 { 513 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 514 DE_NULL, 515 controlBufferAllocation->getMemory(), 516 0u, 517 VK_WHOLE_SIZE 518 }; 519 520 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range)); 521 } 522 } 523 524 // Depth Buffer 525 { 526 VkImageSubresourceRange depthSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u); 527 const VkImageCreateInfo depthImageCreateInfo = 528 { 529 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 530 DE_NULL, // const void* pNext 531 (VkImageCreateFlags)0, // VkImageCreateFlags flags 532 VK_IMAGE_TYPE_2D, // VkImageType imageType 533 m_format, // VkFormat format 534 makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent 535 1u, // uint32_t mipLevels 536 1u, // uint32_t arrayLayers 537 m_samples, // VkSampleCountFlagsBits samples 538 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 539 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 540 VK_IMAGE_USAGE_TRANSFER_DST_BIT | 541 VK_IMAGE_USAGE_SAMPLED_BIT | 542 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage 543 VK_SHARING_MODE_EXCLUSIVE, // VkShaderingMode sharingMode 544 0u, // uint32_t queueFamilyIndexCount 545 DE_NULL, // const uint32_t* pQueueFamilyIndices 546 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 547 }; 548 549 depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL); 550 depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any); 551 VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset())); 552 553 const VkImageViewCreateInfo imageViewParams = 554 { 555 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 556 DE_NULL, // const void* pNext; 557 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 558 *depthImage, // VkImage image; 559 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 560 m_format, // VkFormat format; 561 makeComponentMappingRGBA(), // VkComponentMapping components; 562 depthSubresourceRange, // VkImageSubresourceRange subresourceRange; 563 }; 564 depthImageView = createImageView(vk, device, &imageViewParams); 565 566 const VkSamplerCreateInfo depthSamplerCreateInfo = 567 { 568 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType 569 DE_NULL, // const void* pNext 570 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags 571 VK_FILTER_NEAREST, // VkFilter minFilter 572 VK_FILTER_NEAREST, // VkFilter magFilter 573 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipMapMode mipMapMode 574 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU 575 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV 576 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressmodeW 577 0.0f, // float mipLodBias 578 VK_FALSE, // VkBool32 anisotropyEnable 579 0.0f, // float maxAnisotropy 580 VK_FALSE, // VkBool32 compareEnable 581 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp 582 0.0f, // float minLod 583 0.0f, // float maxLod 584 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor 585 VK_FALSE // VkBool32 unnormalizedCoordinates 586 }; 587 588 depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL); 589 } 590 591 // Command Pool 592 { 593 const VkCommandPoolCreateInfo cmdPoolCreateInfo = 594 { 595 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType 596 DE_NULL, // const void* pNext 597 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags 598 queueFamilyIndex // uint32_t queueFamilyIndex 599 }; 600 601 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo); 602 } 603 604 // Command buffer for data transfers 605 { 606 const VkCommandBufferAllocateInfo cmdBufferAllocInfo = 607 { 608 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType, 609 DE_NULL, // const void* pNext 610 *cmdPool, // VkCommandPool commandPool 611 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level 612 1u // uint32_t bufferCount 613 }; 614 615 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo); 616 } 617 618 // Fence for data transfer 619 { 620 const VkFenceCreateInfo fenceCreateInfo = 621 { 622 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType 623 DE_NULL, // const void* pNext 624 (VkFenceCreateFlags)0 // VkFenceCreateFlags flags 625 }; 626 627 fence = createFence(vk, device, &fenceCreateInfo); 628 } 629 630 // Initialize Marker Buffer 631 { 632 VkImageAspectFlags depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; 633 if (hasStencilComponent(mapVkFormat(m_format).order)) 634 depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; 635 636 const VkImageMemoryBarrier imageBarrier[] = 637 { 638 { 639 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 640 DE_NULL, // const void* pNext 641 0, // VkAccessMask srcAccessMask 642 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessMask dstAccessMask 643 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout 644 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout 645 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 646 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 647 *markerImage, // VkImage image 648 { 649 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 650 0u, // uint32_t baseMipLevel 651 1u, // uint32_t mipLevels 652 0u, // uint32_t baseArray 653 1u // uint32_t arraySize 654 } 655 }, 656 }; 657 658 const VkImageMemoryBarrier imagePostBarrier[] = 659 { 660 { 661 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 662 DE_NULL, // const void* pNext 663 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlagBits srcAccessMask 664 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlagBits dstAccessMask 665 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout 666 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout 667 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 668 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 669 *markerImage, // VkImage image 670 { 671 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 672 0u, // uint32_t baseMipLevel 673 1u, // uint32_t mipLevels 674 0u, // uint32_t baseArray 675 1u // uint32_t arraySize 676 } 677 }, 678 }; 679 680 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 681 { 682 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 683 DE_NULL, // const void* pNext 684 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 685 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 686 }; 687 688 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 689 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 690 (VkDependencyFlags)0, 691 0, (const VkMemoryBarrier*)DE_NULL, 692 0, (const VkBufferMemoryBarrier*)DE_NULL, 693 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier); 694 695 const VkClearValue colorClearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 696 const VkImageSubresourceRange colorClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 697 698 vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange); 699 700 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 701 (VkDependencyFlags)0, 702 0, (const VkMemoryBarrier*)DE_NULL, 703 0, (const VkBufferMemoryBarrier*)DE_NULL, 704 DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier); 705 706 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 707 708 const VkSubmitInfo submitInfo = 709 { 710 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 711 DE_NULL, // const void* pNext 712 0u, // uint32_t waitSemaphoreCount 713 DE_NULL, // const VkSemaphore* pWaitSemaphores 714 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 715 1u, // uint32_t commandBufferCount 716 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 717 0u, // uint32_t signalSemaphoreCount 718 DE_NULL // const VkSemaphore* pSignalSemaphores 719 }; 720 721 VK_CHECK(vk.resetFences(device, 1, &fence.get())); 722 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 723 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull))); 724 } 725 726 727 // Perform Draw 728 { 729 std::vector<Vec4> vertices; 730 std::vector<VulkanShader> shaders; 731 Move<VkDescriptorSetLayout> descriptorSetLayout; 732 Move<VkDescriptorPool> descriptorPool; 733 Move<VkDescriptorSet> descriptorSet; 734 735 // Descriptors 736 { 737 DescriptorSetLayoutBuilder layoutBuilder; 738 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT); 739 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); 740 descriptorSetLayout = layoutBuilder.build(vk, device); 741 descriptorPool = DescriptorPoolBuilder() 742 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 743 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 744 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 745 746 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 747 { 748 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 749 DE_NULL, 750 *descriptorPool, 751 1u, 752 &descriptorSetLayout.get() 753 }; 754 755 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 756 757 const VkDescriptorBufferInfo bufferInfo = 758 { 759 *controlBuffer, 760 0u, 761 VK_WHOLE_SIZE 762 }; 763 764 const VkDescriptorImageInfo imageInfo = 765 { 766 (VkSampler)DE_NULL, 767 *markerImageView, 768 VK_IMAGE_LAYOUT_GENERAL 769 }; 770 771 DescriptorSetUpdateBuilder() 772 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo) 773 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo) 774 .update(vk, device); 775 } 776 777 vertices.push_back(Vec4( -0.70f, 0.5f, 0.0f, 1.0f)); 778 vertices.push_back(Vec4( 0.45f, -0.75f, 0.0f, 1.0f)); 779 vertices.push_back(Vec4( 0.78f, 0.0f, 0.0f, 1.0f)); 780 vertices.push_back(Vec4( -0.1f, 0.6f, 0.0f, 1.0f)); 781 782 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert"))); 783 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag"))); 784 785 DrawState drawState(m_topology, m_renderSize.x(), m_renderSize.y()); 786 DrawCallData drawCallData(vertices); 787 VulkanProgram vulkanProgram(shaders); 788 789 drawState.depthClampEnable = m_depthClampEnable; 790 drawState.depthFormat = m_format; 791 drawState.numSamples = m_samples; 792 drawState.compareOp = rr::TESTFUNC_ALWAYS; 793 drawState.depthTestEnable = true; 794 drawState.depthWriteEnable = true; 795 drawState.sampleShadingEnable = true; 796 vulkanProgram.depthImageView = *depthImageView; 797 vulkanProgram.descriptorSetLayout = *descriptorSetLayout; 798 vulkanProgram.descriptorSet = *descriptorSet; 799 800 VulkanDrawContext vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram); 801 vulkanDrawContext.draw(); 802 803 log << TestLog::Image( "resultColor", 804 "Result Color Buffer", 805 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 806 vulkanDrawContext.getColorPixels().getFormat()), 807 vulkanDrawContext.getColorPixels().getWidth(), 808 vulkanDrawContext.getColorPixels().getHeight(), 809 1, 810 vulkanDrawContext.getColorPixels().getDataPtr())); 811 } 812 813 // Barrier to transition between first and second pass 814 { 815 VkImageAspectFlags depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; 816 if (hasStencilComponent(mapVkFormat(m_format).order)) 817 depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; 818 819 const VkImageMemoryBarrier imageBarrier[] = 820 { 821 { 822 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 823 DE_NULL, // const void* pNext 824 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 825 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask 826 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout 827 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout 828 0u, // deUint32 srcQueueFamilyIndex 829 0u, // deUint32 dstQueueFamilyIndex 830 *depthImage, // VkImage image 831 { 832 depthImageAspectFlags, // VkImageAspectFlags aspectMask 833 0u, // deUint32 baseMipLevel 834 1u, // deUint32 levelCount 835 0u, // deUint32 baseArrayLayer 836 1u // deUint32 layerCount 837 } 838 }, 839 { 840 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 841 DE_NULL, // const void* pNext 842 0u, // VkAccessFlags srcAccessMask 843 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask 844 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout 845 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout 846 0u, // deUint32 srcQueueFamilyIndex 847 0u, // deUint32 dstQueueFamilyIndex 848 *depthResolveImage, // VkImage image 849 { 850 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 851 0u, // deUint32 baseMipLevel 852 1u, // deUint32 levelCount 853 0u, // deUint32 baseArrayLayer 854 1u, // deUint32 layerCount 855 856 } 857 } 858 }; 859 860 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 861 { 862 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 863 DE_NULL, // const void* pNext 864 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 865 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 866 }; 867 868 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 869 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 870 (VkDependencyFlags)0, 871 0, (const VkMemoryBarrier*)DE_NULL, 872 0, (const VkBufferMemoryBarrier*)DE_NULL, 873 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier); 874 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 875 876 const VkSubmitInfo submitInfo = 877 { 878 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 879 DE_NULL, // const void* pNext 880 0u, // uint32_t waitSemaphoreCount 881 DE_NULL, // const VkSemaphore* pWaitSemaphores 882 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 883 1u, // uint32_t commandBufferCount 884 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 885 0u, // uint32_t signalSemaphoreCount 886 DE_NULL // const VkSemaphore* pSignalSemaphores 887 }; 888 889 VK_CHECK(vk.resetFences(device, 1, &fence.get())); 890 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 891 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull))); 892 } 893 894 // Resolve Depth Buffer 895 { 896 std::vector<Vec4> vertices; 897 std::vector<VulkanShader> shaders; 898 Move<VkDescriptorSetLayout> descriptorSetLayout; 899 Move<VkDescriptorPool> descriptorPool; 900 Move<VkDescriptorSet> descriptorSet; 901 902 // Descriptors 903 { 904 DescriptorSetLayoutBuilder layoutBuilder; 905 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT); 906 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); 907 descriptorSetLayout = layoutBuilder.build(vk, device); 908 descriptorPool = DescriptorPoolBuilder() 909 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 910 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 911 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 912 913 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 914 { 915 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 916 DE_NULL, 917 *descriptorPool, 918 1u, 919 &descriptorSetLayout.get() 920 }; 921 922 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 923 924 const VkDescriptorImageInfo depthImageInfo = 925 { 926 *depthSampler, 927 *depthImageView, 928 VK_IMAGE_LAYOUT_GENERAL 929 }; 930 931 const VkDescriptorImageInfo imageInfo = 932 { 933 (VkSampler)DE_NULL, 934 *depthResolveImageView, 935 VK_IMAGE_LAYOUT_GENERAL 936 }; 937 938 DescriptorSetUpdateBuilder() 939 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo) 940 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo) 941 .update(vk, device); 942 } 943 944 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f)); 945 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f)); 946 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f)); 947 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f)); 948 949 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2"))); 950 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2"))); 951 952 DrawState drawState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_renderSize.x(), m_renderSize.y()); 953 DrawCallData drawCallData(vertices); 954 VulkanProgram vulkanProgram(shaders); 955 956 drawState.numSamples = m_samples; 957 drawState.sampleShadingEnable = true; 958 vulkanProgram.descriptorSetLayout = *descriptorSetLayout; 959 vulkanProgram.descriptorSet = *descriptorSet; 960 961 VulkanDrawContext vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram); 962 vulkanDrawContext.draw(); 963 } 964 965 // Transfer marker buffer 966 { 967 const UVec2 copySize = UVec2(m_renderSize.x() * m_samples, m_renderSize.y()); 968 const VkImageMemoryBarrier imageBarrier = 969 { 970 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 971 DE_NULL, // const void* pNext 972 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask 973 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessMask dstAccessMask 974 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout 975 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout 976 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 977 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 978 *markerImage, // VkImage image 979 { 980 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 981 0u, // uint32_t baseMipLevel 982 1u, // uint32_t mipLevels 983 0u, // uint32_t baseArray 984 1u // uint32_t arraySize 985 } 986 }; 987 988 const VkBufferMemoryBarrier bufferBarrier = 989 { 990 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType 991 DE_NULL, // const void* pNext 992 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 993 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask 994 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 995 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 996 *markerBuffer, // VkBufer buffer 997 0u, // VkDeviceSize offset 998 VK_WHOLE_SIZE // VkDeviceSize size 999 }; 1000 1001 const VkBufferImageCopy bufferImageCopy = 1002 { 1003 0u, // VkDeviceSize bufferOffset 1004 copySize.x(), // uint32_t bufferRowLength 1005 copySize.y(), // uint32_t bufferImageHeight 1006 { 1007 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect 1008 0u, // uint32_t mipLevel 1009 0u, // uint32_t baseArrayLayer 1010 1u // uint32_t layerCount 1011 }, 1012 { 0, 0, 0 }, // VkOffset3D imageOffset 1013 { 1014 copySize.x(), // uint32_t width 1015 copySize.y(), // uint32_t height, 1016 1u // uint32_t depth 1017 } 1018 }; 1019 1020 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1021 { 1022 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 1023 DE_NULL, // const void* pNext 1024 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 1025 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 1026 }; 1027 1028 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 1029 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1030 (VkDependencyFlags)0, 1031 0, (const VkMemoryBarrier*)DE_NULL, 1032 0, (const VkBufferMemoryBarrier*)DE_NULL, 1033 1, &imageBarrier); 1034 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *markerBuffer, 1u, &bufferImageCopy); 1035 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 1036 (VkDependencyFlags)0, 1037 0, (const VkMemoryBarrier*)DE_NULL, 1038 1, &bufferBarrier, 1039 0, (const VkImageMemoryBarrier*)DE_NULL); 1040 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 1041 1042 const VkSubmitInfo submitInfo = 1043 { 1044 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 1045 DE_NULL, // const void* pNext 1046 0u, // uint32_t waitSemaphoreCount 1047 DE_NULL, // const VkSemaphore* pWaitSemaphores 1048 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 1049 1u, // uint32_t commandBufferCount 1050 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 1051 0u, // uint32_t signalSemaphoreCount 1052 DE_NULL // const VkSemaphore* pSignalSemaphores 1053 }; 1054 1055 VK_CHECK(vk.resetFences(device, 1, &fence.get())); 1056 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1057 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull))); 1058 } 1059 1060 // Verify depth buffer 1061 { 1062 bool status; 1063 1064 const VkBufferMemoryBarrier bufferBarrier = 1065 { 1066 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType 1067 DE_NULL, // const void* pNext 1068 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 1069 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask 1070 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1071 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1072 *validationBuffer, // VkBuffer buffer 1073 0u, // VkDeviceSize offset 1074 VK_WHOLE_SIZE // VkDeviceSize size 1075 }; 1076 1077 const VkImageMemoryBarrier imageBarrier = 1078 { 1079 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1080 DE_NULL, // const void* pNext 1081 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask 1082 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask 1083 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout 1084 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout 1085 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1086 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1087 *depthResolveImage, // VkImage image 1088 { 1089 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 1090 0u, // uint32_t baseMipLevel 1091 1u, // uint32_t mipLevels, 1092 0u, // uint32_t baseArray 1093 1u, // uint32_t arraySize 1094 } 1095 }; 1096 1097 const VkBufferImageCopy bufferImageCopy = 1098 { 1099 0u, // VkDeviceSize bufferOffset 1100 m_samples * m_renderSize.x(), // uint32_t bufferRowLength 1101 m_renderSize.y(), // uint32_t bufferImageHeight 1102 { 1103 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect 1104 0u, // uint32_t mipLevel 1105 0u, // uint32_t baseArrayLayer 1106 1u // uint32_t layerCount 1107 }, 1108 { 0, 0, 0 }, // VkOffset3D imageOffset 1109 { 1110 m_samples * m_renderSize.x(), // uint32_t width 1111 m_renderSize.y(), // uint32_t height 1112 1u // uint32_t depth 1113 } 1114 }; 1115 1116 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1117 { 1118 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 1119 DE_NULL, // const void* pNext 1120 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 1121 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 1122 }; 1123 1124 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 1125 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1126 (VkDependencyFlags)0, 1127 0, (const VkMemoryBarrier*)DE_NULL, 1128 0, (const VkBufferMemoryBarrier*)DE_NULL, 1129 1, &imageBarrier); 1130 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *depthResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *validationBuffer, 1u, &bufferImageCopy); 1131 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 1132 (VkDependencyFlags)0, 1133 0, (const VkMemoryBarrier*)DE_NULL, 1134 1, &bufferBarrier, 1135 0, (const VkImageMemoryBarrier*)DE_NULL); 1136 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 1137 1138 const VkSubmitInfo submitInfo = 1139 { 1140 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 1141 DE_NULL, // const void* pNext 1142 0u, // uint32_t waitSemaphoreCount 1143 DE_NULL, // const VkSemaphore* pWaitSemaphores 1144 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 1145 1u, // uint32_t commandBufferCount 1146 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 1147 0u, // uint32_t signalSemaphoreCount 1148 DE_NULL // const VkSemaphore* pSignalSemaphores 1149 }; 1150 1151 VK_CHECK(vk.resetFences(device, 1, &fence.get())); 1152 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1153 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull))); 1154 1155 invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE); 1156 invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE); 1157 1158 tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr()); 1159 tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr()); 1160 status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f); 1161 testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " "; 1162 if (status) 1163 { 1164 testDesc += "passed"; 1165 return tcu::TestStatus::pass(testDesc.c_str()); 1166 } 1167 else 1168 { 1169 log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer); 1170 testDesc += "failed"; 1171 return tcu::TestStatus::fail(testDesc.c_str()); 1172 } 1173 } 1174} 1175 1176bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const 1177{ 1178 TestLog& log = m_context.getTestContext().getLog(); 1179 1180 for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++) 1181 { 1182 for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++) 1183 { 1184 const float multiplier = m_depthClampEnable ? 0.0f : 1.0f; 1185 float expectedValue = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier; 1186 1187 if (m_largeDepthEnable) 1188 expectedValue += m_largeDepthBase; 1189 1190 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++) 1191 { 1192 const float actualValue = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x(); 1193 const float markerValue = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x(); 1194 1195 if (markerValue != 0) 1196 { 1197 if (de::abs(expectedValue - actualValue) > tolerance) 1198 { 1199 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage; 1200 return false; 1201 } 1202 } 1203 else 1204 { 1205 if (de::abs(actualValue - m_defaultDepthValue) > tolerance) 1206 { 1207 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage; 1208 return false; 1209 } 1210 } 1211 } 1212 } 1213 } 1214 1215 return true; 1216} 1217 1218class BuiltinFragCoordMsaaCaseInstance : public TestInstance 1219{ 1220public: 1221 enum 1222 { 1223 RENDERWIDTH = 16, 1224 RENDERHEIGHT = 16 1225 }; 1226 BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount); 1227 TestStatus iterate (void); 1228private: 1229 bool validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const; 1230 1231 const tcu::UVec2 m_renderSize; 1232 const VkSampleCountFlagBits m_sampleCount; 1233}; 1234 1235BuiltinFragCoordMsaaCaseInstance::BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount) 1236 : TestInstance (context) 1237 , m_renderSize (RENDERWIDTH, RENDERHEIGHT) 1238 , m_sampleCount (sampleCount) 1239{ 1240 const InstanceInterface& vki = m_context.getInstanceInterface(); 1241 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 1242 1243 try 1244 { 1245 VkImageFormatProperties imageFormatProperties; 1246 VkFormatProperties formatProperties; 1247 1248 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE) 1249 throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported"); 1250 1251 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_TYPE_2D, 1252 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, (VkImageCreateFlags)0); 1253 1254 if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0) 1255 throw tcu::NotSupportedError("Image format and sample count not supported"); 1256 1257 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT); 1258 1259 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0) 1260 throw tcu::NotSupportedError("Output format not supported as storage image"); 1261 } 1262 catch (const vk::Error& e) 1263 { 1264 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED) 1265 throw tcu::NotSupportedError("Image format not supported"); 1266 else 1267 throw; 1268 1269 } 1270} 1271 1272TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void) 1273{ 1274 const VkDevice device = m_context.getDevice(); 1275 const DeviceInterface& vk = m_context.getDeviceInterface(); 1276 const VkQueue queue = m_context.getUniversalQueue(); 1277 Allocator& allocator = m_context.getDefaultAllocator(); 1278 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1279 TestLog& log = m_context.getTestContext().getLog(); 1280 Move<VkImage> outputImage; 1281 Move<VkImageView> outputImageView; 1282 MovePtr<Allocation> outputImageAllocation; 1283 Move<VkDescriptorSetLayout> descriptorSetLayout; 1284 Move<VkDescriptorPool> descriptorPool; 1285 Move<VkDescriptorSet> descriptorSet; 1286 Move<VkBuffer> sampleLocationBuffer; 1287 MovePtr<Allocation> sampleLocationBufferAllocation; 1288 Move<VkCommandPool> cmdPool; 1289 Move<VkCommandBuffer> transferCmdBuffer; 1290 Move<VkFence> fence; 1291 1292 // Coordinate result image 1293 { 1294 const VkImageCreateInfo outputImageCreateInfo = 1295 { 1296 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 1297 DE_NULL, // const void* pNext 1298 (VkImageCreateFlags)0, // VkImageCreateFlags flags 1299 VK_IMAGE_TYPE_2D, // VkImageType imageType 1300 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format 1301 makeExtent3D(m_sampleCount * m_renderSize.x(), m_renderSize.y(), 1u), // VkExtent3D extent3d 1302 1u, // uint32_t mipLevels 1303 1u, // uint32_t arrayLayers 1304 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples 1305 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 1306 VK_IMAGE_USAGE_STORAGE_BIT | // VkImageUsageFlags usage 1307 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1308 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 1309 0u, // uint32_t queueFamilyIndexCount 1310 DE_NULL, // const uint32_t* pQueueFamilyIndices 1311 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 1312 }; 1313 1314 outputImage = createImage(vk, device, &outputImageCreateInfo, DE_NULL); 1315 outputImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *outputImage), MemoryRequirement::Any); 1316 vk.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset()); 1317 1318 VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 1319 const VkImageViewCreateInfo outputImageViewCreateInfo = 1320 { 1321 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType 1322 DE_NULL, // const void* pNext 1323 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags 1324 *outputImage, // VkImage image 1325 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType 1326 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format, 1327 makeComponentMappingRGBA(), // VkComponentMapping components 1328 imageSubresourceRange // VkImageSubresourceRange imageSubresourceRange 1329 }; 1330 1331 outputImageView = createImageView(vk, device, &outputImageViewCreateInfo); 1332 } 1333 1334 // Validation buffer 1335 { 1336 VkDeviceSize pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT)); 1337 const VkBufferCreateInfo sampleLocationBufferCreateInfo = 1338 { 1339 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType 1340 DE_NULL, // const void* pNext 1341 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags 1342 m_sampleCount * m_renderSize.x() * m_renderSize.y() * pixelSize, // VkDeviceSize size 1343 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage 1344 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode mode 1345 0u, // uint32_t queueFamilyIndexCount 1346 DE_NULL // const uint32_t* pQueueFamilyIndices 1347 }; 1348 1349 sampleLocationBuffer = createBuffer(vk, device, &sampleLocationBufferCreateInfo, DE_NULL); 1350 sampleLocationBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *sampleLocationBuffer), MemoryRequirement::HostVisible); 1351 vk.bindBufferMemory(device, *sampleLocationBuffer, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset()); 1352 } 1353 1354 // Descriptors 1355 { 1356 DescriptorSetLayoutBuilder layoutBuilder; 1357 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); 1358 descriptorSetLayout = layoutBuilder.build(vk, device); 1359 descriptorPool = DescriptorPoolBuilder() 1360 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 1361 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1362 1363 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo = 1364 { 1365 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1366 DE_NULL, 1367 *descriptorPool, 1368 1u, 1369 &*descriptorSetLayout 1370 }; 1371 1372 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo); 1373 1374 const VkDescriptorImageInfo imageInfo = 1375 { 1376 (VkSampler)DE_NULL, 1377 *outputImageView, 1378 VK_IMAGE_LAYOUT_GENERAL 1379 }; 1380 1381 DescriptorSetUpdateBuilder() 1382 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo) 1383 .update(vk, device); 1384 } 1385 1386 // Command Pool 1387 { 1388 const VkCommandPoolCreateInfo cmdPoolCreateInfo = 1389 { 1390 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType 1391 DE_NULL, // const void* pNext 1392 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags 1393 queueFamilyIndex // uint32_t queueFamilyIndex 1394 }; 1395 1396 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo); 1397 } 1398 1399 // Command buffer for data transfers 1400 { 1401 const VkCommandBufferAllocateInfo cmdBufferAllocInfo = 1402 { 1403 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType, 1404 DE_NULL, // const void* pNext 1405 *cmdPool, // VkCommandPool commandPool 1406 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level 1407 1u // uint32_t bufferCount 1408 }; 1409 1410 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo); 1411 } 1412 1413 // Fence for data transfer 1414 { 1415 const VkFenceCreateInfo fenceCreateInfo = 1416 { 1417 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType 1418 DE_NULL, // const void* pNext 1419 (VkFenceCreateFlags)0 // VkFenceCreateFlags flags 1420 }; 1421 1422 fence = createFence(vk, device, &fenceCreateInfo); 1423 } 1424 1425 // Transition the output image to LAYOUT_GENERAL 1426 { 1427 const VkImageMemoryBarrier barrier = 1428 { 1429 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1430 DE_NULL, // const void* pNext 1431 0u, // VkAccessFlags srcAccessMask 1432 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask 1433 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout 1434 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout 1435 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1436 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1437 *outputImage, // VkImage image 1438 { 1439 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 1440 0u, // uint32_t baseMipLevel 1441 1u, // uint32_t mipLevels 1442 0u, // uint32_t baseArray 1443 1u // uint32_t arraySize 1444 } 1445 }; 1446 1447 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1448 { 1449 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 1450 DE_NULL, // const void* pNext 1451 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 1452 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 1453 }; 1454 1455 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 1456 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1457 (VkDependencyFlags)0, 1458 0, (const VkMemoryBarrier*)DE_NULL, 1459 0, (const VkBufferMemoryBarrier*)DE_NULL, 1460 1, &barrier); 1461 1462 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 1463 1464 const VkSubmitInfo submitInfo = 1465 { 1466 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 1467 DE_NULL, // const void* pNext 1468 0u, // uint32_t waitSemaphoreCount 1469 DE_NULL, // const VkSemaphore* pWaitSemaphores 1470 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 1471 1u, // uint32_t commandBufferCount 1472 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 1473 0u, // uint32_t signalSemaphoreCount 1474 DE_NULL // const VkSemaphore* pSignalSemaphores 1475 }; 1476 1477 vk.resetFences(device, 1, &fence.get()); 1478 vk.queueSubmit(queue, 1, &submitInfo, *fence); 1479 vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)); 1480 } 1481 1482 // Perform draw 1483 { 1484 std::vector<Vec4> vertices; 1485 std::vector<VulkanShader> shaders; 1486 1487 vertices.push_back(Vec4( -1.0f, -1.0f, 0.0f, 1.0f)); 1488 vertices.push_back(Vec4( -1.0f, 1.0f, 0.0f, 1.0f)); 1489 vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f)); 1490 vertices.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f)); 1491 1492 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragCoordMsaaVert"))); 1493 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragCoordMsaaFrag"))); 1494 1495 DrawState drawState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_renderSize.x(), m_renderSize.y()); 1496 DrawCallData drawCallData(vertices); 1497 VulkanProgram vulkanProgram(shaders); 1498 1499 drawState.numSamples = m_sampleCount; 1500 drawState.sampleShadingEnable = true; 1501 vulkanProgram.descriptorSetLayout = *descriptorSetLayout; 1502 vulkanProgram.descriptorSet = *descriptorSet; 1503 1504 VulkanDrawContext vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram); 1505 vulkanDrawContext.draw(); 1506 1507 log << TestLog::Image( "result", 1508 "result", 1509 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1510 vulkanDrawContext.getColorPixels().getFormat()), 1511 vulkanDrawContext.getColorPixels().getWidth(), 1512 vulkanDrawContext.getColorPixels().getHeight(), 1513 1, 1514 vulkanDrawContext.getColorPixels().getDataPtr())); 1515 } 1516 1517 // Transfer location image to buffer 1518 { 1519 const VkImageMemoryBarrier imageBarrier = 1520 { 1521 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1522 DE_NULL, // const void* pNext 1523 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask 1524 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessMask dstAccessMask 1525 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout 1526 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout 1527 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1528 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1529 *outputImage, // VkImage image 1530 { 1531 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 1532 0u, // uint32_t baseMipLevel 1533 1u, // uint32_t mipLevels 1534 0u, // uint32_t baseArray 1535 1u // uint32_t arraySize 1536 } 1537 }; 1538 1539 const VkBufferMemoryBarrier bufferBarrier = 1540 { 1541 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType 1542 DE_NULL, // const void* pNext 1543 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 1544 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask 1545 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1546 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1547 *sampleLocationBuffer, // VkBufer buffer 1548 0u, // VkDeviceSize offset 1549 VK_WHOLE_SIZE // VkDeviceSize size 1550 }; 1551 1552 const VkBufferImageCopy bufferImageCopy = 1553 { 1554 0u, // VkDeviceSize bufferOffset 1555 m_sampleCount * m_renderSize.x(), // uint32_t bufferRowLength 1556 m_renderSize.y(), // uint32_t bufferImageHeight 1557 { 1558 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect 1559 0u, // uint32_t mipLevel 1560 0u, // uint32_t baseArrayLayer 1561 1u // uint32_t layerCount 1562 }, 1563 { 0, 0, 0 }, // VkOffset3D imageOffset 1564 { 1565 m_sampleCount * m_renderSize.x(), // uint32_t width 1566 m_renderSize.y(), // uint32_t height, 1567 1u // uint32_t depth 1568 } 1569 }; 1570 1571 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1572 { 1573 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType 1574 DE_NULL, // const void* pNext 1575 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags 1576 (const VkCommandBufferInheritanceInfo*)DE_NULL // VkCommandBufferInheritanceInfo pInheritanceInfo 1577 }; 1578 1579 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo)); 1580 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1581 (VkDependencyFlags)0, 1582 0, (const VkMemoryBarrier*)DE_NULL, 1583 0, (const VkBufferMemoryBarrier*)DE_NULL, 1584 1, &imageBarrier); 1585 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *outputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *sampleLocationBuffer, 1u, &bufferImageCopy); 1586 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 1587 (VkDependencyFlags)0, 1588 0, (const VkMemoryBarrier*)DE_NULL, 1589 1, &bufferBarrier, 1590 0, (const VkImageMemoryBarrier*)DE_NULL); 1591 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer)); 1592 1593 const VkSubmitInfo submitInfo = 1594 { 1595 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType 1596 DE_NULL, // const void* pNext 1597 0u, // uint32_t waitSemaphoreCount 1598 DE_NULL, // const VkSemaphore* pWaitSemaphores 1599 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask 1600 1u, // uint32_t commandBufferCount 1601 &transferCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers 1602 0u, // uint32_t signalSemaphoreCount 1603 DE_NULL // const VkSemaphore* pSignalSemaphores 1604 }; 1605 1606 vk.resetFences(device, 1, &fence.get()); 1607 vk.queueSubmit(queue, 1, &submitInfo, *fence); 1608 vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)); 1609 1610 invalidateMappedMemoryRange(vk, device, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset(), VK_WHOLE_SIZE); 1611 } 1612 1613 // Validate result 1614 { 1615 bool status; 1616 1617 ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(), 1618 m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr()); 1619 1620 status = validateSampleLocations(sampleLocationPixelBuffer); 1621 if (status) 1622 return TestStatus::pass("FragCoordMsaa passed"); 1623 else 1624 return TestStatus::fail("FragCoordMsaa failed"); 1625 } 1626} 1627 1628static bool pixelOffsetCompare (const Vec2& a, const Vec2& b) 1629{ 1630 return a.x() < b.x(); 1631} 1632 1633bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const 1634{ 1635 const InstanceInterface& vki = m_context.getInstanceInterface(); 1636 TestLog& log = m_context.getTestContext().getLog(); 1637 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 1638 deUint32 logSampleCount = deLog2Floor32(m_sampleCount); 1639 VkPhysicalDeviceProperties physicalDeviceProperties; 1640 1641 static const Vec2 sampleCount1Bit[] = 1642 { 1643 Vec2(0.5f, 0.5f) 1644 }; 1645 1646 static const Vec2 sampleCount2Bit[] = 1647 { 1648 Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f) 1649 }; 1650 1651 static const Vec2 sampleCount4Bit[] = 1652 { 1653 Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f) 1654 }; 1655 1656 static const Vec2 sampleCount8Bit[] = 1657 { 1658 Vec2(0.5625f, 0.3125f), Vec2(0.4375f, 0.6875f), Vec2(0.8125f,0.5625f), Vec2(0.3125f, 0.1875f), 1659 Vec2(0.1875f, 0.8125f), Vec2(0.0625f, 0.4375f), Vec2(0.6875f,0.9375f), Vec2(0.9375f, 0.0625f) 1660 }; 1661 1662 static const Vec2 sampleCount16Bit[] = 1663 { 1664 Vec2(0.5625f, 0.5625f), Vec2(0.4375f, 0.3125f), Vec2(0.3125f,0.6250f), Vec2(0.7500f, 0.4375f), 1665 Vec2(0.1875f, 0.3750f), Vec2(0.6250f, 0.8125f), Vec2(0.8125f,0.6875f), Vec2(0.6875f, 0.1875f), 1666 Vec2(0.3750f, 0.8750f), Vec2(0.5000f, 0.0625f), Vec2(0.2500f,0.1250f), Vec2(0.1250f, 0.7500f), 1667 Vec2(0.0000f, 0.5000f), Vec2(0.9375f, 0.2500f), Vec2(0.8750f,0.9375f), Vec2(0.0625f, 0.0000f) 1668 }; 1669 1670 static const Vec2* standardSampleLocationTable[] = 1671 { 1672 sampleCount1Bit, 1673 sampleCount2Bit, 1674 sampleCount4Bit, 1675 sampleCount8Bit, 1676 sampleCount16Bit 1677 }; 1678 1679 vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties); 1680 1681 for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++) 1682 { 1683 for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++) 1684 { 1685 std::vector<Vec2> locations; 1686 1687 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++) 1688 { 1689 const UVec2 pixelAddress = UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx); 1690 const Vec4 pixelData = sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y()); 1691 1692 locations.push_back(Vec2(pixelData.x(), pixelData.y())); 1693 } 1694 1695 std::sort(locations.begin(), locations.end(), pixelOffsetCompare); 1696 for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++) 1697 { 1698 IVec2 sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y())); 1699 IVec2 sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y())); 1700 1701 if ( (sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1) ) 1702 { 1703 log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage; 1704 return false; 1705 } 1706 } 1707 1708 std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end()); 1709 if (last != locations.end()) 1710 { 1711 log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage; 1712 return false; 1713 } 1714 1715 // Check standard sample locations 1716 if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable)) 1717 { 1718 if (physicalDeviceProperties.limits.standardSampleLocations) 1719 { 1720 for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++) 1721 { 1722 if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx)))) 1723 { 1724 log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage; 1725 return false; 1726 } 1727 } 1728 } 1729 } 1730 } 1731 } 1732 1733 return true; 1734} 1735 1736class BuiltinFragCoordMsaaTestCase : public TestCase 1737{ 1738public: 1739 BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount); 1740 virtual ~BuiltinFragCoordMsaaTestCase (void); 1741 void initPrograms (SourceCollections& sourceCollections) const; 1742 TestInstance* createInstance (Context& context) const; 1743private: 1744 const VkSampleCountFlagBits m_sampleCount; 1745}; 1746 1747BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount) 1748 : TestCase (testCtx, name, description) 1749 , m_sampleCount (sampleCount) 1750{ 1751} 1752 1753BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void) 1754{ 1755} 1756 1757void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const 1758{ 1759 { 1760 std::ostringstream vertexSource; 1761 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1762 << "\n" 1763 << "layout (location = 0) in vec4 position;\n" 1764 << "void main()\n" 1765 << "{\n" 1766 << " gl_Position = position;\n" 1767 << "}\n"; 1768 programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str()); 1769 } 1770 1771 { 1772 std::ostringstream fragmentSource; 1773 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1774 << "\n" 1775 << "layout(location = 0) out mediump vec4 color;\n" 1776 << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n" 1777 << "void main()\n" 1778 << "{\n" 1779 << " const int sampleNdx = int(gl_SampleID);\n" 1780 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_sampleCount << ", int(gl_FragCoord.y));\n" 1781 << " imageStore(storageImage, imageCoord, vec4(gl_FragCoord.xy,vec2(0)));\n" 1782 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 1783 << "}\n"; 1784 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str()); 1785 } 1786} 1787 1788TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const 1789{ 1790 return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount); 1791} 1792 1793class BuiltinFragDepthCase : public TestCase 1794{ 1795public: 1796 BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples); 1797 virtual ~BuiltinFragDepthCase (void); 1798 1799 void initPrograms (SourceCollections& dst) const; 1800 TestInstance* createInstance (Context& context) const; 1801 1802private: 1803 const VkPrimitiveTopology m_topology; 1804 const VkFormat m_format; 1805 const bool m_largeDepthEnable; 1806 const float m_defaultDepth; 1807 const bool m_depthClampEnable; 1808 const VkSampleCountFlagBits m_samples; 1809}; 1810 1811BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples) 1812 : TestCase (testCtx, name, description) 1813 , m_topology (topology) 1814 , m_format (format) 1815 , m_largeDepthEnable (largeDepthEnable) 1816 , m_defaultDepth (0.0f) 1817 , m_depthClampEnable (depthClampEnable) 1818 , m_samples (samples) 1819{ 1820} 1821 1822BuiltinFragDepthCase::~BuiltinFragDepthCase(void) 1823{ 1824} 1825 1826void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const 1827{ 1828 // Vertex 1829 { 1830 // Pass 1 1831 { 1832 std::ostringstream vertexSource; 1833 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1834 << "\n" 1835 << "layout (location = 0) in vec4 position;\n" 1836 << "void main()\n" 1837 << "{\n" 1838 << " gl_Position = position;\n" 1839 << " gl_PointSize = 1.0;\n" 1840 << "}\n"; 1841 programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str()); 1842 } 1843 1844 // Pass 2 1845 { 1846 std::ostringstream vertexSource; 1847 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1848 << "\n" 1849 << "layout (location = 0) in vec4 position;\n" 1850 << "layout (location = 1) out vec2 texCoord;\n" 1851 << "void main()\n" 1852 << "{\n" 1853 << " gl_Position = position;\n" 1854 << " gl_PointSize = 1.0;\n" 1855 << " texCoord = position.xy/2 + vec2(0.5);\n" 1856 << "}\n"; 1857 programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str()); 1858 } 1859 } 1860 1861 // Fragment 1862 { 1863 // Pass 1 1864 { 1865 std::ostringstream fragmentSource; 1866 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1867 << "\n" 1868 << "layout(location = 0) out mediump vec4 color;\n" 1869 << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n" 1870 << "{\n" 1871 << " float data[256];\n" 1872 << "} control_buffer;\n" 1873 << "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n" 1874 << "float controlDepthValue;\n" 1875 << "void recheck(float controlDepthValue)\n" 1876 << "{\n" 1877 << " if (gl_FragDepth != controlDepthValue)\n" 1878 << " gl_FragDepth = 1.0;\n" 1879 << "}\n" 1880 << "void main()\n" 1881 << "{\n" 1882 << " const int numSamples = " << m_samples << ";\n" 1883 << " if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n" 1884 << " discard;\n" 1885 << " highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n" 1886 << " controlDepthValue = control_buffer.data[index];\n" 1887 << " gl_FragDepth = controlDepthValue;\n" 1888 << " const int sampleNdx = int(gl_SampleID);\n" 1889 << " ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n" 1890 << " imageStore(storageImage, imageCoord, uvec4(1));\n" 1891 << " recheck(controlDepthValue);\n" 1892 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 1893 << "}\n"; 1894 programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str()); 1895 } 1896 1897 // Pass 2 1898 { 1899 const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : ""; 1900 std::ostringstream fragmentSource; 1901 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1902 << "\n" 1903 << "layout (location = 0) out mediump vec4 color;\n" 1904 << "layout (location = 1) in vec2 texCoord;\n" 1905 << "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n" 1906 << "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n" 1907 << "void main (void)\n" 1908 << "{\n" 1909 << " const int numSamples = " << m_samples << ";\n" 1910 << " const int sampleNdx = int(gl_SampleID);\n" 1911 << " ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n" 1912 << " ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n" 1913 << " vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n" 1914 << " imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n" 1915 << " color = vec4(1.0, 0.0, 0.0, 1.0);\n" 1916 << "}\n"; 1917 programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str()); 1918 } 1919 } 1920} 1921 1922TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const 1923{ 1924 return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples); 1925} 1926 1927class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance 1928{ 1929public: 1930 BuiltinGlFragCoordXYZCaseInstance (Context& context); 1931 1932 TestStatus iterate (void); 1933 virtual void setupDefaultInputs (void); 1934}; 1935 1936BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context) 1937 : ShaderRenderCaseInstance (context) 1938{ 1939 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM; 1940} 1941 1942TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void) 1943{ 1944 const UVec2 viewportSize = getViewportSize(); 1945 const int width = viewportSize.x(); 1946 const int height = viewportSize.y(); 1947 const tcu::Vec3 scale (1.f / float(width), 1.f / float(height), 1.0f); 1948 const float precision = 0.00001f; 1949 const deUint16 indices[6] = 1950 { 1951 2, 1, 3, 1952 0, 1, 2, 1953 }; 1954 1955 setup(); 1956 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale); 1957 1958 render(4, 2, indices); 1959 1960 // Reference image 1961 for (int y = 0; y < height; y++) 1962 { 1963 for (int x = 0; x < width; x++) 1964 { 1965 const float xf = (float(x) + .5f) / float(width); 1966 const float yf = (float(height - y - 1) + .5f) / float(height); 1967 const float z = (xf + yf) / 2.0f; 1968 const Vec3 fragCoord (float(x) + .5f, float(y) + .5f, z); 1969 const Vec3 scaledFC = fragCoord*scale; 1970 const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f); 1971 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y); 1972 1973 if (de::abs(color.x() - resultColor.x()) > precision || 1974 de::abs(color.y() - resultColor.y()) > precision || 1975 de::abs(color.z() - resultColor.z()) > precision) 1976 return TestStatus::fail("Image mismatch"); 1977 } 1978 } 1979 1980 return TestStatus::pass("Result image matches reference"); 1981} 1982 1983void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void) 1984{ 1985 const float vertices[] = 1986 { 1987 -1.0f, 1.0f, 0.0f, 1.0f, 1988 -1.0f, -1.0f, 0.5f, 1.0f, 1989 1.0f, 1.0f, 0.5f, 1.0f, 1990 1.0f, -1.0f, 1.0f, 1.0f, 1991 }; 1992 1993 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices); 1994} 1995 1996class BuiltinGlFragCoordXYZCase : public TestCase 1997{ 1998public: 1999 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description); 2000 virtual ~BuiltinGlFragCoordXYZCase (void); 2001 2002 void initPrograms (SourceCollections& dst) const; 2003 TestInstance* createInstance (Context& context) const; 2004 2005private: 2006 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed! 2007 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed! 2008}; 2009 2010BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description) 2011 : TestCase(testCtx, name, description) 2012{ 2013} 2014 2015BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void) 2016{ 2017} 2018 2019void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const 2020{ 2021 dst.glslSources.add("vert") << glu::VertexSource( 2022 "#version 310 es\n" 2023 "layout(location = 0) in highp vec4 a_position;\n" 2024 "void main (void)\n" 2025 "{\n" 2026 " gl_Position = a_position;\n" 2027 "}\n"); 2028 2029 dst.glslSources.add("frag") << glu::FragmentSource( 2030 "#version 310 es\n" 2031 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n" 2032 "layout(location = 0) out highp vec4 o_color;\n" 2033 "void main (void)\n" 2034 "{\n" 2035 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n" 2036 "}\n"); 2037} 2038 2039TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const 2040{ 2041 return new BuiltinGlFragCoordXYZCaseInstance(context); 2042} 2043 2044inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny) 2045{ 2046 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]); 2047} 2048 2049class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance 2050{ 2051public: 2052 BuiltinGlFragCoordWCaseInstance (Context& context); 2053 2054 TestStatus iterate (void); 2055 virtual void setupDefaultInputs (void); 2056 2057private: 2058 2059 const Vec4 m_w; 2060 2061}; 2062 2063BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context) 2064 : ShaderRenderCaseInstance (context) 2065 , m_w (1.7f, 2.0f, 1.2f, 1.0f) 2066{ 2067 m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM; 2068} 2069 2070TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void) 2071{ 2072 const UVec2 viewportSize = getViewportSize(); 2073 const int width = viewportSize.x(); 2074 const int height = viewportSize.y(); 2075 const float precision = 0.00001f; 2076 const deUint16 indices[6] = 2077 { 2078 2, 1, 3, 2079 0, 1, 2, 2080 }; 2081 2082 setup(); 2083 render(4, 2, indices); 2084 2085 // Reference image 2086 for (int y = 0; y < height; y++) 2087 { 2088 for (int x = 0; x < width; x++) 2089 { 2090 const float xf = (float(x) + .5f) / float(width); 2091 const float yf = (float(height - y - 1) +.5f) / float(height); 2092 const float oow = ((xf + yf) < 1.0f) 2093 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf) 2094 : 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); 2095 const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f); 2096 const Vec4 resultColor = getResultImage().getAccess().getPixel(x, y); 2097 2098 if (de::abs(color.x() - resultColor.x()) > precision || 2099 de::abs(color.y() - resultColor.y()) > precision || 2100 de::abs(color.z() - resultColor.z()) > precision) 2101 return TestStatus::fail("Image mismatch"); 2102 } 2103 } 2104 2105 return TestStatus::pass("Result image matches reference"); 2106} 2107 2108void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void) 2109{ 2110 const float vertices[] = 2111 { 2112 -m_w[0], m_w[0], 0.0f, m_w[0], 2113 -m_w[1], -m_w[1], 0.0f, m_w[1], 2114 m_w[2], m_w[2], 0.0f, m_w[2], 2115 m_w[3], -m_w[3], 0.0f, m_w[3] 2116 }; 2117 2118 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices); 2119} 2120 2121class BuiltinGlFragCoordWCase : public TestCase 2122{ 2123public: 2124 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description); 2125 virtual ~BuiltinGlFragCoordWCase (void); 2126 2127 void initPrograms (SourceCollections& dst) const; 2128 TestInstance* createInstance (Context& context) const; 2129 2130private: 2131 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed! 2132 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed! 2133}; 2134 2135BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description) 2136 : TestCase(testCtx, name, description) 2137{ 2138} 2139 2140BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void) 2141{ 2142} 2143 2144void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const 2145{ 2146 dst.glslSources.add("vert") << glu::VertexSource( 2147 "#version 310 es\n" 2148 "layout(location = 0) in highp vec4 a_position;\n" 2149 "void main (void)\n" 2150 "{\n" 2151 " gl_Position = a_position;\n" 2152 "}\n"); 2153 2154 dst.glslSources.add("frag") << glu::FragmentSource( 2155 "#version 310 es\n" 2156 "layout(location = 0) out highp vec4 o_color;\n" 2157 "void main (void)\n" 2158 "{\n" 2159 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n" 2160 "}\n"); 2161} 2162 2163TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const 2164{ 2165 return new BuiltinGlFragCoordWCaseInstance(context); 2166} 2167 2168class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance 2169{ 2170public: 2171 BuiltinGlPointCoordCaseInstance (Context& context); 2172 2173 TestStatus iterate (void); 2174 virtual void setupDefaultInputs (void); 2175}; 2176 2177BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context) 2178 : ShaderRenderCaseInstance (context) 2179{ 2180} 2181 2182TestStatus BuiltinGlPointCoordCaseInstance::iterate (void) 2183{ 2184 const UVec2 viewportSize = getViewportSize(); 2185 const int width = viewportSize.x(); 2186 const int height = viewportSize.y(); 2187 const float threshold = 0.02f; 2188 const int numPoints = 16; 2189 vector<Vec3> coords (numPoints); 2190 de::Random rnd (0x145fa); 2191 Surface resImage (width, height); 2192 Surface refImage (width, height); 2193 bool compareOk = false; 2194 2195 // Compute coordinates. 2196 { 2197 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits; 2198 const float minPointSize = limits.pointSizeRange[0]; 2199 const float maxPointSize = limits.pointSizeRange[1]; 2200 const int pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity)); 2201 2202 TCU_CHECK(minPointSize <= maxPointSize); 2203 2204 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord) 2205 { 2206 coord->x() = rnd.getFloat(-0.9f, 0.9f); 2207 coord->y() = rnd.getFloat(-0.9f, 0.9f); 2208 coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity); 2209 } 2210 } 2211 2212 setup(); 2213 addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]); 2214 render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST); 2215 copy(resImage.getAccess(), getResultImage().getAccess()); 2216 2217 // Draw reference 2218 clear(refImage.getAccess(), m_clearColor); 2219 2220 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter) 2221 { 2222 const float centerX = float(width) *(pointIter->x()*0.5f + 0.5f); 2223 const float centerY = float(height)*(pointIter->y()*0.5f + 0.5f); 2224 const float size = pointIter->z(); 2225 const int x0 = deRoundFloatToInt32(centerX - size*0.5f); 2226 const int y0 = deRoundFloatToInt32(centerY - size*0.5f); 2227 const int x1 = deRoundFloatToInt32(centerX + size*0.5f); 2228 const int y1 = deRoundFloatToInt32(centerY + size*0.5f); 2229 const int w = x1-x0; 2230 const int h = y1-y0; 2231 2232 for (int yo = 0; yo < h; yo++) 2233 { 2234 for (int xo = 0; xo < w; xo++) 2235 { 2236 const int dx = x0+xo; 2237 const int dy = y0+yo; 2238 const float fragX = float(dx) + 0.5f; 2239 const float fragY = float(dy) + 0.5f; 2240 const float s = 0.5f + (fragX - centerX) / size; 2241 const float t = 0.5f + (fragY - centerY) / size; 2242 const Vec4 color (s, t, 0.0f, 1.0f); 2243 2244 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight())) 2245 refImage.setPixel(dx, dy, RGBA(color)); 2246 } 2247 } 2248 } 2249 2250 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT); 2251 2252 if (compareOk) 2253 return TestStatus::pass("Result image matches reference"); 2254 else 2255 return TestStatus::fail("Image mismatch"); 2256} 2257 2258void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void) 2259{ 2260} 2261 2262class BuiltinGlPointCoordCase : public TestCase 2263{ 2264public: 2265 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description); 2266 virtual ~BuiltinGlPointCoordCase (void); 2267 2268 void initPrograms (SourceCollections& dst) const; 2269 TestInstance* createInstance (Context& context) const; 2270 2271private: 2272 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed! 2273 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed! 2274}; 2275 2276BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description) 2277 : TestCase(testCtx, name, description) 2278{ 2279} 2280 2281BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void) 2282{ 2283} 2284 2285void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const 2286{ 2287 dst.glslSources.add("vert") << glu::VertexSource( 2288 "#version 310 es\n" 2289 "layout(location = 0) in highp vec3 a_position;\n" 2290 "void main (void)\n" 2291 "{\n" 2292 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" 2293 " gl_PointSize = a_position.z;\n" 2294 "}\n"); 2295 2296 dst.glslSources.add("frag") << glu::FragmentSource( 2297 "#version 310 es\n" 2298 "layout(location = 0) out lowp vec4 o_color;\n" 2299 "void main (void)\n" 2300 "{\n" 2301 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n" 2302 "}\n"); 2303} 2304 2305TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const 2306{ 2307 return new BuiltinGlPointCoordCaseInstance(context); 2308} 2309 2310enum ShaderInputTypeBits 2311{ 2312 SHADER_INPUT_BUILTIN_BIT = 0x01, 2313 SHADER_INPUT_VARYING_BIT = 0x02, 2314 SHADER_INPUT_CONSTANT_BIT = 0x04 2315}; 2316 2317typedef deUint16 ShaderInputTypes; 2318 2319string shaderInputTypeToString (ShaderInputTypes type) 2320{ 2321 string typeString = "input"; 2322 2323 if (type == 0) 2324 return "input_none"; 2325 2326 if (type & SHADER_INPUT_BUILTIN_BIT) 2327 typeString += "_builtin"; 2328 2329 if (type & SHADER_INPUT_VARYING_BIT) 2330 typeString += "_varying"; 2331 2332 if (type & SHADER_INPUT_CONSTANT_BIT) 2333 typeString += "_constant"; 2334 2335 return typeString; 2336} 2337 2338class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance 2339{ 2340public: 2341 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes); 2342 2343 TestStatus iterate (void); 2344 virtual void setupDefaultInputs (void); 2345 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout); 2346 2347private: 2348 const ShaderInputTypes m_shaderInputTypes; 2349 const Vec4 m_constantColor; 2350}; 2351 2352BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes) 2353 : ShaderRenderCaseInstance (context) 2354 , m_shaderInputTypes (shaderInputTypes) 2355 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f) 2356{ 2357} 2358 2359TestStatus BuiltinInputVariationsCaseInstance::iterate (void) 2360{ 2361 const UVec2 viewportSize = getViewportSize(); 2362 const int width = viewportSize.x(); 2363 const int height = viewportSize.y(); 2364 const tcu::RGBA threshold (2, 2, 2, 2); 2365 Surface resImage (width, height); 2366 Surface refImage (width, height); 2367 bool compareOk = false; 2368 const VkPushConstantRange pcRanges = 2369 { 2370 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 2371 0u, // deUint32 offset; 2372 sizeof(Vec4) // deUint32 size; 2373 }; 2374 const deUint16 indices[12] = 2375 { 2376 0, 4, 1, 2377 0, 5, 4, 2378 1, 2, 3, 2379 1, 3, 4 2380 }; 2381 2382 setup(); 2383 2384 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2385 setPushConstantRanges(1, &pcRanges); 2386 2387 render(6, 4, indices); 2388 copy(resImage.getAccess(), getResultImage().getAccess()); 2389 2390 // Reference image 2391 for (int y = 0; y < refImage.getHeight(); y++) 2392 { 2393 for (int x = 0; x < refImage.getWidth(); x++) 2394 { 2395 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f); 2396 2397 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) || 2398 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT)) 2399 { 2400 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT) 2401 { 2402 const float xf = (float(x)+.5f) / float(refImage.getWidth()); 2403 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f); 2404 } 2405 else 2406 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f); 2407 } 2408 2409 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2410 color += m_constantColor; 2411 2412 refImage.setPixel(x, y, RGBA(color)); 2413 } 2414 } 2415 2416 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT); 2417 2418 if (compareOk) 2419 return TestStatus::pass("Result image matches reference"); 2420 else 2421 return TestStatus::fail("Image mismatch"); 2422} 2423 2424void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void) 2425{ 2426 const float vertices[] = 2427 { 2428 -1.0f, -1.0f, 0.0f, 1.0f, 2429 0.0f, -1.0f, 0.0f, 1.0f, 2430 1.0f, -1.0f, 0.0f, 1.0f, 2431 1.0f, 1.0f, 0.0f, 1.0f, 2432 0.0f, 1.0f, 0.0f, 1.0f, 2433 -1.0f, 1.0f, 0.0f, 1.0f 2434 }; 2435 2436 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices); 2437 2438 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT) 2439 { 2440 const float colors[] = 2441 { 2442 0.6f, 0.0f, 0.0f, 1.0f, 2443 0.3f, 0.3f, 0.0f, 1.0f, 2444 0.0f, 0.6f, 0.0f, 1.0f, 2445 0.0f, 0.6f, 0.0f, 1.0f, 2446 0.3f, 0.3f, 0.0f, 1.0f, 2447 0.6f, 0.0f, 0.0f, 1.0f 2448 }; 2449 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors); 2450 } 2451} 2452 2453void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout) 2454{ 2455 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT) 2456 { 2457 const DeviceInterface& vk = m_context.getDeviceInterface(); 2458 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor); 2459 } 2460} 2461 2462class BuiltinInputVariationsCase : public TestCase 2463{ 2464public: 2465 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes); 2466 virtual ~BuiltinInputVariationsCase (void); 2467 2468 void initPrograms (SourceCollections& dst) const; 2469 TestInstance* createInstance (Context& context) const; 2470 2471private: 2472 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed! 2473 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed! 2474 const ShaderInputTypes m_shaderInputTypes; 2475}; 2476 2477BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes) 2478 : TestCase (testCtx, name, description) 2479 , m_shaderInputTypes (shaderInputTypes) 2480{ 2481} 2482 2483BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void) 2484{ 2485} 2486 2487void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const 2488{ 2489 map<string, string> vertexParams; 2490 map<string, string> fragmentParams; 2491 const tcu::StringTemplate vertexCodeTemplate ( 2492 "#version 450\n" 2493 "layout(location = 0) in highp vec4 a_position;\n" 2494 "out gl_PerVertex {\n" 2495 " vec4 gl_Position;\n" 2496 "};\n" 2497 "${VARYING_DECL}" 2498 "void main (void)\n" 2499 "{\n" 2500 " gl_Position = a_position;\n" 2501 " ${VARYING_USAGE}" 2502 "}\n"); 2503 2504 const tcu::StringTemplate fragmentCodeTemplate ( 2505 "#version 450\n" 2506 "${VARYING_DECL}" 2507 "${CONSTANT_DECL}" 2508 "layout(location = 0) out highp vec4 o_color;\n" 2509 "void main (void)\n" 2510 "{\n" 2511 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n" 2512 " ${BUILTIN_USAGE}" 2513 " ${VARYING_USAGE}" 2514 " ${CONSTANT_USAGE}" 2515 "}\n"); 2516 2517 vertexParams["VARYING_DECL"] = 2518 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n" 2519 "layout(location = 0) out highp vec4 v_color;\n" 2520 : ""; 2521 2522 vertexParams["VARYING_USAGE"] = 2523 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n" 2524 : ""; 2525 2526 fragmentParams["VARYING_DECL"] = 2527 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n" 2528 : ""; 2529 2530 fragmentParams["CONSTANT_DECL"] = 2531 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n" 2532 " vec4 color;\n" 2533 "} pc;\n" 2534 : ""; 2535 2536 fragmentParams["BUILTIN_USAGE"] = 2537 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n" 2538 : ""; 2539 2540 fragmentParams["VARYING_USAGE"] = 2541 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n" 2542 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n"; 2543 2544 2545 fragmentParams["CONSTANT_USAGE"] = 2546 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n" 2547 : ""; 2548 2549 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams)); 2550 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams)); 2551} 2552 2553TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const 2554{ 2555 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes); 2556} 2557 2558} // anonymous 2559 2560TestCaseGroup* createBuiltinVarTests (TestContext& testCtx) 2561{ 2562 de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests.")); 2563 de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases.")); 2564 de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests.")); 2565 de::MovePtr<TestCaseGroup> frontFacingGroup (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword.")); 2566 de::MovePtr<TestCaseGroup> fragDepthGroup (new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword.")); 2567 de::MovePtr<TestCaseGroup> fragCoordMsaaGroup (new TestCaseGroup(testCtx, "fragcoord_msaa", "Test interation between gl_FragCoord and msaa")); 2568 2569 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test")); 2570 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test")); 2571 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test")); 2572 2573 // FragCoord_msaa 2574 { 2575 static const struct FragCoordMsaaCaseList 2576 { 2577 const char* name; 2578 const char* description; 2579 VkSampleCountFlagBits sampleCount; 2580 } fragCoordMsaaCaseList[] = 2581 { 2582 { "1_bit", "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_1_BIT }, 2583 { "2_bit", "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_2_BIT }, 2584 { "4_bit", "Test FragCoord locations with 4 samples", VK_SAMPLE_COUNT_4_BIT }, 2585 { "8_bit", "Test FragCoord locations with 8 samples", VK_SAMPLE_COUNT_8_BIT }, 2586 { "16_bit", "Test FragCoord locations with 16 samples", VK_SAMPLE_COUNT_16_BIT }, 2587 { "32_bit", "Test FragCoord locations with 32 samples", VK_SAMPLE_COUNT_32_BIT }, 2588 { "64-bit", "Test FragCoord locaitons with 64 samples", VK_SAMPLE_COUNT_64_BIT } 2589 }; 2590 2591 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++) 2592 fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount)); 2593 } 2594 2595 // gl_FrontFacing tests 2596 { 2597 static const struct PrimitiveTable 2598 { 2599 const char* name; 2600 const char* desc; 2601 VkPrimitiveTopology primitive; 2602 } frontfacingCases[] = 2603 { 2604 { "point_list", "Test that points are frontfacing", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 2605 { "line_list", "Test that lines are frontfacing", VK_PRIMITIVE_TOPOLOGY_LINE_LIST }, 2606 { "triangle_list", "Test that triangles can be frontfacing or backfacing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST }, 2607 { "triangle_strip", "Test that traiangle strips can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 2608 { "triangle_fan", "Test that triangle fans can be front or back facing", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN }, 2609 }; 2610 2611 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++) 2612 frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc)); 2613 } 2614 2615 // gl_FragDepth 2616 { 2617 static const struct PrimitiveTopologyTable 2618 { 2619 std::string name; 2620 std::string desc; 2621 VkPrimitiveTopology prim; 2622 } primitiveTopologyTable[] = 2623 { 2624 { "point_list", "test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 2625 { "line_list", "test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST }, 2626 { "triangle_list", "test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 2627 }; 2628 2629 static const struct TestCaseTable 2630 { 2631 VkFormat format; 2632 std::string name; 2633 bool largeDepthEnable; 2634 bool depthClampEnable; 2635 VkSampleCountFlagBits samples; 2636 } testCaseTable[] = 2637 { 2638 { VK_FORMAT_D16_UNORM, "d16_unorm_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2639 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2640 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2641 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2642 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2643 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint_no_depth_clamp", false, false, VK_SAMPLE_COUNT_1_BIT }, 2644 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_large_depth", true, false, VK_SAMPLE_COUNT_1_BIT }, 2645 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", false, true, VK_SAMPLE_COUNT_1_BIT }, 2646 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", false, true, VK_SAMPLE_COUNT_1_BIT }, 2647 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_2", false, false, VK_SAMPLE_COUNT_2_BIT }, 2648 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_4", false, false, VK_SAMPLE_COUNT_4_BIT }, 2649 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_8", false, false, VK_SAMPLE_COUNT_8_BIT }, 2650 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_16", false, false, VK_SAMPLE_COUNT_16_BIT }, 2651 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_32", false, false, VK_SAMPLE_COUNT_32_BIT }, 2652 { VK_FORMAT_D32_SFLOAT, "d32_sfloat_multisample_64", false, false, VK_SAMPLE_COUNT_64_BIT }, 2653 }; 2654 2655 for (deUint32 primNdx = 0; primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++) 2656 { 2657 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++) 2658 fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(), 2659 primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples)); 2660 2661 } 2662 } 2663 2664 builtinGroup->addChild(frontFacingGroup.release()); 2665 builtinGroup->addChild(fragDepthGroup.release()); 2666 builtinGroup->addChild(fragCoordMsaaGroup.release()); 2667 builtinGroup->addChild(simpleGroup.release()); 2668 2669 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType) 2670 { 2671 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType)); 2672 } 2673 2674 builtinGroup->addChild(inputVariationsGroup.release()); 2675 return builtinGroup.release(); 2676} 2677 2678} // sr 2679} // vkt 2680