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