1/*------------------------------------------------------------------------ 2* Vulkan Conformance Tests 3* ------------------------ 4* 5* Copyright (c) 2017 The Khronos Group Inc. 6* Copyright (c) 2017 Nvidia Corporation 7* 8* Licensed under the Apache License, Version 2.0 (the "License"); 9* you may not use this file except in compliance with the License. 10* You may obtain a copy of the License at 11* 12* http://www.apache.org/licenses/LICENSE-2.0 13* 14* Unless required by applicable law or agreed to in writing, software 15* distributed under the License is distributed on an "AS IS" BASIS, 16* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17* See the License for the specific language governing permissions and 18* limitations under the License. 19* 20*//*! 21* \file 22* \brief Device Group Tests 23*//*--------------------------------------------------------------------*/ 24 25#include "vktDeviceGroupTests.hpp" 26 27#include "vkDefs.hpp" 28#include "vkDeviceUtil.hpp" 29#include "vkImageUtil.hpp" 30#include "vkMemUtil.hpp" 31#include "vkPlatform.hpp" 32#include "vkPrograms.hpp" 33#include "vkQueryUtil.hpp" 34#include "vkRef.hpp" 35#include "vkRefUtil.hpp" 36#include "vkStrUtil.hpp" 37#include "vkTypeUtil.hpp" 38#include "vktTestCase.hpp" 39#include "vktTestCaseUtil.hpp" 40#include "vktTestGroupUtil.hpp" 41 42#include "tcuDefs.hpp" 43#include "tcuFormatUtil.hpp" 44#include "tcuImageCompare.hpp" 45#include "tcuResource.hpp" 46#include "tcuTestCase.hpp" 47#include "tcuTestLog.hpp" 48#include "tcuCommandLine.hpp" 49#include "tcuTextureUtil.hpp" 50#include "tcuImageIO.hpp" 51 52#include "rrRenderer.hpp" 53 54namespace vkt 55{ 56namespace DeviceGroup 57{ 58namespace 59{ 60 61using namespace vk; 62using std::string; 63using std::vector; 64using tcu::TestLog; 65using de::UniquePtr; 66 67//Device group test modes 68enum TestModeType 69{ 70 TEST_MODE_SFR = 1 << 0, //!< Split frame remdering 71 TEST_MODE_AFR = 1 << 1, //!< Alternate frame rendering 72 TEST_MODE_HOSTMEMORY = 1 << 2, //!< Use host memory for rendertarget 73 TEST_MODE_DEDICATED = 1 << 3, //!< Use dedicated allocations 74 TEST_MODE_PEER_FETCH = 1 << 4, //!< Peer vertex attributes from peer memroy 75 TEST_MODE_TESSELLATION = 1 << 5, //!< Generate a tessellated sphere instead of triangle 76 TEST_MODE_LINEFILL = 1 << 6, //!< Draw polygon edges as line segments 77}; 78 79class RefVertexShader : public rr::VertexShader 80{ 81public: 82 RefVertexShader (void) 83 : rr::VertexShader(1, 0) 84 { 85 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 86 } 87 virtual ~RefVertexShader(void) {} 88 89 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 90 { 91 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 92 { 93 packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0], 94 packets[packetNdx]->instanceNdx, 95 packets[packetNdx]->vertexNdx); 96 } 97 } 98}; 99 100class RefFragmentShader : public rr::FragmentShader 101{ 102public: 103 RefFragmentShader (void) 104 : rr::FragmentShader(0, 1) 105 { 106 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 107 } 108 109 virtual ~RefFragmentShader(void) {} 110 111 void shadeFragments (rr::FragmentPacket*, const int numPackets, const rr::FragmentShadingContext& context) const 112 { 113 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 114 { 115 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx) 116 { 117 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); 118 } 119 } 120 } 121}; 122 123void renderReferenceTriangle (const tcu::PixelBufferAccess& dst, const tcu::Vec4(&vertices)[3]) 124{ 125 const RefVertexShader vertShader; 126 const RefFragmentShader fragShader; 127 const rr::Program program(&vertShader, &fragShader); 128 const rr::MultisamplePixelBufferAccess colorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst); 129 const rr::RenderTarget renderTarget(colorBuffer); 130 const rr::RenderState renderState((rr::ViewportState(colorBuffer))); 131 const rr::Renderer renderer; 132 const rr::VertexAttrib vertexAttribs[] = 133 { 134 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, vertices[0].getPtr()) 135 }; 136 renderer.draw(rr::DrawCommand(renderState, 137 renderTarget, 138 program, 139 DE_LENGTH_OF_ARRAY(vertexAttribs), 140 &vertexAttribs[0], 141 rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, DE_LENGTH_OF_ARRAY(vertices), 0))); 142} 143 144class DeviceGroupTestInstance : public TestInstance 145{ 146public: 147 DeviceGroupTestInstance(Context& context, deUint32 mode); 148 ~DeviceGroupTestInstance(void) {} 149private: 150 void init (void); 151 deUint32 getMemoryIndex (deUint32 memoryTypeBits, deUint32 memoryPropertyFlag); 152 void getDeviceLayers (vector<string>& enabledLayers); 153 bool isPeerFetchAllowed (deUint32 memoryTypeIndex, deUint32 firstdeviceID, deUint32 seconddeviceID); 154 void SubmitBufferAndWaitForIdle (const DeviceDriver& vk, VkCommandBuffer cmdBuf, VkDeviceGroupSubmitInfo); 155 virtual tcu::TestStatus iterate (void); 156 157 Move<VkDevice> m_deviceGroup; 158 deUint32 m_physicalDeviceCount; 159 VkQueue m_deviceGroupQueue; 160 vector<VkPhysicalDevice> m_physicalDevices; 161 162 deUint32 m_testMode; 163 bool m_useHostMemory; 164 bool m_useDedicated; 165 bool m_usePeerFetch; 166 bool m_subsetAllocation; 167 bool m_fillModeNonSolid; 168 bool m_drawTessellatedSphere; 169}; 170 171DeviceGroupTestInstance::DeviceGroupTestInstance (Context& context, const deUint32 mode) 172 : TestInstance (context) 173 , m_physicalDeviceCount (0) 174 , m_deviceGroupQueue (DE_NULL) 175 , m_testMode (mode) 176 , m_useHostMemory (m_testMode & TEST_MODE_HOSTMEMORY) 177 , m_useDedicated (m_testMode & TEST_MODE_DEDICATED) 178 , m_usePeerFetch (m_testMode & TEST_MODE_PEER_FETCH) 179 , m_subsetAllocation (true) 180 , m_fillModeNonSolid (m_testMode & TEST_MODE_LINEFILL) 181 , m_drawTessellatedSphere (m_testMode & TEST_MODE_TESSELLATION) 182{ 183 init(); 184} 185 186deUint32 DeviceGroupTestInstance::getMemoryIndex (const deUint32 memoryTypeBits, const deUint32 memoryPropertyFlag) 187{ 188 const VkPhysicalDeviceMemoryProperties deviceMemProps = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()); 189 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemProps.memoryTypeCount; memoryTypeNdx++) 190 { 191 if ((memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 192 (deviceMemProps.memoryTypes[memoryTypeNdx].propertyFlags & memoryPropertyFlag) == memoryPropertyFlag) 193 return memoryTypeNdx; 194 } 195 TCU_THROW(NotSupportedError, "No compatible memory type found"); 196} 197 198bool DeviceGroupTestInstance::isPeerFetchAllowed (deUint32 memoryTypeIndex, deUint32 firstdeviceID, deUint32 seconddeviceID) 199{ 200 VkPeerMemoryFeatureFlags peerMemFeatures1; 201 VkPeerMemoryFeatureFlags peerMemFeatures2; 202 const DeviceDriver vk (m_context.getInstanceInterface(), *m_deviceGroup); 203 const VkPhysicalDeviceMemoryProperties deviceMemProps1 = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_physicalDevices[firstdeviceID]); 204 const VkPhysicalDeviceMemoryProperties deviceMemProps2 = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_physicalDevices[seconddeviceID]); 205 vk.getDeviceGroupPeerMemoryFeatures(*m_deviceGroup, deviceMemProps2.memoryTypes[memoryTypeIndex].heapIndex, firstdeviceID, seconddeviceID, &peerMemFeatures1); 206 vk.getDeviceGroupPeerMemoryFeatures(*m_deviceGroup, deviceMemProps1.memoryTypes[memoryTypeIndex].heapIndex, seconddeviceID, firstdeviceID, &peerMemFeatures2); 207 return (peerMemFeatures1 & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) && (peerMemFeatures2 & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT); 208} 209 210void DeviceGroupTestInstance::getDeviceLayers (vector<string>& enabledLayers) 211{ 212 const tcu::CommandLine& cmdLine = m_context.getTestContext().getCommandLine(); 213 if (cmdLine.isValidationEnabled()) 214 { 215 const vector<VkLayerProperties> layerProperties = enumerateDeviceLayerProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()); 216 217 static const char* s_magicLayer = "VK_LAYER_LUNARG_standard_validation"; 218 static const char* s_defaultLayers[] = 219 { 220 "VK_LAYER_GOOGLE_threading", 221 "VK_LAYER_LUNARG_parameter_validation", 222 "VK_LAYER_LUNARG_device_limits", 223 "VK_LAYER_LUNARG_object_tracker", 224 "VK_LAYER_LUNARG_image", 225 "VK_LAYER_LUNARG_core_validation", 226 "VK_LAYER_LUNARG_swapchain", 227 "VK_LAYER_GOOGLE_unique_objects", 228 }; 229 230 if (isLayerSupported(layerProperties, RequiredLayer(s_magicLayer))) 231 enabledLayers.push_back(s_magicLayer); 232 else 233 { 234 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx) 235 { 236 if (isLayerSupported(layerProperties, RequiredLayer(s_defaultLayers[ndx]))) 237 enabledLayers.push_back(s_defaultLayers[ndx]); 238 } 239 } 240 if (enabledLayers.empty()) 241 TCU_THROW(NotSupportedError, "No device validation layers found"); 242 } 243} 244 245void DeviceGroupTestInstance::init (void) 246{ 247 if (!isInstanceExtensionSupported(m_context.getUsedApiVersion(), m_context.getInstanceExtensions(), "VK_KHR_device_group_creation")) 248 TCU_THROW(NotSupportedError, "Device Group tests are not supported, no device group extension present."); 249 250 const InstanceInterface& instanceInterface = m_context.getInstanceInterface(); 251 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 252 const deUint32 queueIndex = 0; 253 const float queuePriority = 1.0f; 254 vector<const char*> extensionPtrs; 255 de::MovePtr<vk::DeviceDriver> deviceDriver; 256 vector<const char*> layerPtrs; 257 vector<string> deviceExtensions; 258 vector<string> enabledLayers; 259 260 if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_device_group")) 261 TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_device_group"); 262 263 if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_device_group")) 264 deviceExtensions.push_back("VK_KHR_device_group"); 265 266 if(m_useDedicated) 267 { 268 if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_dedicated_allocation")) 269 TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_dedicated_allocation"); 270 271 if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_dedicated_allocation")) 272 deviceExtensions.push_back("VK_KHR_dedicated_allocation"); 273 } 274 275 { 276 const tcu::CommandLine& cmdLine = m_context.getTestContext().getCommandLine(); 277 const vector<VkPhysicalDeviceGroupProperties> properties = enumeratePhysicalDeviceGroups(instanceInterface, m_context.getInstance()); 278 if ((size_t)cmdLine.getVKDeviceGroupId() > properties.size()) 279 TCU_THROW(TestError, "Invalid device group index."); 280 281 m_physicalDeviceCount = properties[cmdLine.getVKDeviceGroupId() - 1].physicalDeviceCount; 282 for (deUint32 idx = 0; idx < m_physicalDeviceCount; idx++) 283 { 284 m_physicalDevices.push_back(properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices[idx]); 285 } 286 287 if (m_usePeerFetch && m_physicalDeviceCount < 2) 288 TCU_THROW(NotSupportedError, "Peer fetching needs more than 1 physical device."); 289 290 if (!(m_testMode & TEST_MODE_AFR) || (m_physicalDeviceCount > 1)) 291 { 292 if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), std::string("VK_KHR_bind_memory2"))) 293 TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_bind_memory2"); 294 deviceExtensions.push_back("VK_KHR_bind_memory2"); 295 } 296 297 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 298 { 299 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //type 300 DE_NULL, //pNext 301 (VkDeviceQueueCreateFlags)0u, //flags 302 queueFamilyIndex, //queueFamilyIndex; 303 1u, //queueCount; 304 &queuePriority, //pQueuePriorities; 305 }; 306 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo = 307 { 308 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, //stype 309 DE_NULL, //pNext 310 properties[cmdLine.getVKDeviceGroupId() - 1].physicalDeviceCount, //physicalDeviceCount 311 properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices //physicalDevices 312 }; 313 314 VkPhysicalDevice physicalDevice = properties[cmdLine.getVKDeviceGroupId() - 1].physicalDevices[(size_t)(cmdLine.getVKDeviceId() - 1)]; 315 VkPhysicalDeviceFeatures enabledDeviceFeatures = getPhysicalDeviceFeatures(instanceInterface, physicalDevice); 316 m_subsetAllocation = properties[cmdLine.getVKDeviceGroupId() - 1].subsetAllocation; 317 318 if (m_drawTessellatedSphere & static_cast<bool>(!enabledDeviceFeatures.tessellationShader)) 319 TCU_THROW(NotSupportedError, "Tessellation is not supported."); 320 321 if (m_fillModeNonSolid & static_cast<bool>(!enabledDeviceFeatures.fillModeNonSolid)) 322 TCU_THROW(NotSupportedError, "Line polygon mode is not supported."); 323 324 extensionPtrs.resize(deviceExtensions.size()); 325 for (size_t ndx = 0; ndx < deviceExtensions.size(); ++ndx) 326 extensionPtrs[ndx] = deviceExtensions[ndx].c_str(); 327 328 // Get Layers 329 getDeviceLayers(enabledLayers); 330 layerPtrs.resize(enabledLayers.size()); 331 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx) 332 layerPtrs[ndx] = enabledLayers[ndx].c_str(); 333 334 const VkDeviceCreateInfo deviceCreateInfo = 335 { 336 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 337 &deviceGroupInfo, //pNext; 338 (VkDeviceCreateFlags)0u, //flags 339 1, //queueRecordCount; 340 &deviceQueueCreateInfo, //pRequestedQueues; 341 (deUint32)layerPtrs.size(), //layerCount; 342 (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]), //ppEnabledLayerNames; 343 (deUint32)extensionPtrs.size(), //extensionCount; 344 (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]), //ppEnabledExtensionNames; 345 &enabledDeviceFeatures, //pEnabledFeatures; 346 }; 347 m_deviceGroup = createDevice(instanceInterface, physicalDevice, &deviceCreateInfo); 348 } 349 350 deviceDriver = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(instanceInterface, *m_deviceGroup)); 351 m_deviceGroupQueue = getDeviceQueue(*deviceDriver, *m_deviceGroup, queueFamilyIndex, queueIndex); 352} 353 354void DeviceGroupTestInstance::SubmitBufferAndWaitForIdle(const DeviceDriver& vk, VkCommandBuffer cmdBuf, VkDeviceGroupSubmitInfo deviceGroupSubmitInfo) 355{ 356 const VkFenceCreateInfo fenceParams = 357 { 358 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType 359 DE_NULL, // pNext 360 0u, // flags 361 }; 362 const VkSubmitInfo submitInfo = 363 { 364 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType 365 &deviceGroupSubmitInfo, // pNext 366 0u, // waitSemaphoreCount 367 DE_NULL, // pWaitSemaphores 368 (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask 369 1u, // commandBufferCount 370 &cmdBuf, // pCommandBuffers 371 0u, // signalSemaphoreCount 372 DE_NULL, // pSignalSemaphores 373 }; 374 const Unique<VkFence> fence(createFence(vk, *m_deviceGroup, &fenceParams)); 375 376 VK_CHECK(vk.queueSubmit(m_deviceGroupQueue, 1u, &submitInfo, *fence)); 377 VK_CHECK(vk.waitForFences(*m_deviceGroup, 1u, &fence.get(), DE_TRUE, ~0ull)); 378 VK_CHECK(vk.deviceWaitIdle(*m_deviceGroup)); 379} 380 381tcu::TestStatus DeviceGroupTestInstance::iterate (void) 382{ 383 const InstanceInterface& vki (m_context.getInstanceInterface()); 384 const DeviceDriver vk (vki, *m_deviceGroup); 385 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 386 const tcu::UVec2 renderSize (256, 256); 387 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 388 const tcu::Vec4 clearColor (0.125f, 0.25f, 0.75f, 1.0f); 389 const tcu::Vec4 drawColor (1.0f, 1.0f, 0.0f, 1.0f); 390 const float tessLevel = 16.0f; 391 SimpleAllocator memAlloc (vk, *m_deviceGroup, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 392 bool iterateResultSuccess = false; 393 const tcu::Vec4 sphereVertices[] = 394 { 395 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), 396 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), 397 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 398 tcu::Vec4(0.0f, 0.0f, -1.0f, 1.0f), 399 tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f), 400 tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), 401 }; 402 const deUint32 sphereIndices[] = {0, 1, 2, 2, 1, 3, 3, 1, 5, 5, 1, 0, 0, 2, 4, 2, 3, 4, 3, 5, 4, 5, 0, 4}; 403 const tcu::Vec4 triVertices[] = 404 { 405 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), 406 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f), 407 tcu::Vec4(0.0f, +0.5f, 0.0f, 1.0f) 408 }; 409 const deUint32 triIndices[] = {0, 1, 2}; 410 const tcu::Vec4 * vertices = m_drawTessellatedSphere ? &sphereVertices[0] : &triVertices[0]; 411 const deUint32 * indices = m_drawTessellatedSphere ? &sphereIndices[0] : &triIndices[0]; 412 const deUint32 verticesSize = m_drawTessellatedSphere ? deUint32(sizeof(sphereVertices)) : deUint32(sizeof(triVertices)); 413 const deUint32 numIndices = m_drawTessellatedSphere ? deUint32(sizeof(sphereIndices)/sizeof(sphereIndices[0])) : deUint32(sizeof(triIndices)/sizeof(triIndices[0])); 414 const deUint32 indicesSize = m_drawTessellatedSphere ? deUint32(sizeof(sphereIndices)) : deUint32(sizeof(triIndices)); 415 416 // Loop through all physical devices in the device group 417 for (deUint32 physDevID = 0; physDevID < m_physicalDeviceCount; physDevID++) 418 { 419 const deUint32 firstDeviceID = physDevID; 420 const deUint32 secondDeviceID = (firstDeviceID + 1 ) % m_physicalDeviceCount; 421 vector<deUint32> deviceIndices (m_physicalDeviceCount); 422 bool isPeerMemAsCopySrcAllowed = true; 423 // Set broadcast on memory allocation 424 const deUint32 allocDeviceMask = m_subsetAllocation ? (1 << firstDeviceID) | (1 << secondDeviceID) : (1 << m_physicalDeviceCount) - 1; 425 426 for (deUint32 i = 0; i < m_physicalDeviceCount; i++) 427 deviceIndices[i] = i; 428 deviceIndices[firstDeviceID] = secondDeviceID; 429 deviceIndices[secondDeviceID] = firstDeviceID; 430 431 VkMemoryRequirements memReqs = 432 { 433 0, // VkDeviceSize size 434 0, // VkDeviceSize alignment 435 0, // uint32_t memoryTypeBits 436 }; 437 deUint32 memoryTypeNdx = 0; 438 de::MovePtr<Allocation> stagingVertexBufferMemory; 439 de::MovePtr<Allocation> stagingIndexBufferMemory; 440 de::MovePtr<Allocation> stagingUniformBufferMemory; 441 de::MovePtr<Allocation> stagingSboBufferMemory; 442 443 vk::Move<vk::VkDeviceMemory> vertexBufferMemory; 444 vk::Move<vk::VkDeviceMemory> indexBufferMemory; 445 vk::Move<vk::VkDeviceMemory> uniformBufferMemory; 446 vk::Move<vk::VkDeviceMemory> sboBufferMemory; 447 vk::Move<vk::VkDeviceMemory> imageMemory; 448 449 Move<VkRenderPass> renderPass; 450 Move<VkImage> renderImage; 451 Move<VkImage> readImage; 452 453 Move<VkDescriptorSetLayout> descriptorSetLayout; 454 Move<VkDescriptorPool> descriptorPool; 455 Move<VkDescriptorSet> descriptorSet; 456 457 Move<VkBuffer> stagingVertexBuffer; 458 Move<VkBuffer> stagingUniformBuffer; 459 Move<VkBuffer> stagingIndexBuffer; 460 Move<VkBuffer> stagingSboBuffer; 461 462 Move<VkBuffer> vertexBuffer; 463 Move<VkBuffer> indexBuffer; 464 Move<VkBuffer> uniformBuffer; 465 Move<VkBuffer> sboBuffer; 466 467 Move<VkPipeline> pipeline; 468 Move<VkPipelineLayout> pipelineLayout; 469 470 Move<VkImageView> colorAttView; 471 Move<VkFramebuffer> framebuffer; 472 Move<VkCommandPool> cmdPool; 473 Move<VkCommandBuffer> cmdBuffer; 474 475 VkMemoryDedicatedAllocateInfo dedicatedAllocInfo = 476 { 477 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // sType 478 DE_NULL, // pNext 479 DE_NULL, // image 480 DE_NULL // buffer 481 }; 482 483 VkMemoryAllocateFlagsInfo allocDeviceMaskInfo = 484 { 485 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, // sType 486 m_useDedicated ? &dedicatedAllocInfo : DE_NULL, // pNext 487 VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, // flags 488 allocDeviceMask, // deviceMask 489 }; 490 491 VkMemoryAllocateInfo allocInfo = 492 { 493 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType 494 &allocDeviceMaskInfo, // pNext 495 0u, // allocationSize 496 0u, // memoryTypeIndex 497 }; 498 499 VkDeviceGroupSubmitInfo deviceGroupSubmitInfo = 500 { 501 VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, // sType 502 DE_NULL, // pNext 503 0u, // waitSemaphoreCount 504 DE_NULL, // pWaitSemaphoreDeviceIndices 505 0u, // commandBufferCount 506 DE_NULL, // pCommandBufferDeviceMasks 507 0u, // signalSemaphoreCount 508 DE_NULL, // pSignalSemaphoreDeviceIndices 509 }; 510 511 // create vertex buffers 512 { 513 const VkBufferCreateInfo stagingVertexBufferParams = 514 { 515 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 516 DE_NULL, // pNext 517 0u, // flags 518 (VkDeviceSize)verticesSize, // size 519 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage 520 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 521 1u, // queueFamilyIndexCount 522 &queueFamilyIndex, // pQueueFamilyIndices 523 }; 524 stagingVertexBuffer = createBuffer(vk, *m_deviceGroup, &stagingVertexBufferParams); 525 stagingVertexBufferMemory = memAlloc.allocate(getBufferMemoryRequirements(vk, *m_deviceGroup, *stagingVertexBuffer), MemoryRequirement::HostVisible); 526 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *stagingVertexBuffer, stagingVertexBufferMemory->getMemory(), stagingVertexBufferMemory->getOffset())); 527 528 const VkMappedMemoryRange range = 529 { 530 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 531 DE_NULL, // pNext 532 stagingVertexBufferMemory->getMemory(), // memory 533 0u, // offset 534 (VkDeviceSize)verticesSize, // size 535 }; 536 void* vertexBufPtr = stagingVertexBufferMemory->getHostPtr(); 537 deMemcpy(vertexBufPtr, &vertices[0], verticesSize); 538 VK_CHECK(vk.flushMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 539 } 540 541 { 542 const VkBufferCreateInfo vertexBufferParams = 543 { 544 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 545 DE_NULL, // pNext 546 0u, // flags 547 (VkDeviceSize)verticesSize, // size 548 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage 549 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 550 1u, // queueFamilyIndexCount 551 &queueFamilyIndex, // pQueueFamilyIndices 552 }; 553 vertexBuffer = createBuffer(vk, *m_deviceGroup, &vertexBufferParams); 554 555 memReqs = getBufferMemoryRequirements(vk, *m_deviceGroup, vertexBuffer.get()); 556 memoryTypeNdx = getMemoryIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 557 558 dedicatedAllocInfo.buffer = vertexBuffer.get(); 559 allocInfo.allocationSize = memReqs.size; 560 allocInfo.memoryTypeIndex = memoryTypeNdx; 561 vertexBufferMemory = allocateMemory(vk, *m_deviceGroup, &allocInfo); 562 563 if (m_usePeerFetch && !isPeerFetchAllowed(memoryTypeNdx, firstDeviceID, secondDeviceID)) 564 TCU_THROW(NotSupportedError, "Peer fetch is not supported."); 565 566 // Bind vertex buffer 567 if (m_usePeerFetch) 568 { 569 VkBindBufferMemoryDeviceGroupInfo devGroupBindInfo = 570 { 571 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, // sType 572 DE_NULL, // pNext 573 m_physicalDeviceCount, // deviceIndexCount 574 &deviceIndices[0], // pDeviceIndices 575 }; 576 577 VkBindBufferMemoryInfo bindInfo = 578 { 579 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, // sType 580 &devGroupBindInfo, // pNext 581 vertexBuffer.get(), // buffer 582 vertexBufferMemory.get(), // memory 583 0u, // memoryOffset 584 }; 585 VK_CHECK(vk.bindBufferMemory2(*m_deviceGroup, 1, &bindInfo)); 586 } 587 else 588 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *vertexBuffer, vertexBufferMemory.get(), 0)); 589 } 590 591 // create index buffers 592 { 593 const VkBufferCreateInfo stagingIndexBufferParams = 594 { 595 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 596 DE_NULL, // pNext 597 0u, // flags 598 (VkDeviceSize)indicesSize, // size 599 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage 600 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 601 1u, // queueFamilyIndexCount 602 &queueFamilyIndex, // pQueueFamilyIndices 603 }; 604 stagingIndexBuffer = createBuffer(vk, *m_deviceGroup, &stagingIndexBufferParams); 605 stagingIndexBufferMemory = memAlloc.allocate(getBufferMemoryRequirements(vk, *m_deviceGroup, *stagingIndexBuffer), MemoryRequirement::HostVisible); 606 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *stagingIndexBuffer, stagingIndexBufferMemory->getMemory(), stagingIndexBufferMemory->getOffset())); 607 608 const VkMappedMemoryRange range = 609 { 610 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 611 DE_NULL, // pNext 612 stagingIndexBufferMemory->getMemory(), // memory 613 0u, // offset 614 (VkDeviceSize)indicesSize, // size 615 }; 616 void* indexBufPtr = stagingIndexBufferMemory->getHostPtr(); 617 deMemcpy(indexBufPtr, &indices[0], indicesSize); 618 VK_CHECK(vk.flushMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 619 } 620 621 { 622 const VkBufferCreateInfo indexBufferParams = 623 { 624 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 625 DE_NULL, // pNext 626 0u, // flags 627 (VkDeviceSize)indicesSize, // size 628 VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage 629 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 630 1u, // queueFamilyIndexCount 631 &queueFamilyIndex, // pQueueFamilyIndices 632 }; 633 indexBuffer = createBuffer(vk, *m_deviceGroup, &indexBufferParams); 634 635 memReqs = getBufferMemoryRequirements(vk, *m_deviceGroup, indexBuffer.get()); 636 memoryTypeNdx = getMemoryIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 637 638 dedicatedAllocInfo.buffer = indexBuffer.get(); 639 allocInfo.allocationSize = memReqs.size; 640 allocInfo.memoryTypeIndex = memoryTypeNdx; 641 indexBufferMemory = allocateMemory(vk, *m_deviceGroup, &allocInfo); 642 643 if (m_usePeerFetch && !isPeerFetchAllowed(memoryTypeNdx, firstDeviceID, secondDeviceID)) 644 TCU_THROW(NotSupportedError, "Peer fetch is not supported."); 645 646 // Bind index buffer 647 if (m_usePeerFetch) 648 { 649 VkBindBufferMemoryDeviceGroupInfo devGroupBindInfo = 650 { 651 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, // sType 652 DE_NULL, // pNext 653 m_physicalDeviceCount, // deviceIndexCount 654 &deviceIndices[0], // pDeviceIndices 655 }; 656 657 VkBindBufferMemoryInfo bindInfo = 658 { 659 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, // sType 660 &devGroupBindInfo, // pNext 661 indexBuffer.get(), // buffer 662 indexBufferMemory.get(), // memory 663 0u, // memoryOffset 664 }; 665 VK_CHECK(vk.bindBufferMemory2(*m_deviceGroup, 1, &bindInfo)); 666 } 667 else 668 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *indexBuffer, indexBufferMemory.get(), 0)); 669 } 670 671 // create uniform buffers 672 { 673 const VkBufferCreateInfo stagingUniformBufferParams = 674 { 675 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 676 DE_NULL, // pNext 677 0u, // flags 678 (VkDeviceSize)sizeof(drawColor), // size 679 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage 680 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 681 1u, // queueFamilyIndexCount 682 &queueFamilyIndex, // pQueueFamilyIndices 683 }; 684 stagingUniformBuffer = createBuffer(vk, *m_deviceGroup, &stagingUniformBufferParams); 685 stagingUniformBufferMemory = memAlloc.allocate(getBufferMemoryRequirements(vk, *m_deviceGroup, *stagingUniformBuffer), MemoryRequirement::HostVisible); 686 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *stagingUniformBuffer, stagingUniformBufferMemory->getMemory(), stagingUniformBufferMemory->getOffset())); 687 688 const VkMappedMemoryRange range = 689 { 690 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 691 DE_NULL, // pNext 692 stagingUniformBufferMemory->getMemory(),// memory 693 0u, // offset 694 (VkDeviceSize)sizeof(drawColor), // size 695 }; 696 void* uniformBufPtr = stagingUniformBufferMemory->getHostPtr(); 697 deMemcpy(uniformBufPtr, &drawColor[0], sizeof(drawColor)); 698 VK_CHECK(vk.flushMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 699 } 700 701 { 702 const VkBufferCreateInfo uniformBufferParams = 703 { 704 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 705 DE_NULL, // pNext 706 0u, // flags 707 (VkDeviceSize)sizeof(drawColor), // size 708 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage 709 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 710 1u, // queueFamilyIndexCount 711 &queueFamilyIndex, // pQueueFamilyIndices 712 }; 713 uniformBuffer = createBuffer(vk, *m_deviceGroup, &uniformBufferParams); 714 715 memReqs = getBufferMemoryRequirements(vk, *m_deviceGroup, uniformBuffer.get()); 716 memoryTypeNdx = getMemoryIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 717 718 dedicatedAllocInfo.buffer = uniformBuffer.get(); 719 allocInfo.allocationSize = memReqs.size; 720 allocInfo.memoryTypeIndex = memoryTypeNdx; 721 uniformBufferMemory = allocateMemory(vk, *m_deviceGroup, &allocInfo); 722 723 if (m_usePeerFetch && !isPeerFetchAllowed(memoryTypeNdx, firstDeviceID, secondDeviceID)) 724 TCU_THROW(NotSupportedError, "Peer fetch is not supported."); 725 726 if (m_usePeerFetch) 727 { 728 VkBindBufferMemoryDeviceGroupInfo devGroupBindInfo = 729 { 730 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, // sType 731 DE_NULL, // pNext 732 m_physicalDeviceCount, // deviceIndexCount 733 &deviceIndices[0], // pDeviceIndices 734 }; 735 736 VkBindBufferMemoryInfo bindInfo = 737 { 738 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, // sType 739 &devGroupBindInfo, // pNext 740 uniformBuffer.get(), // buffer 741 uniformBufferMemory.get(), // memory 742 0u, // memoryOffset 743 }; 744 VK_CHECK(vk.bindBufferMemory2(*m_deviceGroup, 1, &bindInfo)); 745 } 746 else 747 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, uniformBuffer.get(), uniformBufferMemory.get(), 0)); 748 } 749 750 // create SBO buffers 751 { 752 const VkBufferCreateInfo stagingSboBufferParams = 753 { 754 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 755 DE_NULL, // pNext 756 0u, // flags 757 (VkDeviceSize)sizeof(tessLevel), // size 758 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage 759 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 760 1u, // queueFamilyIndexCount 761 &queueFamilyIndex, // pQueueFamilyIndices 762 }; 763 stagingSboBuffer = createBuffer(vk, *m_deviceGroup, &stagingSboBufferParams); 764 stagingSboBufferMemory = memAlloc.allocate(getBufferMemoryRequirements(vk, *m_deviceGroup, *stagingSboBuffer), MemoryRequirement::HostVisible); 765 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *stagingSboBuffer, stagingSboBufferMemory->getMemory(), stagingSboBufferMemory->getOffset())); 766 767 const VkMappedMemoryRange range = 768 { 769 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 770 DE_NULL, // pNext 771 stagingSboBufferMemory->getMemory(), // memory 772 0u, // offset 773 (VkDeviceSize)sizeof(tessLevel), // size 774 }; 775 void* sboBufPtr = stagingSboBufferMemory->getHostPtr(); 776 deMemcpy(sboBufPtr, &tessLevel, sizeof(tessLevel)); 777 VK_CHECK(vk.flushMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 778 } 779 780 { 781 const VkBufferCreateInfo sboBufferParams = 782 { 783 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 784 DE_NULL, // pNext 785 0u, // flags 786 (VkDeviceSize)sizeof(tessLevel), // size 787 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage 788 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 789 1u, // queueFamilyIndexCount 790 &queueFamilyIndex, // pQueueFamilyIndices 791 }; 792 sboBuffer = createBuffer(vk, *m_deviceGroup, &sboBufferParams); 793 794 memReqs = getBufferMemoryRequirements(vk, *m_deviceGroup, sboBuffer.get()); 795 memoryTypeNdx = getMemoryIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 796 797 dedicatedAllocInfo.buffer = sboBuffer.get(); 798 allocInfo.allocationSize = memReqs.size; 799 allocInfo.memoryTypeIndex = memoryTypeNdx; 800 sboBufferMemory = allocateMemory(vk, *m_deviceGroup, &allocInfo); 801 802 if (m_usePeerFetch && !isPeerFetchAllowed(memoryTypeNdx, firstDeviceID, secondDeviceID)) 803 TCU_THROW(NotSupportedError, "Peer fetch is not supported."); 804 805 if (m_usePeerFetch) 806 { 807 VkBindBufferMemoryDeviceGroupInfo devGroupBindInfo = 808 { 809 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, // sType 810 DE_NULL, // pNext 811 m_physicalDeviceCount, // deviceIndexCount 812 &deviceIndices[0], // pDeviceIndices 813 }; 814 815 VkBindBufferMemoryInfo bindInfo = 816 { 817 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, // sType 818 &devGroupBindInfo, // pNext 819 sboBuffer.get(), // buffer 820 sboBufferMemory.get(), // memory 821 0u, // memoryOffset 822 }; 823 VK_CHECK(vk.bindBufferMemory2(*m_deviceGroup, 1, &bindInfo)); 824 } 825 else 826 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, sboBuffer.get(), sboBufferMemory.get(), 0)); 827 } 828 829 // Create image resources 830 // Use a consistent usage flag because of memory aliasing 831 VkImageUsageFlags imageUsageFlag = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 832 { 833 // Check for SFR support 834 VkImageFormatProperties properties; 835 if ((m_testMode & TEST_MODE_SFR) && vki.getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), 836 colorFormat, // format 837 VK_IMAGE_TYPE_2D, // type 838 VK_IMAGE_TILING_OPTIMAL, // tiling 839 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage 840 VK_IMAGE_CREATE_BIND_SFR_BIT, // flags 841 &properties) != VK_SUCCESS) // properties 842 { 843 TCU_THROW(NotSupportedError, "Format not supported for SFR"); 844 } 845 846 VkImageCreateFlags imageCreateFlags = VK_IMAGE_CREATE_ALIAS_BIT; // The image objects alias same memory 847 if ((m_testMode & TEST_MODE_SFR) && (m_physicalDeviceCount > 1)) 848 { 849 imageCreateFlags |= VK_IMAGE_CREATE_BIND_SFR_BIT; 850 } 851 852 const VkImageCreateInfo imageParams = 853 { 854 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 855 DE_NULL, // pNext 856 imageCreateFlags, // flags 857 VK_IMAGE_TYPE_2D, // imageType 858 colorFormat, // format 859 { renderSize.x(), renderSize.y(), 1 }, // extent 860 1u, // mipLevels 861 1u, // arraySize 862 VK_SAMPLE_COUNT_1_BIT, // samples 863 VK_IMAGE_TILING_OPTIMAL, // tiling 864 imageUsageFlag, // usage 865 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 866 1u, // queueFamilyIndexCount 867 &queueFamilyIndex, // pQueueFamilyIndices 868 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout 869 }; 870 871 renderImage = createImage(vk, *m_deviceGroup, &imageParams); 872 readImage = createImage(vk, *m_deviceGroup, &imageParams); 873 874 dedicatedAllocInfo.image = *renderImage; 875 dedicatedAllocInfo.buffer = DE_NULL; 876 memReqs = getImageMemoryRequirements(vk, *m_deviceGroup, renderImage.get()); 877 memoryTypeNdx = getMemoryIndex(memReqs.memoryTypeBits, m_useHostMemory ? 0 : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 878 allocInfo.allocationSize = memReqs.size; 879 allocInfo.memoryTypeIndex = memoryTypeNdx; 880 imageMemory = allocateMemory(vk, *m_deviceGroup, &allocInfo); 881 } 882 883 if ((m_testMode & TEST_MODE_SFR) && (m_physicalDeviceCount > 1)) 884 { 885 if (m_usePeerFetch && !isPeerFetchAllowed(memoryTypeNdx, firstDeviceID, secondDeviceID)) 886 TCU_THROW(NotSupportedError, "Peer texture reads is not supported."); 887 888 // Check if peer memory can be used as source of a copy command in case of SFR bindings, always allowed in case of 1 device 889 VkPeerMemoryFeatureFlags peerMemFeatures; 890 const VkPhysicalDeviceMemoryProperties deviceMemProps = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_physicalDevices[secondDeviceID]); 891 vk.getDeviceGroupPeerMemoryFeatures(*m_deviceGroup, deviceMemProps.memoryTypes[memoryTypeNdx].heapIndex, firstDeviceID, secondDeviceID, &peerMemFeatures); 892 isPeerMemAsCopySrcAllowed = (peerMemFeatures & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT); 893 894 VkRect2D zeroRect = { 895 { 896 0, // VkOffset2D.x 897 0, // VkOffset2D.x 898 }, 899 { 900 0, // VkExtent2D.x 901 0, // VkExtent2D.x 902 } 903 }; 904 vector<VkRect2D> sfrRects; 905 for (deUint32 i = 0; i < m_physicalDeviceCount*m_physicalDeviceCount; i++) 906 sfrRects.push_back(zeroRect); 907 908 if (m_physicalDeviceCount == 1u) 909 { 910 sfrRects[0].extent.width = (deInt32)renderSize.x(); 911 sfrRects[0].extent.height = (deInt32)renderSize.y(); 912 } 913 else 914 { 915 // Split into 2 vertical halves 916 sfrRects[firstDeviceID * m_physicalDeviceCount + firstDeviceID].extent.width = (deInt32)renderSize.x() / 2; 917 sfrRects[firstDeviceID * m_physicalDeviceCount + firstDeviceID].extent.height = (deInt32)renderSize.y(); 918 sfrRects[firstDeviceID * m_physicalDeviceCount + secondDeviceID] = sfrRects[firstDeviceID * m_physicalDeviceCount + firstDeviceID]; 919 sfrRects[firstDeviceID * m_physicalDeviceCount + secondDeviceID].offset.x = (deInt32)renderSize.x() / 2; 920 sfrRects[secondDeviceID * m_physicalDeviceCount + firstDeviceID] = sfrRects[firstDeviceID * m_physicalDeviceCount + firstDeviceID]; 921 sfrRects[secondDeviceID * m_physicalDeviceCount + secondDeviceID] = sfrRects[firstDeviceID * m_physicalDeviceCount + secondDeviceID]; 922 } 923 924 VkBindImageMemoryDeviceGroupInfo devGroupBindInfo = 925 { 926 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, // sType 927 DE_NULL, // pNext 928 0u, // deviceIndexCount 929 DE_NULL, // pDeviceIndices 930 m_physicalDeviceCount*m_physicalDeviceCount, // SFRRectCount 931 &sfrRects[0], // pSFRRects 932 }; 933 934 VkBindImageMemoryInfo bindInfo = 935 { 936 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, // sType 937 &devGroupBindInfo, // pNext 938 *renderImage, // image 939 imageMemory.get(), // memory 940 0u, // memoryOffset 941 }; 942 VK_CHECK(vk.bindImageMemory2(*m_deviceGroup, 1, &bindInfo)); 943 } 944 else 945 VK_CHECK(vk.bindImageMemory(*m_deviceGroup, *renderImage, imageMemory.get(), 0)); 946 947 VK_CHECK(vk.bindImageMemory(*m_deviceGroup, *readImage, imageMemory.get(), 0)); 948 949 // Create renderpass 950 { 951 const VkAttachmentDescription colorAttDesc = 952 { 953 0u, // flags 954 colorFormat, // format 955 VK_SAMPLE_COUNT_1_BIT, // samples 956 VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp 957 VK_ATTACHMENT_STORE_OP_STORE, // storeOp 958 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp 959 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp 960 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout 961 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout 962 }; 963 const VkAttachmentReference colorAttRef = 964 { 965 0u, // attachment 966 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout 967 }; 968 const VkSubpassDescription subpassDesc = 969 { 970 (VkSubpassDescriptionFlags)0u, // flags 971 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint 972 0u, // inputAttachmentCount 973 DE_NULL, // pInputAttachments 974 1u, // colorAttachmentCount 975 &colorAttRef, // pColorAttachments 976 DE_NULL, // pResolveAttachments 977 DE_NULL, // depthStencilAttachment 978 0u, // preserveAttachmentCount 979 DE_NULL, // pPreserveAttachments 980 }; 981 const VkRenderPassCreateInfo renderPassParams = 982 { 983 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType 984 DE_NULL, // pNext 985 0u, // flags 986 1u, // attachmentCount 987 &colorAttDesc, // pAttachments 988 1u, // subpassCount 989 &subpassDesc, // pSubpasses 990 0u, // dependencyCount 991 DE_NULL, // pDependencies 992 }; 993 renderPass = createRenderPass(vk, *m_deviceGroup, &renderPassParams); 994 } 995 996 // Create descriptors 997 { 998 vector<VkDescriptorSetLayoutBinding> layoutBindings; 999 vector<VkDescriptorPoolSize> descriptorTypes; 1000 vector<VkWriteDescriptorSet> writeDescritporSets; 1001 1002 const VkDescriptorSetLayoutBinding layoutBindingUBO = 1003 { 1004 0u, // deUint32 binding; 1005 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType; 1006 1u, // deUint32 descriptorCount; 1007 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 1008 DE_NULL // const VkSampler* pImmutableSamplers; 1009 }; 1010 const VkDescriptorSetLayoutBinding layoutBindingSBO = 1011 { 1012 1u, // deUint32 binding; 1013 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType; 1014 1u, // deUint32 descriptorCount; 1015 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlags stageFlags; 1016 DE_NULL // const VkSampler* pImmutableSamplers; 1017 }; 1018 1019 layoutBindings.push_back(layoutBindingUBO); 1020 if (m_drawTessellatedSphere) 1021 layoutBindings.push_back(layoutBindingSBO); 1022 1023 const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams = 1024 { 1025 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType; 1026 DE_NULL, // cost void* pNext; 1027 (VkDescriptorSetLayoutCreateFlags)0, // VkDescriptorSetLayoutCreateFlags flags 1028 deUint32(layoutBindings.size()), // deUint32 count; 1029 layoutBindings.data() // const VkDescriptorSetLayoutBinding pBinding; 1030 }; 1031 descriptorSetLayout = createDescriptorSetLayout(vk, *m_deviceGroup, &descriptorLayoutParams); 1032 1033 const VkDescriptorPoolSize descriptorTypeUBO = 1034 { 1035 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType type; 1036 1 // deUint32 count; 1037 }; 1038 const VkDescriptorPoolSize descriptorTypeSBO = 1039 { 1040 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType type; 1041 1 // deUint32 count; 1042 }; 1043 descriptorTypes.push_back(descriptorTypeUBO); 1044 if (m_drawTessellatedSphere) 1045 descriptorTypes.push_back(descriptorTypeSBO); 1046 1047 const VkDescriptorPoolCreateInfo descriptorPoolParams = 1048 { 1049 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType; 1050 DE_NULL, // void* pNext; 1051 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags; 1052 1u, // deUint32 maxSets; 1053 deUint32(descriptorTypes.size()), // deUint32 count; 1054 descriptorTypes.data() // const VkDescriptorTypeCount* pTypeCount 1055 }; 1056 descriptorPool = createDescriptorPool(vk, *m_deviceGroup, &descriptorPoolParams); 1057 1058 const VkDescriptorSetAllocateInfo descriptorSetParams = 1059 { 1060 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1061 DE_NULL, 1062 *descriptorPool, 1063 1u, 1064 &descriptorSetLayout.get(), 1065 }; 1066 descriptorSet = allocateDescriptorSet(vk, *m_deviceGroup, &descriptorSetParams); 1067 1068 const VkDescriptorBufferInfo uboDescriptorInfo = 1069 { 1070 uniformBuffer.get(), 1071 0, 1072 (VkDeviceSize)sizeof(drawColor) 1073 }; 1074 const VkDescriptorBufferInfo sboDescriptorInfo = 1075 { 1076 sboBuffer.get(), 1077 0, 1078 (VkDeviceSize)sizeof(tessLevel) 1079 }; 1080 const VkWriteDescriptorSet writeDescritporSetUBO = 1081 { 1082 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 1083 DE_NULL, // const void* pNext; 1084 *descriptorSet, // VkDescriptorSet destSet; 1085 0, // deUint32 destBinding; 1086 0, // deUint32 destArrayElement; 1087 1u, // deUint32 count; 1088 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType; 1089 (const VkDescriptorImageInfo*)DE_NULL, // VkDescriptorImageInfo* pImageInfo; 1090 &uboDescriptorInfo, // VkDescriptorBufferInfo* pBufferInfo; 1091 (const VkBufferView*)DE_NULL // VkBufferView* pTexelBufferView; 1092 }; 1093 1094 const VkWriteDescriptorSet writeDescritporSetSBO = 1095 { 1096 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 1097 DE_NULL, // const void* pNext; 1098 *descriptorSet, // VkDescriptorSet destSet; 1099 1, // deUint32 destBinding; 1100 0, // deUint32 destArrayElement; 1101 1u, // deUint32 count; 1102 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType; 1103 (const VkDescriptorImageInfo*)DE_NULL, // VkDescriptorImageInfo* pImageInfo; 1104 &sboDescriptorInfo, // VkDescriptorBufferInfo* pBufferInfo; 1105 (const VkBufferView*)DE_NULL // VkBufferView* pTexelBufferView; 1106 }; 1107 writeDescritporSets.push_back(writeDescritporSetUBO); 1108 if (m_drawTessellatedSphere) 1109 writeDescritporSets.push_back(writeDescritporSetSBO); 1110 1111 vk.updateDescriptorSets(*m_deviceGroup, deUint32(writeDescritporSets.size()), writeDescritporSets.data(), 0u, DE_NULL); 1112 } 1113 1114 // Create Pipeline 1115 { 1116 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 1117 Move<VkShaderModule> vertShaderModule; 1118 Move<VkShaderModule> tcssShaderModule; 1119 Move<VkShaderModule> tessShaderModule; 1120 Move<VkShaderModule> fragShaderModule; 1121 1122 const VkDescriptorSetLayout descset = descriptorSetLayout.get(); 1123 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1124 { 1125 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 1126 DE_NULL, // pNext 1127 (vk::VkPipelineLayoutCreateFlags)0, // flags 1128 1u, // setLayoutCount 1129 &descset, // pSetLayouts 1130 0u, // pushConstantRangeCount 1131 DE_NULL, // pPushConstantRanges 1132 }; 1133 pipelineLayout = createPipelineLayout(vk, *m_deviceGroup, &pipelineLayoutParams); 1134 1135 // Shaders 1136 vertShaderModule = createShaderModule(vk, *m_deviceGroup, m_context.getBinaryCollection().get("vert"), 0); 1137 fragShaderModule = createShaderModule(vk, *m_deviceGroup, m_context.getBinaryCollection().get("frag"), 0); 1138 1139 const VkSpecializationInfo emptyShaderSpecParams = 1140 { 1141 0u, // mapEntryCount 1142 DE_NULL, // pMap 1143 0, // dataSize 1144 DE_NULL, // pData 1145 }; 1146 const VkPipelineShaderStageCreateInfo vertexShaderStageParams = 1147 { 1148 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1149 DE_NULL, // pNext 1150 0u, // flags 1151 VK_SHADER_STAGE_VERTEX_BIT, // stage 1152 *vertShaderModule, // module 1153 "main", // pName 1154 &emptyShaderSpecParams, // pSpecializationInfo 1155 }; 1156 shaderStageParams.push_back(vertexShaderStageParams); 1157 1158 if (m_drawTessellatedSphere) 1159 { 1160 tcssShaderModule = createShaderModule(vk, *m_deviceGroup, m_context.getBinaryCollection().get("tesc"), 0); 1161 tessShaderModule = createShaderModule(vk, *m_deviceGroup, m_context.getBinaryCollection().get("tese"), 0); 1162 1163 const VkPipelineShaderStageCreateInfo tessControlShaderStageParams = 1164 { 1165 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1166 DE_NULL, // pNext 1167 0u, // flags 1168 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // stage 1169 *tcssShaderModule, // module 1170 "main", // pName 1171 &emptyShaderSpecParams, // pSpecializationInfo 1172 }; 1173 const VkPipelineShaderStageCreateInfo tessEvalShaderStageParams = 1174 { 1175 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1176 DE_NULL, // pNext 1177 0u, // flags 1178 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // stage 1179 *tessShaderModule, // module 1180 "main", // pName 1181 &emptyShaderSpecParams, // pSpecializationInfo 1182 }; 1183 1184 shaderStageParams.push_back(tessControlShaderStageParams); 1185 shaderStageParams.push_back(tessEvalShaderStageParams); 1186 } 1187 1188 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams = 1189 { 1190 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1191 DE_NULL, // pNext 1192 0u, // flags 1193 VK_SHADER_STAGE_FRAGMENT_BIT, // stage 1194 *fragShaderModule, // module 1195 "main", // pName 1196 &emptyShaderSpecParams, // pSpecializationInfo 1197 }; 1198 shaderStageParams.push_back(fragmentShaderStageParams); 1199 1200 const VkPipelineDepthStencilStateCreateInfo depthStencilParams = 1201 { 1202 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType 1203 DE_NULL, // pNext 1204 0u, // flags 1205 DE_FALSE, // depthTestEnable 1206 DE_FALSE, // depthWriteEnable 1207 VK_COMPARE_OP_ALWAYS, // depthCompareOp 1208 DE_FALSE, // depthBoundsTestEnable 1209 DE_FALSE, // stencilTestEnable 1210 { 1211 VK_STENCIL_OP_KEEP, // failOp 1212 VK_STENCIL_OP_KEEP, // passOp 1213 VK_STENCIL_OP_KEEP, // depthFailOp 1214 VK_COMPARE_OP_ALWAYS, // compareOp 1215 0u, // compareMask 1216 0u, // writeMask 1217 0u, // reference 1218 }, // front 1219 { 1220 VK_STENCIL_OP_KEEP, // failOp 1221 VK_STENCIL_OP_KEEP, // passOp 1222 VK_STENCIL_OP_KEEP, // depthFailOp 1223 VK_COMPARE_OP_ALWAYS, // compareOp 1224 0u, // compareMask 1225 0u, // writeMask 1226 0u, // reference 1227 }, // back; 1228 0.0f, // minDepthBounds; 1229 1.0f, // maxDepthBounds; 1230 }; 1231 const VkViewport viewport0 = 1232 { 1233 0.0f, // x 1234 0.0f, // y 1235 (float)renderSize.x(), // width 1236 (float)renderSize.y(), // height 1237 0.0f, // minDepth 1238 1.0f, // maxDepth 1239 }; 1240 const VkRect2D scissor0 = 1241 { 1242 { 1243 0u, // x 1244 0u, // y 1245 }, // offset 1246 { 1247 renderSize.x(), // width 1248 renderSize.y(), // height 1249 }, // extent; 1250 }; 1251 const VkPipelineViewportStateCreateInfo viewportParams = 1252 { 1253 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType 1254 DE_NULL, // pNext 1255 0u, // flags 1256 1u, // viewportCount 1257 &viewport0, // pViewports 1258 1u, // scissorCount 1259 &scissor0 // pScissors 1260 }; 1261 const VkSampleMask sampleMask = ~0u; 1262 const VkPipelineMultisampleStateCreateInfo multisampleParams = 1263 { 1264 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType 1265 DE_NULL, // pNext 1266 0u, // flags 1267 VK_SAMPLE_COUNT_1_BIT, // rasterizationSamples 1268 VK_FALSE, // sampleShadingEnable 1269 0.0f, // minSampleShading 1270 &sampleMask, // sampleMask 1271 VK_FALSE, // alphaToCoverageEnable 1272 VK_FALSE, // alphaToOneEnable 1273 }; 1274 const VkPipelineRasterizationStateCreateInfo rasterParams = 1275 { 1276 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType 1277 DE_NULL, // pNext 1278 0u, // flags 1279 VK_TRUE, // depthClampEnable 1280 VK_FALSE, // rasterizerDiscardEnable 1281 m_fillModeNonSolid ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL, // polygonMode 1282 VK_CULL_MODE_NONE, // cullMode 1283 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace 1284 VK_FALSE, // depthBiasEnable 1285 0.0f, // depthBiasConstantFactor 1286 0.0f, // depthBiasClamp 1287 0.0f, // depthBiasSlopeFactor 1288 1.0f, // lineWidth 1289 }; 1290 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams = 1291 { 1292 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType 1293 DE_NULL, // pNext 1294 0u, // flags 1295 m_drawTessellatedSphere ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology 1296 DE_FALSE, // primitiveRestartEnable 1297 }; 1298 const VkVertexInputBindingDescription vertexBinding0 = 1299 { 1300 0u, // binding 1301 (deUint32)sizeof(tcu::Vec4), // stride 1302 VK_VERTEX_INPUT_RATE_VERTEX, // inputRate 1303 }; 1304 const VkVertexInputAttributeDescription vertexAttrib0 = 1305 { 1306 0u, // location 1307 0u, // binding 1308 VK_FORMAT_R32G32B32A32_SFLOAT, // format 1309 0u, // offset 1310 }; 1311 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1312 { 1313 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType 1314 DE_NULL, // pNext 1315 0u, // flags 1316 1u, // vertexBindingDescriptionCount 1317 &vertexBinding0, // pVertexBindingDescriptions 1318 1u, // vertexAttributeDescriptionCount 1319 &vertexAttrib0, // pVertexAttributeDescriptions 1320 }; 1321 const VkPipelineColorBlendAttachmentState attBlendParams = 1322 { 1323 VK_FALSE, // blendEnable 1324 VK_BLEND_FACTOR_ONE, // srcColorBlendFactor 1325 VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor 1326 VK_BLEND_OP_ADD, // colorBlendOp 1327 VK_BLEND_FACTOR_ONE, // srcAlphaBlendFactor 1328 VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor 1329 VK_BLEND_OP_ADD, // alphaBlendOp 1330 (VK_COLOR_COMPONENT_R_BIT | 1331 VK_COLOR_COMPONENT_G_BIT | 1332 VK_COLOR_COMPONENT_B_BIT | 1333 VK_COLOR_COMPONENT_A_BIT), // colorWriteMask 1334 }; 1335 const VkPipelineColorBlendStateCreateInfo blendParams = 1336 { 1337 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType 1338 DE_NULL, // pNext 1339 0u, // flags 1340 DE_FALSE, // logicOpEnable 1341 VK_LOGIC_OP_COPY, // logicOp 1342 1u, // attachmentCount 1343 &attBlendParams, // pAttachments 1344 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConstants[4] 1345 }; 1346 1347 const VkPipelineTessellationStateCreateInfo tessState = 1348 { 1349 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // sType 1350 DE_NULL, // pNext 1351 0u, // flags 1352 3u, // patchControlPoints 1353 }; 1354 const VkGraphicsPipelineCreateInfo pipelineParams = 1355 { 1356 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType 1357 DE_NULL, // pNext 1358 0u, // flags 1359 deUint32(shaderStageParams.size()), // stageCount 1360 shaderStageParams.data(), // pStages 1361 &vertexInputStateParams, // pVertexInputState 1362 &inputAssemblyParams, // pInputAssemblyState 1363 m_drawTessellatedSphere ? &tessState : DE_NULL, // pTessellationState 1364 &viewportParams, // pViewportState 1365 &rasterParams, // pRasterizationState 1366 &multisampleParams, // pMultisampleState 1367 &depthStencilParams, // pDepthStencilState 1368 &blendParams, // pColorBlendState 1369 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState 1370 *pipelineLayout, // layout 1371 *renderPass, // renderPass 1372 0u, // subpass 1373 DE_NULL, // basePipelineHandle 1374 0u, // basePipelineIndex 1375 }; 1376 pipeline = createGraphicsPipeline(vk, *m_deviceGroup, DE_NULL, &pipelineParams); 1377 } 1378 1379 // Create Framebuffer 1380 { 1381 const VkImageViewCreateInfo colorAttViewParams = 1382 { 1383 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType 1384 DE_NULL, // pNext 1385 0u, // flags 1386 *renderImage, // image 1387 VK_IMAGE_VIEW_TYPE_2D, // viewType 1388 colorFormat, // format 1389 { 1390 VK_COMPONENT_SWIZZLE_R, 1391 VK_COMPONENT_SWIZZLE_G, 1392 VK_COMPONENT_SWIZZLE_B, 1393 VK_COMPONENT_SWIZZLE_A 1394 }, // components 1395 { 1396 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1397 0u, // baseMipLevel 1398 1u, // levelCount 1399 0u, // baseArrayLayer 1400 1u, // layerCount 1401 }, // subresourceRange 1402 }; 1403 colorAttView = createImageView(vk, *m_deviceGroup, &colorAttViewParams); 1404 1405 const VkFramebufferCreateInfo framebufferParams = 1406 { 1407 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType 1408 DE_NULL, // pNext 1409 0u, // flags 1410 *renderPass, // renderPass 1411 1u, // attachmentCount 1412 &*colorAttView, // pAttachments 1413 renderSize.x(), // width 1414 renderSize.y(), // height 1415 1u, // layers 1416 }; 1417 framebuffer = createFramebuffer(vk, *m_deviceGroup, &framebufferParams); 1418 } 1419 1420 // Create Command buffer 1421 { 1422 const VkCommandPoolCreateInfo cmdPoolParams = 1423 { 1424 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType 1425 DE_NULL, // pNext 1426 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags 1427 queueFamilyIndex, // queueFamilyIndex 1428 }; 1429 cmdPool = createCommandPool(vk, *m_deviceGroup, &cmdPoolParams); 1430 1431 const VkCommandBufferAllocateInfo cmdBufParams = 1432 { 1433 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType 1434 DE_NULL, // pNext 1435 *cmdPool, // pool 1436 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level 1437 1u, // bufferCount 1438 }; 1439 cmdBuffer = allocateCommandBuffer(vk, *m_deviceGroup, &cmdBufParams); 1440 } 1441 1442 // Begin recording 1443 VkCommandBufferBeginInfo cmdBufBeginParams = 1444 { 1445 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType 1446 DE_NULL, // pNext 1447 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags 1448 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1449 }; 1450 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufBeginParams)); 1451 1452 // Prepare render target for rendering 1453 { 1454 const VkMemoryBarrier vertFlushBarrier = 1455 { 1456 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType 1457 DE_NULL, // pNext 1458 VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask 1459 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // dstAccessMask 1460 }; 1461 const VkImageMemoryBarrier colorAttBarrier = 1462 { 1463 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 1464 DE_NULL, // pNext 1465 0u, // srcAccessMask 1466 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1467 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask 1468 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout 1469 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout 1470 queueFamilyIndex, // srcQueueFamilyIndex 1471 queueFamilyIndex, // dstQueueFamilyIndex 1472 *renderImage, // image 1473 { 1474 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1475 0u, // baseMipLevel 1476 1u, // levelCount 1477 0u, // baseArrayLayer 1478 1u, // layerCount 1479 } // subresourceRange 1480 }; 1481 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier); 1482 } 1483 1484 // Update buffers 1485 { 1486 const VkBufferMemoryBarrier stagingVertexBufferUpdateBarrier = 1487 { 1488 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1489 DE_NULL, // const void* pNext; 1490 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1491 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1492 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1493 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1494 stagingVertexBuffer.get(), // VkBuffer buffer; 1495 0u, // VkDeviceSize offset; 1496 verticesSize // VkDeviceSize size; 1497 }; 1498 1499 const VkBufferMemoryBarrier vertexBufferUpdateBarrier = 1500 { 1501 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1502 DE_NULL, // const void* pNext; 1503 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1504 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkAccessFlags dstAccessMask; 1505 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1506 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1507 vertexBuffer.get(), // VkBuffer buffer; 1508 0u, // VkDeviceSize offset; 1509 verticesSize // VkDeviceSize size; 1510 }; 1511 1512 const VkBufferMemoryBarrier stagingIndexBufferUpdateBarrier = 1513 { 1514 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1515 DE_NULL, // const void* pNext; 1516 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1517 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1518 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1519 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1520 stagingIndexBuffer.get(), // VkBuffer buffer; 1521 0u, // VkDeviceSize offset; 1522 indicesSize // VkDeviceSize size; 1523 }; 1524 1525 const VkBufferMemoryBarrier indexBufferUpdateBarrier = 1526 { 1527 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1528 DE_NULL, // const void* pNext; 1529 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1530 VK_ACCESS_INDEX_READ_BIT, // VkAccessFlags dstAccessMask; 1531 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1532 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1533 indexBuffer.get(), // VkBuffer buffer; 1534 0u, // VkDeviceSize offset; 1535 indicesSize // VkDeviceSize size; 1536 }; 1537 1538 const VkBufferMemoryBarrier stagingUboBufferUpdateBarrier = 1539 { 1540 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1541 DE_NULL, // const void* pNext; 1542 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1543 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1544 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1545 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1546 stagingUniformBuffer.get(), // VkBuffer buffer; 1547 0u, // VkDeviceSize offset; 1548 indicesSize // VkDeviceSize size; 1549 }; 1550 1551 const VkBufferMemoryBarrier uboUpdateBarrier = 1552 { 1553 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1554 DE_NULL, // const void* pNext; 1555 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1556 VK_ACCESS_UNIFORM_READ_BIT, // VkAccessFlags dstAccessMask; 1557 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1558 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1559 uniformBuffer.get(), // VkBuffer buffer; 1560 0u, // VkDeviceSize offset; 1561 sizeof(drawColor) // VkDeviceSize size; 1562 }; 1563 1564 1565 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &stagingVertexBufferUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1566 VkBufferCopy vertexBufferCopy = { 0u, 0u, verticesSize }; 1567 vk.cmdCopyBuffer(*cmdBuffer, stagingVertexBuffer.get(), vertexBuffer.get(), 1u, &vertexBufferCopy); 1568 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &vertexBufferUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1569 1570 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &stagingIndexBufferUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1571 VkBufferCopy indexBufferCopy = { 0u, 0u, indicesSize }; 1572 vk.cmdCopyBuffer(*cmdBuffer, stagingIndexBuffer.get(), indexBuffer.get(), 1u, &indexBufferCopy); 1573 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &indexBufferUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1574 1575 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &stagingUboBufferUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1576 VkBufferCopy uboBufferCopy = { 0u, 0u, sizeof(drawColor) }; 1577 vk.cmdCopyBuffer(*cmdBuffer, stagingUniformBuffer.get(), uniformBuffer.get(), 1u, &uboBufferCopy); 1578 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &uboUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1579 1580 if (m_drawTessellatedSphere) 1581 { 1582 const VkBufferMemoryBarrier stagingsboUpdateBarrier = 1583 { 1584 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1585 DE_NULL, // const void* pNext; 1586 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1587 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1588 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1589 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1590 stagingSboBuffer.get(), // VkBuffer buffer; 1591 0u, // VkDeviceSize offset; 1592 sizeof(tessLevel) // VkDeviceSize size; 1593 }; 1594 1595 const VkBufferMemoryBarrier sboUpdateBarrier = 1596 { 1597 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1598 DE_NULL, // const void* pNext; 1599 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1600 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1601 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1602 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1603 sboBuffer.get(), // VkBuffer buffer; 1604 0u, // VkDeviceSize offset; 1605 sizeof(tessLevel) // VkDeviceSize size; 1606 }; 1607 1608 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &stagingsboUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1609 VkBufferCopy sboBufferCopy = { 0u, 0u, sizeof(tessLevel) }; 1610 vk.cmdCopyBuffer(*cmdBuffer, stagingSboBuffer.get(), sboBuffer.get(), 1u, &sboBufferCopy); 1611 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &sboUpdateBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1612 } 1613 1614 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1615 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL); 1616 { 1617 const VkDeviceSize bindingOffset = 0; 1618 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset); 1619 vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT32); 1620 } 1621 } 1622 1623 // Begin renderpass 1624 { 1625 const VkClearValue clearValue = makeClearValueColorF32( 1626 clearColor[0], 1627 clearColor[1], 1628 clearColor[2], 1629 clearColor[3]); 1630 1631 VkRect2D zeroRect = { { 0, 0, },{ 0, 0, } }; 1632 vector<VkRect2D> renderAreas; 1633 for (deUint32 i = 0; i < m_physicalDeviceCount; i++) 1634 renderAreas.push_back(zeroRect); 1635 1636 // Render completely if there is only 1 device 1637 if (m_physicalDeviceCount == 1u) 1638 { 1639 renderAreas[0].extent.width = (deInt32)renderSize.x(); 1640 renderAreas[0].extent.height = (deInt32)renderSize.y(); 1641 } 1642 else 1643 { 1644 // Split into 2 vertical halves 1645 renderAreas[firstDeviceID].extent.width = (deInt32)renderSize.x() / 2; 1646 renderAreas[firstDeviceID].extent.height = (deInt32)renderSize.y(); 1647 renderAreas[secondDeviceID] = renderAreas[firstDeviceID]; 1648 renderAreas[secondDeviceID].offset.x = (deInt32)renderSize.x() / 2; 1649 } 1650 1651 const VkDeviceGroupRenderPassBeginInfo deviceGroupRPBeginInfo = 1652 { 1653 VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, 1654 DE_NULL, 1655 (deUint32)((1 << m_physicalDeviceCount) - 1), 1656 m_physicalDeviceCount, 1657 &renderAreas[0] 1658 }; 1659 1660 const VkRenderPassBeginInfo passBeginParams = 1661 { 1662 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // sType 1663 (m_testMode & TEST_MODE_SFR) ? &deviceGroupRPBeginInfo : DE_NULL, // pNext 1664 *renderPass, // renderPass 1665 *framebuffer, // framebuffer 1666 { 1667 { 0, 0 }, 1668 { renderSize.x(), renderSize.y() } 1669 }, // renderArea 1670 1u, // clearValueCount 1671 &clearValue, // pClearValues 1672 }; 1673 vk.cmdBeginRenderPass(*cmdBuffer, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE); 1674 } 1675 1676 // Draw 1677 if (m_testMode & TEST_MODE_AFR) 1678 { 1679 vk.cmdSetDeviceMask(*cmdBuffer, 1 << secondDeviceID); 1680 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1u, 0, 0, 0); 1681 1682 } 1683 else 1684 { 1685 vk.cmdSetDeviceMask(*cmdBuffer, ((1 << firstDeviceID) | (1 << secondDeviceID))); 1686 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1u, 0, 0, 0); 1687 } 1688 vk.cmdEndRenderPass(*cmdBuffer); 1689 1690 // Change image layout for copy 1691 { 1692 const VkImageMemoryBarrier renderFinishBarrier = 1693 { 1694 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 1695 DE_NULL, // pNext 1696 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // outputMask 1697 VK_ACCESS_TRANSFER_READ_BIT, // inputMask 1698 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout 1699 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout 1700 queueFamilyIndex, // srcQueueFamilyIndex 1701 queueFamilyIndex, // dstQueueFamilyIndex 1702 *renderImage, // image 1703 { 1704 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1705 0u, // baseMipLevel 1706 1u, // mipLevels 1707 0u, // baseArraySlice 1708 1u, // arraySize 1709 } // subresourceRange 1710 }; 1711 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &renderFinishBarrier); 1712 } 1713 1714 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1715 1716 // Submit & wait for completion 1717 { 1718 const deUint32 deviceMask = (1 << firstDeviceID) | (1 << secondDeviceID); 1719 deviceGroupSubmitInfo.commandBufferCount = 1; 1720 deviceGroupSubmitInfo.pCommandBufferDeviceMasks = &deviceMask; 1721 SubmitBufferAndWaitForIdle(vk, cmdBuffer.get(), deviceGroupSubmitInfo); 1722 } 1723 1724 // Copy image from secondDeviceID in case of AFR and SFR(only if Peer memory as copy source is not allowed) 1725 if ((m_physicalDeviceCount > 1) && ((m_testMode & TEST_MODE_AFR) || (!isPeerMemAsCopySrcAllowed))) 1726 { 1727 Move<VkImage> peerImage; 1728 1729 // Create and bind peer image 1730 { 1731 const VkImageCreateInfo peerImageParams = 1732 { 1733 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 1734 DE_NULL, // pNext 1735 VK_IMAGE_CREATE_ALIAS_BIT, // flags 1736 VK_IMAGE_TYPE_2D, // imageType 1737 colorFormat, // format 1738 { renderSize.x(), renderSize.y(), 1 }, // extent 1739 1u, // mipLevels 1740 1u, // arraySize 1741 VK_SAMPLE_COUNT_1_BIT, // samples 1742 VK_IMAGE_TILING_OPTIMAL, // tiling 1743 imageUsageFlag, // usage 1744 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 1745 1u, // queueFamilyIndexCount 1746 &queueFamilyIndex, // pQueueFamilyIndices 1747 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout 1748 }; 1749 peerImage = createImage(vk, *m_deviceGroup, &peerImageParams); 1750 1751 VkBindImageMemoryDeviceGroupInfo devGroupBindInfo = 1752 { 1753 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, // sType 1754 DE_NULL, // pNext 1755 m_physicalDeviceCount, // deviceIndexCount 1756 &deviceIndices[0], // pDeviceIndices 1757 0u, // SFRRectCount 1758 DE_NULL, // pSFRRects 1759 }; 1760 1761 VkBindImageMemoryInfo bindInfo = 1762 { 1763 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, // sType 1764 &devGroupBindInfo, // pNext 1765 peerImage.get(), // image 1766 imageMemory.get(), // memory 1767 0u, // memoryOffset 1768 }; 1769 VK_CHECK(vk.bindImageMemory2(*m_deviceGroup, 1, &bindInfo)); 1770 } 1771 1772 // Copy peer image (only needed in SFR case when peer memory as copy source is not allowed) 1773 { 1774 // Change layout on firstDeviceID 1775 { 1776 const VkImageMemoryBarrier preCopyBarrier = 1777 { 1778 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1779 DE_NULL, // const void* pNext; 1780 0, // VkAccessFlags srcAccessMask; 1781 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1782 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1783 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1784 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1785 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1786 *renderImage, // VkImage image; 1787 { // VkImageSubresourceRange subresourceRange; 1788 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1789 0u, // deUint32 baseMipLevel; 1790 1u, // deUint32 mipLevels; 1791 0u, // deUint32 baseArraySlice; 1792 1u // deUint32 arraySize; 1793 } 1794 }; 1795 1796 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufBeginParams)); 1797 vk.cmdSetDeviceMask(*cmdBuffer, 1 << firstDeviceID); 1798 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &preCopyBarrier); 1799 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1800 1801 const deUint32 deviceMask = 1 << firstDeviceID; 1802 deviceGroupSubmitInfo.pCommandBufferDeviceMasks = &deviceMask; 1803 SubmitBufferAndWaitForIdle(vk, cmdBuffer.get(), deviceGroupSubmitInfo); 1804 } 1805 1806 // Copy Image from secondDeviceID to firstDeviceID 1807 { 1808 // AFR: Copy entire image from secondDeviceID 1809 // SFR: Copy the right half of image from secondDeviceID to firstDeviceID, so that the copy 1810 // to a buffer below (for checking) does not require VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT 1811 deInt32 imageOffsetX = (m_testMode & TEST_MODE_AFR) ? 0 : renderSize.x() / 2; 1812 deUint32 imageExtentX = (m_testMode & TEST_MODE_AFR) ? (deUint32)renderSize.x() : (deUint32)renderSize.x() / 2; 1813 1814 const VkImageCopy imageCopy = 1815 { 1816 { 1817 VK_IMAGE_ASPECT_COLOR_BIT, 1818 0, // mipLevel 1819 0, // arrayLayer 1820 1 // layerCount 1821 }, 1822 { imageOffsetX, 0, 0 }, 1823 { 1824 VK_IMAGE_ASPECT_COLOR_BIT, 1825 0, // mipLevel 1826 0, // arrayLayer 1827 1 // layerCount 1828 }, 1829 { imageOffsetX, 0, 0 }, 1830 { 1831 imageExtentX, 1832 (deUint32)renderSize.y(), 1833 1u 1834 } 1835 }; 1836 1837 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufBeginParams)); 1838 vk.cmdSetDeviceMask(*cmdBuffer, 1 << secondDeviceID); 1839 vk.cmdCopyImage(*cmdBuffer, *renderImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *peerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy); 1840 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1841 1842 const deUint32 deviceMask = 1 << secondDeviceID; 1843 deviceGroupSubmitInfo.pCommandBufferDeviceMasks = &deviceMask; 1844 SubmitBufferAndWaitForIdle(vk, cmdBuffer.get(), deviceGroupSubmitInfo); 1845 } 1846 1847 // Change layout back on firstDeviceID 1848 { 1849 const VkImageMemoryBarrier postCopyBarrier = 1850 { 1851 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1852 DE_NULL, // const void* pNext; 1853 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1854 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1855 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1856 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 1857 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1858 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1859 *renderImage, // VkImage image; 1860 { // VkImageSubresourceRange subresourceRange; 1861 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1862 0u, // deUint32 baseMipLevel; 1863 1u, // deUint32 mipLevels; 1864 0u, // deUint32 baseArraySlice; 1865 1u // deUint32 arraySize; 1866 } 1867 }; 1868 1869 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufBeginParams)); 1870 vk.cmdSetDeviceMask(*cmdBuffer, 1 << firstDeviceID); 1871 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postCopyBarrier); 1872 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1873 1874 const deUint32 deviceMask = 1 << firstDeviceID; 1875 deviceGroupSubmitInfo.pCommandBufferDeviceMasks = &deviceMask; 1876 SubmitBufferAndWaitForIdle(vk, cmdBuffer.get(), deviceGroupSubmitInfo); 1877 } 1878 } 1879 } 1880 1881 // copy image to read buffer for checking 1882 { 1883 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * renderSize.x() * renderSize.y()); 1884 const VkBufferCreateInfo readImageBufferParams = 1885 { 1886 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 1887 DE_NULL, // pNext 1888 (VkBufferCreateFlags)0u, // flags 1889 imageSizeBytes, // size 1890 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage 1891 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 1892 1u, // queueFamilyIndexCount 1893 &queueFamilyIndex, // pQueueFamilyIndices 1894 }; 1895 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, *m_deviceGroup, &readImageBufferParams)); 1896 const UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, *m_deviceGroup, *readImageBuffer), MemoryRequirement::HostVisible)); 1897 VK_CHECK(vk.bindBufferMemory(*m_deviceGroup, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 1898 1899 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufBeginParams)); 1900 1901 // Copy image to buffer 1902 { 1903 const VkBufferImageCopy copyParams = 1904 { 1905 (VkDeviceSize)0u, // bufferOffset 1906 renderSize.x(), // bufferRowLength 1907 renderSize.y(), // bufferImageHeight 1908 { 1909 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1910 0u, // mipLevel 1911 0u, // baseArrayLayer 1912 1u, // layerCount 1913 }, // imageSubresource 1914 { 0, 0, 0 }, // imageOffset 1915 { 1916 renderSize.x(), 1917 renderSize.y(), 1918 1u 1919 } // imageExtent 1920 }; 1921 1922 // Use a diffferent binding in SFR when peer memory as copy source is not allowed 1923 vk.cmdCopyImageToBuffer(*cmdBuffer, isPeerMemAsCopySrcAllowed ? *renderImage : *readImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 1924 1925 const VkBufferMemoryBarrier copyFinishBarrier = 1926 { 1927 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType 1928 DE_NULL, // pNext 1929 VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask 1930 VK_ACCESS_HOST_READ_BIT, // dstAccessMask 1931 queueFamilyIndex, // srcQueueFamilyIndex 1932 queueFamilyIndex, // dstQueueFamilyIndex 1933 *readImageBuffer, // buffer 1934 0u, // offset 1935 imageSizeBytes // size 1936 }; 1937 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©FinishBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1938 } 1939 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1940 1941 // Submit & wait for completion 1942 { 1943 const deUint32 deviceMask = 1 << firstDeviceID; 1944 deviceGroupSubmitInfo.pCommandBufferDeviceMasks = &deviceMask; 1945 SubmitBufferAndWaitForIdle(vk, cmdBuffer.get(), deviceGroupSubmitInfo); 1946 } 1947 1948 // Read results and check against reference image 1949 if (m_drawTessellatedSphere) 1950 { 1951 const tcu::TextureFormat tcuFormat = vk::mapVkFormat(colorFormat); 1952 const VkMappedMemoryRange range = 1953 { 1954 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 1955 DE_NULL, // pNext 1956 readImageBufferMemory->getMemory(), // memory 1957 0, // offset 1958 imageSizeBytes, // size 1959 }; 1960 const tcu::ConstPixelBufferAccess resultAccess(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1961 VK_CHECK(vk.invalidateMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 1962 1963 tcu::TextureLevel referenceImage; 1964 string refImage = m_fillModeNonSolid ? "vulkan/data/device_group/sphere.png" : "vulkan/data/device_group/spherefilled.png"; 1965 tcu::ImageIO::loadPNG(referenceImage, m_context.getTestContext().getArchive(), refImage.c_str()); 1966 iterateResultSuccess = tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ImageComparison", "Image Comparison", 1967 referenceImage.getAccess(), resultAccess, 0.001f, tcu::COMPARE_LOG_RESULT); 1968 } 1969 else 1970 { 1971 const tcu::TextureFormat tcuFormat = vk::mapVkFormat(colorFormat); 1972 const VkMappedMemoryRange range = 1973 { 1974 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType 1975 DE_NULL, // pNext 1976 readImageBufferMemory->getMemory(), // memory 1977 0, // offset 1978 imageSizeBytes, // size 1979 }; 1980 const tcu::ConstPixelBufferAccess resultAccess(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1981 VK_CHECK(vk.invalidateMappedMemoryRanges(*m_deviceGroup, 1u, &range)); 1982 1983 // Render reference and compare 1984 { 1985 tcu::TextureLevel refImage(tcuFormat, (deInt32)renderSize.x(), (deInt32)renderSize.y()); 1986 const tcu::UVec4 threshold(0u); 1987 const tcu::IVec3 posDeviation(1, 1, 0); 1988 1989 tcu::clear(refImage.getAccess(), clearColor); 1990 renderReferenceTriangle(refImage.getAccess(), triVertices); 1991 1992 iterateResultSuccess = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 1993 "ComparisonResult", 1994 "Image comparison result", 1995 refImage.getAccess(), 1996 resultAccess, 1997 threshold, 1998 posDeviation, 1999 false, 2000 tcu::COMPARE_LOG_RESULT); 2001 } 2002 } 2003 } 2004 2005 if (!iterateResultSuccess) 2006 return tcu::TestStatus::fail("Image comparison failed"); 2007 } 2008 2009 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Device group verification passed"); 2010} 2011 2012template<class Instance> 2013class DeviceGroupTestCase : public TestCase 2014{ 2015public: 2016 DeviceGroupTestCase (tcu::TestContext& context, 2017 const char* name, 2018 const char* description, 2019 deUint32 mode) 2020 : TestCase(context, name, description) 2021 , m_testMode (mode) 2022 {} 2023 2024private: 2025 2026 deUint32 m_testMode; 2027 2028 TestInstance* createInstance (Context& context) const 2029 { 2030 return new Instance(context, m_testMode); 2031 } 2032 2033 void initPrograms (vk::SourceCollections& programCollection) const 2034 { 2035 programCollection.glslSources.add("vert") << glu::VertexSource("#version 430\n" 2036 "layout(location = 0) in vec4 in_Position;\n" 2037 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n" 2038 "void main() {\n" 2039 " gl_Position = in_Position;\n" 2040 " gl_PointSize = 1.0;\n" 2041 "}\n"); 2042 2043 if (m_testMode & TEST_MODE_TESSELLATION) 2044 { 2045 programCollection.glslSources.add("tesc") << glu::TessellationControlSource("#version 450\n" 2046 "#extension GL_EXT_tessellation_shader : require\n" 2047 "layout(vertices=3) out;\n" 2048 "layout(set=0, binding=1) buffer tessLevel { \n" 2049 " float tessLvl;\n" 2050 "};\n" 2051 "void main()\n" 2052 "{\n" 2053 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 2054 " if (gl_InvocationID == 0) {\n" 2055 " for (int i = 0; i < 4; i++)\n" 2056 " gl_TessLevelOuter[i] = tessLvl;\n" 2057 " for (int i = 0; i < 2; i++)\n" 2058 " gl_TessLevelInner[i] = tessLvl;\n" 2059 " }\n" 2060 "}\n"); 2061 2062 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource("#version 450\n" 2063 "#extension GL_EXT_tessellation_shader : require\n" 2064 "layout(triangles) in;\n" 2065 "layout(equal_spacing) in;\n" 2066 "layout(ccw) in;\n" 2067 "void main()\n" 2068 "{\n" 2069 " vec4 pos = vec4(0, 0, 0, 0);\n" 2070 " vec3 tessCoord = gl_TessCoord.xyz;\n" 2071 " pos += tessCoord.z * gl_in[0].gl_Position;\n" 2072 " pos += tessCoord.x * gl_in[1].gl_Position;\n" 2073 " pos += tessCoord.y * gl_in[2].gl_Position;\n" 2074 " vec3 sign = sign(pos.xyz);\n" 2075 " pos.xyz = 0.785398 - abs(pos.xyz) * 1.5707963;\n" 2076 " pos.xyz = (1 - tan(pos.xyz))/2.0;\n" 2077 " pos.xyz = (sign * pos.xyz) / length(pos.xyz);\n" 2078 " gl_Position = pos;\n" 2079 "}\n"); 2080 } 2081 2082 programCollection.glslSources.add("frag") << glu::FragmentSource("#version 430\n" 2083 "layout(location = 0) out vec4 out_FragColor;\n" 2084 "layout(std140, set=0, binding=0) uniform bufferData { \n" 2085 " vec4 color;\n" 2086 "};\n" 2087 "void main()\n" 2088 "{\n" 2089 " out_FragColor = color;\n" 2090 "}\n"); 2091 } 2092}; 2093 2094} //anonymous 2095 2096class DeviceGroupTestRendering : public tcu::TestCaseGroup 2097{ 2098public: 2099 DeviceGroupTestRendering (tcu::TestContext& testCtx); 2100 ~DeviceGroupTestRendering (void) {} 2101 void init(void); 2102 2103private: 2104 DeviceGroupTestRendering (const DeviceGroupTestRendering& other); 2105 DeviceGroupTestRendering& operator= (const DeviceGroupTestRendering& other); 2106}; 2107 2108DeviceGroupTestRendering::DeviceGroupTestRendering (tcu::TestContext& testCtx) 2109 : TestCaseGroup (testCtx, "device_group", "Testing device group test cases") 2110{ 2111 // Left blank on purpose 2112} 2113 2114void DeviceGroupTestRendering::init (void) 2115{ 2116 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr", "Test split frame rendering", TEST_MODE_SFR)); 2117 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr_sys", "Test split frame rendering with render target in host memory", TEST_MODE_SFR | TEST_MODE_HOSTMEMORY)); 2118 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr_dedicated", "Test split frame rendering with dedicated memory allocations", TEST_MODE_SFR | TEST_MODE_DEDICATED)); 2119 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr_dedicated_peer", "Test split frame rendering with dedicated memory allocations and peer fetching", TEST_MODE_SFR | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2120 2121 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr", "Test alternate frame rendering", TEST_MODE_AFR)); 2122 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr_sys", "Test split frame rendering with render target in host memory", TEST_MODE_AFR | TEST_MODE_HOSTMEMORY)); 2123 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr_dedicated", "Test split frame rendering with dedicated memory allocations", TEST_MODE_AFR | TEST_MODE_DEDICATED)); 2124 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr_dedicated_peer", "Test split frame rendering with dedicated memory allocations and peer fetching", TEST_MODE_AFR | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2125 2126 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr_tessellated", "Test split frame rendering with tessellated sphere", TEST_MODE_SFR | TEST_MODE_TESSELLATION | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2127 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "sfr_tessellated_linefill", "Test split frame rendering with tessellated sphere with line segments", TEST_MODE_SFR | TEST_MODE_TESSELLATION | TEST_MODE_LINEFILL | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2128 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr_tessellated", "Test alternate frame rendering with tesselated sphere", TEST_MODE_AFR | TEST_MODE_TESSELLATION | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2129 addChild(new DeviceGroupTestCase<DeviceGroupTestInstance>(m_testCtx, "afr_tessellated_linefill", "Test alternate frame rendering with tesselated sphere with line segments", TEST_MODE_AFR | TEST_MODE_TESSELLATION | TEST_MODE_LINEFILL | TEST_MODE_DEDICATED | TEST_MODE_PEER_FETCH)); 2130} 2131 2132tcu::TestCaseGroup* createTests(tcu::TestContext& testCtx) 2133{ 2134 return new DeviceGroupTestRendering(testCtx); 2135} 2136} // DeviceGroup 2137} // vkt 2138