1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Vulkan Multi View Render Tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktMultiViewRenderTests.hpp" 25 #include "vktMultiViewRenderUtil.hpp" 26 27 #include "vktTestCase.hpp" 28 #include "vkBuilderUtil.hpp" 29 #include "vkRefUtil.hpp" 30 #include "vkQueryUtil.hpp" 31 #include "vkTypeUtil.hpp" 32 #include "vkPrograms.hpp" 33 #include "vkPlatform.hpp" 34 #include "vkMemUtil.hpp" 35 #include "vkImageUtil.hpp" 36 37 #include "tcuTestLog.hpp" 38 #include "tcuResource.hpp" 39 #include "tcuImageCompare.hpp" 40 #include "tcuCommandLine.hpp" 41 #include "tcuTextureUtil.hpp" 42 #include "tcuRGBA.hpp" 43 44 #include "deSharedPtr.hpp" 45 46 namespace vkt 47 { 48 namespace MultiView 49 { 50 namespace 51 { 52 53 using namespace vk; 54 using de::MovePtr; 55 using de::UniquePtr; 56 using std::vector; 57 using std::map; 58 using std::string; 59 60 enum TestType 61 { 62 TEST_TYPE_VIEW_MASK, 63 TEST_TYPE_VIEW_INDEX_IN_VERTEX, 64 TEST_TYPE_VIEW_INDEX_IN_FRAGMENT, 65 TEST_TYPE_VIEW_INDEX_IN_GEOMETRY, 66 TEST_TYPE_VIEW_INDEX_IN_TESELLATION, 67 TEST_TYPE_INPUT_ATTACHMENTS, 68 TEST_TYPE_INSTANCED_RENDERING, 69 TEST_TYPE_INPUT_RATE_INSTANCE, 70 TEST_TYPE_DRAW_INDIRECT, 71 TEST_TYPE_CLEAR_ATTACHMENTS, 72 TEST_TYPE_SECONDARY_CMD_BUFFER, 73 TEST_TYPE_LAST 74 }; 75 76 struct TestParameters 77 { 78 VkExtent3D extent; 79 vector<deUint32> viewMasks; 80 TestType viewIndex; 81 }; 82 83 class ImageAttachment 84 { 85 public: 86 ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat); 87 VkImageView getImageView (void) const 88 { 89 return *m_imageView; 90 } 91 VkImage getImage (void) const 92 { 93 return *m_image; 94 } 95 private: 96 Move<VkImage> m_image; 97 MovePtr<Allocation> m_allocationImage; 98 Move<VkImageView> m_imageView; 99 }; 100 101 ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat) 102 { 103 const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, extent.depth); 104 const VkImageCreateInfo colorAttachmentImageInfo = makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, 105 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); 106 107 m_image = createImage(device, logicalDevice, &colorAttachmentImageInfo); 108 m_allocationImage = allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any); 109 VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset())); 110 m_imageView = makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange); 111 } 112 113 class MultiViewRenderTestInstance : public TestInstance 114 { 115 public: 116 MultiViewRenderTestInstance (Context& context, const TestParameters& parameters); 117 protected: 118 typedef de::SharedPtr<Unique<VkPipeline> > PipelineSp; 119 typedef de::SharedPtr<Unique<VkShaderModule> > ShaderModuleSP; 120 121 struct VertexData 122 { 123 VertexData (const tcu::Vec4 position_, const tcu::Vec4 color_) 124 : position (position_) 125 , color (color_) 126 {} 127 tcu::Vec4 position; 128 tcu::Vec4 color; 129 }; 130 131 virtual tcu::TestStatus iterate (void); 132 virtual void beforeDraw (void); 133 virtual void afterDraw (void); 134 virtual void draw (const deUint32 subpassCount, 135 VkRenderPass renderPass, 136 VkFramebuffer frameBuffer, 137 vector<PipelineSp>& pipelines); 138 virtual void createVertexData (void); 139 TestParameters fillMissingParameters (const TestParameters& parameters); 140 void createVertexBuffer (void); 141 void createMultiViewDevices (void); 142 void createCommandBuffer (void); 143 void madeShaderModule (map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams); 144 Move<VkPipeline> makeGraphicsPipeline (const VkRenderPass renderPass, 145 const VkPipelineLayout pipelineLayout, 146 const deUint32 pipelineShaderStageCount, 147 const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, 148 const deUint32 subpass, 149 const VkVertexInputRate vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX); 150 void readImage (VkImage image, const tcu::PixelBufferAccess& dst); 151 bool checkImage (tcu::ConstPixelBufferAccess& dst); 152 MovePtr<tcu::Texture2DArray> imageData (void); 153 154 const TestParameters m_parameters; 155 VkFormat m_colorFormat; 156 const deUint32 m_squareCount; 157 Move<VkDevice> m_logicalDevice; 158 MovePtr<DeviceInterface> m_device; 159 MovePtr<Allocator> m_allocator; 160 deUint32 m_queueFamilyIndex; 161 VkQueue m_queue; 162 vector<VertexData> m_data; 163 Move<VkBuffer> m_vertexBuffer; 164 MovePtr<Allocation> m_allocationBuffer; 165 Move<VkCommandPool> m_cmdPool; 166 Move<VkCommandBuffer> m_cmdBuffer; 167 de::SharedPtr<ImageAttachment> m_colorAttachment; 168 VkBool32 m_hasMultiDrawIndirect; 169 }; 170 171 MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters) 172 : TestInstance (context) 173 , m_parameters (fillMissingParameters(parameters)) 174 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 175 , m_squareCount (4u) 176 ,m_queueFamilyIndex (0u) 177 { 178 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_multiview")) 179 throw tcu::NotSupportedError("VK_KHR_multiview is not supported"); 180 181 createMultiViewDevices(); 182 183 // Color attachment 184 m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat)); 185 } 186 187 tcu::TestStatus MultiViewRenderTestInstance::iterate (void) 188 { 189 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 190 191 // FrameBuffer & renderPass 192 Unique<VkRenderPass> renderPass (makeRenderPass (*m_device, *m_logicalDevice, m_colorFormat, m_parameters.viewMasks)); 193 194 vector<VkImageView> attachments; 195 attachments.push_back(m_colorAttachment->getImageView()); 196 Unique<VkFramebuffer> frameBuffer (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, attachments, m_parameters.extent.width, m_parameters.extent.height, 1u)); 197 198 // pipelineLayout 199 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 200 201 // pipelines 202 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 203 vector<PipelineSp> pipelines(subpassCount); 204 const VkVertexInputRate vertexInputRate = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; 205 206 { 207 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 208 madeShaderModule(shaderModule, shaderStageParams); 209 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 210 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate)))); 211 } 212 213 createCommandBuffer(); 214 createVertexData(); 215 createVertexBuffer(); 216 217 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 218 219 { 220 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_colorFormat).getPixelSize()); 221 tcu::PixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 222 223 readImage(m_colorAttachment->getImage(), dst); 224 if (!checkImage(dst)) 225 return tcu::TestStatus::fail("Fail"); 226 } 227 228 return tcu::TestStatus::pass("Pass"); 229 } 230 231 void MultiViewRenderTestInstance::beforeDraw (void) 232 { 233 const VkImageSubresourceRange subresourceRange = 234 { 235 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 236 0u, //deUint32 baseMipLevel; 237 1u, //deUint32 levelCount; 238 0u, //deUint32 baseArrayLayer; 239 m_parameters.extent.depth, //deUint32 layerCount; 240 }; 241 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT); 242 243 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 244 m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); 245 246 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); 247 248 } 249 250 void MultiViewRenderTestInstance::afterDraw (void) 251 { 252 const VkImageSubresourceRange subresourceRange = 253 { 254 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 255 0u, //deUint32 baseMipLevel; 256 1u, //deUint32 levelCount; 257 0u, //deUint32 baseArrayLayer; 258 m_parameters.extent.depth, //deUint32 layerCount; 259 }; 260 261 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), 262 subresourceRange, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 263 } 264 265 void MultiViewRenderTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 266 { 267 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 268 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 269 const VkDeviceSize vertexBufferOffset = 0u; 270 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 271 272 const VkRenderPassBeginInfo renderPassBeginInfo = 273 { 274 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 275 DE_NULL, // const void* pNext; 276 renderPass, // VkRenderPass renderPass; 277 frameBuffer, // VkFramebuffer framebuffer; 278 renderArea, // VkRect2D renderArea; 279 1u, // uint32_t clearValueCount; 280 &renderPassClearValue, // const VkClearValue* pClearValues; 281 }; 282 283 beginCommandBuffer(*m_device, *m_cmdBuffer); 284 285 beforeDraw(); 286 287 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 288 289 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 290 291 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 292 { 293 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 294 295 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 296 m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 297 298 if (subpassNdx < subpassCount - 1u) 299 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 300 } 301 302 m_device->cmdEndRenderPass(*m_cmdBuffer); 303 304 afterDraw(); 305 306 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 307 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 308 } 309 310 void MultiViewRenderTestInstance::createVertexData (void) 311 { 312 tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 313 m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color)); 314 m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color)); 315 m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color)); 316 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 317 318 color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f); 319 m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color)); 320 m_data.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color)); 321 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 322 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color)); 323 324 color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f); 325 m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color)); 326 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 327 m_data.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color)); 328 m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color)); 329 330 color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f); 331 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 332 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color)); 333 m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color)); 334 m_data.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color)); 335 } 336 337 TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters) 338 { 339 if (!parameters.viewMasks.empty()) 340 return parameters; 341 else 342 { 343 if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_multiview")) 344 throw tcu::NotSupportedError("VK_KHR_multiview is not supported"); 345 346 const InstanceInterface& instance = m_context.getInstanceInterface(); 347 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 348 349 VkPhysicalDeviceMultiviewProperties multiviewProperties = 350 { 351 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, // VkStructureType sType; 352 DE_NULL, // void* pNext; 353 0u, // deUint32 maxMultiviewViewCount; 354 0u // deUint32 maxMultiviewInstanceIndex; 355 }; 356 357 VkPhysicalDeviceProperties2 deviceProperties2; 358 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 359 deviceProperties2.pNext = &multiviewProperties; 360 361 instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); 362 363 TestParameters newParameters = parameters; 364 newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount; 365 366 vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount); 367 for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++) 368 viewMasks[i] = 1 << i; 369 newParameters.viewMasks = viewMasks; 370 371 return newParameters; 372 } 373 } 374 375 void MultiViewRenderTestInstance::createVertexBuffer (void) 376 { 377 const VkDeviceSize vertexDataSize = static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(VertexData)), 378 static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize))); 379 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 380 381 m_vertexBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 382 m_allocationBuffer = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 383 384 // Init host buffer data 385 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexBuffer, m_allocationBuffer->getMemory(), m_allocationBuffer->getOffset())); 386 deMemcpy(m_allocationBuffer->getHostPtr(), m_data.data(), static_cast<size_t>(vertexDataSize)); 387 flushMappedMemoryRange(*m_device, *m_logicalDevice, m_allocationBuffer->getMemory(), m_allocationBuffer->getOffset(), static_cast<size_t>(vertexDataSize)); 388 } 389 390 void MultiViewRenderTestInstance::createMultiViewDevices (void) 391 { 392 const InstanceInterface& instance = m_context.getInstanceInterface(); 393 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 394 const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice); 395 396 for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex) 397 { 398 if (queueFamilyProperties[m_queueFamilyIndex].queueFlags | VK_QUEUE_GRAPHICS_BIT ) 399 break; 400 } 401 402 const float queuePriorities = 1.0f; 403 const VkDeviceQueueCreateInfo queueInfo = 404 { 405 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //VkStructureType sType; 406 DE_NULL, //const void* pNext; 407 (VkDeviceQueueCreateFlags)0u, //VkDeviceQueueCreateFlags flags; 408 m_queueFamilyIndex, //deUint32 queueFamilyIndex; 409 1u, //deUint32 queueCount; 410 &queuePriorities //const float* pQueuePriorities; 411 }; 412 413 VkPhysicalDeviceMultiviewFeatures multiviewFeatures = 414 { 415 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR, // VkStructureType sType; 416 DE_NULL, // void* pNext; 417 DE_FALSE, // VkBool32 multiview; 418 DE_FALSE, // VkBool32 multiviewGeometryShader; 419 DE_FALSE, // VkBool32 multiviewTessellationShader; 420 }; 421 422 VkPhysicalDeviceFeatures2 enabledFeatures; 423 enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 424 enabledFeatures.pNext = &multiviewFeatures; 425 426 instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures); 427 428 if (!multiviewFeatures.multiview) 429 TCU_THROW(NotSupportedError, "MultiView not supported"); 430 431 bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) || 432 (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex) || 433 (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex) || 434 (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex); 435 436 if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader) 437 TCU_THROW(NotSupportedError, "Geometry shader is not supported"); 438 439 if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader) 440 TCU_THROW(NotSupportedError, "Tessellation shader is not supported"); 441 442 VkPhysicalDeviceMultiviewProperties multiviewProperties = 443 { 444 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, //VkStructureType sType; 445 DE_NULL, //void* pNext; 446 0u, //deUint32 maxMultiviewViewCount; 447 0u //deUint32 maxMultiviewInstanceIndex; 448 }; 449 450 VkPhysicalDeviceProperties2 propertiesDeviceProperties2; 451 propertiesDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 452 propertiesDeviceProperties2.pNext = &multiviewProperties; 453 454 instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2); 455 456 if (multiviewProperties.maxMultiviewViewCount < 6u) 457 TCU_FAIL("maxMultiviewViewCount below min value"); 458 459 if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1 460 TCU_FAIL("maxMultiviewInstanceIndex below min value"); 461 462 if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth) 463 TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test"); 464 465 m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect; 466 467 { 468 vector<const char*> deviceExtensions; 469 470 if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview")) 471 deviceExtensions.push_back("VK_KHR_multiview"); 472 473 const VkDeviceCreateInfo deviceInfo = 474 { 475 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //VkStructureType sType; 476 &enabledFeatures, //const void* pNext; 477 0u, //VkDeviceCreateFlags flags; 478 1u, //deUint32 queueCreateInfoCount; 479 &queueInfo, //const VkDeviceQueueCreateInfo* pQueueCreateInfos; 480 0u, //deUint32 enabledLayerCount; 481 DE_NULL, //const char* const* ppEnabledLayerNames; 482 static_cast<deUint32>(deviceExtensions.size()), //deUint32 enabledExtensionCount; 483 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0], //const char* const* pEnabledExtensionNames; 484 DE_NULL //const VkPhysicalDeviceFeatures* pEnabledFeatures; 485 }; 486 487 m_logicalDevice = createDevice(instance, physicalDevice, &deviceInfo); 488 m_device = MovePtr<DeviceDriver>(new DeviceDriver(instance, *m_logicalDevice)); 489 m_allocator = MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice))); 490 m_device->getDeviceQueue (*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue); 491 } 492 } 493 494 void MultiViewRenderTestInstance::createCommandBuffer (void) 495 { 496 // cmdPool 497 { 498 const VkCommandPoolCreateInfo cmdPoolParams = 499 { 500 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 501 DE_NULL, // const void* pNext; 502 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCmdPoolCreateFlags flags; 503 m_queueFamilyIndex, // deUint32 queueFamilyIndex; 504 }; 505 m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams); 506 } 507 508 // cmdBuffer 509 { 510 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 511 { 512 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 513 DE_NULL, // const void* pNext; 514 *m_cmdPool, // VkCommandPool commandPool; 515 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 516 1u, // deUint32 bufferCount; 517 }; 518 m_cmdBuffer = allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo); 519 } 520 } 521 522 void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams) 523 { 524 // create shaders modules 525 switch (m_parameters.viewIndex) 526 { 527 case TEST_TYPE_VIEW_MASK: 528 case TEST_TYPE_VIEW_INDEX_IN_VERTEX: 529 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: 530 case TEST_TYPE_INSTANCED_RENDERING: 531 case TEST_TYPE_INPUT_RATE_INSTANCE: 532 case TEST_TYPE_DRAW_INDIRECT: 533 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 534 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 535 break; 536 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: 537 case TEST_TYPE_INPUT_ATTACHMENTS: 538 case TEST_TYPE_CLEAR_ATTACHMENTS: 539 case TEST_TYPE_SECONDARY_CMD_BUFFER: 540 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 541 shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0)))); 542 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 543 break; 544 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: 545 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 546 shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0)))); 547 shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0)))); 548 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 549 break; 550 default: 551 DE_ASSERT(0); 552 break; 553 }; 554 555 VkPipelineShaderStageCreateInfo pipelineShaderStage = 556 { 557 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 558 DE_NULL, // const void* pNext; 559 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 560 (VkShaderStageFlagBits)0, // VkShaderStageFlagBits stage; 561 (VkShaderModule)0, // VkShaderModule module; 562 "main", // const char* pName; 563 (const VkSpecializationInfo*)DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 564 }; 565 566 for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it) 567 { 568 pipelineShaderStage.stage = it->first; 569 pipelineShaderStage.module = **it->second; 570 shaderStageParams.push_back(pipelineShaderStage); 571 } 572 } 573 574 Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass renderPass, 575 const VkPipelineLayout pipelineLayout, 576 const deUint32 pipelineShaderStageCount, 577 const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, 578 const deUint32 subpass, 579 const VkVertexInputRate vertexInputRate) 580 { 581 const VkVertexInputBindingDescription vertexInputBindingDescription = 582 { 583 0u, // binding; 584 static_cast<deUint32>(sizeof(VertexData)), // stride; 585 vertexInputRate // inputRate 586 }; 587 588 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = 589 { 590 { 591 0u, 592 0u, 593 VK_FORMAT_R32G32B32A32_SFLOAT, 594 0u 595 }, // VertexElementData::position 596 { 597 1u, 598 0u, 599 VK_FORMAT_R32G32B32A32_SFLOAT, 600 static_cast<deUint32>(sizeof(tcu::Vec4)) 601 }, // VertexElementData::color 602 }; 603 604 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 605 { // sType; 606 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // pNext; 607 NULL, // flags; 608 0u, // vertexBindingDescriptionCount; 609 1u, // pVertexBindingDescriptions; 610 &vertexInputBindingDescription, // vertexAttributeDescriptionCount; 611 2u, // pVertexAttributeDescriptions; 612 vertexInputAttributeDescriptions 613 }; 614 615 616 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 617 { 618 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 619 DE_NULL, // const void* pNext; 620 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 621 (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology; 622 VK_FALSE, // VkBool32 primitiveRestartEnable; 623 }; 624 625 const VkViewport viewport = 626 { 627 0.0f, // float originX; 628 0.0f, // float originY; 629 (float)m_parameters.extent.width, // float width; 630 (float)m_parameters.extent.height, // float height; 631 0.0f, // float minDepth; 632 1.0f // float maxDepth; 633 }; 634 635 const VkRect2D scissor = 636 { 637 { 0, 0 }, // VkOffset2D offset; 638 { m_parameters.extent.width, m_parameters.extent.height } // VkExtent2D extent; 639 }; 640 641 const VkPipelineViewportStateCreateInfo viewportStateParams = 642 { 643 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 644 DE_NULL, // const void* pNext; 645 0u, // VkPipelineViewportStateCreateFlags flags; 646 1u, // deUint32 viewportCount; 647 &viewport, // const VkViewport* pViewports; 648 1u, // deUint32 scissorCount; 649 &scissor // const VkRect2D* pScissors; 650 }; 651 652 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 653 { 654 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 655 DE_NULL, // const void* pNext; 656 0u, // VkPipelineRasterizationStateCreateFlags flags; 657 VK_FALSE, // VkBool32 depthClampEnable; 658 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 659 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 660 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 661 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 662 VK_FALSE, // VkBool32 depthBiasEnable; 663 0.0f, // float depthBiasConstantFactor; 664 0.0f, // float depthBiasClamp; 665 0.0f, // float depthBiasSlopeFactor; 666 1.0f, // float lineWidth; 667 }; 668 669 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 670 { 671 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 672 DE_NULL, // const void* pNext; 673 0u, // VkPipelineMultisampleStateCreateFlags flags; 674 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 675 VK_FALSE, // VkBool32 sampleShadingEnable; 676 0.0f, // float minSampleShading; 677 DE_NULL, // const VkSampleMask* pSampleMask; 678 VK_FALSE, // VkBool32 alphaToCoverageEnable; 679 VK_FALSE, // VkBool32 alphaToOneEnable; 680 }; 681 682 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 683 { 684 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 685 DE_NULL, // const void* pNext; 686 0u, // VkPipelineDepthStencilStateCreateFlags flags; 687 VK_TRUE, // VkBool32 depthTestEnable; 688 VK_TRUE, // VkBool32 depthWriteEnable; 689 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp; 690 VK_FALSE, // VkBool32 depthBoundsTestEnable; 691 VK_FALSE, // VkBool32 stencilTestEnable; 692 // VkStencilOpState front; 693 { 694 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 695 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 696 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 697 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 698 0u, // deUint32 compareMask; 699 0u, // deUint32 writeMask; 700 0u, // deUint32 reference; 701 }, 702 // VkStencilOpState back; 703 { 704 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 705 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 706 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 707 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 708 0u, // deUint32 compareMask; 709 0u, // deUint32 writeMask; 710 0u, // deUint32 reference; 711 }, 712 0.0f, // float minDepthBounds; 713 1.0f, // float maxDepthBounds; 714 }; 715 716 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 717 { 718 VK_FALSE, // VkBool32 blendEnable; 719 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 720 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 721 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 722 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 723 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 724 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 725 VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask; 726 VK_COLOR_COMPONENT_G_BIT | 727 VK_COLOR_COMPONENT_B_BIT | 728 VK_COLOR_COMPONENT_A_BIT 729 }; 730 731 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 732 { 733 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 734 DE_NULL, // const void* pNext; 735 0u, // VkPipelineColorBlendStateCreateFlags flags; 736 VK_FALSE, // VkBool32 logicOpEnable; 737 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 738 1u, // deUint32 attachmentCount; 739 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 740 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 741 }; 742 743 VkPipelineTessellationStateCreateInfo TessellationState = 744 { 745 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 746 DE_NULL, // const void* pNext; 747 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 748 4u // deUint32 patchControlPoints; 749 }; 750 751 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 752 { 753 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 754 DE_NULL, // const void* pNext; 755 (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags; 756 pipelineShaderStageCount, // deUint32 stageCount; 757 pipelineShaderStageCreate, // const VkPipelineShaderStageCreateInfo* pStages; 758 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 759 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 760 (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 761 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 762 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterState; 763 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 764 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 765 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 766 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 767 pipelineLayout, // VkPipelineLayout layout; 768 renderPass, // VkRenderPass renderPass; 769 subpass, // deUint32 subpass; 770 0u, // VkPipeline basePipelineHandle; 771 0, // deInt32 basePipelineIndex; 772 }; 773 774 return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams); 775 } 776 777 void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst) 778 { 779 Move<VkBuffer> buffer; 780 MovePtr<Allocation> bufferAlloc; 781 const VkDeviceSize pixelDataSize = dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_colorFormat).getPixelSize(); 782 783 // Create destination buffer 784 { 785 const VkBufferCreateInfo bufferParams = 786 { 787 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 788 DE_NULL, // const void* pNext; 789 0u, // VkBufferCreateFlags flags; 790 pixelDataSize, // VkDeviceSize size; 791 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 792 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 793 1u, // deUint32 queueFamilyIndexCount; 794 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 795 }; 796 797 buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); 798 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); 799 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 800 801 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize)); 802 flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); 803 } 804 805 const VkBufferMemoryBarrier bufferBarrier = 806 { 807 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 808 DE_NULL, // const void* pNext; 809 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 810 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 811 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 812 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 813 *buffer, // VkBuffer buffer; 814 0u, // VkDeviceSize offset; 815 pixelDataSize // VkDeviceSize size; 816 }; 817 818 // Copy image to buffer 819 const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); 820 const VkBufferImageCopy copyRegion = 821 { 822 0u, // VkDeviceSize bufferOffset; 823 (deUint32)dst.getWidth(), // deUint32 bufferRowLength; 824 (deUint32)dst.getHeight(), // deUint32 bufferImageHeight; 825 { 826 aspect, // VkImageAspectFlags aspect; 827 0u, // deUint32 mipLevel; 828 0u, // deUint32 baseArrayLayer; 829 m_parameters.extent.depth, // deUint32 layerCount; 830 }, // VkImageSubresourceLayers imageSubresource; 831 { 0, 0, 0 }, // VkOffset3D imageOffset; 832 { m_parameters.extent.width, m_parameters.extent.height, 1u } // VkExtent3D imageExtent; 833 }; 834 835 beginCommandBuffer (*m_device, *m_cmdBuffer); 836 { 837 VkImageSubresourceRange subresourceRange = 838 { 839 aspect, // VkImageAspectFlags aspectMask; 840 0u, // deUint32 baseMipLevel; 841 1u, // deUint32 mipLevels; 842 0u, // deUint32 baseArraySlice; 843 m_parameters.extent.depth, // deUint32 arraySize; 844 }; 845 846 imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 847 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 848 849 m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); 850 m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL); 851 } 852 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 853 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 854 855 // Read buffer data 856 invalidateMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); 857 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); 858 } 859 860 bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame) 861 { 862 const MovePtr<tcu::Texture2DArray> referenceFrame = imageData(); 863 864 if (tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR)) 865 return true; 866 867 for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++) 868 { 869 tcu::ConstPixelBufferAccess ref (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx)); 870 tcu::ConstPixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx)); 871 tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING); 872 } 873 874 return false; 875 } 876 877 MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void) 878 { 879 MovePtr<tcu::Texture2DArray> referenceFrame = MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth)); 880 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 881 referenceFrame->allocLevel(0); 882 883 deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_colorFormat).getPixelSize()); 884 885 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 886 { 887 int layerNdx = 0; 888 deUint32 mask = m_parameters.viewMasks[subpassNdx]; 889 890 while (mask > 0u) 891 { 892 int colorNdx = 0; 893 if (mask & 1u) 894 { 895 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 896 { 897 struct ColorDataRGBA 898 { 899 deUint8 r; 900 deUint8 g; 901 deUint8 b; 902 deUint8 a; 903 }; 904 905 ColorDataRGBA clear = 906 { 907 tcu::floatToU8 (1.0f), 908 tcu::floatToU8 (0.0f), 909 tcu::floatToU8 (0.0f), 910 tcu::floatToU8 (1.0f) 911 }; 912 913 ColorDataRGBA* dataSrc = (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx); 914 ColorDataRGBA* dataDes = dataSrc + 1; 915 deUint32 copySize = 1u; 916 deUint32 layerSize = m_parameters.extent.width * m_parameters.extent.height - copySize; 917 deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA)); 918 919 while (layerSize > 0) 920 { 921 deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA)); 922 dataDes = dataDes + copySize; 923 layerSize = layerSize - copySize; 924 copySize = 2u * copySize; 925 if (copySize >= layerSize) 926 copySize = layerSize; 927 } 928 } 929 930 const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount; 931 if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 932 { 933 const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color : 934 (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.10f, 0.0) : 935 (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.10f, 0.0) : 936 m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 937 for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y) 938 for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x) 939 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); 940 } 941 942 colorNdx += 4; 943 if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 944 { 945 const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color : 946 (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.20f, 0.0) : 947 (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.20f, 0.0) : 948 m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 949 for (deUint32 y = m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y) 950 for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x) 951 referenceFrame->getLevel(0).setPixel(color , x, y, layerNdx); 952 } 953 954 colorNdx += 4; 955 if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 956 { 957 const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color : 958 (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.30f, 0.0) : 959 (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.30f, 0.0) : 960 m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 961 for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y) 962 for (deUint32 x = m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x) 963 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); 964 } 965 966 colorNdx += 4; 967 if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 968 { 969 const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color : 970 (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.40f, 0.0) : 971 (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.40f, 0.0) : 972 m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 973 for (deUint32 y = m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y) 974 for (deUint32 x = m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x) 975 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); 976 } 977 978 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 979 { 980 const tcu::Vec4 color (0.0f, 0.0f, 1.0f, 1.0f); 981 const int maxY = static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f); 982 const int maxX = static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f); 983 for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y) 984 for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x) 985 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); 986 } 987 } 988 989 mask = mask >> 1; 990 ++layerNdx; 991 } 992 } 993 return referenceFrame; 994 } 995 996 class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance 997 { 998 public: 999 MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters); 1000 protected: 1001 tcu::TestStatus iterate (void); 1002 void beforeDraw (void); 1003 void setImageData (VkImage image); 1004 de::SharedPtr<ImageAttachment> m_inputAttachment; 1005 Move<VkDescriptorPool> m_descriptorPool; 1006 Move<VkDescriptorSet> m_descriptorSet; 1007 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1008 Move<VkPipelineLayout> m_pipelineLayout; 1009 1010 }; 1011 1012 MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters) 1013 : MultiViewRenderTestInstance (context, parameters) 1014 { 1015 } 1016 1017 tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void) 1018 { 1019 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 1020 // All color attachment 1021 m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat)); 1022 m_inputAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat)); 1023 1024 // FrameBuffer & renderPass 1025 Unique<VkRenderPass> renderPass (makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_colorFormat, m_parameters.viewMasks)); 1026 1027 vector<VkImageView> attachments; 1028 attachments.push_back(m_colorAttachment->getImageView()); 1029 attachments.push_back(m_inputAttachment->getImageView()); 1030 Unique<VkFramebuffer> frameBuffer (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, attachments, m_parameters.extent.width, m_parameters.extent.height, 1u)); 1031 1032 // pipelineLayout 1033 m_descriptorSetLayout = makeDescriptorSetLayout(*m_device, *m_logicalDevice); 1034 m_pipelineLayout = makePipelineLayout(*m_device, *m_logicalDevice, &m_descriptorSetLayout.get()); 1035 1036 // pipelines 1037 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 1038 vector<PipelineSp> pipelines(subpassCount); 1039 1040 { 1041 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 1042 madeShaderModule(shaderModule, shaderStageParams); 1043 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 1044 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx)))); 1045 } 1046 1047 createVertexData(); 1048 createVertexBuffer(); 1049 1050 createCommandBuffer(); 1051 setImageData(m_inputAttachment->getImage()); 1052 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 1053 1054 { 1055 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_colorFormat).getPixelSize()); 1056 tcu::PixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 1057 1058 readImage (m_colorAttachment->getImage(), dst); 1059 if (!checkImage(dst)) 1060 return tcu::TestStatus::fail("Fail"); 1061 } 1062 1063 return tcu::TestStatus::pass("Pass"); 1064 } 1065 1066 void MultiViewAttachmentsTestInstance::beforeDraw (void) 1067 { 1068 const VkDescriptorPoolSize poolSize = 1069 { 1070 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1071 1u 1072 }; 1073 1074 const VkDescriptorPoolCreateInfo createInfo = 1075 { 1076 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 1077 DE_NULL, 1078 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1079 1u, 1080 1u, 1081 &poolSize 1082 }; 1083 1084 m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo); 1085 1086 const VkDescriptorSetAllocateInfo allocateInfo = 1087 { 1088 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1089 DE_NULL, 1090 *m_descriptorPool, 1091 1u, 1092 &m_descriptorSetLayout.get() 1093 }; 1094 1095 m_descriptorSet = vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo); 1096 1097 const VkDescriptorImageInfo imageInfo = 1098 { 1099 (VkSampler)0, 1100 m_inputAttachment->getImageView(), 1101 VK_IMAGE_LAYOUT_GENERAL 1102 }; 1103 1104 const VkWriteDescriptorSet write = 1105 { 1106 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, //VkStructureType sType; 1107 DE_NULL, //const void* pNext; 1108 *m_descriptorSet, //VkDescriptorSet dstSet; 1109 0u, //deUint32 dstBinding; 1110 0u, //deUint32 dstArrayElement; 1111 1u, //deUint32 descriptorCount; 1112 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, //VkDescriptorType descriptorType; 1113 &imageInfo, //const VkDescriptorImageInfo* pImageInfo; 1114 DE_NULL, //const VkDescriptorBufferInfo* pBufferInfo; 1115 DE_NULL, //const VkBufferView* pTexelBufferView; 1116 }; 1117 1118 m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL); 1119 1120 const VkImageSubresourceRange subresourceRange = 1121 { 1122 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 1123 0u, //deUint32 baseMipLevel; 1124 1u, //deUint32 levelCount; 1125 0u, //deUint32 baseArrayLayer; 1126 m_parameters.extent.depth, //deUint32 layerCount; 1127 }; 1128 m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL); 1129 1130 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT); 1131 1132 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1133 m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); 1134 1135 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); 1136 1137 imageBarrier(*m_device, *m_cmdBuffer, m_inputAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, 0, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT); 1138 } 1139 1140 void MultiViewAttachmentsTestInstance::setImageData (VkImage image) 1141 { 1142 const MovePtr<tcu::Texture2DArray> data = imageData(); 1143 Move<VkBuffer> buffer; 1144 const deUint32 bufferSize = m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_colorFormat)); 1145 MovePtr<Allocation> bufferAlloc; 1146 1147 // Create source buffer 1148 { 1149 const VkBufferCreateInfo bufferParams = 1150 { 1151 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1152 DE_NULL, // const void* pNext; 1153 0u, // VkBufferCreateFlags flags; 1154 bufferSize, // VkDeviceSize size; 1155 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1156 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1157 1u, // deUint32 queueFamilyIndexCount; 1158 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1159 }; 1160 1161 buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); 1162 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); 1163 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1164 } 1165 1166 // Barriers for copying buffer to image 1167 const VkBufferMemoryBarrier preBufferBarrier = 1168 { 1169 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1170 DE_NULL, // const void* pNext; 1171 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1172 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1173 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1174 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1175 *buffer, // VkBuffer buffer; 1176 0u, // VkDeviceSize offset; 1177 bufferSize // VkDeviceSize size; 1178 }; 1179 1180 const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(m_colorFormat)); 1181 VkImageSubresourceRange subresourceRange = 1182 { // VkImageSubresourceRange subresourceRange; 1183 formatAspect, // VkImageAspectFlags aspect; 1184 0u, // deUint32 baseMipLevel; 1185 1u, // deUint32 mipLevels; 1186 0u, // deUint32 baseArraySlice; 1187 m_parameters.extent.depth, // deUint32 arraySize; 1188 }; 1189 1190 const VkBufferImageCopy copyRegion = 1191 { 1192 0u, // VkDeviceSize bufferOffset; 1193 (deUint32)data->getLevel(0).getWidth(), // deUint32 bufferRowLength; 1194 (deUint32)data->getLevel(0).getHeight(), // deUint32 bufferImageHeight; 1195 { 1196 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect; 1197 0u, // deUint32 mipLevel; 1198 0u, // deUint32 baseArrayLayer; 1199 m_parameters.extent.depth, // deUint32 layerCount; 1200 }, // VkImageSubresourceLayers imageSubresource; 1201 { 0, 0, 0 }, // VkOffset3D imageOffset; 1202 {m_parameters.extent.width, m_parameters.extent.height, 1u} // VkExtent3D imageExtent; 1203 }; 1204 1205 // Write buffer data 1206 deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize); 1207 flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize); 1208 1209 beginCommandBuffer(*m_device, *m_cmdBuffer); 1210 1211 m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1212 imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, 1213 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 1214 m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); 1215 imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, 1216 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 1217 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1218 1219 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1220 } 1221 1222 class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance 1223 { 1224 public: 1225 MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters); 1226 protected: 1227 void createVertexData (void); 1228 void draw (const deUint32 subpassCount, 1229 VkRenderPass renderPass, 1230 VkFramebuffer frameBuffer, 1231 vector<PipelineSp>& pipelines); 1232 }; 1233 1234 MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters) 1235 : MultiViewRenderTestInstance (context, parameters) 1236 { 1237 } 1238 void MultiViewInstancedTestInstance::createVertexData (void) 1239 { 1240 tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 1241 m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color)); 1242 m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color)); 1243 m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color)); 1244 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 1245 } 1246 1247 void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1248 { 1249 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1250 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1251 const VkDeviceSize vertexBufferOffset = 0u; 1252 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1253 1254 const VkRenderPassBeginInfo renderPassBeginInfo = 1255 { 1256 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1257 DE_NULL, // const void* pNext; 1258 renderPass, // VkRenderPass renderPass; 1259 frameBuffer, // VkFramebuffer framebuffer; 1260 renderArea, // VkRect2D renderArea; 1261 1u, // uint32_t clearValueCount; 1262 &renderPassClearValue, // const VkClearValue* pClearValues; 1263 }; 1264 1265 beginCommandBuffer(*m_device, *m_cmdBuffer); 1266 1267 beforeDraw(); 1268 1269 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1270 1271 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 1272 1273 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1274 { 1275 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 1276 1277 m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount); 1278 1279 if (subpassNdx < subpassCount - 1u) 1280 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1281 } 1282 1283 m_device->cmdEndRenderPass(*m_cmdBuffer); 1284 1285 afterDraw(); 1286 1287 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1288 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1289 } 1290 1291 class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance 1292 { 1293 public: 1294 MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters); 1295 protected: 1296 void createVertexData (void); 1297 void draw (const deUint32 subpassCount, 1298 VkRenderPass renderPass, 1299 VkFramebuffer frameBuffer, 1300 vector<PipelineSp>& pipelines); 1301 }; 1302 1303 MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters) 1304 : MultiViewRenderTestInstance (context, parameters) 1305 { 1306 } 1307 1308 void MultiViewInputRateInstanceTestInstance::createVertexData (void) 1309 { 1310 tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 1311 m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color)); 1312 1313 color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f); 1314 m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color)); 1315 1316 color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f); 1317 m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color)); 1318 1319 color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f); 1320 m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color)); 1321 } 1322 1323 void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1324 { 1325 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1326 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1327 const VkDeviceSize vertexBufferOffset = 0u; 1328 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1329 1330 const VkRenderPassBeginInfo renderPassBeginInfo = 1331 { 1332 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1333 DE_NULL, // const void* pNext; 1334 renderPass, // VkRenderPass renderPass; 1335 frameBuffer, // VkFramebuffer framebuffer; 1336 renderArea, // VkRect2D renderArea; 1337 1u, // uint32_t clearValueCount; 1338 &renderPassClearValue, // const VkClearValue* pClearValues; 1339 }; 1340 1341 beginCommandBuffer(*m_device, *m_cmdBuffer); 1342 1343 beforeDraw(); 1344 1345 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1346 1347 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 1348 1349 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1350 { 1351 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 1352 1353 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 1354 m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u); 1355 1356 if (subpassNdx < subpassCount - 1u) 1357 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1358 } 1359 1360 m_device->cmdEndRenderPass(*m_cmdBuffer); 1361 1362 afterDraw(); 1363 1364 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1365 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1366 } 1367 1368 class MultiViewIDrawIndirectTestInstance : public MultiViewRenderTestInstance 1369 { 1370 public: 1371 MultiViewIDrawIndirectTestInstance (Context& context, const TestParameters& parameters); 1372 protected: 1373 void draw (const deUint32 subpassCount, 1374 VkRenderPass renderPass, 1375 VkFramebuffer frameBuffer, 1376 vector<PipelineSp>& pipelines); 1377 }; 1378 1379 MultiViewIDrawIndirectTestInstance::MultiViewIDrawIndirectTestInstance (Context& context, const TestParameters& parameters) 1380 : MultiViewRenderTestInstance (context, parameters) 1381 { 1382 } 1383 1384 void MultiViewIDrawIndirectTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1385 { 1386 typedef de::SharedPtr<Unique<VkBuffer> > BufferSP; 1387 typedef de::SharedPtr<UniquePtr<Allocation> > AllocationSP; 1388 1389 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1390 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1391 const VkDeviceSize vertexBufferOffset = 0u; 1392 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1393 vector< BufferSP > indirectBuffers(subpassCount); 1394 vector< AllocationSP > indirectAllocations(subpassCount); 1395 deUint32 strideInBuffer = (deUint32)sizeof(vk::VkDrawIndirectCommand); 1396 1397 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1398 { 1399 vector<VkDrawIndirectCommand> drawCommands; 1400 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 1401 { 1402 const VkDrawIndirectCommand drawCommand = 1403 { 1404 4u, //deUint32 vertexCount; 1405 1u, //deUint32 instanceCount; 1406 (drawNdx + subpassNdx % m_squareCount) * 4u, //deUint32 firstVertex; 1407 0u //deUint32 firstInstance; 1408 }; 1409 drawCommands.push_back(drawCommand); 1410 } 1411 1412 const VkDeviceSize bufferSize = static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>(drawCommands.size() * strideInBuffer), 1413 static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize))); 1414 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); 1415 Move<VkBuffer> indirectBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 1416 MovePtr<Allocation> allocationBuffer = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 1417 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset())); 1418 1419 deMemcpy(allocationBuffer->getHostPtr(), &drawCommands[0], static_cast<size_t>(bufferSize)); 1420 1421 flushMappedMemoryRange(*m_device, *m_logicalDevice, allocationBuffer->getMemory(), allocationBuffer->getOffset(), static_cast<size_t>(bufferSize)); 1422 indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer))); 1423 indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer))); 1424 } 1425 1426 const VkRenderPassBeginInfo renderPassBeginInfo = 1427 { 1428 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1429 DE_NULL, // const void* pNext; 1430 renderPass, // VkRenderPass renderPass; 1431 frameBuffer, // VkFramebuffer framebuffer; 1432 renderArea, // VkRect2D renderArea; 1433 1u, // uint32_t clearValueCount; 1434 &renderPassClearValue, // const VkClearValue* pClearValues; 1435 }; 1436 1437 beginCommandBuffer(*m_device, *m_cmdBuffer); 1438 1439 beforeDraw(); 1440 1441 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1442 1443 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 1444 1445 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1446 { 1447 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 1448 1449 if (m_hasMultiDrawIndirect) 1450 { 1451 m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer); 1452 } 1453 else 1454 { 1455 for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++) 1456 { 1457 m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer); 1458 } 1459 } 1460 1461 if (subpassNdx < subpassCount - 1u) 1462 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1463 } 1464 1465 m_device->cmdEndRenderPass(*m_cmdBuffer); 1466 1467 afterDraw(); 1468 1469 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1470 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1471 } 1472 1473 class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance 1474 { 1475 public: 1476 MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters); 1477 protected: 1478 void draw (const deUint32 subpassCount, 1479 VkRenderPass renderPass, 1480 VkFramebuffer frameBuffer, 1481 vector<PipelineSp>& pipelines); 1482 }; 1483 1484 MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters) 1485 : MultiViewRenderTestInstance (context, parameters) 1486 { 1487 } 1488 1489 void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1490 { 1491 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1492 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1493 const VkDeviceSize vertexBufferOffset = 0u; 1494 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1495 1496 const VkRenderPassBeginInfo renderPassBeginInfo = 1497 { 1498 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1499 DE_NULL, // const void* pNext; 1500 renderPass, // VkRenderPass renderPass; 1501 frameBuffer, // VkFramebuffer framebuffer; 1502 renderArea, // VkRect2D renderArea; 1503 1u, // uint32_t clearValueCount; 1504 &renderPassClearValue, // const VkClearValue* pClearValues; 1505 }; 1506 1507 beginCommandBuffer(*m_device, *m_cmdBuffer); 1508 1509 beforeDraw(); 1510 1511 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1512 1513 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 1514 1515 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1516 { 1517 VkClearAttachment clearAttachment = 1518 { 1519 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 1520 0u, // deUint32 colorAttachment 1521 makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) // VkClearValue clearValue 1522 }; 1523 1524 const VkOffset2D offset[2] = 1525 { 1526 {0, 0}, 1527 {static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)} 1528 }; 1529 1530 const VkExtent2D extent[2] = 1531 { 1532 {m_parameters.extent.width, m_parameters.extent.height}, 1533 {static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)} 1534 }; 1535 1536 const VkRect2D rect2D[2] = 1537 { 1538 {offset[0], extent[0]}, 1539 {offset[1], extent[1]} 1540 }; 1541 1542 VkClearRect clearRect = 1543 { 1544 rect2D[0], // VkRect2D rect 1545 0u, // deUint32 baseArrayLayer 1546 1u, // deUint32 layerCount 1547 }; 1548 1549 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); 1550 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 1551 1552 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 1553 m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 1554 1555 clearRect.rect = rect2D[1]; 1556 clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 1557 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); 1558 1559 if (subpassNdx < subpassCount - 1u) 1560 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1561 } 1562 1563 m_device->cmdEndRenderPass(*m_cmdBuffer); 1564 1565 afterDraw(); 1566 1567 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1568 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1569 } 1570 1571 1572 class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance 1573 { 1574 public: 1575 MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters); 1576 protected: 1577 void draw (const deUint32 subpassCount, 1578 VkRenderPass renderPass, 1579 VkFramebuffer frameBuffer, 1580 vector<PipelineSp>& pipelines); 1581 }; 1582 1583 MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters) 1584 : MultiViewRenderTestInstance (context, parameters) 1585 { 1586 } 1587 1588 void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1589 { 1590 typedef de::SharedPtr<Unique<VkCommandBuffer> > VkCommandBufferSp; 1591 1592 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1593 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1594 const VkDeviceSize vertexBufferOffset = 0u; 1595 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1596 1597 const VkRenderPassBeginInfo renderPassBeginInfo = 1598 { 1599 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1600 DE_NULL, // const void* pNext; 1601 renderPass, // VkRenderPass renderPass; 1602 frameBuffer, // VkFramebuffer framebuffer; 1603 renderArea, // VkRect2D renderArea; 1604 1u, // uint32_t clearValueCount; 1605 &renderPassClearValue, // const VkClearValue* pClearValues; 1606 }; 1607 1608 beginCommandBuffer(*m_device, *m_cmdBuffer); 1609 1610 beforeDraw(); 1611 1612 m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 1613 1614 //Create secondary buffer 1615 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1616 { 1617 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1618 DE_NULL, // const void* pNext; 1619 *m_cmdPool, // VkCommandPool commandPool; 1620 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; 1621 1u, // deUint32 bufferCount; 1622 }; 1623 vector<VkCommandBufferSp> cmdBufferSecondary; 1624 1625 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1626 { 1627 cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo)))); 1628 1629 beginSecondaryCommandBuffer(*m_device, cmdBufferSecondary.back().get()->get(), renderPass, subpassNdx, frameBuffer); 1630 m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset); 1631 m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 1632 1633 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 1634 m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 1635 1636 VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get())); 1637 1638 m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get()); 1639 if (subpassNdx < subpassCount - 1u) 1640 m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 1641 } 1642 1643 m_device->cmdEndRenderPass(*m_cmdBuffer); 1644 1645 afterDraw(); 1646 1647 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1648 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1649 } 1650 1651 class MultiViewRenderTestsCase : public vkt::TestCase 1652 { 1653 public: 1654 MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters) 1655 : TestCase (context, name, description) 1656 , m_parameters (parameters) 1657 { 1658 } 1659 private: 1660 const TestParameters m_parameters; 1661 1662 vkt::TestInstance* createInstance (vkt::Context& context) const 1663 { 1664 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex) 1665 return new MultiViewAttachmentsTestInstance(context, m_parameters); 1666 1667 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) 1668 return new MultiViewInstancedTestInstance(context, m_parameters); 1669 1670 if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1671 return new MultiViewInputRateInstanceTestInstance(context, m_parameters); 1672 1673 if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex) 1674 return new MultiViewIDrawIndirectTestInstance(context, m_parameters); 1675 1676 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 1677 return new MultiViewClearAttachmentsTestInstance(context, m_parameters); 1678 1679 if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex) 1680 return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters); 1681 1682 return new MultiViewRenderTestInstance(context, m_parameters); 1683 } 1684 1685 void initPrograms (SourceCollections& programCollection) const 1686 { 1687 // Create vertex shader 1688 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) 1689 { 1690 std::ostringstream source; 1691 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1692 << "#extension GL_EXT_multiview : enable\n" 1693 << "layout(location = 0) in highp vec4 in_position;\n" 1694 << "layout(location = 1) in vec4 in_color;\n" 1695 << "layout(location = 0) out vec4 out_color;\n" 1696 << "void main (void)\n" 1697 << "{\n" 1698 << " int modInstance = gl_InstanceIndex % 4;\n" 1699 << " int instance = gl_InstanceIndex + 1;\n" 1700 << " gl_Position = in_position;\n" 1701 << " if (modInstance == 1)\n" 1702 << " gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n" 1703 << " if (modInstance == 2)\n" 1704 << " gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n" 1705 << " if (modInstance == 3)\n" 1706 << " gl_Position = in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n" 1707 << " out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n" 1708 << "}\n"; 1709 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 1710 } 1711 else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1712 { 1713 std::ostringstream source; 1714 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1715 << "#extension GL_EXT_multiview : enable\n" 1716 << "layout(location = 0) in highp vec4 in_position;\n" 1717 << "layout(location = 1) in vec4 in_color;\n" 1718 << "layout(location = 0) out vec4 out_color;\n" 1719 << "void main (void)\n" 1720 << "{\n" 1721 << " int instance = gl_InstanceIndex + 1;\n" 1722 << " gl_Position = in_position;\n" 1723 << " if (gl_VertexIndex == 1)\n" 1724 << " gl_Position.y += 1.0f;\n" 1725 << " else if (gl_VertexIndex == 2)\n" 1726 << " gl_Position.x += 1.0f;\n" 1727 << " else if (gl_VertexIndex == 3)\n" 1728 << " {\n" 1729 << " gl_Position.x += 1.0f;\n" 1730 << " gl_Position.y += 1.0f;\n" 1731 << " }\n" 1732 << " out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n" 1733 << "}\n"; 1734 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 1735 } 1736 else 1737 { 1738 std::ostringstream source; 1739 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1740 << "#extension GL_EXT_multiview : enable\n" 1741 << "layout(location = 0) in highp vec4 in_position;\n" 1742 << "layout(location = 1) in vec4 in_color;\n" 1743 << "layout(location = 0) out vec4 out_color;\n" 1744 << "void main (void)\n" 1745 << "{\n" 1746 << " gl_Position = in_position;\n"; 1747 if (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex || TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex) 1748 source << " out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"; 1749 else 1750 source << " out_color = in_color;\n"; 1751 source << "}\n"; 1752 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 1753 } 1754 1755 if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) 1756 {// Tessellation control & evaluation 1757 std::ostringstream source_tc; 1758 source_tc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1759 << "#extension GL_EXT_multiview : enable\n" 1760 << "#extension GL_EXT_tessellation_shader : require\n" 1761 << "layout(vertices = 4) out;\n" 1762 << "layout(location = 0) in vec4 in_color[];\n" 1763 << "layout(location = 0) out vec4 out_color[];\n" 1764 << "\n" 1765 << "void main (void)\n" 1766 << "{\n" 1767 << " if ( gl_InvocationID == 0 )\n" 1768 << " {\n" 1769 << " gl_TessLevelInner[0] = 4.0f;\n" 1770 << " gl_TessLevelInner[1] = 4.0f;\n" 1771 << " gl_TessLevelOuter[0] = 4.0f;\n" 1772 << " gl_TessLevelOuter[1] = 4.0f;\n" 1773 << " gl_TessLevelOuter[2] = 4.0f;\n" 1774 << " gl_TessLevelOuter[3] = 4.0f;\n" 1775 << " }\n" 1776 << " out_color[gl_InvocationID] = in_color[gl_InvocationID];\n" 1777 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 1778 << "}\n"; 1779 programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str()); 1780 1781 std::ostringstream source_te; 1782 source_te << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1783 << "#extension GL_EXT_multiview : enable\n" 1784 << "#extension GL_EXT_tessellation_shader : require\n" 1785 << "layout( quads, equal_spacing, ccw ) in;\n" 1786 << "layout(location = 0) in vec4 in_color[];\n" 1787 << "layout(location = 0) out vec4 out_color;\n" 1788 << "void main (void)\n" 1789 << "{\n" 1790 << " const float u = gl_TessCoord.x;\n" 1791 << " const float v = gl_TessCoord.y;\n" 1792 << " const float w = gl_TessCoord.z;\n" 1793 << " gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n" 1794 << " out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 1795 << "}\n"; 1796 programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str()); 1797 } 1798 1799 if (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex || 1800 TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex || 1801 TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex || 1802 TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex) 1803 {// Geometry Shader 1804 std::ostringstream source; 1805 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1806 << "#extension GL_EXT_multiview : enable\n" 1807 << "layout(triangles) in;\n" 1808 << "layout(triangle_strip, max_vertices = 16) out;\n" 1809 << "layout(location = 0) in vec4 in_color[];\n" 1810 << "layout(location = 0) out vec4 out_color;\n" 1811 << "void main (void)\n" 1812 << "{\n" 1813 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 1814 << " gl_Position = gl_in[0].gl_Position;\n" 1815 << " EmitVertex();\n" 1816 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 1817 << " gl_Position = gl_in[1].gl_Position;\n" 1818 << " EmitVertex();\n" 1819 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 1820 << " gl_Position = gl_in[2].gl_Position;\n" 1821 << " EmitVertex();\n" 1822 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 1823 << " gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n" 1824 << " EmitVertex();\n" 1825 << " EndPrimitive();\n" 1826 << "}\n"; 1827 programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str()); 1828 } 1829 1830 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex) 1831 {// Create fragment shader read/write attachment 1832 std::ostringstream source; 1833 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1834 << "#extension GL_EXT_multiview : enable\n" 1835 << "layout(location = 0) in vec4 in_color;\n" 1836 << "layout(location = 0) out vec4 out_color;\n" 1837 << "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n" 1838 << "void main()\n" 1839 <<"{\n" 1840 << " out_color = vec4(subpassLoad(in_color_attachment));\n" 1841 << "}\n"; 1842 programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str()); 1843 } 1844 else 1845 {// Create fragment shader 1846 std::ostringstream source; 1847 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 1848 << "#extension GL_EXT_multiview : enable\n" 1849 << "layout(location = 0) in vec4 in_color;\n" 1850 << "layout(location = 0) out vec4 out_color;\n" 1851 << "void main()\n" 1852 <<"{\n"; 1853 if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex) 1854 source << " out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"; 1855 else 1856 source << " out_color = in_color;\n"; 1857 source << "}\n"; 1858 programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str()); 1859 } 1860 } 1861 }; 1862 } //anonymous 1863 1864 void multiViewRenderCreateTests (tcu::TestCaseGroup* group) 1865 { 1866 tcu::TestContext& testCtx = group->getTestContext(); 1867 const deUint32 testCaseCount = 6u; 1868 MovePtr<tcu::TestCaseGroup> groupViewIndex (new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests.")); 1869 const string shaderName[TEST_TYPE_LAST] = 1870 { 1871 "masks", 1872 "vertex_shader", 1873 "fragment_shader", 1874 "geometry_shader", 1875 "tesellation_shader", 1876 "input_attachments", 1877 "instanced", 1878 "input_instance", 1879 "draw_indirect", 1880 "clear_attachments", 1881 "secondary_cmd_buffer" 1882 }; 1883 const VkExtent3D extent3D[testCaseCount] = 1884 { 1885 {16u, 16u, 4u}, 1886 {64u, 64u, 8u}, 1887 {128u, 128u, 4u}, 1888 {32u, 32u, 5u}, 1889 {64u, 64u, 6u}, 1890 {16u, 16u, 10u}, 1891 }; 1892 vector<deUint32> viewMasks[testCaseCount]; 1893 1894 viewMasks[0].push_back(15u); //1111 1895 1896 viewMasks[1].push_back(8u); //1000 1897 1898 viewMasks[2].push_back(1u); //0001 1899 viewMasks[2].push_back(2u); //0010 1900 viewMasks[2].push_back(4u); //0100 1901 viewMasks[2].push_back(8u); //1000 1902 1903 viewMasks[3].push_back(15u); //1111 1904 viewMasks[3].push_back(15u); //1111 1905 viewMasks[3].push_back(15u); //1111 1906 viewMasks[3].push_back(15u); //1111 1907 1908 viewMasks[4].push_back(8u); //1000 1909 viewMasks[4].push_back(1u); //0001 1910 viewMasks[4].push_back(1u); //0001 1911 viewMasks[4].push_back(8u); //1000 1912 1913 const deUint32 minSupportedMultiviewViewCount = 6u; 1914 const deUint32 maxViewMask = (1u << minSupportedMultiviewViewCount) - 1u; 1915 1916 for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u) 1917 viewMasks[5].push_back(mask); 1918 1919 for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx) 1920 { 1921 MovePtr<tcu::TestCaseGroup> groupShader (new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), "")); 1922 for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx) 1923 { 1924 const TestParameters parameters = {extent3D[testCaseNdx], viewMasks[testCaseNdx], (TestType)testTypeNdx}; 1925 std::ostringstream masks; 1926 const deUint32 viewMaksSize = static_cast<deUint32>(viewMasks[testCaseNdx].size()); 1927 1928 for (deUint32 ndx = 0u; ndx < viewMaksSize; ++ndx) 1929 { 1930 masks<<viewMasks[testCaseNdx][ndx]; 1931 if (viewMaksSize - 1 != ndx) 1932 masks<<"_"; 1933 } 1934 groupShader->addChild(new MultiViewRenderTestsCase(testCtx, masks.str().c_str(), "", parameters)); 1935 } 1936 1937 // maxMultiviewViewCount case 1938 { 1939 const VkExtent3D incompleteExtent3D = { 16u, 16u, 0u }; 1940 const vector<deUint32> dummyMasks; 1941 const TestParameters parameters = { incompleteExtent3D, dummyMasks, (TestType)testTypeNdx }; 1942 1943 groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters)); 1944 } 1945 1946 switch (testTypeNdx) 1947 { 1948 case TEST_TYPE_VIEW_MASK: 1949 case TEST_TYPE_INPUT_ATTACHMENTS: 1950 case TEST_TYPE_INSTANCED_RENDERING: 1951 case TEST_TYPE_INPUT_RATE_INSTANCE: 1952 case TEST_TYPE_DRAW_INDIRECT: 1953 case TEST_TYPE_CLEAR_ATTACHMENTS: 1954 case TEST_TYPE_SECONDARY_CMD_BUFFER: 1955 group->addChild(groupShader.release()); 1956 break; 1957 case TEST_TYPE_VIEW_INDEX_IN_VERTEX: 1958 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: 1959 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: 1960 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: 1961 groupViewIndex->addChild(groupShader.release()); 1962 break; 1963 default: 1964 DE_ASSERT(0); 1965 break; 1966 }; 1967 } 1968 1969 group->addChild(groupViewIndex.release()); 1970 } 1971 1972 } //MultiView 1973 } //vkt 1974 1975