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#include "vktMultiViewRenderPassUtil.hpp" 27#include "vktCustomInstancesDevices.hpp" 28 29#include "vktTestCase.hpp" 30#include "vkBuilderUtil.hpp" 31#include "vkRefUtil.hpp" 32#include "vkQueryUtil.hpp" 33#include "vkDeviceUtil.hpp" 34#include "vkTypeUtil.hpp" 35#include "vkPrograms.hpp" 36#include "vkPlatform.hpp" 37#include "vkMemUtil.hpp" 38#include "vkImageUtil.hpp" 39#include "vkCmdUtil.hpp" 40#include "vkObjUtil.hpp" 41#include "vkBarrierUtil.hpp" 42 43#include "tcuTestLog.hpp" 44#include "tcuResource.hpp" 45#include "tcuImageCompare.hpp" 46#include "tcuCommandLine.hpp" 47#include "tcuTextureUtil.hpp" 48#include "tcuRGBA.hpp" 49 50#include "deRandom.hpp" 51#include "deMath.h" 52#include "deSharedPtr.hpp" 53#ifdef CTS_USES_VULKANSC 54#include "vkSafetyCriticalUtil.hpp" 55#endif 56 57#include <algorithm> 58#include <bitset> 59 60namespace vkt 61{ 62namespace MultiView 63{ 64namespace 65{ 66 67using namespace vk; 68using de::MovePtr; 69using de::UniquePtr; 70using std::vector; 71using std::map; 72using std::string; 73 74enum TestType 75{ 76 TEST_TYPE_VIEW_MASK, 77 TEST_TYPE_VIEW_INDEX_IN_VERTEX, 78 TEST_TYPE_VIEW_INDEX_IN_FRAGMENT, 79 TEST_TYPE_VIEW_INDEX_IN_GEOMETRY, 80 TEST_TYPE_VIEW_INDEX_IN_TESELLATION, 81 TEST_TYPE_INPUT_ATTACHMENTS, 82 TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY, 83 TEST_TYPE_INSTANCED_RENDERING, 84 TEST_TYPE_INPUT_RATE_INSTANCE, 85 TEST_TYPE_DRAW_INDIRECT, 86 TEST_TYPE_DRAW_INDIRECT_INDEXED, 87 TEST_TYPE_DRAW_INDEXED, 88 TEST_TYPE_CLEAR_ATTACHMENTS, 89 TEST_TYPE_SECONDARY_CMD_BUFFER, 90 TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY, 91 TEST_TYPE_POINT_SIZE, 92 TEST_TYPE_MULTISAMPLE, 93 TEST_TYPE_QUERIES, 94 TEST_TYPE_NON_PRECISE_QUERIES, 95 TEST_TYPE_NON_PRECISE_QUERIES_WITH_AVAILABILITY, 96 TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR, 97 TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR, 98 TEST_TYPE_DEPTH, 99 TEST_TYPE_DEPTH_DIFFERENT_RANGES, 100 TEST_TYPE_STENCIL, 101 TEST_TYPE_VIEW_MASK_ITERATION, 102 TEST_TYPE_LAST 103}; 104 105enum RenderingType 106{ 107 RENDERING_TYPE_RENDERPASS_LEGACY = 0, 108 RENDERING_TYPE_RENDERPASS2, 109 RENDERING_TYPE_DYNAMIC_RENDERING 110}; 111 112enum QueryType 113{ 114 QUERY_TYPE_GET_QUERY_POOL_RESULTS, 115 QUERY_TYPE_CMD_COPY_QUERY_POOL_RESULTS 116}; 117 118struct TestParameters 119{ 120 VkExtent3D extent; 121 vector<deUint32> viewMasks; 122 TestType viewIndex; 123 VkSampleCountFlagBits samples; 124 VkFormat colorFormat; 125 QueryType queryType; 126 RenderingType renderingType; 127 128 bool geometryShaderNeeded (void) const 129 { 130 return ((TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == viewIndex) || 131 (TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == viewIndex) || 132 (TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == viewIndex)); 133 } 134}; 135 136const int TEST_POINT_SIZE_SMALL = 2; 137const int TEST_POINT_SIZE_WIDE = 4; 138 139vk::Move<vk::VkRenderPass> makeRenderPass (const DeviceInterface& vk, 140 const VkDevice device, 141 const VkFormat colorFormat, 142 const vector<deUint32>& viewMasks, 143 RenderingType renderingType, 144 const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT, 145 const VkAttachmentLoadOp colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, 146 const VkFormat dsFormat = VK_FORMAT_UNDEFINED) 147{ 148 switch (renderingType) 149 { 150 case RENDERING_TYPE_RENDERPASS_LEGACY: 151 return MultiView::makeRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat); 152 case RENDERING_TYPE_RENDERPASS2: 153 return MultiView::makeRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat); 154 default: 155 TCU_THROW(InternalError, "Impossible"); 156 } 157} 158 159vk::Move<vk::VkRenderPass> makeRenderPassWithAttachments (const DeviceInterface& vk, 160 const VkDevice device, 161 const VkFormat colorFormat, 162 const vector<deUint32>& viewMasks, 163 RenderingType renderingType) 164{ 165 switch (renderingType) 166 { 167 case RENDERING_TYPE_RENDERPASS_LEGACY: 168 return MultiView::makeRenderPassWithAttachments<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, false); 169 case RENDERING_TYPE_RENDERPASS2: 170 return MultiView::makeRenderPassWithAttachments<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, true); 171 default: 172 TCU_THROW(InternalError, "Impossible"); 173 } 174} 175 176vk::Move<vk::VkRenderPass> makeRenderPassWithDepth (const DeviceInterface& vk, 177 const VkDevice device, 178 const VkFormat colorFormat, 179 const vector<deUint32>& viewMasks, 180 const VkFormat dsFormat, 181 RenderingType renderingType) 182{ 183 switch (renderingType) 184 { 185 case RENDERING_TYPE_RENDERPASS_LEGACY: 186 return MultiView::makeRenderPassWithDepth<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, dsFormat); 187 case RENDERING_TYPE_RENDERPASS2: 188 return MultiView::makeRenderPassWithDepth<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, dsFormat); 189 default: 190 TCU_THROW(InternalError, "Impossible"); 191 } 192} 193 194template<typename RenderpassSubpass> 195void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents) 196{ 197 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents); 198 199 RenderpassSubpass::cmdBeginRenderPass(vkd, cmdBuffer, pRenderPassBegin, &subpassBeginInfo); 200} 201 202void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents, RenderingType renderingType) 203{ 204 switch (renderingType) 205 { 206 case RENDERING_TYPE_RENDERPASS_LEGACY: cmdBeginRenderPass<RenderpassSubpass1>(vkd, cmdBuffer, pRenderPassBegin, contents); break; 207 case RENDERING_TYPE_RENDERPASS2: cmdBeginRenderPass<RenderpassSubpass2>(vkd, cmdBuffer, pRenderPassBegin, contents); break; 208 default: TCU_THROW(InternalError, "Impossible"); 209 } 210} 211 212template<typename RenderpassSubpass> 213void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents) 214{ 215 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents); 216 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL); 217 218 RenderpassSubpass::cmdNextSubpass(vkd, cmdBuffer, &subpassBeginInfo, &subpassEndInfo); 219} 220 221void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents, RenderingType renderingType) 222{ 223 switch (renderingType) 224 { 225 case RENDERING_TYPE_RENDERPASS_LEGACY: cmdNextSubpass<RenderpassSubpass1>(vkd, cmdBuffer, contents); break; 226 case RENDERING_TYPE_RENDERPASS2: cmdNextSubpass<RenderpassSubpass2>(vkd, cmdBuffer, contents); break; 227 default: TCU_THROW(InternalError, "Impossible"); 228 } 229} 230 231template<typename RenderpassSubpass> 232void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer) 233{ 234 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL); 235 236 RenderpassSubpass::cmdEndRenderPass(vkd, cmdBuffer, &subpassEndInfo); 237} 238 239void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, RenderingType renderingType) 240{ 241 switch (renderingType) 242 { 243 case RENDERING_TYPE_RENDERPASS_LEGACY: cmdEndRenderPass<RenderpassSubpass1>(vkd, cmdBuffer); break; 244 case RENDERING_TYPE_RENDERPASS2: cmdEndRenderPass<RenderpassSubpass2>(vkd, cmdBuffer); break; 245 default: TCU_THROW(InternalError, "Impossible"); 246 } 247} 248 249class ImageAttachment 250{ 251public: 252 ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT); 253 VkImageView getImageView (void) const 254 { 255 return *m_imageView; 256 } 257 VkImage getImage (void) const 258 { 259 return *m_image; 260 } 261private: 262 Move<VkImage> m_image; 263 MovePtr<Allocation> m_allocationImage; 264 Move<VkImageView> m_imageView; 265}; 266 267ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples) 268{ 269 const bool depthStencilFormat = isDepthStencilFormat(colorFormat); 270 const VkImageAspectFlags aspectFlags = depthStencilFormat ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 271 const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, 0u, extent.depth); 272 const VkImageUsageFlags imageUsageFlagsDependent = depthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 273 const VkImageUsageFlags imageUsageFlags = imageUsageFlagsDependent | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 274 const VkImageCreateInfo colorAttachmentImageInfo = makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, imageUsageFlags, samples); 275 276 m_image = createImage(device, logicalDevice, &colorAttachmentImageInfo); 277 m_allocationImage = allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any); 278 VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset())); 279 m_imageView = makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange); 280} 281 282class MultiViewRenderTestInstance : public TestInstance 283{ 284public: 285 MultiViewRenderTestInstance (Context& context, const TestParameters& parameters); 286 ~MultiViewRenderTestInstance(); 287protected: 288 typedef de::SharedPtr<Unique<VkPipeline> > PipelineSp; 289 typedef de::SharedPtr<Unique<VkShaderModule> > ShaderModuleSP; 290 291 virtual tcu::TestStatus iterate (void); 292 virtual void beforeRenderPass (void); 293 virtual void afterRenderPass (void); 294 virtual void bindResources (void) {} 295 virtual void draw (const deUint32 subpassCount, 296 VkRenderPass renderPass, 297 VkFramebuffer frameBuffer, 298 vector<PipelineSp>& pipelines); 299 virtual void createVertexData (void); 300 virtual MovePtr<tcu::Texture2DArray> imageData (void) const; 301 TestParameters fillMissingParameters (const TestParameters& parameters); 302 void createVertexBuffer (void); 303 void createMultiViewDevices (void); 304 void createCommandBuffer (void); 305 void createSecondaryCommandPool (void); 306 void madeShaderModule (map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams); 307 Move<VkPipeline> makeGraphicsPipeline (const VkRenderPass renderPass, 308 const VkPipelineLayout pipelineLayout, 309 const deUint32 pipelineShaderStageCount, 310 const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, 311 const deUint32 subpass, 312 const VkVertexInputRate vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX, 313 const bool useDepthTest = false, 314 const bool useStencilTest = false, 315 const float minDepth = 0.0f, 316 const float maxDepth = 1.0f, 317 const VkFormat dsFormat = VK_FORMAT_UNDEFINED); 318 void readImage (VkImage image, const tcu::PixelBufferAccess& dst); 319 bool checkImage (tcu::ConstPixelBufferAccess& dst); 320 const tcu::Vec4 getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background = true, const deUint32 subpassNdx = 0u) const; 321 void appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color); 322 void setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const; 323 void fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const; 324 void fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const; 325 void fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const; 326#ifndef CTS_USES_VULKANSC 327 void addRenderingSubpassDependencyIfRequired (deUint32 currentSubpassNdx); 328#endif // CTS_USES_VULKANSC 329 330 const TestParameters m_parameters; 331 const bool m_useDynamicRendering; 332 const bool m_cmdCopyQueryPoolResults; 333 const int m_seed; 334 const deUint32 m_squareCount; 335 336 Move<VkDevice> m_logicalDevice; 337#ifndef CTS_USES_VULKANSC 338 de::MovePtr<vk::DeviceDriver> m_device; 339#else 340 de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter> m_device; 341#endif // CTS_USES_VULKANSC 342 MovePtr<Allocator> m_allocator; 343 deUint32 m_queueFamilyIndex; 344 VkQueue m_queue; 345 vector<tcu::Vec4> m_vertexCoord; 346 Move<VkBuffer> m_vertexCoordBuffer; 347 MovePtr<Allocation> m_vertexCoordAlloc; 348 vector<tcu::Vec4> m_vertexColor; 349 Move<VkBuffer> m_vertexColorBuffer; 350 MovePtr<Allocation> m_vertexColorAlloc; 351 vector<deUint32> m_vertexIndices; 352 Move<VkBuffer> m_vertexIndicesBuffer; 353 MovePtr<Allocation> m_vertexIndicesAllocation; 354 Move<VkCommandPool> m_cmdPool; 355 Move<VkCommandBuffer> m_cmdBuffer; 356 Move<VkCommandPool> m_cmdPoolSecondary; 357 de::SharedPtr<ImageAttachment> m_colorAttachment; 358 VkBool32 m_hasMultiDrawIndirect; 359 vector<tcu::Vec4> m_colorTable; 360}; 361 362MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters) 363 : TestInstance (context) 364 , m_parameters (fillMissingParameters(parameters)) 365 , m_useDynamicRendering (parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) 366 , m_cmdCopyQueryPoolResults (parameters.queryType == QUERY_TYPE_CMD_COPY_QUERY_POOL_RESULTS) 367 , m_seed (context.getTestContext().getCommandLine().getBaseSeed()) 368 , m_squareCount (4u) 369 , m_queueFamilyIndex (0u) 370{ 371 const float v = 0.75f; 372 const float o = 0.25f; 373 374 m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f)); 375 m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f)); 376 m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f)); 377 m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f)); 378 m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f)); 379 m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f)); 380 m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f)); 381 m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f)); 382 383 createMultiViewDevices(); 384 385 // Color attachment 386 m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples)); 387} 388 389MultiViewRenderTestInstance::~MultiViewRenderTestInstance() 390{ 391} 392 393tcu::TestStatus MultiViewRenderTestInstance::iterate (void) 394{ 395 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 396 Move<VkRenderPass> renderPass; 397 Move<VkFramebuffer> frameBuffer; 398 399 // FrameBuffer & renderPass 400 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 401 { 402 renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType); 403 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); 404 } 405 406 // pipelineLayout 407 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 408 409 // pipelines 410 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 411 vector<PipelineSp> pipelines(subpassCount); 412 const VkVertexInputRate vertexInputRate = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; 413 414 { 415 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 416 madeShaderModule(shaderModule, shaderStageParams); 417 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 418 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate)))); 419 } 420 421 createCommandBuffer(); 422 createVertexData(); 423 createVertexBuffer(); 424 425 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 426 427 { 428 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); 429 tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 430 431 readImage(m_colorAttachment->getImage(), dst); 432 433 if (!checkImage(dst)) 434 return tcu::TestStatus::fail("Fail"); 435 } 436 437 return tcu::TestStatus::pass("Pass"); 438} 439 440void MultiViewRenderTestInstance::beforeRenderPass (void) 441{ 442 const VkImageSubresourceRange subresourceRange = 443 { 444 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 445 0u, //deUint32 baseMipLevel; 446 1u, //deUint32 levelCount; 447 0u, //deUint32 baseArrayLayer; 448 m_parameters.extent.depth, //deUint32 layerCount; 449 }; 450 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 451 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 452 0, VK_ACCESS_TRANSFER_WRITE_BIT, 453 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 454 455 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 456 m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); 457 458 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 459 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 460 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 461 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 462} 463 464void MultiViewRenderTestInstance::afterRenderPass (void) 465{ 466 const VkImageSubresourceRange subresourceRange = 467 { 468 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 469 0u, //deUint32 baseMipLevel; 470 1u, //deUint32 levelCount; 471 0u, //deUint32 baseArrayLayer; 472 m_parameters.extent.depth, //deUint32 layerCount; 473 }; 474 475 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 476 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 477 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 478 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 479} 480 481#ifndef CTS_USES_VULKANSC 482void MultiViewRenderTestInstance::addRenderingSubpassDependencyIfRequired (deUint32 currentSubpassNdx) 483{ 484 // Get the combined view mask since the last pipeline barrier. 485 deUint32 viewMask = 0; 486 487 for (deUint32 subpassNdx = 0; subpassNdx < currentSubpassNdx; ++subpassNdx) 488 { 489 if ((viewMask & m_parameters.viewMasks[subpassNdx]) != 0) 490 { 491 viewMask = 0; // This subpass should have a pipeline barrier so reset the view mask. 492 } 493 494 viewMask |= m_parameters.viewMasks[subpassNdx]; 495 } 496 497 // Add a pipeline barrier if the view mask for this subpass contains bits used in previous subpasses 498 // since the last pipeline barrier. 499 if ((viewMask & m_parameters.viewMasks[currentSubpassNdx]) != 0) 500 { 501 const VkImageSubresourceRange subresourceRange = 502 { 503 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 504 0u, //deUint32 baseMipLevel; 505 1u, //deUint32 levelCount; 506 0u, //deUint32 baseArrayLayer; 507 m_parameters.extent.depth, //deUint32 layerCount; 508 }; 509 510 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 511 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 512 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 513 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 514 } 515} 516#endif // CTS_USES_VULKANSC 517 518void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 519{ 520 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 521 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 522 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 523 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 524 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 525 526 beginCommandBuffer(*m_device, *m_cmdBuffer); 527 528 beforeRenderPass(); 529 530 if (!m_useDynamicRendering) 531 { 532 const VkRenderPassBeginInfo renderPassBeginInfo 533 { 534 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 535 DE_NULL, // const void* pNext; 536 renderPass, // VkRenderPass renderPass; 537 frameBuffer, // VkFramebuffer framebuffer; 538 renderArea, // VkRect2D renderArea; 539 1u, // uint32_t clearValueCount; 540 &renderPassClearValue, // const VkClearValue* pClearValues; 541 }; 542 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 543 } 544 545 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 546 { 547 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 548 549 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED) 550 m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32); 551 552 bindResources(); 553 554#ifndef CTS_USES_VULKANSC 555 if (m_useDynamicRendering) 556 { 557 addRenderingSubpassDependencyIfRequired(subpassNdx); 558 559 beginRendering( 560 *m_device, 561 *m_cmdBuffer, 562 m_colorAttachment->getImageView(), 563 renderArea, 564 renderPassClearValue, 565 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 566 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 567 0u, 568 m_parameters.extent.depth, 569 m_parameters.viewMasks[subpassNdx]); 570 } 571#endif // CTS_USES_VULKANSC 572 573 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 574 575 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 576 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED) 577 m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u); 578 else 579 m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 580 581#ifndef CTS_USES_VULKANSC 582 if (m_useDynamicRendering) 583 endRendering(*m_device, *m_cmdBuffer); 584 else 585#endif // CTS_USES_VULKANSC 586 if (subpassNdx < subpassCount - 1u) 587 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 588 } 589 590 if (!m_useDynamicRendering) 591 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 592 593 afterRenderPass(); 594 595 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 596 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 597} 598 599void MultiViewRenderTestInstance::createVertexData (void) 600{ 601 tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 602 603 appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); 604 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); 605 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); 606 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 607 608 color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f); 609 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); 610 appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color); 611 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 612 appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color); 613 614 color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f); 615 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); 616 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 617 appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color); 618 appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color); 619 620 color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f); 621 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 622 appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color); 623 appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color); 624 appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color); 625 626 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 627 { 628 const size_t verticesCount = m_vertexCoord.size(); 629 vector<tcu::Vec4> vertexColor (verticesCount); 630 vector<tcu::Vec4> vertexCoord (verticesCount); 631 632 m_vertexIndices.clear(); 633 m_vertexIndices.reserve(verticesCount); 634 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) 635 m_vertexIndices.push_back(vertexIdx); 636 637 de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end()); 638 639 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) 640 vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx]; 641 m_vertexColor.assign(vertexColor.begin(), vertexColor.end()); 642 643 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx) 644 vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx]; 645 m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end()); 646 } 647} 648 649TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters) 650{ 651 if (!parameters.viewMasks.empty()) 652 return parameters; 653 else 654 { 655 const auto& instanceDriver = m_context.getInstanceInterface(); 656 const auto physicalDevice = m_context.getPhysicalDevice(); 657 658 VkPhysicalDeviceMultiviewProperties multiviewProperties = 659 { 660 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, // VkStructureType sType; 661 DE_NULL, // void* pNext; 662 0u, // deUint32 maxMultiviewViewCount; 663 0u // deUint32 maxMultiviewInstanceIndex; 664 }; 665 666 VkPhysicalDeviceProperties2 deviceProperties2; 667 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 668 deviceProperties2.pNext = &multiviewProperties; 669 670 instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); 671 672 TestParameters newParameters = parameters; 673 newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount; 674 675 vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount); 676 for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++) 677 viewMasks[i] = 1 << i; 678 newParameters.viewMasks = viewMasks; 679 680 return newParameters; 681 } 682} 683 684void MultiViewRenderTestInstance::createVertexBuffer (void) 685{ 686 DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size()); 687 DE_ASSERT(m_vertexCoord.size() != 0); 688 689 const size_t nonCoherentAtomSize = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize); 690 691 // Upload vertex coordinates 692 { 693 const size_t dataSize = static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0])); 694 const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); 695 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 696 697 m_vertexCoordBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 698 m_vertexCoordAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible); 699 700 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset())); 701 deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize)); 702 flushAlloc(*m_device, *m_logicalDevice, *m_vertexCoordAlloc); 703 } 704 705 // Upload vertex colors 706 { 707 const size_t dataSize = static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0])); 708 const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); 709 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 710 711 m_vertexColorBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 712 m_vertexColorAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible); 713 714 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset())); 715 deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize)); 716 flushAlloc(*m_device, *m_logicalDevice, *m_vertexColorAlloc); 717 } 718 719 // Upload vertex indices 720 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 721 { 722 const size_t dataSize = static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0])); 723 const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); 724 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); 725 726 DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size()); 727 728 m_vertexIndicesBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 729 m_vertexIndicesAllocation = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible); 730 731 // Init host buffer data 732 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset())); 733 deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize)); 734 flushAlloc(*m_device, *m_logicalDevice, *m_vertexIndicesAllocation); 735 } 736 else 737 DE_ASSERT(m_vertexIndices.empty()); 738} 739 740void MultiViewRenderTestInstance::createMultiViewDevices (void) 741{ 742 const auto& instanceDriver = m_context.getInstanceInterface(); 743 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 744 const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice); 745 746 for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex) 747 { 748 if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) 749 break; 750 } 751 752 const float queuePriorities = 1.0f; 753 const VkDeviceQueueCreateInfo queueInfo = 754 { 755 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //VkStructureType sType; 756 DE_NULL, //const void* pNext; 757 (VkDeviceQueueCreateFlags)0u, //VkDeviceQueueCreateFlags flags; 758 m_queueFamilyIndex, //deUint32 queueFamilyIndex; 759 1u, //deUint32 queueCount; 760 &queuePriorities //const float* pQueuePriorities; 761 }; 762 763#ifndef CTS_USES_VULKANSC 764 VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = 765 { 766 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, // VkStructureType sType; 767 DE_NULL, // void* pNext; 768 DE_FALSE, // VkBool32 dynamicRendering 769 }; 770#endif // CTS_USES_VULKANSC 771 772 VkPhysicalDeviceMultiviewFeatures multiviewFeatures = 773 { 774 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, // VkStructureType sType; 775#ifndef CTS_USES_VULKANSC 776 &dynamicRenderingFeatures, // void* pNext; 777#else 778 DE_NULL, // void* pNext; 779#endif // CTS_USES_VULKANSC 780 DE_FALSE, // VkBool32 multiview; 781 DE_FALSE, // VkBool32 multiviewGeometryShader; 782 DE_FALSE, // VkBool32 multiviewTessellationShader; 783 }; 784 785 VkPhysicalDeviceFeatures2 enabledFeatures; 786 enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 787 enabledFeatures.pNext = &multiviewFeatures; 788 789 instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures); 790 791 if (!multiviewFeatures.multiview) 792 TCU_THROW(NotSupportedError, "MultiView not supported"); 793 794 if (m_parameters.geometryShaderNeeded() && !multiviewFeatures.multiviewGeometryShader) 795 TCU_THROW(NotSupportedError, "Geometry shader is not supported"); 796 797 if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader) 798 TCU_THROW(NotSupportedError, "Tessellation shader is not supported"); 799 800 VkPhysicalDeviceMultiviewProperties multiviewProperties = 801 { 802 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, //VkStructureType sType; 803 DE_NULL, //void* pNext; 804 0u, //deUint32 maxMultiviewViewCount; 805 0u //deUint32 maxMultiviewInstanceIndex; 806 }; 807 808 VkPhysicalDeviceProperties2 propertiesDeviceProperties2; 809 propertiesDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 810 propertiesDeviceProperties2.pNext = &multiviewProperties; 811 812 instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2); 813 814#ifndef CTS_USES_VULKANSC 815 if (multiviewProperties.maxMultiviewViewCount < 6u) 816 TCU_FAIL("maxMultiviewViewCount below min value"); 817#endif // CTS_USES_VULKANSC 818 819 if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1 820 TCU_FAIL("maxMultiviewInstanceIndex below min value"); 821 822 if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth) 823 TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test"); 824 825 m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect; 826 827 { 828 vector<const char*> deviceExtensions; 829 830 if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview")) 831 deviceExtensions.push_back("VK_KHR_multiview"); 832 833 if ((m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2) && 834 !isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2")) 835 deviceExtensions.push_back("VK_KHR_create_renderpass2"); 836 if ((m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) && 837 !isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_dynamic_rendering")) 838 deviceExtensions.push_back("VK_KHR_dynamic_rendering"); 839 840 if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES) 841 deviceExtensions.push_back("VK_EXT_depth_range_unrestricted"); 842 843 void* pNext = &enabledFeatures; 844#ifdef CTS_USES_VULKANSC 845 VkDeviceObjectReservationCreateInfo memReservationInfo = m_context.getTestContext().getCommandLine().isSubProcess() ? m_context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo(); 846 memReservationInfo.pNext = pNext; 847 pNext = &memReservationInfo; 848 849 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features(); 850 sc10Features.pNext = pNext; 851 pNext = &sc10Features; 852 853 VkPipelineCacheCreateInfo pcCI; 854 std::vector<VkPipelinePoolSize> poolSizes; 855 if (m_context.getTestContext().getCommandLine().isSubProcess()) 856 { 857 if (m_context.getResourceInterface()->getCacheDataSize() > 0) 858 { 859 pcCI = 860 { 861 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; 862 DE_NULL, // const void* pNext; 863 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | 864 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags; 865 m_context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize; 866 m_context.getResourceInterface()->getCacheData() // const void* pInitialData; 867 }; 868 memReservationInfo.pipelineCacheCreateInfoCount = 1; 869 memReservationInfo.pPipelineCacheCreateInfos = &pcCI; 870 } 871 872 poolSizes = m_context.getResourceInterface()->getPipelinePoolSizes(); 873 if (!poolSizes.empty()) 874 { 875 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size()); 876 memReservationInfo.pPipelinePoolSizes = poolSizes.data(); 877 } 878 } 879#endif // CTS_USES_VULKANSC 880 881 const VkDeviceCreateInfo deviceInfo = 882 { 883 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //VkStructureType sType; 884 pNext, //const void* pNext; 885 0u, //VkDeviceCreateFlags flags; 886 1u, //deUint32 queueCreateInfoCount; 887 &queueInfo, //const VkDeviceQueueCreateInfo* pQueueCreateInfos; 888 0u, //deUint32 enabledLayerCount; 889 DE_NULL, //const char* const* ppEnabledLayerNames; 890 static_cast<deUint32>(deviceExtensions.size()), //deUint32 enabledExtensionCount; 891 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0], //const char* const* pEnabledExtensionNames; 892 DE_NULL //const VkPhysicalDeviceFeatures* pEnabledFeatures; 893 }; 894 895 const auto instance = m_context.getInstance(); 896 897 m_logicalDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), instance, instanceDriver, physicalDevice, &deviceInfo); 898#ifndef CTS_USES_VULKANSC 899 m_device = de::MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), instance, *m_logicalDevice, m_context.getUsedApiVersion())); 900#else 901 m_device = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(m_context.getPlatformInterface(), instance, *m_logicalDevice, m_context.getTestContext().getCommandLine(), m_context.getResourceInterface(), m_context.getDeviceVulkanSC10Properties(), m_context.getDeviceProperties(), m_context.getUsedApiVersion()), vk::DeinitDeviceDeleter(m_context.getResourceInterface().get(), *m_logicalDevice)); 902#endif // CTS_USES_VULKANSC 903 m_allocator = MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instanceDriver, physicalDevice))); 904 m_device->getDeviceQueue (*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue); 905 } 906} 907 908void MultiViewRenderTestInstance::createCommandBuffer (void) 909{ 910 // cmdPool 911 { 912 const VkCommandPoolCreateInfo cmdPoolParams = 913 { 914 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 915 DE_NULL, // const void* pNext; 916 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCmdPoolCreateFlags flags; 917 m_queueFamilyIndex, // deUint32 queueFamilyIndex; 918 }; 919 m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams); 920 } 921 922 // cmdBuffer 923 { 924 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 925 { 926 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 927 DE_NULL, // const void* pNext; 928 *m_cmdPool, // VkCommandPool commandPool; 929 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 930 1u, // deUint32 bufferCount; 931 }; 932 m_cmdBuffer = allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo); 933 } 934} 935 936void MultiViewRenderTestInstance::createSecondaryCommandPool(void) 937{ 938 // cmdPool 939 { 940 const VkCommandPoolCreateInfo cmdPoolParams = 941 { 942 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 943 DE_NULL, // const void* pNext; 944 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCmdPoolCreateFlags flags; 945 m_queueFamilyIndex, // deUint32 queueFamilyIndex; 946 }; 947 m_cmdPoolSecondary = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams); 948 } 949} 950 951void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams) 952{ 953 // create shaders modules 954 switch (m_parameters.viewIndex) 955 { 956 case TEST_TYPE_VIEW_MASK: 957 case TEST_TYPE_VIEW_INDEX_IN_VERTEX: 958 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: 959 case TEST_TYPE_INSTANCED_RENDERING: 960 case TEST_TYPE_INPUT_RATE_INSTANCE: 961 case TEST_TYPE_DRAW_INDIRECT: 962 case TEST_TYPE_DRAW_INDIRECT_INDEXED: 963 case TEST_TYPE_DRAW_INDEXED: 964 case TEST_TYPE_CLEAR_ATTACHMENTS: 965 case TEST_TYPE_SECONDARY_CMD_BUFFER: 966 case TEST_TYPE_INPUT_ATTACHMENTS: 967 case TEST_TYPE_POINT_SIZE: 968 case TEST_TYPE_MULTISAMPLE: 969 case TEST_TYPE_QUERIES: 970 case TEST_TYPE_NON_PRECISE_QUERIES: 971 case TEST_TYPE_NON_PRECISE_QUERIES_WITH_AVAILABILITY: 972 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR: 973 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR: 974 case TEST_TYPE_DEPTH: 975 case TEST_TYPE_DEPTH_DIFFERENT_RANGES: 976 case TEST_TYPE_STENCIL: 977 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 978 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 979 break; 980 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: 981 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY: 982 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY: 983 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 984 shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0)))); 985 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 986 break; 987 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: 988 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0)))); 989 shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0)))); 990 shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0)))); 991 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0)))); 992 break; 993 case TEST_TYPE_VIEW_MASK_ITERATION: 994 { 995 const auto vk12Support = m_context.contextSupports(vk::ApiVersion(0u, 1u, 2u, 0u)); 996 const auto vertShaderName = vk12Support ? "vert-spv15" : "vert-spv10"; 997 shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get(vertShaderName), 0)))); 998 shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("view_mask_iteration"), 0)))); 999 break; 1000 } 1001 default: 1002 DE_ASSERT(0); 1003 break; 1004 } 1005 1006 VkPipelineShaderStageCreateInfo pipelineShaderStage = 1007 { 1008 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1009 DE_NULL, // const void* pNext; 1010 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1011 (VkShaderStageFlagBits)0, // VkShaderStageFlagBits stage; 1012 (VkShaderModule)0, // VkShaderModule module; 1013 "main", // const char* pName; 1014 (const VkSpecializationInfo*)DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 1015 }; 1016 1017 for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it) 1018 { 1019 pipelineShaderStage.stage = it->first; 1020 pipelineShaderStage.module = **it->second; 1021 shaderStageParams.push_back(pipelineShaderStage); 1022 } 1023} 1024 1025Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass renderPass, 1026 const VkPipelineLayout pipelineLayout, 1027 const deUint32 pipelineShaderStageCount, 1028 const VkPipelineShaderStageCreateInfo* pipelineShaderStageCreate, 1029 const deUint32 subpass, 1030 const VkVertexInputRate vertexInputRate, 1031 const bool useDepthTest, 1032 const bool useStencilTest, 1033 const float minDepth, 1034 const float maxDepth, 1035 const VkFormat dsFormat) 1036{ 1037 const VkVertexInputBindingDescription vertexInputBindingDescriptions[] = 1038 { 1039 { 1040 0u, // binding; 1041 static_cast<deUint32>(sizeof(m_vertexCoord[0])), // stride; 1042 vertexInputRate // inputRate 1043 }, 1044 { 1045 1u, // binding; 1046 static_cast<deUint32>(sizeof(m_vertexColor[0])), // stride; 1047 vertexInputRate // inputRate 1048 } 1049 }; 1050 1051 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = 1052 { 1053 { 1054 0u, // deUint32 location; 1055 0u, // deUint32 binding; 1056 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1057 0u // deUint32 offset; 1058 }, // VertexElementData::position 1059 { 1060 1u, // deUint32 location; 1061 1u, // deUint32 binding; 1062 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1063 0u // deUint32 offset; 1064 }, // VertexElementData::color 1065 }; 1066 1067 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1068 { 1069 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1070 NULL, // const void* pNext; 1071 0u, // VkPipelineVertexInputStateCreateFlags flags; 1072 DE_LENGTH_OF_ARRAY(vertexInputBindingDescriptions), // deUint32 vertexBindingDescriptionCount; 1073 vertexInputBindingDescriptions, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1074 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // deUint32 vertexAttributeDescriptionCount; 1075 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1076 }; 1077 1078 const VkPrimitiveTopology topology = (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : 1079 (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : 1080 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 1081 1082 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1083 { 1084 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1085 DE_NULL, // const void* pNext; 1086 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 1087 topology, // VkPrimitiveTopology topology; 1088 VK_FALSE, // VkBool32 primitiveRestartEnable; 1089 }; 1090 1091 const VkViewport viewport = makeViewport(0.0f, 0.0f, (float)m_parameters.extent.width, (float)m_parameters.extent.height, minDepth, maxDepth); 1092 const VkRect2D scissor = makeRect2D(m_parameters.extent); 1093 1094 const VkPipelineViewportStateCreateInfo viewportStateParams = 1095 { 1096 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1097 DE_NULL, // const void* pNext; 1098 0u, // VkPipelineViewportStateCreateFlags flags; 1099 1u, // deUint32 viewportCount; 1100 &viewport, // const VkViewport* pViewports; 1101 1u, // deUint32 scissorCount; 1102 &scissor // const VkRect2D* pScissors; 1103 }; 1104 1105 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1106 { 1107 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1108 DE_NULL, // const void* pNext; 1109 0u, // VkPipelineRasterizationStateCreateFlags flags; 1110 VK_FALSE, // VkBool32 depthClampEnable; 1111 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 1112 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 1113 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 1114 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1115 VK_FALSE, // VkBool32 depthBiasEnable; 1116 0.0f, // float depthBiasConstantFactor; 1117 0.0f, // float depthBiasClamp; 1118 0.0f, // float depthBiasSlopeFactor; 1119 1.0f, // float lineWidth; 1120 }; 1121 1122 const VkSampleCountFlagBits sampleCountFlagBits = (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) ? VK_SAMPLE_COUNT_4_BIT : 1123 VK_SAMPLE_COUNT_1_BIT; 1124 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1125 { 1126 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1127 DE_NULL, // const void* pNext; 1128 0u, // VkPipelineMultisampleStateCreateFlags flags; 1129 sampleCountFlagBits, // VkSampleCountFlagBits rasterizationSamples; 1130 VK_FALSE, // VkBool32 sampleShadingEnable; 1131 0.0f, // float minSampleShading; 1132 DE_NULL, // const VkSampleMask* pSampleMask; 1133 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1134 VK_FALSE, // VkBool32 alphaToOneEnable; 1135 }; 1136 1137 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 1138 { 1139 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 1140 DE_NULL, // const void* pNext; 1141 0u, // VkPipelineDepthStencilStateCreateFlags flags; 1142 useDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable; 1143 useDepthTest ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable; 1144 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp; 1145 VK_FALSE, // VkBool32 depthBoundsTestEnable; 1146 useStencilTest ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable; 1147 // VkStencilOpState front; 1148 { 1149 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 1150 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; 1151 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 1152 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 1153 ~0u, // deUint32 compareMask; 1154 ~0u, // deUint32 writeMask; 1155 0u, // deUint32 reference; 1156 }, 1157 // VkStencilOpState back; 1158 { 1159 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 1160 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; 1161 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 1162 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 1163 ~0u, // deUint32 compareMask; 1164 ~0u, // deUint32 writeMask; 1165 0u, // deUint32 reference; 1166 }, 1167 0.0f, // float minDepthBounds; 1168 1.0f, // float maxDepthBounds; 1169 }; 1170 1171 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 1172 { 1173 VK_FALSE, // VkBool32 blendEnable; 1174 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 1175 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 1176 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 1177 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 1178 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 1179 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 1180 VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask; 1181 VK_COLOR_COMPONENT_G_BIT | 1182 VK_COLOR_COMPONENT_B_BIT | 1183 VK_COLOR_COMPONENT_A_BIT 1184 }; 1185 1186 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1187 { 1188 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1189 DE_NULL, // const void* pNext; 1190 0u, // VkPipelineColorBlendStateCreateFlags flags; 1191 VK_FALSE, // VkBool32 logicOpEnable; 1192 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1193 1u, // deUint32 attachmentCount; 1194 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1195 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1196 }; 1197 1198 VkPipelineTessellationStateCreateInfo TessellationState = 1199 { 1200 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 1201 DE_NULL, // const void* pNext; 1202 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 1203 4u // deUint32 patchControlPoints; 1204 }; 1205 1206#ifndef CTS_USES_VULKANSC 1207 VkPipelineRenderingCreateInfoKHR renderingCreateInfo 1208 { 1209 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, 1210 DE_NULL, 1211 m_parameters.viewMasks[subpass], 1212 1u, 1213 &m_parameters.colorFormat, 1214 dsFormat, 1215 dsFormat 1216 }; 1217#else 1218 DE_UNREF(dsFormat); 1219#endif // CTS_USES_VULKANSC 1220 1221 const VkGraphicsPipelineCreateInfo graphicsPipelineParams 1222 { 1223 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1224#ifndef CTS_USES_VULKANSC 1225 (renderPass == 0) ? &renderingCreateInfo : DE_NULL, // const void* pNext; 1226#else 1227 DE_NULL, // const void* pNext; 1228#endif // CTS_USES_VULKANSC 1229 (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags; 1230 pipelineShaderStageCount, // deUint32 stageCount; 1231 pipelineShaderStageCreate, // const VkPipelineShaderStageCreateInfo* pStages; 1232 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1233 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1234 (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1235 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1236 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterState; 1237 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1238 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1239 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1240 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1241 pipelineLayout, // VkPipelineLayout layout; 1242 renderPass, // VkRenderPass renderPass; 1243 subpass, // deUint32 subpass; 1244 0u, // VkPipeline basePipelineHandle; 1245 0, // deInt32 basePipelineIndex; 1246 }; 1247 1248 return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams); 1249} 1250 1251void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst) 1252{ 1253 Move<VkBuffer> buffer; 1254 MovePtr<Allocation> bufferAlloc; 1255 const VkDeviceSize pixelDataSize = dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_parameters.colorFormat).getPixelSize(); 1256 1257 // Create destination buffer 1258 { 1259 const VkBufferCreateInfo bufferParams = 1260 { 1261 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1262 DE_NULL, // const void* pNext; 1263 0u, // VkBufferCreateFlags flags; 1264 pixelDataSize, // VkDeviceSize size; 1265 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1266 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1267 1u, // deUint32 queueFamilyIndexCount; 1268 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1269 }; 1270 1271 buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); 1272 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); 1273 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1274 1275 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize)); 1276 flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc); 1277 } 1278 1279 const VkBufferMemoryBarrier bufferBarrier = 1280 { 1281 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1282 DE_NULL, // const void* pNext; 1283 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1284 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1285 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1286 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1287 *buffer, // VkBuffer buffer; 1288 0u, // VkDeviceSize offset; 1289 pixelDataSize // VkDeviceSize size; 1290 }; 1291 1292 // Copy image to buffer 1293 const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); 1294 const VkBufferImageCopy copyRegion = 1295 { 1296 0u, // VkDeviceSize bufferOffset; 1297 (deUint32)dst.getWidth(), // deUint32 bufferRowLength; 1298 (deUint32)dst.getHeight(), // deUint32 bufferImageHeight; 1299 { 1300 aspect, // VkImageAspectFlags aspect; 1301 0u, // deUint32 mipLevel; 1302 0u, // deUint32 baseArrayLayer; 1303 m_parameters.extent.depth, // deUint32 layerCount; 1304 }, // VkImageSubresourceLayers imageSubresource; 1305 { 0, 0, 0 }, // VkOffset3D imageOffset; 1306 { m_parameters.extent.width, m_parameters.extent.height, 1u } // VkExtent3D imageExtent; 1307 }; 1308 1309 beginCommandBuffer (*m_device, *m_cmdBuffer); 1310 { 1311 VkImageSubresourceRange subresourceRange = 1312 { 1313 aspect, // VkImageAspectFlags aspectMask; 1314 0u, // deUint32 baseMipLevel; 1315 1u, // deUint32 mipLevels; 1316 0u, // deUint32 baseArraySlice; 1317 m_parameters.extent.depth, // deUint32 arraySize; 1318 }; 1319 1320 imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange, 1321 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1322 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1323 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 1324 1325 m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); 1326 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); 1327 } 1328 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1329 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1330 1331 // Read buffer data 1332 invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc); 1333 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); 1334} 1335 1336bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame) 1337{ 1338 const MovePtr<tcu::Texture2DArray> referenceFrame = imageData(); 1339 const bool result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), 1340 "Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING); 1341 1342 if (!result) 1343 for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++) 1344 { 1345 tcu::ConstPixelBufferAccess ref (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx)); 1346 tcu::ConstPixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx)); 1347 tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING); 1348 } 1349 1350 return result; 1351} 1352 1353const tcu::Vec4 MultiViewRenderTestInstance::getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background, const deUint32 subpassNdx) const 1354{ 1355 // this function is used for genrating same colors while rendering and while creating reference 1356 1357 switch (m_parameters.viewIndex) 1358 { 1359 case TEST_TYPE_VIEW_MASK: 1360 case TEST_TYPE_VIEW_MASK_ITERATION: 1361 return m_vertexColor[colorNdx]; 1362 1363 case TEST_TYPE_DRAW_INDEXED: 1364 return m_vertexColor[m_vertexIndices[colorNdx]]; 1365 1366 case TEST_TYPE_INSTANCED_RENDERING: 1367 return m_vertexColor[0] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0); 1368 1369 case TEST_TYPE_INPUT_RATE_INSTANCE: 1370 return m_vertexColor[colorNdx / 4] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0); 1371 1372 case TEST_TYPE_DRAW_INDIRECT_INDEXED: 1373 return m_vertexColor[m_vertexIndices[colorNdx]] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 1374 1375 case TEST_TYPE_VIEW_INDEX_IN_VERTEX: 1376 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: 1377 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: 1378 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: 1379 case TEST_TYPE_INPUT_ATTACHMENTS: 1380 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY: 1381 case TEST_TYPE_DRAW_INDIRECT: 1382 case TEST_TYPE_CLEAR_ATTACHMENTS: 1383 case TEST_TYPE_SECONDARY_CMD_BUFFER: 1384 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY: 1385 return m_vertexColor[colorNdx] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0); 1386 1387 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR: 1388 if (background) 1389 return m_colorTable[4 + quarterNdx % 4]; 1390 else 1391 return m_colorTable[layerNdx % 4]; 1392 1393 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR: 1394 if (background) 1395 return m_colorTable[4 + quarterNdx % 4]; 1396 else 1397 return m_colorTable[0]; 1398 1399 case TEST_TYPE_POINT_SIZE: 1400 case TEST_TYPE_MULTISAMPLE: 1401 if (background) 1402 return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f); 1403 else 1404 return m_vertexColor[colorNdx]; 1405 1406 case TEST_TYPE_DEPTH: 1407 if (background) 1408 if (subpassNdx < 4) 1409 return tcu::Vec4(0.66f, 0.0f, 0.0f, 1.0f); 1410 else 1411 return tcu::Vec4(0.33f, 0.0f, 0.0f, 1.0f); 1412 else 1413 return tcu::Vec4(0.99f, 0.0f, 0.0f, 1.0f); 1414 1415 case TEST_TYPE_DEPTH_DIFFERENT_RANGES: 1416 // for quads from partA generate 1.20, 0.90, 0.60, 0.30 1417 // for quads from partB generate 0.55, 0.35, 0.15, -0.05 1418 // depth ranges in views are <0;0.5>, <0;1> or <0.5;1> so 1419 // at least one quad from partA/partB will always be drawn 1420 if (subpassNdx < 4) 1421 return tcu::Vec4(1.2f - 0.3f * static_cast<float>(subpassNdx), 0.0f, 0.0f, 1.0f); 1422 return tcu::Vec4(0.55f - 0.2f * static_cast<float>(subpassNdx % 4), 0.0f, 0.0f, 1.0f); 1423 1424 case TEST_TYPE_STENCIL: 1425 if (background) 1426 return tcu::Vec4(0.33f, 0.0f, 0.0f, 0.0f); // Increment value 1427 else 1428 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 1429 1430 default: 1431 TCU_THROW(InternalError, "Impossible"); 1432 } 1433} 1434 1435void MultiViewRenderTestInstance::setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const 1436{ 1437 DE_ASSERT(TEST_POINT_SIZE_WIDE > TEST_POINT_SIZE_SMALL); 1438 1439 const int pointOffset = 1 + TEST_POINT_SIZE_WIDE / 2 - (pointSize + 1) / 2; 1440 const int offsetX = pointOffset + static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u); 1441 const int offsetY = pointOffset + static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u); 1442 1443 for (int y = 0; y < pointSize; ++y) 1444 for (int x = 0; x < pointSize; ++x) 1445 pixelBuffer.setPixel(pointColor, offsetX + x, offsetY + y, layerNdx); 1446} 1447 1448void MultiViewRenderTestInstance::fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const 1449{ 1450 const int offsetX = static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u); 1451 const int offsetY = static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u); 1452 const int maxY = static_cast<int>(m_parameters.extent.height / 2u); 1453 const tcu::Vec4 multisampledColor = tcu::Vec4(color[0], color[1], color[2], color[3]) * 0.5f; 1454 1455 for (int y = 0; y < maxY; ++y) 1456 { 1457 for (int x = 0; x < y; ++x) 1458 pixelBuffer.setPixel(color, offsetX + x, offsetY + (maxY - 1) - y, layerNdx); 1459 1460 // Multisampled pixel is on the triangle margin 1461 pixelBuffer.setPixel(multisampledColor, offsetX + y, offsetY + (maxY - 1) - y, layerNdx); 1462 } 1463} 1464 1465void MultiViewRenderTestInstance::fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const 1466{ 1467 for (deUint32 y = 0u; y < m_parameters.extent.height; ++y) 1468 for (deUint32 x = 0u; x < m_parameters.extent.width; ++x) 1469 pixelBuffer.setPixel(color, x, y, layerNdx); 1470} 1471 1472void MultiViewRenderTestInstance::fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const 1473{ 1474 const int h = m_parameters.extent.height; 1475 const int h2 = h / 2; 1476 const int w = m_parameters.extent.width; 1477 const int w2 = w / 2; 1478 int xStart = 0; 1479 int xEnd = 0; 1480 int yStart = 0; 1481 int yEnd = 0; 1482 1483 switch (quarter) 1484 { 1485 case 0: xStart = 0u; xEnd = w2; yStart = 0u; yEnd = h2; break; 1486 case 1: xStart = 0u; xEnd = w2; yStart = h2; yEnd = h; break; 1487 case 2: xStart = w2; xEnd = w; yStart = 0u; yEnd = h2; break; 1488 case 3: xStart = w2; xEnd = w; yStart = h2; yEnd = h; break; 1489 default: TCU_THROW(InternalError, "Impossible"); 1490 } 1491 1492 if (TEST_TYPE_STENCIL == m_parameters.viewIndex || 1493 TEST_TYPE_DEPTH == m_parameters.viewIndex || 1494 TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex) 1495 { 1496 if (subpassNdx < 4) 1497 { // Part A: Horizontal bars near X axis 1498 yStart = h2 + (yStart - h2) / 2; 1499 yEnd = h2 + (yEnd - h2) / 2; 1500 } 1501 else 1502 { // Part B: Vertical bars near Y axis (drawn twice) 1503 xStart = w2 + (xStart - w2) / 2; 1504 xEnd = w2 + (xEnd - w2) / 2; 1505 } 1506 1507 // Update pixels in area 1508 if (TEST_TYPE_STENCIL == m_parameters.viewIndex) 1509 { 1510 for (int y = yStart; y < yEnd; ++y) 1511 for (int x = xStart; x < xEnd; ++x) 1512 pixelBuffer.setPixel(pixelBuffer.getPixel(x, y, layerNdx) + color, x, y, layerNdx); 1513 } 1514 1515 if (TEST_TYPE_DEPTH == m_parameters.viewIndex || 1516 TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex) 1517 { 1518 for (int y = yStart; y < yEnd; ++y) 1519 for (int x = xStart; x < xEnd; ++x) 1520 { 1521 const tcu::Vec4 currentColor = pixelBuffer.getPixel(x, y, layerNdx); 1522 const tcu::Vec4& newColor = (currentColor[0] < color[0]) ? currentColor : color; 1523 1524 pixelBuffer.setPixel(newColor, x, y, layerNdx); 1525 } 1526 } 1527 } 1528 else 1529 { 1530 for (int y = yStart; y < yEnd; ++y) 1531 for (int x = xStart; x < xEnd; ++x) 1532 pixelBuffer.setPixel(color , x, y, layerNdx); 1533 } 1534} 1535 1536MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void) const 1537{ 1538 MovePtr<tcu::Texture2DArray> referenceFrame = MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth)); 1539 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 1540 referenceFrame->allocLevel(0); 1541 1542 deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize()); 1543 1544 if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex) 1545 { 1546 deUint32 clearedViewMask = 0; 1547 1548 // Start from last clear command color, which actually takes effect 1549 for (int subpassNdx = static_cast<int>(subpassCount) - 1; subpassNdx >= 0; --subpassNdx) 1550 { 1551 deUint32 subpassToClearViewMask = m_parameters.viewMasks[subpassNdx] & ~clearedViewMask; 1552 1553 if (subpassToClearViewMask == 0) 1554 continue; 1555 1556 for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx) 1557 if ((subpassToClearViewMask & (1 << layerNdx)) != 0 && (clearedViewMask & (1 << layerNdx)) == 0) 1558 fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, subpassNdx, false), layerNdx); 1559 1560 // These has been cleared. Exclude these layers from upcoming attempts to clear 1561 clearedViewMask |= subpassToClearViewMask; 1562 } 1563 } 1564 1565 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1566 { 1567 int layerNdx = 0; 1568 deUint32 mask = m_parameters.viewMasks[subpassNdx]; 1569 1570 // iterate over image layers 1571 while (mask > 0u) 1572 { 1573 int colorNdx = 0; 1574 1575 if (mask & 1u) 1576 { 1577 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 1578 { 1579 struct ColorDataRGBA 1580 { 1581 deUint8 r; 1582 deUint8 g; 1583 deUint8 b; 1584 deUint8 a; 1585 }; 1586 1587 ColorDataRGBA clear = 1588 { 1589 tcu::floatToU8 (1.0f), 1590 tcu::floatToU8 (0.0f), 1591 tcu::floatToU8 (0.0f), 1592 tcu::floatToU8 (1.0f) 1593 }; 1594 1595 ColorDataRGBA* dataSrc = (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx); 1596 ColorDataRGBA* dataDes = dataSrc + 1; 1597 deUint32 copySize = 1u; 1598 deUint32 layerSize = m_parameters.extent.width * m_parameters.extent.height - copySize; 1599 deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA)); 1600 1601 while (layerSize > 0) 1602 { 1603 deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA)); 1604 dataDes = dataDes + copySize; 1605 layerSize = layerSize - copySize; 1606 copySize = 2u * copySize; 1607 if (copySize >= layerSize) 1608 copySize = layerSize; 1609 } 1610 } 1611 1612 const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount; 1613 if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1614 { 1615 const tcu::Vec4 color = getQuarterRefColor(0u, colorNdx, layerNdx, true, subpassNdx); 1616 1617 fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 0u, subpassNdx); 1618 } 1619 1620 colorNdx += 4; 1621 if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1622 { 1623 const tcu::Vec4 color = getQuarterRefColor(1u, colorNdx, layerNdx, true, subpassNdx); 1624 1625 fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 1u, subpassNdx); 1626 } 1627 1628 colorNdx += 4; 1629 if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1630 { 1631 const tcu::Vec4 color = getQuarterRefColor(2u, colorNdx, layerNdx, true, subpassNdx); 1632 1633 fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 2u, subpassNdx); 1634 } 1635 1636 colorNdx += 4; 1637 if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 1638 { 1639 const tcu::Vec4 color = getQuarterRefColor(3u, colorNdx, layerNdx, true, subpassNdx); 1640 1641 fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 3u, subpassNdx); 1642 } 1643 1644 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 1645 { 1646 const tcu::Vec4 color (0.0f, 0.0f, 1.0f, 1.0f); 1647 const int maxY = static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f); 1648 const int maxX = static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f); 1649 for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y) 1650 for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x) 1651 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx); 1652 } 1653 1654 if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) 1655 { 1656 const deUint32 vertexPerPrimitive = 1u; 1657 const deUint32 unusedQuarterNdx = 0u; 1658 const int pointSize = static_cast<int>(layerNdx == 0u ? TEST_POINT_SIZE_WIDE : TEST_POINT_SIZE_SMALL); 1659 1660 if (subpassCount == 1) 1661 for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx) 1662 setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), pointSize, layerNdx, drawNdx); 1663 else 1664 setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), pointSize, layerNdx, subpassQuarterNdx); 1665 } 1666 1667 if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) 1668 { 1669 const deUint32 vertexPerPrimitive = 3u; 1670 const deUint32 unusedQuarterNdx = 0u; 1671 1672 if (subpassCount == 1) 1673 for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx) 1674 fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), layerNdx, drawNdx); 1675 else 1676 fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), layerNdx, subpassQuarterNdx); 1677 } 1678 } 1679 1680 mask = mask >> 1; 1681 ++layerNdx; 1682 } 1683 } 1684 return referenceFrame; 1685} 1686 1687void MultiViewRenderTestInstance::appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color) 1688{ 1689 m_vertexCoord.push_back(coord); 1690 m_vertexColor.push_back(color); 1691} 1692 1693class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance 1694{ 1695public: 1696 MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters); 1697protected: 1698 tcu::TestStatus iterate (void) override; 1699 void beforeRenderPass (void) override; 1700 void bindResources (void) override; 1701 void setImageData (VkImage image); 1702 de::SharedPtr<ImageAttachment> m_inputAttachment; 1703 Move<VkDescriptorPool> m_descriptorPool; 1704 Move<VkDescriptorSet> m_descriptorSet; 1705 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1706 Move<VkPipelineLayout> m_pipelineLayout; 1707 1708}; 1709 1710MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters) 1711 : MultiViewRenderTestInstance (context, parameters) 1712{ 1713} 1714 1715tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void) 1716{ 1717 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 1718 Move<VkRenderPass> renderPass; 1719 Move<VkFramebuffer> frameBuffer; 1720 1721 // All color attachment 1722 m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat)); 1723 m_inputAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat)); 1724 1725 // FrameBuffer & renderPass 1726 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 1727 { 1728 vector<VkImageView> attachments 1729 { 1730 m_colorAttachment->getImageView(), 1731 m_inputAttachment->getImageView() 1732 }; 1733 renderPass = makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType); 1734 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height); 1735 } 1736 1737 // pipelineLayout 1738 m_descriptorSetLayout = makeDescriptorSetLayout(*m_device, *m_logicalDevice); 1739 m_pipelineLayout = makePipelineLayout(*m_device, *m_logicalDevice, m_descriptorSetLayout.get()); 1740 1741 // pipelines 1742 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 1743 vector<PipelineSp> pipelines(subpassCount); 1744 1745 { 1746 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 1747 madeShaderModule(shaderModule, shaderStageParams); 1748 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 1749 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx)))); 1750 } 1751 1752 createVertexData(); 1753 createVertexBuffer(); 1754 1755 createCommandBuffer(); 1756 setImageData(m_inputAttachment->getImage()); 1757 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 1758 1759 { 1760 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); 1761 tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 1762 1763 readImage (m_colorAttachment->getImage(), dst); 1764 if (!checkImage(dst)) 1765 return tcu::TestStatus::fail("Fail"); 1766 } 1767 1768 return tcu::TestStatus::pass("Pass"); 1769} 1770 1771void MultiViewAttachmentsTestInstance::beforeRenderPass (void) 1772{ 1773 const VkDescriptorPoolSize poolSize = 1774 { 1775 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1776 1u 1777 }; 1778 1779 const VkDescriptorPoolCreateInfo createInfo = 1780 { 1781 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 1782 DE_NULL, 1783 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1784 1u, 1785 1u, 1786 &poolSize 1787 }; 1788 1789 m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo); 1790 1791 const VkDescriptorSetAllocateInfo allocateInfo = 1792 { 1793 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1794 DE_NULL, 1795 *m_descriptorPool, 1796 1u, 1797 &m_descriptorSetLayout.get() 1798 }; 1799 1800 m_descriptorSet = vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo); 1801 1802 const VkDescriptorImageInfo imageInfo = 1803 { 1804 (VkSampler)0, 1805 m_inputAttachment->getImageView(), 1806 VK_IMAGE_LAYOUT_GENERAL 1807 }; 1808 1809 const VkWriteDescriptorSet write = 1810 { 1811 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, //VkStructureType sType; 1812 DE_NULL, //const void* pNext; 1813 *m_descriptorSet, //VkDescriptorSet dstSet; 1814 0u, //deUint32 dstBinding; 1815 0u, //deUint32 dstArrayElement; 1816 1u, //deUint32 descriptorCount; 1817 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, //VkDescriptorType descriptorType; 1818 &imageInfo, //const VkDescriptorImageInfo* pImageInfo; 1819 DE_NULL, //const VkDescriptorBufferInfo* pBufferInfo; 1820 DE_NULL, //const VkBufferView* pTexelBufferView; 1821 }; 1822 1823 m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL); 1824 1825 const VkImageSubresourceRange subresourceRange = 1826 { 1827 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask; 1828 0u, //deUint32 baseMipLevel; 1829 1u, //deUint32 levelCount; 1830 0u, //deUint32 baseArrayLayer; 1831 m_parameters.extent.depth, //deUint32 layerCount; 1832 }; 1833 1834 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 1835 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1836 0, VK_ACCESS_TRANSFER_WRITE_BIT, 1837 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 1838 1839 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1840 m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange); 1841 1842 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 1843 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1844 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 1845 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 1846} 1847 1848void MultiViewAttachmentsTestInstance::bindResources (void) 1849{ 1850 m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL); 1851} 1852 1853void MultiViewAttachmentsTestInstance::setImageData (VkImage image) 1854{ 1855 const MovePtr<tcu::Texture2DArray> data = imageData(); 1856 Move<VkBuffer> buffer; 1857 const deUint32 bufferSize = m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_parameters.colorFormat)); 1858 MovePtr<Allocation> bufferAlloc; 1859 1860 // Create source buffer 1861 { 1862 const VkBufferCreateInfo bufferParams = 1863 { 1864 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1865 DE_NULL, // const void* pNext; 1866 0u, // VkBufferCreateFlags flags; 1867 bufferSize, // VkDeviceSize size; 1868 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1869 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1870 1u, // deUint32 queueFamilyIndexCount; 1871 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1872 }; 1873 1874 buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); 1875 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); 1876 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1877 } 1878 1879 // Barriers for copying buffer to image 1880 const VkBufferMemoryBarrier preBufferBarrier = 1881 { 1882 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1883 DE_NULL, // const void* pNext; 1884 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1885 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1886 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1887 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1888 *buffer, // VkBuffer buffer; 1889 0u, // VkDeviceSize offset; 1890 bufferSize // VkDeviceSize size; 1891 }; 1892 1893 const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(m_parameters.colorFormat)); 1894 VkImageSubresourceRange subresourceRange = 1895 { // VkImageSubresourceRange subresourceRange; 1896 formatAspect, // VkImageAspectFlags aspect; 1897 0u, // deUint32 baseMipLevel; 1898 1u, // deUint32 mipLevels; 1899 0u, // deUint32 baseArraySlice; 1900 m_parameters.extent.depth, // deUint32 arraySize; 1901 }; 1902 1903 const VkBufferImageCopy copyRegion = 1904 { 1905 0u, // VkDeviceSize bufferOffset; 1906 (deUint32)data->getLevel(0).getWidth(), // deUint32 bufferRowLength; 1907 (deUint32)data->getLevel(0).getHeight(), // deUint32 bufferImageHeight; 1908 { 1909 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect; 1910 0u, // deUint32 mipLevel; 1911 0u, // deUint32 baseArrayLayer; 1912 m_parameters.extent.depth, // deUint32 layerCount; 1913 }, // VkImageSubresourceLayers imageSubresource; 1914 { 0, 0, 0 }, // VkOffset3D imageOffset; 1915 {m_parameters.extent.width, m_parameters.extent.height, 1u} // VkExtent3D imageExtent; 1916 }; 1917 1918 // Write buffer data 1919 deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize); 1920 flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc); 1921 1922 beginCommandBuffer(*m_device, *m_cmdBuffer); 1923 1924 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); 1925 imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, 1926 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1927 0u, VK_ACCESS_TRANSFER_WRITE_BIT, 1928 VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 1929 m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); 1930 imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange, 1931 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 1932 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 1933 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 1934 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 1935 1936 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 1937} 1938 1939class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance 1940{ 1941public: 1942 MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters); 1943protected: 1944 void createVertexData (void); 1945 void draw (const deUint32 subpassCount, 1946 VkRenderPass renderPass, 1947 VkFramebuffer frameBuffer, 1948 vector<PipelineSp>& pipelines); 1949}; 1950 1951MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters) 1952 : MultiViewRenderTestInstance (context, parameters) 1953{ 1954} 1955 1956void MultiViewInstancedTestInstance::createVertexData (void) 1957{ 1958 const tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 1959 1960 appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); 1961 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); 1962 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); 1963 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 1964} 1965 1966void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 1967{ 1968 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 1969 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 1970 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 1971 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 1972 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 1973 1974 beginCommandBuffer(*m_device, *m_cmdBuffer); 1975 1976 beforeRenderPass(); 1977 1978 if (!m_useDynamicRendering) 1979 { 1980 const VkRenderPassBeginInfo renderPassBeginInfo = 1981 { 1982 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1983 DE_NULL, // const void* pNext; 1984 renderPass, // VkRenderPass renderPass; 1985 frameBuffer, // VkFramebuffer framebuffer; 1986 renderArea, // VkRect2D renderArea; 1987 1u, // uint32_t clearValueCount; 1988 &renderPassClearValue, // const VkClearValue* pClearValues; 1989 }; 1990 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 1991 } 1992 1993 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 1994 { 1995 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 1996 1997#ifndef CTS_USES_VULKANSC 1998 if (m_useDynamicRendering) 1999 { 2000 addRenderingSubpassDependencyIfRequired(subpassNdx); 2001 2002 beginRendering( 2003 *m_device, 2004 *m_cmdBuffer, 2005 m_colorAttachment->getImageView(), 2006 renderArea, 2007 renderPassClearValue, 2008 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2009 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2010 0u, 2011 m_parameters.extent.depth, 2012 m_parameters.viewMasks[subpassNdx]); 2013 } 2014#endif // CTS_USES_VULKANSC 2015 2016 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2017 2018 m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount); 2019 2020#ifndef CTS_USES_VULKANSC 2021 if (m_useDynamicRendering) 2022 endRendering(*m_device, *m_cmdBuffer); 2023 else 2024#endif // CTS_USES_VULKANSC 2025 if (subpassNdx < subpassCount - 1u) 2026 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2027 } 2028 2029 if (!m_useDynamicRendering) 2030 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2031 2032 afterRenderPass(); 2033 2034 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2035 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2036} 2037 2038class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance 2039{ 2040public: 2041 MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters); 2042protected: 2043 void createVertexData (void); 2044 2045 void draw (const deUint32 subpassCount, 2046 VkRenderPass renderPass, 2047 VkFramebuffer frameBuffer, 2048 vector<PipelineSp>& pipelines); 2049}; 2050 2051MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters) 2052 : MultiViewRenderTestInstance (context, parameters) 2053{ 2054} 2055 2056void MultiViewInputRateInstanceTestInstance::createVertexData (void) 2057{ 2058 appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f)); 2059 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f)); 2060 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f)); 2061 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f)); 2062} 2063 2064void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2065{ 2066 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2067 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2068 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2069 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2070 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2071 2072 beginCommandBuffer(*m_device, *m_cmdBuffer); 2073 2074 beforeRenderPass(); 2075 2076 if (!m_useDynamicRendering) 2077 { 2078 const VkRenderPassBeginInfo renderPassBeginInfo = 2079 { 2080 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2081 DE_NULL, // const void* pNext; 2082 renderPass, // VkRenderPass renderPass; 2083 frameBuffer, // VkFramebuffer framebuffer; 2084 renderArea, // VkRect2D renderArea; 2085 1u, // uint32_t clearValueCount; 2086 &renderPassClearValue, // const VkClearValue* pClearValues; 2087 }; 2088 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2089 } 2090 2091 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2092 { 2093 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2094 2095#ifndef CTS_USES_VULKANSC 2096 if (m_useDynamicRendering) 2097 { 2098 addRenderingSubpassDependencyIfRequired(subpassNdx); 2099 2100 beginRendering( 2101 *m_device, 2102 *m_cmdBuffer, 2103 m_colorAttachment->getImageView(), 2104 renderArea, 2105 renderPassClearValue, 2106 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2107 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2108 0u, 2109 m_parameters.extent.depth, 2110 m_parameters.viewMasks[subpassNdx]); 2111 } 2112#endif // CTS_USES_VULKANSC 2113 2114 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2115 2116 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2117 m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u); 2118 2119#ifndef CTS_USES_VULKANSC 2120 if (m_useDynamicRendering) 2121 endRendering(*m_device, *m_cmdBuffer); 2122 else 2123#endif // CTS_USES_VULKANSC 2124 if (subpassNdx < subpassCount - 1u) 2125 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2126 } 2127 2128 if (!m_useDynamicRendering) 2129 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2130 2131 afterRenderPass(); 2132 2133 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2134 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2135} 2136 2137class MultiViewDrawIndirectTestInstance : public MultiViewRenderTestInstance 2138{ 2139public: 2140 MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters); 2141protected: 2142 2143 void draw (const deUint32 subpassCount, 2144 VkRenderPass renderPass, 2145 VkFramebuffer frameBuffer, 2146 vector<PipelineSp>& pipelines); 2147}; 2148 2149MultiViewDrawIndirectTestInstance::MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters) 2150 : MultiViewRenderTestInstance (context, parameters) 2151{ 2152} 2153 2154void MultiViewDrawIndirectTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2155{ 2156 typedef de::SharedPtr<Unique<VkBuffer> > BufferSP; 2157 typedef de::SharedPtr<UniquePtr<Allocation> > AllocationSP; 2158 2159 const size_t nonCoherentAtomSize = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize); 2160 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2161 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2162 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2163 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2164 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2165 const deUint32 strideInBuffer = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2166 ? static_cast<deUint32>(sizeof(vk::VkDrawIndexedIndirectCommand)) 2167 : static_cast<deUint32>(sizeof(vk::VkDrawIndirectCommand)); 2168 vector< BufferSP > indirectBuffers (subpassCount); 2169 vector< AllocationSP > indirectAllocations (subpassCount); 2170 2171 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2172 { 2173 vector<VkDrawIndirectCommand> drawCommands; 2174 vector<VkDrawIndexedIndirectCommand> drawCommandsIndexed; 2175 2176 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2177 { 2178 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2179 { 2180 const VkDrawIndexedIndirectCommand drawCommandIndexed = 2181 { 2182 4u, // deUint32 indexCount; 2183 1u, // deUint32 instanceCount; 2184 (drawNdx + subpassNdx % m_squareCount) * 4u, // deUint32 firstIndex; 2185 0u, // deInt32 vertexOffset; 2186 0u, // deUint32 firstInstance; 2187 }; 2188 2189 drawCommandsIndexed.push_back(drawCommandIndexed); 2190 } 2191 else 2192 { 2193 const VkDrawIndirectCommand drawCommand = 2194 { 2195 4u, // deUint32 vertexCount; 2196 1u, // deUint32 instanceCount; 2197 (drawNdx + subpassNdx % m_squareCount) * 4u, // deUint32 firstVertex; 2198 0u // deUint32 firstInstance; 2199 }; 2200 2201 drawCommands.push_back(drawCommand); 2202 } 2203 } 2204 2205 const size_t drawCommandsLength = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2206 ? drawCommandsIndexed.size() 2207 : drawCommands.size(); 2208 const void* drawCommandsDataPtr = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2209 ? (void*)&drawCommandsIndexed[0] 2210 : (void*)&drawCommands[0]; 2211 const size_t dataSize = static_cast<size_t>(drawCommandsLength * strideInBuffer); 2212 const VkDeviceSize bufferDataSize = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize)); 2213 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); 2214 Move<VkBuffer> indirectBuffer = createBuffer(*m_device, *m_logicalDevice, &bufferInfo); 2215 MovePtr<Allocation> allocationBuffer = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *indirectBuffer), MemoryRequirement::HostVisible); 2216 2217 DE_ASSERT(drawCommandsLength != 0); 2218 2219 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset())); 2220 2221 deMemcpy(allocationBuffer->getHostPtr(), drawCommandsDataPtr, static_cast<size_t>(dataSize)); 2222 2223 flushAlloc(*m_device, *m_logicalDevice, *allocationBuffer); 2224 indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer))); 2225 indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer))); 2226 } 2227 2228 beginCommandBuffer(*m_device, *m_cmdBuffer); 2229 2230 beforeRenderPass(); 2231 2232 if (!m_useDynamicRendering) 2233 { 2234 const VkRenderPassBeginInfo renderPassBeginInfo 2235 { 2236 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2237 DE_NULL, // const void* pNext; 2238 renderPass, // VkRenderPass renderPass; 2239 frameBuffer, // VkFramebuffer framebuffer; 2240 renderArea, // VkRect2D renderArea; 2241 1u, // uint32_t clearValueCount; 2242 &renderPassClearValue, // const VkClearValue* pClearValues; 2243 }; 2244 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2245 } 2246 2247 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2248 { 2249 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2250 2251 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2252 m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32); 2253 2254#ifndef CTS_USES_VULKANSC 2255 if (m_useDynamicRendering) 2256 { 2257 addRenderingSubpassDependencyIfRequired(subpassNdx); 2258 2259 beginRendering( 2260 *m_device, 2261 *m_cmdBuffer, 2262 m_colorAttachment->getImageView(), 2263 renderArea, 2264 renderPassClearValue, 2265 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2266 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2267 0u, 2268 m_parameters.extent.depth, 2269 m_parameters.viewMasks[subpassNdx]); 2270 } 2271#endif // CTS_USES_VULKANSC 2272 2273 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2274 2275 if (m_hasMultiDrawIndirect) 2276 { 2277 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2278 m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer); 2279 else 2280 m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer); 2281 } 2282 else 2283 { 2284 for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++) 2285 { 2286 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED) 2287 m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer); 2288 else 2289 m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer); 2290 } 2291 } 2292 2293#ifndef CTS_USES_VULKANSC 2294 if (m_useDynamicRendering) 2295 endRendering(*m_device, *m_cmdBuffer); 2296 else 2297#endif // CTS_USES_VULKANSC 2298 if (subpassNdx < subpassCount - 1u) 2299 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2300 } 2301 2302 if (!m_useDynamicRendering) 2303 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2304 2305 afterRenderPass(); 2306 2307 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2308 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2309} 2310 2311class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance 2312{ 2313public: 2314 MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters); 2315protected: 2316 void draw (const deUint32 subpassCount, 2317 VkRenderPass renderPass, 2318 VkFramebuffer frameBuffer, 2319 vector<PipelineSp>& pipelines); 2320}; 2321 2322MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters) 2323 : MultiViewRenderTestInstance (context, parameters) 2324{ 2325} 2326 2327void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2328{ 2329 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2330 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2331 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2332 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2333 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2334 2335 beginCommandBuffer(*m_device, *m_cmdBuffer); 2336 2337 beforeRenderPass(); 2338 2339 if (!m_useDynamicRendering) 2340 { 2341 const VkRenderPassBeginInfo renderPassBeginInfo 2342 { 2343 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2344 DE_NULL, // const void* pNext; 2345 renderPass, // VkRenderPass renderPass; 2346 frameBuffer, // VkFramebuffer framebuffer; 2347 renderArea, // VkRect2D renderArea; 2348 1u, // uint32_t clearValueCount; 2349 &renderPassClearValue, // const VkClearValue* pClearValues; 2350 }; 2351 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2352 } 2353 2354 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2355 { 2356 VkClearAttachment clearAttachment = 2357 { 2358 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 2359 0u, // deUint32 colorAttachment 2360 makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) // VkClearValue clearValue 2361 }; 2362 2363 const VkOffset2D offset[2] = 2364 { 2365 {0, 0}, 2366 {static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)} 2367 }; 2368 2369 const VkExtent2D extent[2] = 2370 { 2371 {m_parameters.extent.width, m_parameters.extent.height}, 2372 {static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)} 2373 }; 2374 2375 const VkRect2D rect2D[2] = 2376 { 2377 {offset[0], extent[0]}, 2378 {offset[1], extent[1]} 2379 }; 2380 2381 VkClearRect clearRect = 2382 { 2383 rect2D[0], // VkRect2D rect 2384 0u, // deUint32 baseArrayLayer 2385 1u, // deUint32 layerCount 2386 }; 2387 2388#ifndef CTS_USES_VULKANSC 2389 if (m_useDynamicRendering) 2390 { 2391 addRenderingSubpassDependencyIfRequired(subpassNdx); 2392 2393 beginRendering( 2394 *m_device, 2395 *m_cmdBuffer, 2396 m_colorAttachment->getImageView(), 2397 renderArea, 2398 renderPassClearValue, 2399 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2400 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2401 0u, 2402 m_parameters.extent.depth, 2403 m_parameters.viewMasks[subpassNdx]); 2404 } 2405#endif // CTS_USES_VULKANSC 2406 2407 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); 2408 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2409 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2410 2411 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2412 m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 2413 2414 clearRect.rect = rect2D[1]; 2415 clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 2416 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect); 2417 2418#ifndef CTS_USES_VULKANSC 2419 if (m_useDynamicRendering) 2420 endRendering(*m_device, *m_cmdBuffer); 2421 else 2422#endif // CTS_USES_VULKANSC 2423 if (subpassNdx < subpassCount - 1u) 2424 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2425 } 2426 2427 if (!m_useDynamicRendering) 2428 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2429 2430 afterRenderPass(); 2431 2432 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2433 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2434} 2435 2436class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance 2437{ 2438public: 2439 MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters); 2440protected: 2441 void draw (const deUint32 subpassCount, 2442 VkRenderPass renderPass, 2443 VkFramebuffer frameBuffer, 2444 vector<PipelineSp>& pipelines); 2445}; 2446 2447MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters) 2448 : MultiViewRenderTestInstance (context, parameters) 2449{ 2450} 2451 2452void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2453{ 2454 typedef de::SharedPtr<Unique<VkCommandBuffer> > VkCommandBufferSp; 2455 2456 createSecondaryCommandPool(); 2457 2458 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2459 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2460 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2461 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2462 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2463 2464 beginCommandBuffer(*m_device, *m_cmdBuffer); 2465 2466 beforeRenderPass(); 2467 2468 const VkRenderPassBeginInfo renderPassBeginInfo 2469 { 2470 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2471 DE_NULL, // const void* pNext; 2472 renderPass, // VkRenderPass renderPass; 2473 frameBuffer, // VkFramebuffer framebuffer; 2474 renderArea, // VkRect2D renderArea; 2475 1u, // uint32_t clearValueCount; 2476 &renderPassClearValue, // const VkClearValue* pClearValues; 2477 }; 2478 if (!m_useDynamicRendering) 2479 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType); 2480 2481 //Create secondary buffer 2482 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 2483 { 2484 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 2485 DE_NULL, // const void* pNext; 2486 *m_cmdPoolSecondary, // VkCommandPool commandPool; 2487 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; 2488 1u, // deUint32 bufferCount; 2489 }; 2490 vector<VkCommandBufferSp> cmdBufferSecondary; 2491 2492 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2493 { 2494 cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo)))); 2495 2496#ifndef CTS_USES_VULKANSC 2497 const VkCommandBufferInheritanceRenderingInfoKHR secCmdBufInheritRenderingInfo 2498 { 2499 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType; 2500 DE_NULL, // const void* pNext; 2501 0u, // VkRenderingFlagsKHR flags; 2502 m_parameters.viewMasks[subpassNdx], // uint32_t viewMask; 2503 1u, // uint32_t colorAttachmentCount; 2504 &m_parameters.colorFormat, // const VkFormat* pColorAttachmentFormats; 2505 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat; 2506 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat; 2507 m_parameters.samples // VkSampleCountFlagBits rasterizationSamples; 2508 }; 2509#endif // CTS_USES_VULKANSC 2510 2511 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo 2512 { 2513 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType; 2514#ifndef CTS_USES_VULKANSC 2515 m_useDynamicRendering ? &secCmdBufInheritRenderingInfo : DE_NULL, // const void* pNext; 2516#else 2517 DE_NULL, // const void* pNext; 2518#endif // CTS_USES_VULKANSC 2519 renderPass, // VkRenderPass renderPass; 2520 subpassNdx, // deUint32 subpass; 2521 frameBuffer, // VkFramebuffer framebuffer; 2522 VK_FALSE, // VkBool32 occlusionQueryEnable; 2523 (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags; 2524 (VkQueryPipelineStatisticFlags)0u, // VkQueryPipelineStatisticFlags pipelineStatistics; 2525 }; 2526 2527 const VkCommandBufferBeginInfo info 2528 { 2529 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 2530 DE_NULL, // const void* pNext; 2531 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // VkCommandBufferUsageFlags flags; 2532 &secCmdBufInheritInfo, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 2533 }; 2534 2535 VK_CHECK(m_device->beginCommandBuffer(cmdBufferSecondary.back().get()->get(), &info)); 2536 2537 m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2538 m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2539 2540#ifndef CTS_USES_VULKANSC 2541 if (m_useDynamicRendering) 2542 { 2543 addRenderingSubpassDependencyIfRequired(subpassNdx); 2544 2545 beginRendering( 2546 *m_device, 2547 *m_cmdBuffer, 2548 m_colorAttachment->getImageView(), 2549 renderArea, 2550 renderPassClearValue, 2551 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2552 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2553 VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR, 2554 m_parameters.extent.depth, 2555 m_parameters.viewMasks[subpassNdx]); 2556 } 2557#endif // CTS_USES_VULKANSC 2558 2559 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2560 m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u); 2561 2562 VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get())); 2563 2564 m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get()); 2565#ifndef CTS_USES_VULKANSC 2566 if (m_useDynamicRendering) 2567 endRendering(*m_device, *m_cmdBuffer); 2568 else 2569#endif // CTS_USES_VULKANSC 2570 if (subpassNdx < subpassCount - 1u) 2571 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType); 2572 } 2573 2574 if (!m_useDynamicRendering) 2575 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2576 2577 afterRenderPass(); 2578 2579 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2580 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2581} 2582 2583class MultiViewPointSizeTestInstance : public MultiViewRenderTestInstance 2584{ 2585public: 2586 MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters); 2587protected: 2588 void validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize); 2589 void createVertexData (void); 2590 void draw (const deUint32 subpassCount, 2591 VkRenderPass renderPass, 2592 VkFramebuffer frameBuffer, 2593 vector<PipelineSp>& pipelines); 2594}; 2595 2596MultiViewPointSizeTestInstance::MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters) 2597 : MultiViewRenderTestInstance (context, parameters) 2598{ 2599 const auto& vki = m_context.getInstanceInterface(); 2600 const auto physDevice = m_context.getPhysicalDevice(); 2601 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits; 2602 2603 validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_WIDE)); 2604 validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_SMALL)); 2605} 2606 2607void MultiViewPointSizeTestInstance::validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize) 2608{ 2609 const float testPointSizeFloat = static_cast<float>(pointSize); 2610 float granuleCount = 0.0f; 2611 2612 if (!de::inRange(testPointSizeFloat, limits.pointSizeRange[0], limits.pointSizeRange[1])) 2613 TCU_THROW(NotSupportedError, "Required point size is outside of the the limits range"); 2614 2615 granuleCount = static_cast<float>(deCeilFloatToInt32((testPointSizeFloat - limits.pointSizeRange[0]) / limits.pointSizeGranularity)); 2616 2617 if (limits.pointSizeRange[0] + granuleCount * limits.pointSizeGranularity != testPointSizeFloat) 2618 TCU_THROW(NotSupportedError, "Granuliraty does not allow to get required point size"); 2619 2620 DE_ASSERT(pointSize + 1 <= m_parameters.extent.width / 2); 2621 DE_ASSERT(pointSize + 1 <= m_parameters.extent.height / 2); 2622} 2623 2624void MultiViewPointSizeTestInstance::createVertexData (void) 2625{ 2626 const float pixelStepX = 2.0f / static_cast<float>(m_parameters.extent.width); 2627 const float pixelStepY = 2.0f / static_cast<float>(m_parameters.extent.height); 2628 const int pointMargin = 1 + TEST_POINT_SIZE_WIDE / 2; 2629 2630 appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 2631 appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 2632 appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 2633 appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.5f, 0.3f, 1.0f)); 2634} 2635 2636void MultiViewPointSizeTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2637{ 2638 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2639 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2640 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2641 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2642 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2643 2644 beginCommandBuffer(*m_device, *m_cmdBuffer); 2645 2646 beforeRenderPass(); 2647 2648 if (!m_useDynamicRendering) 2649 { 2650 const VkRenderPassBeginInfo renderPassBeginInfo 2651 { 2652 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2653 DE_NULL, // const void* pNext; 2654 renderPass, // VkRenderPass renderPass; 2655 frameBuffer, // VkFramebuffer framebuffer; 2656 renderArea, // VkRect2D renderArea; 2657 1u, // uint32_t clearValueCount; 2658 &renderPassClearValue, // const VkClearValue* pClearValues; 2659 }; 2660 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2661 } 2662 2663 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2664 { 2665 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2666 2667 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2668 2669#ifndef CTS_USES_VULKANSC 2670 if (m_useDynamicRendering) 2671 { 2672 addRenderingSubpassDependencyIfRequired(subpassNdx); 2673 2674 beginRendering( 2675 *m_device, 2676 *m_cmdBuffer, 2677 m_colorAttachment->getImageView(), 2678 renderArea, 2679 renderPassClearValue, 2680 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2681 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2682 0u, 2683 m_parameters.extent.depth, 2684 m_parameters.viewMasks[subpassNdx]); 2685 } 2686#endif // CTS_USES_VULKANSC 2687 2688 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2689 m_device->cmdDraw(*m_cmdBuffer, 1u, 1u, drawNdx + subpassNdx % m_squareCount, 0u); 2690 2691#ifndef CTS_USES_VULKANSC 2692 if (m_useDynamicRendering) 2693 endRendering(*m_device, *m_cmdBuffer); 2694 else 2695#endif // CTS_USES_VULKANSC 2696 if (subpassNdx < subpassCount - 1u) 2697 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2698 } 2699 2700 if (!m_useDynamicRendering) 2701 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2702 2703 afterRenderPass(); 2704 2705 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2706 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2707} 2708 2709class MultiViewMultsampleTestInstance : public MultiViewRenderTestInstance 2710{ 2711public: 2712 MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters); 2713protected: 2714 tcu::TestStatus iterate (void); 2715 void createVertexData (void); 2716 2717 void draw (const deUint32 subpassCount, 2718 VkRenderPass renderPass, 2719 VkFramebuffer frameBuffer, 2720 vector<PipelineSp>& pipelines); 2721 void afterRenderPass (void); 2722private: 2723 de::SharedPtr<ImageAttachment> m_resolveAttachment; 2724}; 2725 2726MultiViewMultsampleTestInstance::MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters) 2727 : MultiViewRenderTestInstance (context, parameters) 2728{ 2729 // Color attachment 2730 m_resolveAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, VK_SAMPLE_COUNT_1_BIT)); 2731} 2732 2733tcu::TestStatus MultiViewMultsampleTestInstance::iterate (void) 2734{ 2735 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 2736 Move<VkRenderPass> renderPass; 2737 Move<VkFramebuffer> frameBuffer; 2738 2739 // FrameBuffer & renderPass 2740 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 2741 { 2742 renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_4_BIT); 2743 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); 2744 } 2745 2746 // pipelineLayout 2747 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 2748 2749 // pipelines 2750 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 2751 vector<PipelineSp> pipelines(subpassCount); 2752 const VkVertexInputRate vertexInputRate = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; 2753 2754 { 2755 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 2756 madeShaderModule(shaderModule, shaderStageParams); 2757 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 2758 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate)))); 2759 } 2760 2761 createCommandBuffer(); 2762 createVertexData(); 2763 createVertexBuffer(); 2764 2765 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 2766 2767 { 2768 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); 2769 tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 2770 2771 readImage(m_resolveAttachment->getImage(), dst); 2772 2773 if (!checkImage(dst)) 2774 return tcu::TestStatus::fail("Fail"); 2775 } 2776 2777 return tcu::TestStatus::pass("Pass"); 2778} 2779 2780void MultiViewMultsampleTestInstance::createVertexData (void) 2781{ 2782 tcu::Vec4 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 2783 2784 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 2785 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); 2786 appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color); 2787 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); 2788 2789 color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); 2790 appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color); 2791 appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color); 2792 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 2793 2794 color = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f); 2795 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 2796 appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color); 2797 appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color); 2798 2799 color = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f); 2800 appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color); 2801 appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color); 2802 appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color); 2803} 2804 2805void MultiViewMultsampleTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 2806{ 2807 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 2808 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 2809 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 2810 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 2811 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 2812 const deUint32 vertexPerPrimitive = 3u; 2813 const VkImageSubresourceLayers subresourceLayer = 2814 { 2815 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2816 0u, // deUint32 mipLevel; 2817 0u, // deUint32 baseArrayLayer; 2818 m_parameters.extent.depth, // deUint32 layerCount; 2819 }; 2820 const VkImageResolve imageResolveRegion = 2821 { 2822 subresourceLayer, // VkImageSubresourceLayers srcSubresource; 2823 makeOffset3D(0, 0, 0), // VkOffset3D srcOffset; 2824 subresourceLayer, // VkImageSubresourceLayers dstSubresource; 2825 makeOffset3D(0, 0, 0), // VkOffset3D dstOffset; 2826 makeExtent3D(m_parameters.extent.width, m_parameters.extent.height, 1u), // VkExtent3D extent; 2827 }; 2828 2829 beginCommandBuffer(*m_device, *m_cmdBuffer); 2830 2831 beforeRenderPass(); 2832 2833 if (!m_useDynamicRendering) 2834 { 2835 const VkRenderPassBeginInfo renderPassBeginInfo 2836 { 2837 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2838 DE_NULL, // const void* pNext; 2839 renderPass, // VkRenderPass renderPass; 2840 frameBuffer, // VkFramebuffer framebuffer; 2841 renderArea, // VkRect2D renderArea; 2842 1u, // uint32_t clearValueCount; 2843 &renderPassClearValue, // const VkClearValue* pClearValues; 2844 }; 2845 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2846 } 2847 2848 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 2849 { 2850 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 2851 2852 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 2853 2854#ifndef CTS_USES_VULKANSC 2855 if (m_useDynamicRendering) 2856 { 2857 addRenderingSubpassDependencyIfRequired(subpassNdx); 2858 2859 beginRendering( 2860 *m_device, 2861 *m_cmdBuffer, 2862 m_colorAttachment->getImageView(), 2863 renderArea, 2864 renderPassClearValue, 2865 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2866 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 2867 0u, 2868 m_parameters.extent.depth, 2869 m_parameters.viewMasks[subpassNdx]); 2870 } 2871#endif // CTS_USES_VULKANSC 2872 2873 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 2874 m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u); 2875 2876#ifndef CTS_USES_VULKANSC 2877 if (m_useDynamicRendering) 2878 endRendering(*m_device, *m_cmdBuffer); 2879 else 2880#endif // CTS_USES_VULKANSC 2881 if (subpassNdx < subpassCount - 1u) 2882 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 2883 } 2884 2885 if (!m_useDynamicRendering) 2886 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 2887 2888 afterRenderPass(); 2889 2890 m_device->cmdResolveImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, m_resolveAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolveRegion); 2891 2892 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 2893 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 2894} 2895 2896void MultiViewMultsampleTestInstance::afterRenderPass (void) 2897{ 2898 const VkImageSubresourceRange subresourceRange = 2899 { 2900 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2901 0u, // deUint32 baseMipLevel; 2902 1u, // deUint32 levelCount; 2903 0u, // deUint32 baseArrayLayer; 2904 m_parameters.extent.depth, // deUint32 layerCount; 2905 }; 2906 2907 imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, 2908 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 2909 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 2910 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 2911 2912 imageBarrier(*m_device, *m_cmdBuffer, m_resolveAttachment->getImage(), subresourceRange, 2913 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 2914 0u, VK_ACCESS_TRANSFER_WRITE_BIT, 2915 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 2916} 2917 2918class MultiViewQueriesTestInstance : public MultiViewRenderTestInstance 2919{ 2920public: 2921 MultiViewQueriesTestInstance (Context& context, const TestParameters& parameters); 2922protected: 2923 tcu::TestStatus iterate (void); 2924 void createVertexData (void); 2925 2926 void draw (const deUint32 subpassCount, 2927 VkRenderPass renderPass, 2928 VkFramebuffer frameBuffer, 2929 vector<PipelineSp>& pipelines); 2930 deUint32 getUsedViewsCount (const deUint32 viewMaskIndex); 2931 deUint32 getQueryCountersNumber (); 2932private: 2933 const deUint32 m_verticesPerPrimitive; 2934 const VkQueryControlFlags m_occlusionQueryFlags; 2935 deUint64 m_timestampMask; 2936 vector<deUint64> m_timestampStartValues; 2937 vector<deUint64> m_timestampEndValues; 2938 vector<uint64_t> m_timestampStartAvailabilityValues; 2939 vector<uint64_t> m_timestampEndAvailabilityValues; 2940 vector<deBool> m_counterSeriesStart; 2941 vector<deBool> m_counterSeriesEnd; 2942 vector<deUint64> m_occlusionValues; 2943 vector<deUint64> m_occlusionExpectedValues; 2944 vector<uint64_t> m_occlusionAvailabilityValues; 2945 deUint32 m_occlusionObjectsOffset; 2946 vector<deUint64> m_occlusionObjectPixelsCount; 2947}; 2948 2949MultiViewQueriesTestInstance::MultiViewQueriesTestInstance (Context& context, const TestParameters& parameters) 2950 : MultiViewRenderTestInstance (context, parameters) 2951 , m_verticesPerPrimitive (4u) 2952 , m_occlusionQueryFlags ((parameters.viewIndex == TEST_TYPE_QUERIES) * VK_QUERY_CONTROL_PRECISE_BIT) 2953 , m_occlusionObjectsOffset (0) 2954{ 2955 // Generate the timestamp mask 2956 const auto& vki = m_context.getInstanceInterface(); 2957 const auto physicalDevice = m_context.getPhysicalDevice(); 2958 2959 const std::vector<VkQueueFamilyProperties> queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice); 2960 2961 if(queueProperties[0].timestampValidBits == 0) 2962 TCU_THROW(NotSupportedError, "Device does not support timestamp."); 2963 2964 m_timestampMask = 0xFFFFFFFFFFFFFFFFull >> (64 - queueProperties[0].timestampValidBits); 2965} 2966 2967void verifyAvailabilityBits (const std::vector<uint64_t>& bits, const char* setName) 2968{ 2969 constexpr auto invalidValue = uint64_t{0}; 2970 for (size_t i = 0u; i < bits.size(); ++i) 2971 { 2972 if (bits[i] == invalidValue) 2973 TCU_FAIL(setName + std::string(" availability bit ") + de::toString(i) + " is " + de::toString(invalidValue)); 2974 } 2975} 2976 2977tcu::TestStatus MultiViewQueriesTestInstance::iterate (void) 2978{ 2979 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 2980 Move<VkRenderPass> renderPass; 2981 Move<VkFramebuffer> frameBuffer; 2982 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 2983 vector<PipelineSp> pipelines (subpassCount); 2984 deUint64 occlusionValue = 0; 2985 deUint64 occlusionExpectedValue = 0; 2986 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 2987 2988 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 2989 { 2990 renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType); 2991 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); 2992 } 2993 2994 { 2995 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 2996 2997 madeShaderModule(shaderModule, shaderStageParams); 2998 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 2999 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx)))); 3000 } 3001 3002 createCommandBuffer(); 3003 createVertexData(); 3004 createVertexBuffer(); 3005 3006 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 3007 3008 DE_ASSERT(!m_occlusionValues.empty()); 3009 DE_ASSERT(m_occlusionValues.size() == m_occlusionExpectedValues.size()); 3010 DE_ASSERT(m_occlusionValues.size() == m_counterSeriesEnd.size()); 3011 for (size_t ndx = 0; ndx < m_counterSeriesEnd.size(); ++ndx) 3012 { 3013 occlusionValue += m_occlusionValues[ndx]; 3014 occlusionExpectedValue += m_occlusionExpectedValues[ndx]; 3015 3016 if (m_counterSeriesEnd[ndx]) 3017 { 3018 if (m_parameters.viewIndex == TEST_TYPE_QUERIES) 3019 { 3020 if (occlusionExpectedValue != occlusionValue) 3021 return tcu::TestStatus::fail("occlusion, result:" + de::toString(occlusionValue) + ", expected:" + de::toString(occlusionExpectedValue)); 3022 } 3023 else // verify non precise occlusion query 3024 { 3025 if (occlusionValue == 0) 3026 return tcu::TestStatus::fail("occlusion, result: 0, expected non zero value"); 3027 } 3028 } 3029 } 3030 verifyAvailabilityBits(m_occlusionAvailabilityValues, "occlusion"); 3031 3032 DE_ASSERT(!m_timestampStartValues.empty()); 3033 DE_ASSERT(m_timestampStartValues.size() == m_timestampEndValues.size()); 3034 DE_ASSERT(m_timestampStartValues.size() == m_counterSeriesStart.size()); 3035 for (size_t ndx = 0; ndx < m_timestampStartValues.size(); ++ndx) 3036 { 3037 if (m_counterSeriesStart[ndx]) 3038 { 3039 if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx]) 3040 continue; 3041 } 3042 else 3043 { 3044 if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx]) 3045 continue; 3046 3047 if (m_timestampEndValues[ndx] == 0 && m_timestampStartValues[ndx] == 0) 3048 continue; 3049 } 3050 3051 return tcu::TestStatus::fail("timestamp"); 3052 } 3053 verifyAvailabilityBits(m_timestampStartAvailabilityValues, "timestamp start"); 3054 verifyAvailabilityBits(m_timestampEndAvailabilityValues, "timestamp end"); 3055 3056 return tcu::TestStatus::pass("Pass"); 3057} 3058 3059void MultiViewQueriesTestInstance::createVertexData (void) 3060{ 3061 tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f); 3062 3063 appendVertex(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), color); 3064 appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color); 3065 appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color); 3066 appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color); 3067 3068 color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f); 3069 appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color); 3070 appendVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), color); 3071 appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color); 3072 appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color); 3073 3074 color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f); 3075 appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color); 3076 appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color); 3077 appendVertex(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), color); 3078 appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color); 3079 3080 color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f); 3081 appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color); 3082 appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color); 3083 appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color); 3084 appendVertex(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), color); 3085 3086 // Create occluded square objects as zoom out of main 3087 const deUint32 mainObjectsVerticesCount = static_cast<deUint32>(m_vertexCoord.size()); 3088 const deUint32 mainObjectsCount = mainObjectsVerticesCount / m_verticesPerPrimitive; 3089 const deUint32 occlusionObjectMultiplierX[] = { 1, 2, 2, 1 }; 3090 const deUint32 occlusionObjectMultiplierY[] = { 1, 1, 3, 3 }; 3091 const deUint32 occlusionObjectDivisor = 4u; 3092 const float occlusionObjectDivisorFloat = static_cast<float>(occlusionObjectDivisor); 3093 3094 DE_ASSERT(0 == m_parameters.extent.width % (2 * occlusionObjectDivisor)); 3095 DE_ASSERT(0 == m_parameters.extent.height % (2 * occlusionObjectDivisor)); 3096 DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierX) == mainObjectsCount); 3097 DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierY) == mainObjectsCount); 3098 3099 for (size_t objectNdx = 0; objectNdx < mainObjectsCount; ++objectNdx) 3100 { 3101 const size_t objectStart = objectNdx * m_verticesPerPrimitive; 3102 const float xRatio = static_cast<float>(occlusionObjectMultiplierX[objectNdx]) / occlusionObjectDivisorFloat; 3103 const float yRatio = static_cast<float>(occlusionObjectMultiplierY[objectNdx]) / occlusionObjectDivisorFloat; 3104 const double areaRatio = static_cast<double>(xRatio) * static_cast<double>(yRatio); 3105 const deUint64 occludedPixelsCount = static_cast<deUint64>(areaRatio * (m_parameters.extent.width / 2) * (m_parameters.extent.height / 2)); 3106 3107 m_occlusionObjectPixelsCount.push_back(occludedPixelsCount); 3108 3109 for (size_t vertexNdx = 0; vertexNdx < m_verticesPerPrimitive; ++vertexNdx) 3110 { 3111 const float occludedObjectVertexXCoord = m_vertexCoord[objectStart + vertexNdx][0] * xRatio; 3112 const float occludedObjectVertexYCoord = m_vertexCoord[objectStart + vertexNdx][1] * yRatio; 3113 const tcu::Vec4 occludedObjectVertexCoord = tcu::Vec4(occludedObjectVertexXCoord, occludedObjectVertexYCoord, 1.0f, 1.0f); 3114 3115 appendVertex(occludedObjectVertexCoord, m_vertexColor[objectStart + vertexNdx]); 3116 } 3117 } 3118 3119 m_occlusionObjectsOffset = mainObjectsVerticesCount; 3120} 3121 3122// Extract single values or pairs of consecutive values from src and store them in dst1 and dst2. 3123// If ds2 is not null, src is processed as containing pairs of values. 3124// The first value will be stored in ds1 and the second one in dst2. 3125void unpackValues (const std::vector<uint64_t>& src, std::vector<uint64_t>* dst1, std::vector<uint64_t>* dst2) 3126{ 3127 if (!dst2) 3128 { 3129 std::copy(begin(src), end(src), begin(*dst1)); 3130 return; 3131 } 3132 3133 constexpr size_t sz0 = 0; 3134 constexpr size_t sz1 = 1; 3135 constexpr size_t sz2 = 2; 3136 3137 DE_UNREF(sz0); // For release builds. 3138 DE_ASSERT(src.size() % sz2 == sz0); 3139 3140 for (size_t i = 0; i < src.size(); i += sz2) 3141 { 3142 const auto j = i / sz2; 3143 dst1->at(j) = src.at(i); 3144 dst2->at(j) = src.at(i + sz1); 3145 } 3146} 3147 3148void MultiViewQueriesTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 3149{ 3150 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 3151 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 3152 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 3153 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 3154 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 3155 const deUint32 queryCountersNumber = (subpassCount == 1) ? m_squareCount * getUsedViewsCount(0) : getQueryCountersNumber(); 3156 3157 const VkQueryPoolCreateInfo occlusionQueryPoolCreateInfo = 3158 { 3159 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType; 3160 DE_NULL, // const void* pNext; 3161 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags; 3162 VK_QUERY_TYPE_OCCLUSION, // VkQueryType queryType; 3163 queryCountersNumber, // deUint32 queryCount; 3164 0u, // VkQueryPipelineStatisticFlags pipelineStatistics; 3165 }; 3166 const VkQueryPoolCreateInfo timestampQueryPoolCreateInfo = 3167 { 3168 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType; 3169 DE_NULL, // const void* pNext; 3170 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags; 3171 VK_QUERY_TYPE_TIMESTAMP, // VkQueryType queryType; 3172 queryCountersNumber, // deUint32 queryCount; 3173 0u, // VkQueryPipelineStatisticFlags pipelineStatistics; 3174 }; 3175 const Unique<VkQueryPool> occlusionQueryPool (createQueryPool(*m_device, *m_logicalDevice, &occlusionQueryPoolCreateInfo)); 3176 const Unique<VkQueryPool> timestampStartQueryPool (createQueryPool(*m_device, *m_logicalDevice, ×tampQueryPoolCreateInfo)); 3177 const Unique<VkQueryPool> timestampEndQueryPool (createQueryPool(*m_device, *m_logicalDevice, ×tampQueryPoolCreateInfo)); 3178 deUint32 queryStartIndex = 0; 3179 3180 const bool withAvailability = (m_parameters.viewIndex == TEST_TYPE_NON_PRECISE_QUERIES_WITH_AVAILABILITY); 3181 const uint32_t valuesPerQuery = (withAvailability ? 2u : 1u); 3182 const uint32_t valuesNumber = queryCountersNumber * valuesPerQuery; 3183 const auto queryStride = static_cast<VkDeviceSize>(sizeof(uint64_t) * valuesPerQuery); 3184 const auto extraFlag = (withAvailability ? VK_QUERY_RESULT_WITH_AVAILABILITY_BIT : static_cast<VkQueryResultFlagBits>(0)); 3185 const auto queryFlags = (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT | extraFlag); 3186 3187 vk::BufferWithMemory queryBuffer (m_context.getDeviceInterface(), *m_logicalDevice, *m_allocator, makeBufferCreateInfo(valuesNumber * sizeof(uint64_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible); 3188 3189 beginCommandBuffer(*m_device, *m_cmdBuffer); 3190 3191 beforeRenderPass(); 3192 3193 // Query pools must be reset before use 3194 m_device->cmdResetQueryPool(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, queryCountersNumber); 3195 m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampStartQueryPool, queryStartIndex, queryCountersNumber); 3196 m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampEndQueryPool, queryStartIndex, queryCountersNumber); 3197 3198 if (!m_useDynamicRendering) 3199 { 3200 const VkRenderPassBeginInfo renderPassBeginInfo 3201 { 3202 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 3203 DE_NULL, // const void* pNext; 3204 renderPass, // VkRenderPass renderPass; 3205 frameBuffer, // VkFramebuffer framebuffer; 3206 renderArea, // VkRect2D renderArea; 3207 1u, // uint32_t clearValueCount; 3208 &renderPassClearValue, // const VkClearValue* pClearValues; 3209 }; 3210 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 3211 } 3212 3213 m_occlusionExpectedValues.reserve(queryCountersNumber); 3214 m_counterSeriesStart.reserve(queryCountersNumber); 3215 m_counterSeriesEnd.reserve(queryCountersNumber); 3216 3217 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 3218 { 3219 deUint32 queryCountersToUse = getUsedViewsCount(subpassNdx); 3220 3221 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 3222 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 3223 3224#ifndef CTS_USES_VULKANSC 3225 if (m_useDynamicRendering) 3226 { 3227 addRenderingSubpassDependencyIfRequired(subpassNdx); 3228 3229 beginRendering( 3230 *m_device, 3231 *m_cmdBuffer, 3232 m_colorAttachment->getImageView(), 3233 renderArea, 3234 renderPassClearValue, 3235 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3236 (subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR), 3237 0u, 3238 m_parameters.extent.depth, 3239 m_parameters.viewMasks[subpassNdx]); 3240 } 3241#endif // CTS_USES_VULKANSC 3242 3243 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 3244 { 3245 const deUint32 primitiveNumber = drawNdx + subpassNdx % m_squareCount; 3246 const deUint32 firstVertex = primitiveNumber * m_verticesPerPrimitive; 3247 3248 m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampStartQueryPool, queryStartIndex); 3249 { 3250 m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, firstVertex, 0u); 3251 3252 // Render occluded object 3253 m_device->cmdBeginQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, m_occlusionQueryFlags); 3254 m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, m_occlusionObjectsOffset + firstVertex, 0u); 3255 m_device->cmdEndQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex); 3256 3257 for (deUint32 viewMaskNdx = 0; viewMaskNdx < queryCountersToUse; ++viewMaskNdx) 3258 { 3259 m_occlusionExpectedValues.push_back(m_occlusionObjectPixelsCount[primitiveNumber]); 3260 m_counterSeriesStart.push_back(viewMaskNdx == 0); 3261 m_counterSeriesEnd.push_back(viewMaskNdx + 1 == queryCountersToUse); 3262 } 3263 } 3264 m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampEndQueryPool, queryStartIndex); 3265 3266 queryStartIndex += queryCountersToUse; 3267 } 3268 3269#ifndef CTS_USES_VULKANSC 3270 if (m_useDynamicRendering) 3271 endRendering(*m_device, *m_cmdBuffer); 3272 else 3273#endif // CTS_USES_VULKANSC 3274 if (subpassNdx < subpassCount - 1u) 3275 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 3276 } 3277 3278 DE_ASSERT(queryStartIndex == queryCountersNumber); 3279 3280 if (!m_useDynamicRendering) 3281 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 3282 3283 afterRenderPass(); 3284 3285 if (m_cmdCopyQueryPoolResults) 3286 m_device->cmdCopyQueryPoolResults(*m_cmdBuffer, *occlusionQueryPool, 0u, queryCountersNumber, *queryBuffer, 0u, queryStride, queryFlags); 3287 3288 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 3289 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 3290 3291 // These vectors will temporarily hold results. 3292 std::vector<uint64_t> occlusionQueryResultsBuffer (valuesNumber, 0u); 3293 std::vector<uint64_t> timestampStartQueryResultsBuffer (valuesNumber, 0u); 3294 std::vector<uint64_t> timestampEndQueryResultsBuffer (valuesNumber, 0u); 3295 3296 m_occlusionValues.resize(queryCountersNumber); 3297 m_timestampStartValues.resize(queryCountersNumber); 3298 m_timestampEndValues.resize(queryCountersNumber); 3299 3300 if (withAvailability) 3301 { 3302 m_occlusionAvailabilityValues.resize(queryCountersNumber); 3303 m_timestampStartAvailabilityValues.resize(queryCountersNumber); 3304 m_timestampEndAvailabilityValues.resize(queryCountersNumber); 3305 } 3306 3307 if (m_cmdCopyQueryPoolResults) 3308 { 3309 memcpy(occlusionQueryResultsBuffer.data(), queryBuffer.getAllocation().getHostPtr(), de::dataSize(occlusionQueryResultsBuffer)); 3310 memcpy(timestampStartQueryResultsBuffer.data(), queryBuffer.getAllocation().getHostPtr(), de::dataSize(timestampStartQueryResultsBuffer)); 3311 memcpy(timestampEndQueryResultsBuffer.data(), queryBuffer.getAllocation().getHostPtr(), de::dataSize(timestampEndQueryResultsBuffer)); 3312 } 3313 else 3314 { 3315 m_device->getQueryPoolResults(*m_logicalDevice, *occlusionQueryPool, 0u, queryCountersNumber, de::dataSize(occlusionQueryResultsBuffer), de::dataOrNull(occlusionQueryResultsBuffer), queryStride, queryFlags); 3316 m_device->getQueryPoolResults(*m_logicalDevice, *timestampStartQueryPool, 0u, queryCountersNumber, de::dataSize(timestampStartQueryResultsBuffer), de::dataOrNull(timestampStartQueryResultsBuffer), queryStride, queryFlags); 3317 m_device->getQueryPoolResults(*m_logicalDevice, *timestampEndQueryPool, 0u, queryCountersNumber, de::dataSize(timestampEndQueryResultsBuffer), de::dataOrNull(timestampEndQueryResultsBuffer), queryStride, queryFlags); 3318 } 3319 3320 unpackValues(occlusionQueryResultsBuffer, &m_occlusionValues, (withAvailability ? &m_occlusionAvailabilityValues : nullptr)); 3321 unpackValues(timestampStartQueryResultsBuffer, &m_timestampStartValues, (withAvailability ? &m_timestampStartAvailabilityValues : nullptr)); 3322 unpackValues(timestampEndQueryResultsBuffer, &m_timestampEndValues, (withAvailability ? &m_timestampEndAvailabilityValues : nullptr)); 3323 3324 for (deUint32 ndx = 0; ndx < m_timestampStartValues.size(); ++ndx) 3325 m_timestampStartValues[ndx] &= m_timestampMask; 3326 3327 for (deUint32 ndx = 0; ndx < m_timestampEndValues.size(); ++ndx) 3328 m_timestampEndValues[ndx] &= m_timestampMask; 3329} 3330 3331deUint32 MultiViewQueriesTestInstance::getUsedViewsCount (const deUint32 viewMaskIndex) 3332{ 3333 deUint32 result = 0; 3334 3335 for (deUint32 viewMask = m_parameters.viewMasks[viewMaskIndex]; viewMask != 0; viewMask >>= 1) 3336 if ((viewMask & 1) != 0) 3337 result++; 3338 3339 return result; 3340} 3341 3342deUint32 MultiViewQueriesTestInstance::getQueryCountersNumber () 3343{ 3344 deUint32 result = 0; 3345 3346 for (deUint32 i = 0; i < m_parameters.viewMasks.size(); ++i) 3347 result += getUsedViewsCount(i); 3348 3349 return result; 3350} 3351 3352class MultiViewReadbackTestInstance : public MultiViewRenderTestInstance 3353{ 3354public: 3355 MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters); 3356protected: 3357 tcu::TestStatus iterate (void); 3358 void drawClears (const deUint32 subpassCount, 3359 VkRenderPass renderPass, 3360 VkFramebuffer frameBuffer, 3361 vector<PipelineSp>& pipelines, 3362 const bool clearPass); 3363 void clear (const VkCommandBuffer commandBuffer, 3364 const VkRect2D& clearRect2D, 3365 const tcu::Vec4& clearColor); 3366private: 3367 vector<VkRect2D> m_quarters; 3368}; 3369 3370MultiViewReadbackTestInstance::MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters) 3371 : MultiViewRenderTestInstance (context, parameters) 3372{ 3373 const deUint32 halfWidth = m_parameters.extent.width / 2; 3374 const deUint32 halfHeight = m_parameters.extent.height / 2; 3375 3376 for (deInt32 x = 0; x < 2; ++x) 3377 for (deInt32 y = 0; y < 2; ++y) 3378 { 3379 const deInt32 offsetX = static_cast<deInt32>(halfWidth) * x; 3380 const deInt32 offsetY = static_cast<deInt32>(halfHeight) * y; 3381 const VkRect2D area = { { offsetX, offsetY}, {halfWidth, halfHeight} }; 3382 3383 m_quarters.push_back(area); 3384 } 3385} 3386 3387tcu::TestStatus MultiViewReadbackTestInstance::iterate (void) 3388{ 3389 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 3390 3391 createCommandBuffer(); 3392 3393 for (deUint32 pass = 0; pass < 2; ++pass) 3394 { 3395 const bool fullClearPass = (pass == 0); 3396 const VkAttachmentLoadOp loadOp = (!fullClearPass) ? VK_ATTACHMENT_LOAD_OP_LOAD : 3397 (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_CLEAR : 3398 (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : 3399 VK_ATTACHMENT_LOAD_OP_DONT_CARE; 3400 Move<VkRenderPass> renderPass; 3401 Move<VkFramebuffer> frameBuffer; 3402 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 3403 vector<PipelineSp> pipelines (subpassCount); 3404 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 3405 3406 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 3407 { 3408 renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_1_BIT, loadOp); 3409 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height); 3410 } 3411 3412 { 3413 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 3414 madeShaderModule(shaderModule, shaderStageParams); 3415 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 3416 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx)))); 3417 } 3418 3419 drawClears(subpassCount, *renderPass, *frameBuffer, pipelines, fullClearPass); 3420 } 3421 3422 { 3423 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); 3424 tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 3425 3426 readImage(m_colorAttachment->getImage(), dst); 3427 3428 if (!checkImage(dst)) 3429 return tcu::TestStatus::fail("Fail"); 3430 } 3431 3432 return tcu::TestStatus::pass("Pass"); 3433} 3434 3435void MultiViewReadbackTestInstance::drawClears (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines, const bool clearPass) 3436{ 3437 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 3438 const VkClearValue renderPassClearValue = makeClearValueColor(m_colorTable[0]); 3439 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 3440 const bool withClearColor = (clearPass && m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR); 3441 3442 beginCommandBuffer(*m_device, *m_cmdBuffer); 3443 3444 if (clearPass) 3445 beforeRenderPass(); 3446 3447 if (!m_useDynamicRendering) 3448 { 3449 const VkRenderPassBeginInfo renderPassBeginInfo 3450 { 3451 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 3452 DE_NULL, // const void* pNext; 3453 renderPass, // VkRenderPass renderPass; 3454 frameBuffer, // VkFramebuffer framebuffer; 3455 renderArea, // VkRect2D renderArea; 3456 withClearColor ? 1u : 0u, // uint32_t clearValueCount; 3457 withClearColor ? &renderPassClearValue : DE_NULL, // const VkClearValue* pClearValues; 3458 }; 3459 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 3460 } 3461 3462 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 3463 { 3464 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 3465 3466#ifndef CTS_USES_VULKANSC 3467 if (m_useDynamicRendering) 3468 { 3469 addRenderingSubpassDependencyIfRequired(subpassNdx); 3470 3471 VkAttachmentLoadOp loadOperation = VK_ATTACHMENT_LOAD_OP_LOAD; 3472 if (clearPass) 3473 { 3474 if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) 3475 loadOperation = VK_ATTACHMENT_LOAD_OP_CLEAR; 3476 else if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) 3477 loadOperation = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 3478 else 3479 loadOperation = VK_ATTACHMENT_LOAD_OP_MAX_ENUM; 3480 } 3481 3482 beginRendering( 3483 *m_device, 3484 *m_cmdBuffer, 3485 m_colorAttachment->getImageView(), 3486 renderArea, 3487 renderPassClearValue, 3488 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3489 loadOperation, 3490 0u, 3491 m_parameters.extent.depth, 3492 m_parameters.viewMasks[subpassNdx]); 3493 } 3494#endif // CTS_USES_VULKANSC 3495 3496 if (clearPass) 3497 { 3498 if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) 3499 clear(*m_cmdBuffer, renderArea, m_colorTable[subpassNdx % 4]); 3500 } 3501 else 3502 { 3503 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 3504 { 3505 const deUint32 primitiveNumber = drawNdx + subpassNdx % m_squareCount; 3506 3507 clear(*m_cmdBuffer, m_quarters[primitiveNumber], m_colorTable[4 + primitiveNumber]); 3508 } 3509 } 3510 3511#ifndef CTS_USES_VULKANSC 3512 if (m_useDynamicRendering) 3513 endRendering(*m_device, *m_cmdBuffer); 3514 else 3515#endif // CTS_USES_VULKANSC 3516 if (subpassNdx < subpassCount - 1u) 3517 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 3518 } 3519 3520 if (!m_useDynamicRendering) 3521 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 3522 3523 if (!clearPass) 3524 afterRenderPass(); 3525 3526 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 3527 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 3528} 3529 3530void MultiViewReadbackTestInstance::clear (const VkCommandBuffer commandBuffer, const VkRect2D& clearRect2D, const tcu::Vec4& clearColor) 3531{ 3532 const VkClearRect clearRect = 3533 { 3534 clearRect2D, // VkRect2D rect 3535 0u, // deUint32 baseArrayLayer 3536 1u, // deUint32 layerCount 3537 }; 3538 const VkClearAttachment clearAttachment = 3539 { 3540 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 3541 0u, // deUint32 colorAttachment 3542 makeClearValueColor(clearColor) // VkClearValue clearValue 3543 }; 3544 3545 m_device->cmdClearAttachments(commandBuffer, 1u, &clearAttachment, 1u, &clearRect); 3546} 3547 3548class MultiViewDepthStencilTestInstance : public MultiViewRenderTestInstance 3549{ 3550public: 3551 MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters); 3552protected: 3553 tcu::TestStatus iterate (void) override; 3554 void createVertexData (void) override; 3555 3556 void draw (const deUint32 subpassCount, 3557 VkRenderPass renderPass, 3558 VkFramebuffer frameBuffer, 3559 vector<PipelineSp>& pipelines) override; 3560 void beforeRenderPass (void) override; 3561 void afterRenderPass (void) override; 3562 vector<VkImageView> makeAttachmentsVector (void); 3563 MovePtr<tcu::Texture2DArray> imageData (void) const override; 3564 void readImage (VkImage image, 3565 const tcu::PixelBufferAccess& dst); 3566 vector<tcu::Vec2> getDepthRanges (void) const; 3567 3568private: 3569 VkFormat m_dsFormat; 3570 de::SharedPtr<ImageAttachment> m_dsAttachment; 3571 bool m_depthTest; 3572 bool m_stencilTest; 3573}; 3574 3575MultiViewDepthStencilTestInstance::MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters) 3576 : MultiViewRenderTestInstance (context, parameters) 3577 , m_dsFormat (VK_FORMAT_UNDEFINED) 3578 , m_depthTest (m_parameters.viewIndex == TEST_TYPE_DEPTH || 3579 m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES) 3580 , m_stencilTest (m_parameters.viewIndex == TEST_TYPE_STENCIL) 3581{ 3582 const VkFormat formats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT }; 3583 3584 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(formats); ++ndx) 3585 { 3586 const VkFormat format = formats[ndx]; 3587 const auto& vki = m_context.getInstanceInterface(); 3588 const auto physicalDevice = m_context.getPhysicalDevice(); 3589 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 3590 3591 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) 3592 { 3593 m_dsFormat = format; 3594 3595 break; 3596 } 3597 } 3598 3599 if (m_dsFormat == VK_FORMAT_UNDEFINED) 3600 TCU_FAIL("Supported depth/stencil format not found, that violates specification"); 3601 3602 // Depth/stencil attachment 3603 m_dsAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_dsFormat)); 3604} 3605 3606vector<VkImageView> MultiViewDepthStencilTestInstance::makeAttachmentsVector (void) 3607{ 3608 vector<VkImageView> attachments; 3609 3610 attachments.push_back(m_colorAttachment->getImageView()); 3611 attachments.push_back(m_dsAttachment->getImageView()); 3612 3613 return attachments; 3614} 3615 3616MovePtr<tcu::Texture2DArray> MultiViewDepthStencilTestInstance::imageData(void) const 3617{ 3618 MovePtr<tcu::Texture2DArray> referenceFrame = MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth)); 3619 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 3620 const vector<tcu::Vec2> depthRanges = getDepthRanges(); 3621 3622 referenceFrame->allocLevel(0); 3623 deMemset(referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize()); 3624 3625 for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx) 3626 fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, 0u, false), layerNdx); 3627 3628 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 3629 { 3630 int layerNdx = 0; 3631 deUint32 mask = m_parameters.viewMasks[subpassNdx]; 3632 const tcu::Vec2& depthRange = depthRanges[subpassNdx]; 3633 const float depthMin = depthRange[0]; 3634 const float depthMax = depthRange[1]; 3635 3636 // iterate over image layers 3637 while (mask > 0u) 3638 { 3639 if (mask & 1u) 3640 { 3641 const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount; 3642 const int colorNdx = subpassQuarterNdx * 4; 3643 tcu::Vec4 color = getQuarterRefColor(subpassQuarterNdx, colorNdx, layerNdx, true, subpassNdx); 3644 3645 if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES) 3646 { 3647 // quads with depth out of range should be cliiped 3648 // to simplify code we are drawing them with background color 3649 if ((color.x() < 0.0f) || (color.x() > 1.0f)) 3650 color.x() = 1.0f; 3651 else 3652 { 3653 const float depthClamped = de::clamp(color.x(), 0.0f, 1.0f); 3654 color.x() = depthClamped * depthMax + (1.0f - depthClamped) * depthMin; 3655 } 3656 } 3657 3658 fillQuarter(referenceFrame->getLevel(0), color, layerNdx, subpassQuarterNdx, subpassNdx); 3659 } 3660 3661 mask = mask >> 1; 3662 ++layerNdx; 3663 } 3664 } 3665 return referenceFrame; 3666} 3667 3668void MultiViewDepthStencilTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst) 3669{ 3670 const VkFormat bufferFormat = m_depthTest ? getDepthBufferFormat(m_dsFormat) : 3671 m_stencilTest ? getStencilBufferFormat(m_dsFormat) : 3672 VK_FORMAT_UNDEFINED; 3673 const deUint32 imagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(bufferFormat))); 3674 const VkDeviceSize pixelDataSize = dst.getWidth() * dst.getHeight() * dst.getDepth() * imagePixelSize; 3675 const tcu::TextureFormat tcuBufferFormat = mapVkFormat(bufferFormat); 3676 Move<VkBuffer> buffer; 3677 MovePtr<Allocation> bufferAlloc; 3678 3679 // Create destination buffer 3680 { 3681 const VkBufferCreateInfo bufferParams = 3682 { 3683 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3684 DE_NULL, // const void* pNext; 3685 0u, // VkBufferCreateFlags flags; 3686 pixelDataSize, // VkDeviceSize size; 3687 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 3688 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3689 1u, // deUint32 queueFamilyIndexCount; 3690 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3691 }; 3692 3693 buffer = createBuffer(*m_device, *m_logicalDevice, &bufferParams); 3694 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible); 3695 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 3696 3697 deMemset(bufferAlloc->getHostPtr(), 0xCC, static_cast<size_t>(pixelDataSize)); 3698 flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc); 3699 } 3700 3701 const VkBufferMemoryBarrier bufferBarrier = 3702 { 3703 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 3704 DE_NULL, // const void* pNext; 3705 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 3706 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 3707 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3708 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3709 *buffer, // VkBuffer buffer; 3710 0u, // VkDeviceSize offset; 3711 pixelDataSize // VkDeviceSize size; 3712 }; 3713 3714 // Copy image to buffer 3715 const VkImageAspectFlags aspect = m_depthTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) : 3716 m_stencilTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT) : 3717 static_cast<VkImageAspectFlags>(0u); 3718 const VkBufferImageCopy copyRegion = 3719 { 3720 0u, // VkDeviceSize bufferOffset; 3721 (deUint32)dst.getWidth(), // deUint32 bufferRowLength; 3722 (deUint32)dst.getHeight(), // deUint32 bufferImageHeight; 3723 { 3724 aspect, // VkImageAspectFlags aspect; 3725 0u, // deUint32 mipLevel; 3726 0u, // deUint32 baseArrayLayer; 3727 m_parameters.extent.depth, // deUint32 layerCount; 3728 }, // VkImageSubresourceLayers imageSubresource; 3729 { 0, 0, 0 }, // VkOffset3D imageOffset; 3730 { // VkExtent3D imageExtent; 3731 m_parameters.extent.width, 3732 m_parameters.extent.height, 3733 1u 3734 } 3735 }; 3736 3737 beginCommandBuffer (*m_device, *m_cmdBuffer); 3738 { 3739 m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); 3740 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); 3741 } 3742 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 3743 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 3744 3745 // Read buffer data 3746 invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc); 3747 3748 if (m_depthTest) 3749 { 3750 // Translate depth into color space 3751 tcu::ConstPixelBufferAccess pixelBuffer (tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr()); 3752 3753 for (int z = 0; z < pixelBuffer.getDepth(); z++) 3754 for (int y = 0; y < pixelBuffer.getHeight(); y++) 3755 for (int x = 0; x < pixelBuffer.getWidth(); x++) 3756 { 3757 const float depth = pixelBuffer.getPixDepth(x, y, z); 3758 const tcu::Vec4 color = tcu::Vec4(depth, 0.0f, 0.0f, 1.0f); 3759 3760 dst.setPixel(color, x, y, z); 3761 } 3762 } 3763 3764 if (m_stencilTest) 3765 { 3766 // Translate stencil into color space 3767 tcu::ConstPixelBufferAccess pixelBuffer (tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr()); 3768 const tcu::Vec4 baseColor = getQuarterRefColor(0u, 0u, 0u, false); 3769 const tcu::Vec4 colorStep = getQuarterRefColor(0u, 0u, 0u, true); 3770 const tcu::Vec4 colorMap[4] = 3771 { 3772 baseColor, 3773 tcu::Vec4(1.0f * colorStep[0], 0.0f, 0.0f, 1.0), 3774 tcu::Vec4(2.0f * colorStep[0], 0.0f, 0.0f, 1.0), 3775 tcu::Vec4(3.0f * colorStep[0], 0.0f, 0.0f, 1.0), 3776 }; 3777 const tcu::Vec4 invalidColor = tcu::Vec4(0.0f); 3778 3779 for (int z = 0; z < pixelBuffer.getDepth(); z++) 3780 for (int y = 0; y < pixelBuffer.getHeight(); y++) 3781 for (int x = 0; x < pixelBuffer.getWidth(); x++) 3782 { 3783 const int stencilInt = pixelBuffer.getPixStencil(x, y, z); 3784 const tcu::Vec4& color = de::inRange(stencilInt, 0, DE_LENGTH_OF_ARRAY(colorMap)) ? colorMap[stencilInt] : invalidColor; 3785 3786 dst.setPixel(color, x, y, z); 3787 } 3788 } 3789} 3790 3791tcu::TestStatus MultiViewDepthStencilTestInstance::iterate (void) 3792{ 3793 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 3794 Move<VkRenderPass> renderPass; 3795 vector<VkImageView> attachments (makeAttachmentsVector()); 3796 Move<VkFramebuffer> frameBuffer; 3797 Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(*m_device, *m_logicalDevice)); 3798 vector<PipelineSp> pipelines (subpassCount); 3799 const vector<tcu::Vec2> depthRanges (getDepthRanges()); 3800 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 3801 3802 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 3803 { 3804 renderPass = makeRenderPassWithDepth(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderingType); 3805 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u); 3806 } 3807 3808 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 3809 { 3810 renderPass = makeRenderPassWithDepth(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderingType); 3811 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u); 3812 } 3813 3814 { 3815 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 3816 madeShaderModule(shaderModule, shaderStageParams); 3817 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 3818 { 3819 const tcu::Vec2& depthRange = depthRanges[subpassNdx]; 3820 const float depthMin = depthRange[0]; 3821 const float depthMax = depthRange[1]; 3822 3823 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline( 3824 *renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), 3825 subpassNdx, VK_VERTEX_INPUT_RATE_VERTEX, m_depthTest, m_stencilTest, depthMin, depthMax, m_dsFormat)))); 3826 } 3827 } 3828 3829 createCommandBuffer(); 3830 createVertexData(); 3831 createVertexBuffer(); 3832 3833 draw(subpassCount, *renderPass, *frameBuffer, pipelines); 3834 3835 { 3836 vector<deUint8> pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize()); 3837 tcu::PixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data()); 3838 3839 readImage(m_dsAttachment->getImage(), dst); 3840 3841 if (!checkImage(dst)) 3842 return tcu::TestStatus::fail("Fail"); 3843 } 3844 3845 return tcu::TestStatus::pass("Pass"); 3846} 3847 3848void MultiViewDepthStencilTestInstance::createVertexData (void) 3849{ 3850/* 3851 partA - draw vertical quads, marked with 1 3852 3853 ViewMasks 3854 0011 3855 0110 3856 1100 3857 1001 3858 3859 Layer3 Layer2 Layer1 Layer0 3860 ^ ^ ^ ^ 3861 00|10 00|10 01|00 01|00 3862 00|10 00|10 01|00 01|00 3863 --+--> --+--> --+--> --+--> 3864 00|10 01|00 01|00 00|10 3865 00|10 01|00 01|00 00|10 3866 3867 3868 partB - draw horizontal quads, marked with 2 3869 3870 ViewMasks 3871 0110 3872 1100 3873 1001 3874 0011 3875 3876 Layer3 Layer2 Layer1 Layer0 3877 ^ ^ ^ ^ 3878 00|00 00|00 00|00 00|00 3879 00|22 22|00 22|00 00|22 3880 --+--> --+--> --+--> --+--> 3881 22|00 22|00 00|22 00|22 3882 00|00 00|00 00|00 00|00 3883 3884 3885 Final - after drawing quads from partA and partB (3 marks where quads overlap) 3886 3887 Layer3 Layer2 Layer1 Layer0 3888 ^ ^ ^ ^ 3889 00|10 00|10 01|00 01|00 3890 00|32 22|10 23|00 01|22 3891 --+--> --+--> --+--> --+--> 3892 22|10 23|00 01|22 00|32 3893 00|10 01|00 01|00 00|10 3894*/ 3895 tcu::Vec4 color (0.0f, 0.0f, 0.0f, 1.0f); // is not essential in this test 3896 float depth (getQuarterRefColor(0u, 0u, 0u, true, 0u)[0]); 3897 3898 // part A - four horizontal quads 3899 appendVertex(tcu::Vec4(-1.0f,-0.5f, depth, 1.0f), color); // when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES 3900 appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color); // this quad will have depth 1.2 3901 appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color); // and will be clipped in all views 3902 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3903 3904 depth = getQuarterRefColor(0u, 0u, 0u, true, 1u)[0]; 3905 appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color); 3906 appendVertex(tcu::Vec4(-1.0f, 0.5f, depth, 1.0f), color); 3907 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3908 appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color); 3909 3910 depth = getQuarterRefColor(0u, 0u, 0u, true, 2u)[0]; 3911 appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color); 3912 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3913 appendVertex(tcu::Vec4( 1.0f,-0.5f, depth, 1.0f), color); 3914 appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color); 3915 3916 depth = getQuarterRefColor(0u, 0u, 0u, true, 3u)[0]; 3917 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3918 appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color); 3919 appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color); 3920 appendVertex(tcu::Vec4( 1.0f, 0.5f, depth, 1.0f), color); 3921 3922 // part B - four vertical quads 3923 depth = getQuarterRefColor(0u, 0u, 0u, true, 4u)[0]; 3924 appendVertex(tcu::Vec4(-0.5f,-1.0f, depth, 1.0f), color); 3925 appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color); 3926 appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color); 3927 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3928 3929 depth = getQuarterRefColor(0u, 0u, 0u, true, 5u)[0]; 3930 appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color); 3931 appendVertex(tcu::Vec4(-0.5f, 1.0f, depth, 1.0f), color); 3932 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3933 appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color); 3934 3935 depth = getQuarterRefColor(0u, 0u, 0u, true, 6u)[0]; 3936 appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color); 3937 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); 3938 appendVertex(tcu::Vec4( 0.5f,-1.0f, depth, 1.0f), color); 3939 appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color); 3940 3941 depth = getQuarterRefColor(0u, 0u, 0u, true, 7u)[0]; // when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES 3942 appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color); // this quad will have depth -0.05 3943 appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color); // and will be clipped in all views 3944 appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color); 3945 appendVertex(tcu::Vec4( 0.5f, 1.0f, depth, 1.0f), color); 3946} 3947 3948vector<tcu::Vec2> MultiViewDepthStencilTestInstance::getDepthRanges(void) const 3949{ 3950 if (TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex) 3951 { 3952 DE_ASSERT(m_parameters.viewMasks.size() == 12); 3953 return 3954 { 3955 // ranges used when four quads from part A are drawn 3956 {0.0f, 1.0f}, 3957 {0.5f, 1.0f}, 3958 {0.0f, 0.5f}, 3959 {0.0f, 1.0f}, 3960 3961 // ranges used when four quads from part B are drawn 3962 {0.0f, 0.5f}, 3963 {0.0f, 1.0f}, 3964 {0.5f, 1.0f}, 3965 {0.0f, 0.5f}, 3966 3967 // ranges used when part B is drawn once again 3968 {0.5f, 1.0f}, 3969 {0.0f, 0.5f}, 3970 {0.0f, 0.5f}, 3971 {0.0f, 1.0f}, 3972 }; 3973 } 3974 3975 // by defaul use <0; 1> range for all subpasses 3976 return { m_parameters.viewMasks.size(), tcu::Vec2(0.0f, 1.0f) }; 3977} 3978 3979void MultiViewDepthStencilTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines) 3980{ 3981 const VkRect2D renderArea = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } }; 3982 const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f)); 3983 const VkBuffer vertexBuffers[] = { *m_vertexCoordBuffer, *m_vertexColorBuffer }; 3984 const VkDeviceSize vertexBufferOffsets[] = { 0u, 0u }; 3985 const deUint32 drawCountPerSubpass = (subpassCount == 1) ? m_squareCount : 1u; 3986 const deUint32 vertexPerPrimitive = 4u; 3987 3988 beginCommandBuffer(*m_device, *m_cmdBuffer); 3989 3990 beforeRenderPass(); 3991 3992 if (!m_useDynamicRendering) 3993 { 3994 const VkRenderPassBeginInfo renderPassBeginInfo 3995 { 3996 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 3997 DE_NULL, // const void* pNext; 3998 renderPass, // VkRenderPass renderPass; 3999 frameBuffer, // VkFramebuffer framebuffer; 4000 renderArea, // VkRect2D renderArea; 4001 1u, // uint32_t clearValueCount; 4002 &renderPassClearValue, // const VkClearValue* pClearValues; 4003 }; 4004 cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 4005 } 4006 4007 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++) 4008 { 4009 deUint32 firstVertexOffset = (subpassNdx < 4) ? 0u : m_squareCount * vertexPerPrimitive; 4010 4011 m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets); 4012 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]); 4013 4014#ifndef CTS_USES_VULKANSC 4015 if (m_useDynamicRendering) 4016 { 4017 addRenderingSubpassDependencyIfRequired(subpassNdx); 4018 4019 VkRenderingAttachmentInfoKHR colorAttachment 4020 { 4021 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 4022 DE_NULL, // const void* pNext; 4023 m_colorAttachment->getImageView(), // VkImageView imageView; 4024 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; 4025 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 4026 DE_NULL, // VkImageView resolveImageView; 4027 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 4028 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; 4029 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 4030 renderPassClearValue // VkClearValue clearValue; 4031 }; 4032 4033 VkRenderingAttachmentInfoKHR dsAttachment 4034 { 4035 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 4036 DE_NULL, // const void* pNext; 4037 m_dsAttachment->getImageView(), // VkImageView imageView; 4038 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; 4039 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 4040 DE_NULL, // VkImageView resolveImageView; 4041 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 4042 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; 4043 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 4044 makeClearValueDepthStencil(0.0f, 0) // VkClearValue clearValue; 4045 }; 4046 4047 vk::VkRenderingInfoKHR renderingInfo 4048 { 4049 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, 4050 DE_NULL, 4051 0u, // VkRenderingFlagsKHR flags; 4052 renderArea, // VkRect2D renderArea; 4053 m_parameters.extent.depth, // deUint32 layerCount; 4054 m_parameters.viewMasks[subpassNdx], // deUint32 viewMask; 4055 1u, // deUint32 colorAttachmentCount; 4056 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments; 4057 (m_depthTest ? &dsAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pDepthAttachment; 4058 (m_stencilTest ? &dsAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pStencilAttachment; 4059 }; 4060 4061 m_device->cmdBeginRendering(*m_cmdBuffer, &renderingInfo); 4062 } 4063#endif // CTS_USES_VULKANSC 4064 4065 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx) 4066 m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, firstVertexOffset + (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u); 4067 4068#ifndef CTS_USES_VULKANSC 4069 if (m_useDynamicRendering) 4070 endRendering(*m_device, *m_cmdBuffer); 4071 else 4072#endif // CTS_USES_VULKANSC 4073 if (subpassNdx < subpassCount - 1u) 4074 cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 4075 } 4076 4077 if (!m_useDynamicRendering) 4078 cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType); 4079 4080 afterRenderPass(); 4081 4082 VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer)); 4083 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer); 4084} 4085 4086void MultiViewDepthStencilTestInstance::beforeRenderPass (void) 4087{ 4088 MultiViewRenderTestInstance::beforeRenderPass(); 4089 4090 const VkImageSubresourceRange subresourceRange = 4091 { 4092 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, //VkImageAspectFlags aspectMask; 4093 0u, //deUint32 baseMipLevel; 4094 1u, //deUint32 levelCount; 4095 0u, //deUint32 baseArrayLayer; 4096 m_parameters.extent.depth, //deUint32 layerCount; 4097 }; 4098 imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange, 4099 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 4100 0, VK_ACCESS_TRANSFER_WRITE_BIT, 4101 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 4102 4103 const tcu::Vec4 baseColor = getQuarterRefColor(0u, 0u, 0u, false); 4104 const float clearDepth = baseColor[0]; 4105 const VkClearValue clearValue = makeClearValueDepthStencil(clearDepth, 0); 4106 4107 m_device->cmdClearDepthStencilImage(*m_cmdBuffer, m_dsAttachment->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange); 4108 4109 imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange, 4110 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 4111 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 4112 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); 4113} 4114 4115void MultiViewDepthStencilTestInstance::afterRenderPass (void) 4116{ 4117 MultiViewRenderTestInstance::afterRenderPass(); 4118 4119 const VkImageSubresourceRange dsSubresourceRange = 4120 { 4121 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask; 4122 0u, // deUint32 baseMipLevel; 4123 1u, // deUint32 levelCount; 4124 0u, // deUint32 baseArrayLayer; 4125 m_parameters.extent.depth, // deUint32 layerCount; 4126 }; 4127 4128 imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), dsSubresourceRange, 4129 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4130 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 4131 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 4132} 4133 4134class MultiViewMaskIterationTestInstance : public MultiViewRenderTestInstance 4135{ 4136public: 4137 MultiViewMaskIterationTestInstance (Context& context, const TestParameters& parameters); 4138protected: 4139 void beforeRender (const VkCommandBuffer cmdBuffer); 4140 void afterRender (const VkCommandBuffer cmdBuffer); 4141 tcu::TestStatus iterate (void) override; 4142 4143 using ImageWithBufferPtr = std::unique_ptr<ImageWithBuffer>; 4144 ImageWithBufferPtr m_colorImage; 4145 tcu::IVec3 m_dim; 4146 uint32_t m_layerCount; 4147 VkImageSubresourceRange m_colorSRR; 4148 VkClearValue m_clearValue; 4149}; 4150 4151MultiViewMaskIterationTestInstance::MultiViewMaskIterationTestInstance (Context& context, const TestParameters& parameters) 4152 : MultiViewRenderTestInstance (context, parameters) 4153{ 4154 m_dim = tcu::IVec3(m_parameters.extent.width, m_parameters.extent.height, 1); 4155 m_layerCount = m_parameters.extent.depth; 4156 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); 4157 m_colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_layerCount); 4158 m_colorImage = ImageWithBufferPtr (new ImageWithBuffer(*m_device, *m_logicalDevice, *m_allocator, makeExtent3D(m_dim), m_parameters.colorFormat, colorUsage, VK_IMAGE_TYPE_2D, m_colorSRR, m_layerCount)); 4159 m_clearValue = makeClearValueColor(tcu::Vec4(0)); 4160} 4161 4162 4163void MultiViewMaskIterationTestInstance::beforeRender (const VkCommandBuffer cmdBuffer) 4164{ 4165 imageBarrier(*m_device, cmdBuffer, m_colorImage->getImage(), m_colorSRR, 4166 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 4167 0, VK_ACCESS_TRANSFER_WRITE_BIT, 4168 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 4169 4170 4171 m_device->cmdClearColorImage(cmdBuffer, m_colorImage->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.color, 1u, &m_colorSRR); 4172 4173 imageBarrier(*m_device, cmdBuffer, m_colorImage->getImage(), m_colorSRR, 4174 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4175 VK_ACCESS_TRANSFER_WRITE_BIT, (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), 4176 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 4177} 4178 4179void MultiViewMaskIterationTestInstance::afterRender (const VkCommandBuffer cmdBuffer) 4180{ 4181 imageBarrier(*m_device, cmdBuffer, m_colorImage->getImage(), m_colorSRR, 4182 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4183 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), VK_ACCESS_TRANSFER_READ_BIT, 4184 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); 4185} 4186 4187tcu::TestStatus MultiViewMaskIterationTestInstance::iterate (void) 4188{ 4189 bool failure = false; 4190 const deUint32 subpassCount = static_cast<deUint32>(m_parameters.viewMasks.size()); 4191 const auto fbExtent = makeExtent3D(m_dim); 4192 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, m_layerCount); 4193 4194 map<VkShaderStageFlagBits, ShaderModuleSP> shaderModule; 4195 vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 4196 madeShaderModule(shaderModule, shaderStageParams); 4197 const VkShaderModule vertexShaderModule = shaderModule[VK_SHADER_STAGE_VERTEX_BIT]->get(); 4198 const VkShaderModule fragShaderModule = shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]->get(); 4199 4200 const std::vector<VkViewport> viewports (1u, makeViewport(fbExtent)); 4201 const std::vector<VkRect2D> scissors (1u, makeRect2D(fbExtent)); 4202 const auto pipelineLayout = makePipelineLayout(*m_device, *m_logicalDevice, VK_NULL_HANDLE); 4203 4204 const auto colorBlendAttState = makePipelineColorBlendAttachmentState(VK_FALSE, VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT)); 4205 4206 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = initVulkanStructure(); 4207 4208#ifndef CTS_USES_VULKANSC 4209 VkRenderingAttachmentInfoKHR renderingAttInfo = 4210 { 4211 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,// VkStructureType sType; 4212 nullptr, // const void* pNext; 4213 m_colorImage->getImageView(), // VkImageView imageView; 4214 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; 4215 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 4216 VK_NULL_HANDLE, // VkImageView resolveImageView; 4217 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 4218 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; 4219 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 4220 m_clearValue, // VkClearValue clearValue; 4221 }; 4222#endif 4223 4224 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx) 4225 { 4226 const auto layerMask = m_parameters.viewMasks[subpassNdx]; 4227 Move<VkRenderPass> renderPass; 4228 Move<VkFramebuffer> frameBuffer; 4229 4230 // FrameBuffer & renderPass 4231 if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) 4232 { 4233 const std::vector<deUint32> layerMasks (1u, layerMask); 4234 renderPass = makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, layerMasks, m_parameters.renderingType); 4235 frameBuffer = makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorImage->getImageView(), fbExtent.width, fbExtent.height); 4236 } 4237#ifndef CTS_USES_VULKANSC 4238 const VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = 4239 { 4240 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, // VkStructureType sType; 4241 nullptr, // const void* pNext; 4242 layerMask, // uint32_t viewMask; 4243 1u, // uint32_t colorAttachmentCount; 4244 &m_parameters.colorFormat, // const VkFormat* pColorAttachmentFormats; 4245 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat; 4246 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat; 4247 }; 4248#endif // CTS_USES_VULKANSC 4249 const std::vector<VkPipelineColorBlendAttachmentState> colorBlendStateVec (1u, colorBlendAttState); 4250 4251 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = 4252 { 4253 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 4254 nullptr, // const void* pNext; 4255 0u, // VkPipelineColorBlendStateCreateFlags flags; 4256 VK_FALSE, // VkBool32 logicOpEnable; 4257 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 4258 de::sizeU32(colorBlendStateVec), // uint32_t attachmentCount; 4259 de::dataOrNull(colorBlendStateVec), // const VkPipelineColorBlendAttachmentState* pAttachments; 4260 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 4261 }; 4262 4263 const auto pipeline = vk::makeGraphicsPipeline(*m_device, *m_logicalDevice, pipelineLayout.get(), 4264 vertexShaderModule, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShaderModule, 4265 *renderPass, viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u, 4266 &vertexInputStateCreateInfo, nullptr, nullptr, nullptr, &colorBlendStateCreateInfo, nullptr, 4267#ifndef CTS_USES_VULKANSC 4268 (*renderPass == 0) ? &pipelineRenderingCreateInfo : VK_NULL_HANDLE 4269#else 4270 VK_NULL_HANDLE 4271#endif // CTS_USES_VULKANSC 4272 ); 4273 4274 CommandPoolWithBuffer cmd (*m_device, *m_logicalDevice, m_queueFamilyIndex); 4275 const auto cmdBuffer = cmd.cmdBuffer.get(); 4276 4277 beginCommandBuffer(*m_device, cmdBuffer); 4278 4279 beforeRender(cmdBuffer); 4280 4281 if (!m_useDynamicRendering) 4282 { 4283 const VkRect2D renderArea = { { 0, 0 }, { fbExtent.width, fbExtent.height } }; 4284 const VkRenderPassBeginInfo renderPassBeginInfo 4285 { 4286 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 4287 DE_NULL, // const void* pNext; 4288 *renderPass, // VkRenderPass renderPass; 4289 *frameBuffer, // VkFramebuffer framebuffer; 4290 renderArea, // VkRect2D renderArea; 4291 1u, // uint32_t clearValueCount; 4292 &m_clearValue, // const VkClearValue* pClearValues; 4293 }; 4294 cmdBeginRenderPass(*m_device, cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType); 4295 } 4296#ifndef CTS_USES_VULKANSC 4297 else 4298 { 4299 const VkRenderingInfoKHR renderingInfo = 4300 { 4301 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, // VkStructureType sType; 4302 nullptr, // const void* pNext; 4303 0, // VkRenderingFlags flags; 4304 scissors.at(0u), // VkRect2D renderArea; 4305 m_layerCount, // uint32_t m_layerCount; 4306 layerMask, // uint32_t viewMask; 4307 1u, // uint32_t colorAttachmentCount; 4308 &renderingAttInfo, // const VkRenderingAttachmentInfo* pColorAttachments; 4309 DE_NULL, // const VkRenderingAttachmentInfo* pDepthAttachment; 4310 DE_NULL, // const VkRenderingAttachmentInfo* pStencilAttachment; 4311 }; 4312 4313 m_device->cmdBeginRendering(cmdBuffer, &renderingInfo); 4314 } 4315#endif // CTS_USES_VULKANSC 4316 4317 m_device->cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get()); 4318 4319 m_device->cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u); 4320 4321 4322 if (!m_useDynamicRendering) 4323 cmdEndRenderPass(*m_device, cmdBuffer, m_parameters.renderingType); 4324#ifndef CTS_USES_VULKANSC 4325 else 4326 m_device->cmdEndRendering(cmdBuffer); 4327#endif // CTS_USES_VULKANSC 4328 4329 afterRender(cmdBuffer); 4330 4331 // Copy all image contents to their verification buffers 4332 const auto copyRegion = makeBufferImageCopy(fbExtent, colorSRL); 4333 m_device->cmdCopyImageToBuffer(cmdBuffer, m_colorImage->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_colorImage->getBuffer(), 1u, ©Region); 4334 4335 // Global barrier to synchronize verification buffers to host reads. 4336 { 4337 const auto transfer2HostBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 4338 cmdPipelineMemoryBarrier(*m_device, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2HostBarrier); 4339 } 4340 4341 endCommandBuffer(*m_device, cmdBuffer); 4342 submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, cmdBuffer); 4343 4344 // Invalidate all allocations. 4345 invalidateAlloc(*m_device, *m_logicalDevice, m_colorImage->getBufferAllocation()); 4346 4347 // Verify all layers in all images. 4348 const auto colorTcuFormat = mapVkFormat(m_parameters.colorFormat); 4349 const auto colorPixelSize = tcu::getPixelSize(colorTcuFormat); 4350 const auto colorLayerSize = static_cast<size_t>(m_dim.x() * m_dim.y() * m_dim.z() * colorPixelSize); 4351 4352 const tcu::UVec4 threshold (0u, 0u, 0u, 0u); // We expect exact results. 4353 auto& log = m_context.getTestContext().getLog(); 4354 4355 const auto dataPtr = reinterpret_cast<const char*>(m_colorImage->getBufferAllocation().getHostPtr()); 4356 4357 for (uint32_t layerIdx = 0u; layerIdx < m_layerCount; ++layerIdx) 4358 { 4359 const bool layerWritten = ((layerMask & (1 << layerIdx)) != 0u); 4360 const auto layerDataPtr = dataPtr + colorLayerSize * layerIdx; 4361 const tcu::ConstPixelBufferAccess layerAccess (colorTcuFormat, m_dim, layerDataPtr); 4362 const tcu::UVec4 expectedColor = (layerWritten 4363 ? tcu::UVec4(layerIdx, 255u, 0, 255u) // Needs to match frag shader. 4364 : tcu::UVec4(0u, 0u, 0u, 0u)); 4365 const std::string logImgName = "ColorAttachment" + std::to_string(0) + "-Subpass" + std::to_string(subpassNdx) + "-Layer" + std::to_string(layerIdx); 4366 tcu::TextureLevel refLevel (colorTcuFormat, m_dim.x(), m_dim.y(), m_dim.z()); 4367 tcu::PixelBufferAccess refAccess = refLevel.getAccess(); 4368 4369 tcu::clear(refAccess, expectedColor); 4370 4371 if (!tcu::intThresholdCompare(log, logImgName.c_str(), "", refAccess, layerAccess, threshold, tcu::COMPARE_LOG_ON_ERROR)) 4372 failure = true; 4373 } 4374 } 4375 4376 if (failure) 4377 return tcu::TestStatus::fail("Invalid value found in verification buffers; check log for details"); 4378 4379 return tcu::TestStatus::pass("Pass"); 4380} 4381 4382class MultiViewRenderTestsCase : public vkt::TestCase 4383{ 4384public: 4385 MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const TestParameters& parameters) 4386 : TestCase (context, name) 4387 , m_parameters (parameters) 4388 { 4389 DE_ASSERT(m_parameters.extent.width == m_parameters.extent.height); 4390 } 4391private: 4392 const TestParameters m_parameters; 4393 4394 vkt::TestInstance* createInstance (vkt::Context& context) const 4395 { 4396 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex || 4397 TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex) 4398 return new MultiViewAttachmentsTestInstance(context, m_parameters); 4399 4400 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) 4401 return new MultiViewInstancedTestInstance(context, m_parameters); 4402 4403 if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 4404 return new MultiViewInputRateInstanceTestInstance(context, m_parameters); 4405 4406 if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex || 4407 TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex) 4408 return new MultiViewDrawIndirectTestInstance(context, m_parameters); 4409 4410 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex) 4411 return new MultiViewClearAttachmentsTestInstance(context, m_parameters); 4412 4413 if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex || 4414 TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex) 4415 return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters); 4416 4417 if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) 4418 return new MultiViewPointSizeTestInstance(context, m_parameters); 4419 4420 if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) 4421 return new MultiViewMultsampleTestInstance(context, m_parameters); 4422 4423 if (TEST_TYPE_QUERIES == m_parameters.viewIndex || 4424 TEST_TYPE_NON_PRECISE_QUERIES == m_parameters.viewIndex || 4425 TEST_TYPE_NON_PRECISE_QUERIES_WITH_AVAILABILITY == m_parameters.viewIndex) 4426 return new MultiViewQueriesTestInstance(context, m_parameters); 4427 4428 if (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex || 4429 TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex || 4430 TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex || 4431 TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex || 4432 TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex || 4433 TEST_TYPE_DRAW_INDEXED == m_parameters.viewIndex) 4434 return new MultiViewRenderTestInstance(context, m_parameters); 4435 if (TEST_TYPE_VIEW_MASK_ITERATION == m_parameters.viewIndex) 4436 return new MultiViewMaskIterationTestInstance(context, m_parameters); 4437 if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || 4438 TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex) 4439 return new MultiViewReadbackTestInstance(context, m_parameters); 4440 4441 if (TEST_TYPE_DEPTH == m_parameters.viewIndex || 4442 TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex || 4443 TEST_TYPE_STENCIL == m_parameters.viewIndex) 4444 return new MultiViewDepthStencilTestInstance(context, m_parameters); 4445 4446 TCU_THROW(InternalError, "Unknown test type"); 4447 } 4448 4449 virtual void checkSupport (Context& context) const 4450 { 4451 if (m_parameters.geometryShaderNeeded()) 4452 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER); 4453 4454 if (m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2) 4455 context.requireDeviceFunctionality("VK_KHR_create_renderpass2"); 4456 4457 if (m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) 4458 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering"); 4459 4460 context.requireDeviceFunctionality("VK_KHR_multiview"); 4461 4462 if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES) 4463 context.requireDeviceFunctionality("VK_EXT_depth_range_unrestricted"); 4464 if (m_parameters.viewIndex == TEST_TYPE_QUERIES) 4465 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE); 4466 4467#ifdef CTS_USES_VULKANSC 4468 const InstanceInterface& instance = context.getInstanceInterface(); 4469 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 4470 VkPhysicalDeviceMultiviewProperties multiviewProperties = 4471 { 4472 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, //VkStructureType sType; 4473 DE_NULL, //void* pNext; 4474 0u, //deUint32 maxMultiviewViewCount; 4475 0u //deUint32 maxMultiviewInstanceIndex; 4476 }; 4477 4478 VkPhysicalDeviceProperties2 propertiesDeviceProperties2; 4479 propertiesDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 4480 propertiesDeviceProperties2.pNext = &multiviewProperties; 4481 4482 instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2); 4483 4484 if (multiviewProperties.maxMultiviewViewCount < m_parameters.viewMasks.size()) 4485 TCU_THROW(NotSupportedError, "maxMultiviewViewCount is less than required by test"); 4486#endif // CTS_USES_VULKANSC 4487 } 4488 4489 void initPrograms (SourceCollections& programCollection) const 4490 { 4491 // Create vertex shader 4492 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) 4493 { 4494 std::ostringstream source; 4495 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4496 << "#extension GL_EXT_multiview : enable\n" 4497 << "layout(location = 0) in highp vec4 in_position;\n" 4498 << "layout(location = 1) in vec4 in_color;\n" 4499 << "layout(location = 0) out vec4 out_color;\n" 4500 << "void main (void)\n" 4501 << "{\n" 4502 << " int modInstance = gl_InstanceIndex % 4;\n" 4503 << " int instance = gl_InstanceIndex + 1;\n" 4504 << " gl_Position = in_position;\n" 4505 << " if (modInstance == 1)\n" 4506 << " gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n" 4507 << " if (modInstance == 2)\n" 4508 << " gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n" 4509 << " if (modInstance == 3)\n" 4510 << " gl_Position = in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n" 4511 << " out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n" 4512 << "}\n"; 4513 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 4514 } 4515 else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) 4516 { 4517 std::ostringstream source; 4518 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4519 << "#extension GL_EXT_multiview : enable\n" 4520 << "layout(location = 0) in highp vec4 in_position;\n" 4521 << "layout(location = 1) in vec4 in_color;\n" 4522 << "layout(location = 0) out vec4 out_color;\n" 4523 << "void main (void)\n" 4524 << "{\n" 4525 << " int instance = gl_InstanceIndex + 1;\n" 4526 << " gl_Position = in_position;\n" 4527 << " if (gl_VertexIndex == 1)\n" 4528 << " gl_Position.y += 1.0f;\n" 4529 << " else if (gl_VertexIndex == 2)\n" 4530 << " gl_Position.x += 1.0f;\n" 4531 << " else if (gl_VertexIndex == 3)\n" 4532 << " {\n" 4533 << " gl_Position.x += 1.0f;\n" 4534 << " gl_Position.y += 1.0f;\n" 4535 << " }\n" 4536 << " out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n" 4537 << "}\n"; 4538 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 4539 } 4540 else if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) 4541 { 4542 std::ostringstream source; 4543 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4544 << "#extension GL_EXT_multiview : enable\n" 4545 << "layout(location = 0) in highp vec4 in_position;\n" 4546 << "layout(location = 1) in highp vec4 in_color;\n" 4547 << "layout(location = 0) out vec4 out_color;\n" 4548 << "void main (void)\n" 4549 << "{\n" 4550 << " gl_Position = in_position;\n" 4551 << " if (gl_ViewIndex == 0)\n" 4552 << " gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_WIDE), 1) << "f;\n" 4553 << " else\n" 4554 << " gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_SMALL), 1) << "f;\n" 4555 << " out_color = in_color;\n" 4556 << "}\n"; 4557 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 4558 } 4559 else if (TEST_TYPE_VIEW_MASK_ITERATION == m_parameters.viewIndex) 4560 { 4561 std::ostringstream source; 4562 source 4563 << "#version 460\n" 4564 << "#extension GL_ARB_shader_viewport_layer_array : enable\n" 4565 << "vec2 positions[3] = vec2[](\n" 4566 << " vec2(-1.0, -1.0),\n" 4567 << " vec2(-1.0, 3.0),\n" 4568 << " vec2( 3.0, -1.0)\n" 4569 << ");\n" 4570 << "void main() {\n" 4571 << " gl_Position = vec4(positions[gl_VertexIndex % 3], 1.0, 1.0);\n" 4572 << "}\n" 4573 ; 4574 { 4575 const auto src = source.str(); 4576 const vk::ShaderBuildOptions spv15Opts (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_5, 0u, false); 4577 4578 programCollection.glslSources.add("vert-spv10") << glu::VertexSource(src); 4579 programCollection.glslSources.add("vert-spv15") << glu::VertexSource(src) << spv15Opts; 4580 } 4581 } 4582 else 4583 { 4584 const bool generateColor = (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex) 4585 || (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex) 4586 || (TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex) 4587 || (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex); 4588 std::ostringstream source; 4589 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4590 << "#extension GL_EXT_multiview : enable\n" 4591 << "layout(location = 0) in highp vec4 in_position;\n" 4592 << "layout(location = 1) in vec4 in_color;\n" 4593 << "layout(location = 0) out vec4 out_color;\n" 4594 << "void main (void)\n" 4595 << "{\n" 4596 << " gl_Position = in_position;\n"; 4597 if (generateColor) 4598 source << " out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"; 4599 else 4600 source << " out_color = in_color;\n"; 4601 source << "}\n"; 4602 programCollection.glslSources.add("vertex") << glu::VertexSource(source.str()); 4603 } 4604 4605 if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) 4606 {// Tessellation control & evaluation 4607 std::ostringstream source_tc; 4608 source_tc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4609 << "#extension GL_EXT_multiview : enable\n" 4610 << "#extension GL_EXT_tessellation_shader : require\n" 4611 << "layout(vertices = 4) out;\n" 4612 << "layout(location = 0) in vec4 in_color[];\n" 4613 << "layout(location = 0) out vec4 out_color[];\n" 4614 << "\n" 4615 << "void main (void)\n" 4616 << "{\n" 4617 << " if ( gl_InvocationID == 0 )\n" 4618 << " {\n" 4619 << " gl_TessLevelInner[0] = 4.0f;\n" 4620 << " gl_TessLevelInner[1] = 4.0f;\n" 4621 << " gl_TessLevelOuter[0] = 4.0f;\n" 4622 << " gl_TessLevelOuter[1] = 4.0f;\n" 4623 << " gl_TessLevelOuter[2] = 4.0f;\n" 4624 << " gl_TessLevelOuter[3] = 4.0f;\n" 4625 << " }\n" 4626 << " out_color[gl_InvocationID] = in_color[gl_InvocationID];\n" 4627 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 4628 << "}\n"; 4629 programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str()); 4630 4631 std::ostringstream source_te; 4632 source_te << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4633 << "#extension GL_EXT_multiview : enable\n" 4634 << "#extension GL_EXT_tessellation_shader : require\n" 4635 << "layout( quads, equal_spacing, ccw ) in;\n" 4636 << "layout(location = 0) in vec4 in_color[];\n" 4637 << "layout(location = 0) out vec4 out_color;\n" 4638 << "void main (void)\n" 4639 << "{\n" 4640 << " const float u = gl_TessCoord.x;\n" 4641 << " const float v = gl_TessCoord.y;\n" 4642 << " const float w = gl_TessCoord.z;\n" 4643 << " 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" 4644 << " out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 4645 << "}\n"; 4646 programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str()); 4647 } 4648 4649 if (m_parameters.geometryShaderNeeded()) 4650 {// Geometry Shader 4651 std::ostringstream source; 4652 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4653 << "#extension GL_EXT_multiview : enable\n" 4654 << "layout(triangles) in;\n" 4655 << "layout(triangle_strip, max_vertices = 16) out;\n" 4656 << "layout(location = 0) in vec4 in_color[];\n" 4657 << "layout(location = 0) out vec4 out_color;\n" 4658 << "void main (void)\n" 4659 << "{\n" 4660 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 4661 << " gl_Position = gl_in[0].gl_Position;\n" 4662 << " EmitVertex();\n" 4663 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 4664 << " gl_Position = gl_in[1].gl_Position;\n" 4665 << " EmitVertex();\n" 4666 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 4667 << " gl_Position = gl_in[2].gl_Position;\n" 4668 << " EmitVertex();\n" 4669 << " out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n" 4670 << " gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n" 4671 << " EmitVertex();\n" 4672 << " EndPrimitive();\n" 4673 << "}\n"; 4674 programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str()); 4675 } 4676 4677 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex) 4678 {// Create fragment shader read/write attachment 4679 std::ostringstream source; 4680 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4681 << "#extension GL_EXT_multiview : enable\n" 4682 << "layout(location = 0) in vec4 in_color;\n" 4683 << "layout(location = 0) out vec4 out_color;\n" 4684 << "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n" 4685 << "void main()\n" 4686 <<"{\n" 4687 << " out_color = vec4(subpassLoad(in_color_attachment));\n" 4688 << "}\n"; 4689 programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str()); 4690 } 4691 else if (TEST_TYPE_VIEW_MASK_ITERATION == m_parameters.viewIndex) 4692 { 4693 std::ostringstream source; 4694 source << "#version 460\n" 4695 << "#extension " << "GL_EXT_multiview" << " : enable\n" 4696 << "layout (location=" << 0 << ") out uvec4 color;\n" 4697 << "void main (void) {\n" 4698 << " const uint layerIndex = uint(gl_ViewIndex);\n" 4699 << " color = uvec4(layerIndex, 255, " << 0 << ", 255);\n" 4700 << "}\n" 4701 ; 4702 programCollection.glslSources.add("view_mask_iteration") << glu::FragmentSource(source.str()); 4703 } 4704 else 4705 {// Create fragment shader 4706 std::ostringstream source; 4707 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 4708 << "#extension GL_EXT_multiview : enable\n" 4709 << "layout(location = 0) in vec4 in_color;\n" 4710 << "layout(location = 0) out vec4 out_color;\n" 4711 << "void main()\n" 4712 <<"{\n"; 4713 if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex || 4714 TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex) 4715 source << " out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"; 4716 else 4717 source << " out_color = in_color;\n"; 4718 source << "}\n"; 4719 programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str()); 4720 } 4721 } 4722}; 4723} //anonymous 4724 4725static std::string createViewMasksName(const std::vector<deUint32>& viewMasks) 4726{ 4727 std::ostringstream masks; 4728 4729 for (size_t ndx = 0u; ndx < viewMasks.size(); ++ndx) 4730 { 4731 masks << viewMasks[ndx]; 4732 if (viewMasks.size() - 1 != ndx) 4733 masks << "_"; 4734 } 4735 4736 return masks.str(); 4737} 4738 4739static std::vector<deUint32> tripleDepthStencilMasks(std::vector<deUint32>& baseMasks) 4740{ 4741 std::vector<deUint32> tripledMasks(baseMasks); 4742 std::vector<deUint32> partBMasks; 4743 4744 // a,b,c,d => b,c,d,a 4745 partBMasks.insert(partBMasks.end(), baseMasks.begin() + 1, baseMasks.end()); 4746 partBMasks.push_back(baseMasks[0]); 4747 4748 tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end()); 4749 tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end()); 4750 4751 return tripledMasks; 4752} 4753 4754void multiViewRenderCreateTests (tcu::TestCaseGroup* group) 4755{ 4756 const deUint32 testCaseCount = 7u; 4757 const string shaderName[TEST_TYPE_LAST] = 4758 { 4759 "masks", 4760 "vertex_shader", 4761 "fragment_shader", 4762 "geometry_shader", 4763 "tessellation_shader", 4764 "input_attachments", 4765 "input_attachments_geometry", 4766 "instanced", 4767 "input_instance", 4768 "draw_indirect", 4769 "draw_indirect_indexed", 4770 "draw_indexed", 4771 "clear_attachments", 4772 "secondary_cmd_buffer", 4773 "secondary_cmd_buffer_geometry", 4774 "point_size", 4775 "multisample", 4776 "queries", 4777 "non_precise_queries", 4778 "non_precise_queries_with_availability", 4779 "readback_implicit_clear", 4780 "readback_explicit_clear", 4781 "depth", 4782 "depth_different_ranges", 4783 "stencil", 4784 "view_mask_iteration", 4785 }; 4786 const VkExtent3D extent3D[testCaseCount] = 4787 { 4788 {16u, 16u, 4u}, 4789 {64u, 64u, 8u}, 4790 {128u, 128u, 4u}, 4791 {32u, 32u, 5u}, 4792 {64u, 64u, 6u}, 4793 {32u, 32u, 4u}, 4794 {16u, 16u, 10u}, 4795 }; 4796 vector<deUint32> viewMasks[testCaseCount]; 4797 4798 viewMasks[0].push_back(15u); //1111 4799 4800 viewMasks[1].push_back(8u); //1000 4801 4802 viewMasks[2].push_back(1u); //0001 4803 viewMasks[2].push_back(2u); //0010 4804 viewMasks[2].push_back(4u); //0100 4805 viewMasks[2].push_back(8u); //1000 4806 4807 viewMasks[3].push_back(15u); //1111 4808 viewMasks[3].push_back(15u); //1111 4809 viewMasks[3].push_back(15u); //1111 4810 viewMasks[3].push_back(15u); //1111 4811 4812 viewMasks[4].push_back(8u); //1000 4813 viewMasks[4].push_back(1u); //0001 4814 viewMasks[4].push_back(1u); //0001 4815 viewMasks[4].push_back(8u); //1000 4816 4817 viewMasks[5].push_back(5u); //0101 4818 viewMasks[5].push_back(10u); //1010 4819 viewMasks[5].push_back(5u); //0101 4820 viewMasks[5].push_back(10u); //1010 4821 4822 const deUint32 minSupportedMultiviewViewCount = 6u; 4823 const deUint32 maxViewMask = (1u << minSupportedMultiviewViewCount) - 1u; 4824 4825 for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u) 4826 viewMasks[testCaseCount - 1].push_back(mask); 4827 4828 vector<deUint32> depthStencilMasks; 4829 4830 depthStencilMasks.push_back(3u); // 0011 4831 depthStencilMasks.push_back(6u); // 0110 4832 depthStencilMasks.push_back(12u); // 1100 4833 depthStencilMasks.push_back(9u); // 1001 4834 4835#ifndef CTS_USES_VULKANSC 4836 int numberOfRenderingTypes = 3; 4837#else 4838 int numberOfRenderingTypes = 2; 4839#endif // CTS_USES_VULKANSC 4840 4841 for (int renderPassTypeNdx = 0; renderPassTypeNdx < numberOfRenderingTypes; ++renderPassTypeNdx) 4842 { 4843 RenderingType renderPassType (RENDERING_TYPE_RENDERPASS_LEGACY); 4844 MovePtr<tcu::TestCaseGroup> targetGroup (DE_NULL); 4845 tcu::TestCaseGroup* targetGroupPtr (group); 4846 4847 if (renderPassTypeNdx == 1) 4848 { 4849 renderPassType = RENDERING_TYPE_RENDERPASS2; 4850 targetGroup = MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "renderpass2")); 4851 targetGroupPtr = targetGroup.get(); 4852 } 4853 else if (renderPassTypeNdx == 2) 4854 { 4855 renderPassType = RENDERING_TYPE_DYNAMIC_RENDERING; 4856 targetGroup = MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "dynamic_rendering")); 4857 targetGroupPtr = targetGroup.get(); 4858 } 4859 4860 tcu::TestContext& testCtx (targetGroupPtr->getTestContext()); 4861 // ViewIndex rendering tests. 4862 MovePtr<tcu::TestCaseGroup> groupViewIndex (new tcu::TestCaseGroup(testCtx, "index")); 4863 4864 for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx) 4865 { 4866 MovePtr<tcu::TestCaseGroup> groupShader (new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str())); 4867 const TestType testType = static_cast<TestType>(testTypeNdx); 4868 const VkSampleCountFlagBits sampleCountFlags = (testType == TEST_TYPE_MULTISAMPLE) ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT; 4869 VkFormat colorFormat; 4870 4871 if (testType == TEST_TYPE_MULTISAMPLE) 4872 colorFormat = VK_FORMAT_R32G32B32A32_SFLOAT; 4873 else if (testType == TEST_TYPE_VIEW_MASK_ITERATION) 4874 colorFormat = VK_FORMAT_R8G8B8A8_UINT; 4875 else 4876 colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 4877 4878 // subpassLoad can't be used with dynamic rendering 4879 if ((testTypeNdx == TEST_TYPE_INPUT_ATTACHMENTS) && (renderPassType == RENDERING_TYPE_DYNAMIC_RENDERING)) 4880 continue; 4881 4882 if (testTypeNdx == TEST_TYPE_VIEW_MASK_ITERATION) 4883 { 4884 for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx) 4885 { 4886 const TestParameters parameters = { extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, QUERY_TYPE_GET_QUERY_POOL_RESULTS, renderPassType }; 4887 const std::string testName = createViewMasksName(parameters.viewMasks); 4888 4889 groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), parameters)); 4890 } 4891 } 4892 else 4893 { 4894 for (int queryTypeNdx = 0; queryTypeNdx < 2; ++queryTypeNdx) 4895 { 4896 const std::string queryTestName = queryTypeNdx == 0 ? "get_query_pool_results" : "cmd_copy_query_pool_results"; 4897 const auto queryType = queryTypeNdx == 0 ? QUERY_TYPE_GET_QUERY_POOL_RESULTS : QUERY_TYPE_CMD_COPY_QUERY_POOL_RESULTS; 4898 MovePtr<tcu::TestCaseGroup> queryTypeGroup(new tcu::TestCaseGroup(testCtx, queryTestName.c_str())); 4899 4900 if (testTypeNdx == TEST_TYPE_DEPTH || 4901 testTypeNdx == TEST_TYPE_DEPTH_DIFFERENT_RANGES || 4902 testTypeNdx == TEST_TYPE_STENCIL) 4903 { 4904 const VkExtent3D dsTestExtent3D = { 64u, 64u, 4u }; 4905 const TestParameters parameters = { dsTestExtent3D, tripleDepthStencilMasks(depthStencilMasks), testType, sampleCountFlags, colorFormat, queryType, renderPassType }; 4906 const std::string testName = createViewMasksName(parameters.viewMasks); 4907 4908 queryTypeGroup->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), parameters)); 4909 } 4910 else 4911 { 4912 for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx) 4913 { 4914 const TestParameters parameters = { extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, queryType, renderPassType }; 4915 const std::string testName = createViewMasksName(parameters.viewMasks); 4916 4917 queryTypeGroup->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), parameters)); 4918 } 4919 4920 // maxMultiviewViewCount case 4921 { 4922 const VkExtent3D incompleteExtent3D = { 16u, 16u, 0u }; 4923 const vector<deUint32> unusedMasks; 4924 const TestParameters parameters = { incompleteExtent3D, unusedMasks, testType, sampleCountFlags, colorFormat, queryType, renderPassType }; 4925 4926 queryTypeGroup->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", parameters)); 4927 } 4928 } 4929 groupShader->addChild(queryTypeGroup.release()); 4930 } 4931 } 4932 4933 switch (testType) 4934 { 4935 case TEST_TYPE_VIEW_MASK: 4936 case TEST_TYPE_INPUT_ATTACHMENTS: 4937 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY: 4938 case TEST_TYPE_INSTANCED_RENDERING: 4939 case TEST_TYPE_INPUT_RATE_INSTANCE: 4940 case TEST_TYPE_DRAW_INDIRECT: 4941 case TEST_TYPE_DRAW_INDIRECT_INDEXED: 4942 case TEST_TYPE_DRAW_INDEXED: 4943 case TEST_TYPE_CLEAR_ATTACHMENTS: 4944 case TEST_TYPE_SECONDARY_CMD_BUFFER: 4945 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY: 4946 case TEST_TYPE_POINT_SIZE: 4947 case TEST_TYPE_MULTISAMPLE: 4948 case TEST_TYPE_QUERIES: 4949 case TEST_TYPE_NON_PRECISE_QUERIES: 4950 case TEST_TYPE_NON_PRECISE_QUERIES_WITH_AVAILABILITY: 4951 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR: 4952 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR: 4953 case TEST_TYPE_DEPTH: 4954 case TEST_TYPE_DEPTH_DIFFERENT_RANGES: 4955 case TEST_TYPE_STENCIL: 4956 case TEST_TYPE_VIEW_MASK_ITERATION: 4957 targetGroupPtr->addChild(groupShader.release()); 4958 break; 4959 case TEST_TYPE_VIEW_INDEX_IN_VERTEX: 4960 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT: 4961 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY: 4962 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION: 4963 groupViewIndex->addChild(groupShader.release()); 4964 break; 4965 default: 4966 DE_ASSERT(0); 4967 break; 4968 } 4969 } 4970 4971 targetGroupPtr->addChild(groupViewIndex.release()); 4972 4973 if (renderPassType != RENDERING_TYPE_RENDERPASS_LEGACY) 4974 group->addChild(targetGroup.release()); 4975 } 4976} 4977 4978} //MultiView 4979} //vkt 4980