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