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