Fix Fedora 32 gcc/clang warnings
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / conditional_rendering / vktConditionalDrawTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev@gmail.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Test for conditional rendering of vkCmdDraw* functions
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktConditionalDrawTests.hpp"
26 #include "vktConditionalRenderingTestUtil.hpp"
27
28 #include "vktTestCaseUtil.hpp"
29 #include "vktDrawTestCaseUtil.hpp"
30
31 #include "vktDrawBaseClass.hpp"
32
33 #include "tcuTestLog.hpp"
34 #include "tcuResource.hpp"
35 #include "tcuImageCompare.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuRGBA.hpp"
38
39 #include "vkDefs.hpp"
40 #include "vkCmdUtil.hpp"
41
42 namespace vkt
43 {
44 namespace conditional
45 {
46 namespace
47 {
48
49 enum DrawCommandType
50 {
51         DRAW_COMMAND_TYPE_DRAW = 0,
52         DRAW_COMMAND_TYPE_DRAW_INDEXED,
53         DRAW_COMMAND_TYPE_DRAW_INDIRECT,
54         DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT,
55         DRAW_COMMAND_TYPE_DRAW_INDIRECT_COUNT,
56         DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT_COUNT,
57
58         DRAW_COMMAND_TYPE_DRAW_LAST
59 };
60
61 const char* getDrawCommandTypeName (DrawCommandType command)
62 {
63         switch (command)
64         {
65                 case DRAW_COMMAND_TYPE_DRAW:                                        return "draw";
66                 case DRAW_COMMAND_TYPE_DRAW_INDEXED:                        return "draw_indexed";
67                 case DRAW_COMMAND_TYPE_DRAW_INDIRECT:                       return "draw_indirect";
68                 case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:       return "draw_indexed_indirect";
69                 case DRAW_COMMAND_TYPE_DRAW_INDIRECT_COUNT:                     return "draw_indirect_count";
70                 case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT_COUNT:     return "draw_indexed_indirect_count";
71                 default:                                                                DE_ASSERT(false);
72         }
73         return "";
74 }
75
76 struct ConditionalTestSpec : public Draw::TestSpecBase
77 {
78         DrawCommandType         command;
79         deUint32                        drawCalls;
80         ConditionalData         conditionalData;
81 };
82
83 class ConditionalDraw : public Draw::DrawTestsBaseClass
84 {
85 public:
86         typedef         ConditionalTestSpec     TestSpec;
87
88                                                                 ConditionalDraw                         (Context &context, ConditionalTestSpec testSpec);
89
90         virtual         tcu::TestStatus iterate                                         (void);
91                                 void                    createAndBindIndexBuffer        (vk::VkCommandBuffer cmdBuffer);
92                                 void                    createIndirectBuffer            (void);
93                                 void                    createIndexedIndirectBuffer     (void);
94                                 void                    createIndirectCountBuffer       (void);
95                                 void                    recordDraw                                      (vk::VkCommandBuffer cmdBuffer);
96
97 protected:
98         const DrawCommandType               m_command;
99         const deUint32                                  m_drawCalls;
100
101         const ConditionalData                   m_conditionalData;
102         de::SharedPtr<Draw::Buffer>             m_conditionalBuffer;
103
104         vk::Move<vk::VkCommandBuffer>   m_secondaryCmdBuffer;
105
106         std::vector<deUint32>               m_indexes;
107         de::SharedPtr<Draw::Buffer>             m_indexBuffer;
108
109         de::SharedPtr<Draw::Buffer>             m_indirectBuffer;
110         de::SharedPtr<Draw::Buffer>             m_indirectCountBuffer;
111 };
112
113 ConditionalDraw::ConditionalDraw (Context &context, ConditionalTestSpec testSpec)
114         : Draw::DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
115         , m_command(testSpec.command)
116         , m_drawCalls(testSpec.drawCalls)
117         , m_conditionalData(testSpec.conditionalData)
118 {
119         checkConditionalRenderingCapabilities(context, m_conditionalData);
120
121         const float minX = -0.3f;
122         const float maxX = 0.3f;
123         const float drawStep = 0.6f / static_cast<float>(m_drawCalls);
124
125         for (deUint32 drawIdx = 0; drawIdx < m_drawCalls; drawIdx++)
126         {
127                 const float minY = minX + static_cast<float>(drawIdx) * drawStep;
128                 const float maxY = minY + drawStep;
129
130                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     minX,   maxY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
131                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     minX,   minY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
132                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     maxX,   maxY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
133
134                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     minX,   minY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
135                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     maxX,   maxY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
136                 m_data.push_back(Draw::VertexElementData(tcu::Vec4(     maxX,   minY,   0.5f,   1.0f), tcu::RGBA::blue().toVec(), 0));
137         }
138
139         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     -1.0f,  1.0f,   0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
140         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     -1.0f,  -1.0f,  0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
141         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     1.0f,   1.0f,   0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
142
143         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     -1.0f,  -1.0f,  0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
144         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     1.0f,   1.0f,   0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
145         m_data.push_back(Draw::VertexElementData(tcu::Vec4(     1.0f,   -1.0f,  0.0f,   1.0f), tcu::RGBA::red().toVec(), 0));
146
147         for (deUint32 index = 0; index < m_data.size(); index++)
148         {
149                 m_indexes.push_back(index);
150         }
151
152         initialize();
153
154         m_secondaryCmdBuffer = vk::allocateCommandBuffer(m_vk, m_context.getDevice(), *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY);
155 };
156
157 void ConditionalDraw::createAndBindIndexBuffer (vk::VkCommandBuffer cmdBuffer)
158 {
159         const vk::VkDeviceSize indexDataSize = m_indexes.size() * sizeof(deUint32);
160         m_indexBuffer = Draw::Buffer::createAndAlloc(m_vk, m_context.getDevice(),
161                                                                                         Draw::BufferCreateInfo(indexDataSize,
162                                                                                                                         vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT),
163                                                                                         m_context.getDefaultAllocator(),
164                                                                                         vk::MemoryRequirement::HostVisible);
165
166         deUint8* indexBufferPtr = reinterpret_cast<deUint8*>(m_indexBuffer->getBoundMemory().getHostPtr());
167         deMemcpy(indexBufferPtr, &m_indexes[0], static_cast<size_t>(indexDataSize));
168
169         vk::flushAlloc(m_vk, m_context.getDevice(), m_indexBuffer->getBoundMemory());
170
171         const vk::VkBuffer indexBuffer = m_indexBuffer->object();
172         m_vk.cmdBindIndexBuffer(cmdBuffer, indexBuffer, 0, vk::VK_INDEX_TYPE_UINT32);
173 }
174
175 void ConditionalDraw::createIndirectBuffer (void)
176 {
177         const vk::VkDrawIndirectCommand badDrawCommand =
178         {
179                 6u,                                     // vertexCount
180                 1u,                                     // instanceCount
181                 m_drawCalls * 6u,       // firstVertex
182                 0u                                      // firstInstance
183         };
184
185         std::vector<vk::VkDrawIndirectCommand> drawCommands;
186         for (deUint32 drawIdx = 0; drawIdx < m_drawCalls; drawIdx++)
187         {
188                 const vk::VkDrawIndirectCommand goodDrawCommand =
189                 {
190                         6u,                             // vertexCount
191                         1u,                             // instanceCount
192                         6u * drawIdx,   // firstVertex
193                         0u                              // firstInstance
194                 };
195
196                 drawCommands.push_back(goodDrawCommand);
197                 // *Bad* commands should not be rendered by vkCmdDrawIndirectCountKHR
198                 drawCommands.push_back(badDrawCommand);
199                 drawCommands.push_back(badDrawCommand);
200         }
201
202         const vk::VkDeviceSize drawCommandsSize = drawCommands.size() * sizeof(vk::VkDrawIndirectCommand);
203
204         m_indirectBuffer = Draw::Buffer::createAndAlloc(m_vk,
205                                                                                                         m_context.getDevice(),
206                                                                                                         Draw::BufferCreateInfo(drawCommandsSize,
207                                                                                                                                         vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT),
208                                                                                                         m_context.getDefaultAllocator(),
209                                                                                                         vk::MemoryRequirement::HostVisible);
210
211         deUint8* ptr = reinterpret_cast<deUint8*>(m_indirectBuffer->getBoundMemory().getHostPtr());
212         deMemcpy(ptr, &drawCommands[0], static_cast<size_t>(drawCommandsSize));
213
214         vk::flushAlloc(m_vk, m_context.getDevice(), m_indirectBuffer->getBoundMemory());
215 }
216
217 void ConditionalDraw::createIndexedIndirectBuffer (void)
218 {
219         const vk::VkDrawIndexedIndirectCommand badDrawCommand =
220         {
221                 6u,                                     // indexCount
222                 1u,                                     // instanceCount
223                 m_drawCalls * 6u,       // firstIndex
224                 0u,                                     // vertexOffset
225                 0u,                                     // firstInstance
226         };
227
228         std::vector<vk::VkDrawIndexedIndirectCommand> drawCommands;
229         for (deUint32 drawIdx = 0; drawIdx < m_drawCalls; drawIdx++)
230         {
231                 const vk::VkDrawIndexedIndirectCommand goodDrawCommand =
232                 {
233                         6u,                             // indexCount
234                         1u,                             // instanceCount
235                         6u * drawIdx,   // firstIndex
236                         0u,                             // vertexOffset
237                         0u,                             // firstInstance
238                 };
239
240                 drawCommands.push_back(goodDrawCommand);
241                 // *Bad* commands should not be rendered by vkCmdDrawIndexedIndirectCountKHR
242                 drawCommands.push_back(badDrawCommand);
243                 drawCommands.push_back(badDrawCommand);
244         }
245
246         const vk::VkDeviceSize drawCommandsSize = drawCommands.size() * sizeof(vk::VkDrawIndexedIndirectCommand);
247
248         m_indirectBuffer = Draw::Buffer::createAndAlloc(m_vk,
249                                                                                                         m_context.getDevice(),
250                                                                                                         Draw::BufferCreateInfo(drawCommandsSize,
251                                                                                                                                         vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT),
252                                                                                                         m_context.getDefaultAllocator(),
253                                                                                                         vk::MemoryRequirement::HostVisible);
254
255         deUint8* ptr = reinterpret_cast<deUint8*>(m_indirectBuffer->getBoundMemory().getHostPtr());
256         deMemcpy(ptr, &drawCommands[0], static_cast<size_t>(drawCommandsSize));
257
258         vk::flushAlloc(m_vk, m_context.getDevice(), m_indirectBuffer->getBoundMemory());
259 }
260
261 void ConditionalDraw::createIndirectCountBuffer (void)
262 {
263         m_indirectCountBuffer = Draw::Buffer::createAndAlloc(m_vk,
264                                                                                                                 m_context.getDevice(),
265                                                                                                                 Draw::BufferCreateInfo(sizeof(deUint32),
266                                                                                                                                                         vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT),
267                                                                                                                 m_context.getDefaultAllocator(),
268                                                                                                                 vk::MemoryRequirement::HostVisible);
269
270         deUint8* countBufferPtr = reinterpret_cast<deUint8*>(m_indirectCountBuffer->getBoundMemory().getHostPtr());
271         *(deUint32*)(countBufferPtr) = 1;
272
273         vk::flushAlloc(m_vk, m_context.getDevice(), m_indirectCountBuffer->getBoundMemory());
274 }
275
276 void ConditionalDraw::recordDraw(vk::VkCommandBuffer cmdBuffer)
277 {
278         for (deUint32 drawIdx = 0; drawIdx < m_drawCalls; drawIdx++)
279         {
280                 /* Indirect buffer has next layout:
281                  * goodCommand badCommand badCommand goodCommand badCommand badCommand ...
282                  */
283                 const vk::VkDeviceSize indirectOffset = sizeof(vk::VkDrawIndirectCommand) * drawIdx * 3;
284                 const vk::VkDeviceSize indexedIndirectOffset = sizeof(vk::VkDrawIndexedIndirectCommand) * drawIdx * 3;
285                 switch (m_command)
286                 {
287                         case DRAW_COMMAND_TYPE_DRAW:
288                         {
289                                 m_vk.cmdDraw(cmdBuffer, 6, 1, 6 * drawIdx, 0);
290                                 break;
291                         }
292                         case DRAW_COMMAND_TYPE_DRAW_INDEXED:
293                         {
294                                 m_vk.cmdDrawIndexed(cmdBuffer, 6, 1, 6 * drawIdx, 0, 0);
295                                 break;
296                         }
297                         case DRAW_COMMAND_TYPE_DRAW_INDIRECT:
298                         {
299                                 m_vk.cmdDrawIndirect(cmdBuffer, m_indirectBuffer->object(), indirectOffset, 1, 0);
300                                 break;
301                         }
302                         case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:
303                         {
304                                 m_vk.cmdDrawIndexedIndirect(cmdBuffer, m_indirectBuffer->object(), indexedIndirectOffset, 1, 0);
305                                 break;
306                         }
307                         case DRAW_COMMAND_TYPE_DRAW_INDIRECT_COUNT:
308                         {
309                                 m_vk.cmdDrawIndirectCount(      cmdBuffer,
310                                                                                         m_indirectBuffer->object(), indirectOffset,
311                                                                                         m_indirectCountBuffer->object(), 0, 3,
312                                                                                         sizeof(vk::VkDrawIndirectCommand));
313                                 break;
314                         }
315                         case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT_COUNT:
316                         {
317                                 m_vk.cmdDrawIndexedIndirectCount(cmdBuffer,
318                                                                                                  m_indirectBuffer->object(), indexedIndirectOffset,
319                                                                                                  m_indirectCountBuffer->object(), 0, 3,
320                                                                                                  sizeof(vk::VkDrawIndexedIndirectCommand));
321                                 break;
322                         }
323                         default: DE_ASSERT(false);
324                 }
325         }
326 }
327
328 tcu::TestStatus ConditionalDraw::iterate (void)
329 {
330         tcu::TestLog&           log             = m_context.getTestContext().getLog();
331         const vk::VkQueue       queue   = m_context.getUniversalQueue();
332         const vk::VkDevice      device  = m_context.getDevice();
333
334         const bool useSecondaryCmdBuffer = m_conditionalData.conditionInherited || m_conditionalData.conditionInSecondaryCommandBuffer;
335         beginRenderPass(useSecondaryCmdBuffer ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : vk::VK_SUBPASS_CONTENTS_INLINE);
336
337         vk::VkCommandBuffer targetCmdBuffer = *m_cmdBuffer;
338
339         if (useSecondaryCmdBuffer)
340         {
341                 const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo =
342                 {
343                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
344                         DE_NULL,
345                         m_conditionalData.conditionInherited ? VK_TRUE : VK_FALSE       // conditionalRenderingEnable
346                 };
347
348                 const vk::VkCommandBufferInheritanceInfo inheritanceInfo =
349                 {
350                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
351                         &conditionalRenderingInheritanceInfo,
352                         *m_renderPass,                                                                                  // renderPass
353                         0u,                                                                                                                     // subpass
354                         *m_framebuffer,                                                                                 // framebuffer
355                         VK_FALSE,                                                                                                       // occlusionQueryEnable
356                         (vk::VkQueryControlFlags)0u,                                                            // queryFlags
357                         (vk::VkQueryPipelineStatisticFlags)0u,                                          // pipelineStatistics
358                 };
359
360                 const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
361                 {
362                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
363                         DE_NULL,
364                         vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
365                         &inheritanceInfo
366                 };
367
368                 m_vk.beginCommandBuffer(*m_secondaryCmdBuffer, &commandBufferBeginInfo);
369
370                 targetCmdBuffer = *m_secondaryCmdBuffer;
371         }
372
373         const vk::VkDeviceSize vertexBufferOffset = 0;
374         const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
375
376         m_vk.cmdBindVertexBuffers(targetCmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
377
378         switch(m_command)
379         {
380                 case DRAW_COMMAND_TYPE_DRAW:
381                 {
382                         break;
383                 }
384                 case DRAW_COMMAND_TYPE_DRAW_INDEXED:
385                 {
386                         createAndBindIndexBuffer(targetCmdBuffer);
387                         break;
388                 }
389                 case DRAW_COMMAND_TYPE_DRAW_INDIRECT:
390                 {
391                         createIndirectBuffer();
392                         break;
393                 }
394                 case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:
395                 {
396                         createAndBindIndexBuffer(targetCmdBuffer);
397                         createIndexedIndirectBuffer();
398                         break;
399                 }
400                 case DRAW_COMMAND_TYPE_DRAW_INDIRECT_COUNT:
401                 {
402                         createIndirectBuffer();
403                         createIndirectCountBuffer();
404                         break;
405                 }
406                 case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT_COUNT:
407                 {
408                         createAndBindIndexBuffer(targetCmdBuffer);
409                         createIndexedIndirectBuffer();
410                         createIndirectCountBuffer();
411                         break;
412                 }
413                 default: DE_ASSERT(false);
414         }
415
416         m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
417
418         m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
419
420         if (m_conditionalData.conditionInSecondaryCommandBuffer)
421         {
422                 beginConditionalRendering(m_vk, *m_secondaryCmdBuffer, *m_conditionalBuffer, m_conditionalData);
423                 recordDraw(*m_secondaryCmdBuffer);
424                 m_vk.cmdEndConditionalRenderingEXT(*m_secondaryCmdBuffer);
425                 m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
426         }
427         else if (m_conditionalData.conditionInherited)
428         {
429                 recordDraw(*m_secondaryCmdBuffer);
430                 m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
431         }
432
433         if (m_conditionalData.conditionInPrimaryCommandBuffer)
434         {
435                 beginConditionalRendering(m_vk, *m_cmdBuffer, *m_conditionalBuffer, m_conditionalData);
436
437                 if (m_conditionalData.conditionInherited)
438                 {
439                         m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
440                 }
441                 else
442                 {
443                         recordDraw(*m_cmdBuffer);
444                 }
445
446                 m_vk.cmdEndConditionalRenderingEXT(*m_cmdBuffer);
447         }
448         else if (useSecondaryCmdBuffer)
449         {
450                 m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
451         }
452
453         endRenderPass(m_vk, *m_cmdBuffer);
454         endCommandBuffer(m_vk, *m_cmdBuffer);
455
456         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
457
458         // Validation
459         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
460                                                                   referenceFrame.allocLevel(0);
461
462         const deInt32 frameWidth        = referenceFrame.getWidth();
463         const deInt32 frameHeight       = referenceFrame.getHeight();
464
465         const tcu::Vec4 clearColor = tcu::RGBA::black().toVec();
466         const tcu::Vec4 drawColor  = tcu::RGBA::blue().toVec();
467
468         tcu::clear(referenceFrame.getLevel(0), clearColor);
469
470         const tcu::Vec4 referenceColor = m_conditionalData.expectCommandExecution ?
471                                                                                 drawColor : clearColor;
472
473         Draw::ReferenceImageCoordinates refCoords;
474
475         for (int y = 0; y < frameHeight; y++)
476         {
477                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
478
479                 for (int x = 0; x < frameWidth; x++)
480                 {
481                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
482
483                         if ((yCoord >= refCoords.bottom &&
484                                  yCoord <= refCoords.top        &&
485                                  xCoord >= refCoords.left       &&
486                                  xCoord <= refCoords.right))
487                                 referenceFrame.getLevel(0).setPixel(referenceColor, x, y);
488                 }
489         }
490
491         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
492         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
493                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
494
495         qpTestResult res = QP_TEST_RESULT_PASS;
496
497         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
498                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
499                 tcu::COMPARE_LOG_RESULT))
500         {
501                 res = QP_TEST_RESULT_FAIL;
502         }
503
504         return tcu::TestStatus(res, qpGetTestResultName(res));
505 };
506
507 }       // anonymous
508
509 ConditionalDrawTests::ConditionalDrawTests (tcu::TestContext &testCtx)
510         : TestCaseGroup (testCtx, "draw", "Conditional Rendering Of Draw Commands")
511 {
512         /* Left blank on purpose */
513 }
514
515 ConditionalDrawTests::~ConditionalDrawTests (void) {}
516
517 void ConditionalDrawTests::init (void)
518 {
519         for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++)
520         {
521                 const ConditionalData& conditionData = conditional::s_testsData[conditionNdx];
522
523                 tcu::TestCaseGroup* conditionalDrawRootGroup = new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), "Conditionaly execute draw calls");
524
525                 for (deUint32 commandTypeIdx = 0; commandTypeIdx < DRAW_COMMAND_TYPE_DRAW_LAST; ++commandTypeIdx)
526                 {
527                         const DrawCommandType   command = DrawCommandType(commandTypeIdx);
528
529                         ConditionalTestSpec testSpec;
530                         testSpec.command = command;
531                         testSpec.drawCalls = 4;
532                         testSpec.conditionalData = conditionData;
533                         testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
534                         testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
535
536                         conditionalDrawRootGroup->addChild(new Draw::InstanceFactory<ConditionalDraw>(m_testCtx, getDrawCommandTypeName(command), "", testSpec));
537                 }
538
539                 addChild(conditionalDrawRootGroup);
540         }
541 }
542
543 }       // conditional
544 }       // vkt