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