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