dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawIndirectTest.cpp
1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
18 *
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
22 *
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30 *
31 *//*!
32 * \file
33 * \brief Draw Indirect Test
34 *//*--------------------------------------------------------------------*/
35
36 #include "vktDrawIndirectTest.hpp"
37
38 #include "vktTestCaseUtil.hpp"
39 #include "vktDrawTestCaseUtil.hpp"
40
41 #include "vktDrawBaseClass.hpp"
42
43 #include "tcuTestLog.hpp"
44 #include "tcuResource.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuRGBA.hpp"
48
49 #include "vkDefs.hpp"
50
51 namespace vkt
52 {
53 namespace Draw
54 {
55 namespace
56 {
57 struct JunkData
58 {
59         JunkData()
60                 : varA  (0xcd)
61                 , varB  (0xcd)
62         {
63         }
64         const deUint16  varA;
65         const deUint32  varB;
66 };
67
68 class IndirectDraw : public DrawTestsBaseClass
69 {
70 public:
71                                                                 IndirectDraw    (Context &context, ShaderMap shaders, vk::VkPrimitiveTopology topology);
72         virtual tcu::TestStatus         iterate                 (void);
73 private:
74         de::SharedPtr<Buffer>                                   m_indirectBuffer;
75         std::vector<vk::VkDrawIndirectCommand>  m_indirectDrawCmd;
76         vk::VkDeviceSize                                                m_offsetInBuffer;
77         deUint32                                                                m_strideInBuffer;
78         deUint32                                                                m_drawCount;
79         JunkData                                                                m_junkData;
80 };
81
82 class IndirectDrawInstanced : public IndirectDraw
83 {
84 public:
85                                                                 IndirectDrawInstanced   (Context &context, ShaderMap shaders, vk::VkPrimitiveTopology topology);
86         virtual tcu::TestStatus         iterate                                 (void);
87 private:
88         de::SharedPtr<Buffer>                                   m_indirectBuffer;
89         std::vector<vk::VkDrawIndirectCommand>  m_indirectDrawCmd;
90         vk::VkDeviceSize                                                m_offsetInBuffer;
91         deUint32                                                                m_strideInBuffer;
92         deUint32                                                                m_drawCount;
93         JunkData                                                                m_junkData;
94 };
95
96 IndirectDraw::IndirectDraw (Context &context, ShaderMap shaders, vk::VkPrimitiveTopology topology)
97                 : DrawTestsBaseClass(context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
98 {
99         m_topology = topology;
100
101         switch (m_topology)
102         {
103                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
104                         m_data.push_back(PositionColorVertex(tcu::Vec4(  1.0f,  -1.0f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
105                         m_data.push_back(PositionColorVertex(tcu::Vec4( -1.0f,   1.0f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
106                         m_data.push_back(PositionColorVertex(tcu::Vec4( -0.3f,  -0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
107                         m_data.push_back(PositionColorVertex(tcu::Vec4( -0.3f,   0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
108                         m_data.push_back(PositionColorVertex(tcu::Vec4(  0.3f,  -0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
109                         m_data.push_back(PositionColorVertex(tcu::Vec4(  0.3f,  -0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
110                         m_data.push_back(PositionColorVertex(tcu::Vec4(  0.3f,   0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
111                         m_data.push_back(PositionColorVertex(tcu::Vec4( -0.3f,   0.3f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
112                         m_data.push_back(PositionColorVertex(tcu::Vec4( -1.0f,   1.0f,  1.0f,   1.0f), tcu::RGBA::blue().toVec()));
113                         break;
114                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
115                         m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f,   -1.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
116                         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f,    1.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
117                         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.3f,    0.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
118                         m_data.push_back(PositionColorVertex(tcu::Vec4( 0.3f,    0.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
119                         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.3f,   -0.3f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
120                         m_data.push_back(PositionColorVertex(tcu::Vec4( 0.3f,   -0.3f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
121                         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.3f,    0.3f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
122                         m_data.push_back(PositionColorVertex(tcu::Vec4( 0.3f,    0.3f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
123                         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.3f,    0.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
124                         m_data.push_back(PositionColorVertex(tcu::Vec4( 0.3f,    0.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
125                         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f,    1.0f,   1.0f,   1.0f),  tcu::RGBA::blue().toVec()));
126                         break;
127                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
128                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
129                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
130                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
131                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
132                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
133                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
134                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
135                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
136                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
137                         DE_FATAL("Topology not implemented");
138                         break;
139                 default:
140                         DE_FATAL("Unknown topology");
141                         break;
142         }
143         initialize();
144 }
145
146 tcu::TestStatus IndirectDraw::iterate (void)
147 {
148         tcu::TestLog &log = m_context.getTestContext().getLog();
149         const vk::VkQueue queue = m_context.getUniversalQueue();
150
151         switch (m_topology)
152         {
153                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
154                 {
155                         vk::VkDrawIndirectCommand drawCommands[] =
156                         {
157                                 {
158                                         3,              //vertexCount
159                                         1,              //instanceCount
160                                         2,              //firstVertex
161                                         0               //firstInstance
162                                 },
163                                 { (deUint32)-4, (deUint32)-2, (deUint32)-11, (deUint32)-9 }, // junk (stride)
164                                 {
165                                         3,              //vertexCount
166                                         1,              //instanceCount
167                                         5,              //firstVertex
168                                         0               //firstInstance
169                                 }
170                         };
171                         m_indirectDrawCmd.push_back(drawCommands[0]);
172                         m_indirectDrawCmd.push_back(drawCommands[1]);
173                         m_indirectDrawCmd.push_back(drawCommands[2]);
174                         break;
175                 }
176                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
177                 {
178                         vk::VkDrawIndirectCommand drawCommands[] =
179                         {
180                                 {
181                                         4,              //vertexCount
182                                         1,              //instanceCount
183                                         2,              //firstVertex
184                                         0               //firstInstance
185                                 },
186                                 { (deUint32)-4, (deUint32)-2, (deUint32)-11, (deUint32)-9 }, // junk (stride)
187                                 {
188                                         4,              //vertexCount
189                                         1,              //instanceCount
190                                         6,              //firstVertex
191                                         0               //firstInstance
192                                 }
193                         };
194                         m_indirectDrawCmd.push_back(drawCommands[0]);
195                         m_indirectDrawCmd.push_back(drawCommands[1]);
196                         m_indirectDrawCmd.push_back(drawCommands[2]);
197                         break;
198                 }
199                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
200                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
201                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
202                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
203                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
204                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
205                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
206                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
207                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
208                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
209                         DE_FATAL("Topology not implemented");
210                         break;
211                 default:
212                         DE_FATAL("Unknown topology");
213                         break;
214         }
215
216         m_strideInBuffer        = 2 * (deUint32)sizeof(m_indirectDrawCmd[0]);
217         m_drawCount                     = 2;
218         m_offsetInBuffer        = sizeof(m_junkData);
219
220         beginRenderPass();
221
222         const vk::VkDeviceSize vertexBufferOffset       = 0;
223         const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
224
225         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
226
227         const vk::VkDeviceSize dataSize = m_indirectDrawCmd.size()*sizeof(m_indirectDrawCmd[0]);
228
229         m_indirectBuffer = Buffer::createAndAlloc(      m_vk,
230                                                                                                 m_context.getDevice(),
231                                                                                                 BufferCreateInfo(dataSize,
232                                                                                                                                  vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT),
233                                                                                                 m_context.getDefaultAllocator(),
234                                                                                                 vk::MemoryRequirement::HostVisible);
235
236         deUint8* ptr = reinterpret_cast<deUint8*>(m_indirectBuffer->getBoundMemory().getHostPtr());
237
238         deMemcpy(ptr, &m_junkData, static_cast<size_t>(m_offsetInBuffer));
239         deMemcpy((ptr+m_offsetInBuffer), &m_indirectDrawCmd[0], static_cast<size_t>(dataSize));
240
241         vk::flushMappedMemoryRange(m_vk,
242                                                            m_context.getDevice(),
243                                                            m_vertexBuffer->getBoundMemory().getMemory(),
244                                                            m_vertexBuffer->getBoundMemory().getOffset(),
245                                                            dataSize);
246
247         m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
248         m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
249         m_vk.cmdEndRenderPass(*m_cmdBuffer);
250         m_vk.endCommandBuffer(*m_cmdBuffer);
251
252         vk::VkSubmitInfo submitInfo =
253         {
254                 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
255                 DE_NULL,                                                        // const void*                          pNext;
256                 0,                                                                              // deUint32                                     waitSemaphoreCount;
257                 DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
258                 1,                                                                              // deUint32                                     commandBufferCount;
259                 &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
260                 0,                                                                              // deUint32                                     signalSemaphoreCount;
261                 DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
262         };
263         VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
264
265         VK_CHECK(m_vk.queueWaitIdle(queue));
266
267         // Validation
268         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
269         referenceFrame.allocLevel(0);
270
271         const deInt32 frameWidth        = referenceFrame.getWidth();
272         const deInt32 frameHeight       = referenceFrame.getHeight();
273
274         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
275
276         ReferenceImageCoordinates refCoords;
277
278         for (int y = 0; y < frameHeight; y++)
279         {
280                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
281
282                 for (int x = 0; x < frameWidth; x++)
283                 {
284                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
285
286                         if ((yCoord >= refCoords.bottom &&
287                                  yCoord <= refCoords.top        &&
288                                  xCoord >= refCoords.left       &&
289                                  xCoord <= refCoords.right))
290                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
291                 }
292         }
293
294         const vk::VkOffset3D zeroOffset                                 = { 0, 0, 0 };
295         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
296                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
297
298         qpTestResult res = QP_TEST_RESULT_PASS;
299
300         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
301                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
302                 tcu::COMPARE_LOG_RESULT)) {
303                 res = QP_TEST_RESULT_FAIL;
304         }
305
306         return tcu::TestStatus(res, qpGetTestResultName(res));
307
308 }
309
310 IndirectDrawInstanced::IndirectDrawInstanced (Context &context, ShaderMap shaders, vk::VkPrimitiveTopology topology)
311         : IndirectDraw  (context, shaders, topology)
312 {
313 }
314
315 tcu::TestStatus IndirectDrawInstanced::iterate (void)
316 {
317         tcu::TestLog &log = m_context.getTestContext().getLog();
318         const vk::VkQueue queue = m_context.getUniversalQueue();
319
320         switch (m_topology)
321         {
322                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
323                 {
324                         vk::VkDrawIndirectCommand drawCmd[] =
325                         {
326                                 {
327                                         3,              //vertexCount
328                                         4,              //instanceCount
329                                         2,              //firstVertex
330                                         2               //firstInstance
331                                 },
332                                 { (deUint32)-4, (deUint32)-2, (deUint32)-11, (deUint32)-9 }, // junk (stride)
333                                 {
334                                         3,              //vertexCount
335                                         4,              //instanceCount
336                                         5,              //firstVertex
337                                         2               //firstInstance
338                                 }
339                         };
340                         m_indirectDrawCmd.push_back(drawCmd[0]);
341                         m_indirectDrawCmd.push_back(drawCmd[1]);
342                         m_indirectDrawCmd.push_back(drawCmd[2]);
343                         break;
344                 }
345                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
346                 {
347                         vk::VkDrawIndirectCommand drawCmd[] =
348                         {
349                                 {
350                                         4,              //vertexCount
351                                         4,              //instanceCount
352                                         2,              //firstVertex
353                                         2               //firstInstance
354                                 },
355                                 { (deUint32)-4, (deUint32)-2, (deUint32)-11, (deUint32)-9 },
356                                 {
357                                         4,              //vertexCount
358                                         4,              //instanceCount
359                                         6,              //firstVertex
360                                         2               //firstInstance
361                                 }
362                         };
363                         m_indirectDrawCmd.push_back(drawCmd[0]);
364                         m_indirectDrawCmd.push_back(drawCmd[1]);
365                         m_indirectDrawCmd.push_back(drawCmd[2]);
366                         break;
367                 }
368                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
369                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
370                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
371                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
372                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
373                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
374                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
375                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
376                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
377                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
378                         DE_FATAL("Topology not implemented");
379                         break;
380                 default:
381                         DE_FATAL("Unknown topology");
382                         break;
383         }
384
385         m_strideInBuffer        = 2 * (deUint32)sizeof(m_indirectDrawCmd[0]);
386         m_drawCount                     = 2;
387         m_offsetInBuffer        = sizeof(m_junkData);
388
389         beginRenderPass();
390
391         const vk::VkDeviceSize vertexBufferOffset = 0;
392         const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
393
394         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
395
396         const vk::VkDeviceSize dataSize = m_indirectDrawCmd.size()*sizeof(m_indirectDrawCmd[0]);
397
398         m_indirectBuffer = Buffer::createAndAlloc(      m_vk,
399                                                                                                 m_context.getDevice(),
400                                                                                                 BufferCreateInfo(dataSize,
401                                                                                                                                  vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT),
402                                                                                                 m_context.getDefaultAllocator(),
403                                                                                                 vk::MemoryRequirement::HostVisible);
404
405         deUint8* ptr = reinterpret_cast<deUint8*>(m_indirectBuffer->getBoundMemory().getHostPtr());
406
407         deMemcpy(ptr, &m_junkData, static_cast<size_t>(m_offsetInBuffer));
408         deMemcpy((ptr + m_offsetInBuffer), &m_indirectDrawCmd[0], static_cast<size_t>(dataSize));
409
410         vk::flushMappedMemoryRange(m_vk,
411                                                            m_context.getDevice(),
412                                                            m_vertexBuffer->getBoundMemory().getMemory(),
413                                                            m_vertexBuffer->getBoundMemory().getOffset(),
414                                                            dataSize);
415
416         m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
417         m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), m_offsetInBuffer, m_drawCount, m_strideInBuffer);
418         m_vk.cmdEndRenderPass(*m_cmdBuffer);
419         m_vk.endCommandBuffer(*m_cmdBuffer);
420
421         vk::VkSubmitInfo submitInfo =
422         {
423                 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
424                 DE_NULL,                                                        // const void*                          pNext;
425                 0,                                                                              // deUint32                                     waitSemaphoreCount;
426                 DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
427                 1,                                                                              // deUint32                                     commandBufferCount;
428                 &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
429                 0,                                                                              // deUint32                                     signalSemaphoreCount;
430                 DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
431         };
432         VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
433
434         VK_CHECK(m_vk.queueWaitIdle(queue));
435
436         // Validation
437         VK_CHECK(m_vk.queueWaitIdle(queue));
438
439         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
440
441         referenceFrame.allocLevel(0);
442
443         const deInt32 frameWidth        = referenceFrame.getWidth();
444         const deInt32 frameHeight       = referenceFrame.getHeight();
445
446         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
447
448         ReferenceImageInstancedCoordinates refInstancedCoords;
449
450         for (int y = 0; y < frameHeight; y++)
451         {
452                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
453
454                 for (int x = 0; x < frameWidth; x++)
455                 {
456                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
457
458                         if ((yCoord >= refInstancedCoords.bottom        &&
459                                  yCoord <= refInstancedCoords.top               &&
460                                  xCoord >= refInstancedCoords.left              &&
461                                  xCoord <= refInstancedCoords.right))
462                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
463                 }
464         }
465
466         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
467         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
468                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
469
470         qpTestResult res = QP_TEST_RESULT_PASS;
471
472         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
473                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
474                 tcu::COMPARE_LOG_RESULT)) {
475                 res = QP_TEST_RESULT_FAIL;
476         }
477
478         return tcu::TestStatus(res, qpGetTestResultName(res));
479
480         }
481
482 }       // anonymous
483
484 IndirectDrawTests::IndirectDrawTests (tcu::TestContext &testCtx)
485         : TestCaseGroup(testCtx, "indirect_draw", "indirect drawing simple geometry")
486 {
487         /* Left blank on purpose */
488 }
489
490 IndirectDrawTests::~IndirectDrawTests (void) {}
491
492
493 void IndirectDrawTests::init (void)
494 {
495         ShaderMap shaderPaths;
496         shaderPaths[glu::SHADERTYPE_VERTEX]             = "vulkan/draw/VertexFetch.vert";
497         shaderPaths[glu::SHADERTYPE_FRAGMENT]    = "vulkan/draw/VertexFetch.frag";
498
499         addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "indirect_draw_triangle_list", "Draws triangle list", shaderPaths, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
500         addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "indirect_draw_triangle_strip", "Draws triangle strip", shaderPaths, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
501
502         shaderPaths[glu::SHADERTYPE_VERTEX]             = "vulkan/draw/VertexFetchWithInstance.vert";
503         shaderPaths[glu::SHADERTYPE_FRAGMENT]   = "vulkan/draw/VertexFetch.frag";
504
505         addChild(new InstanceFactory<IndirectDrawInstanced>(m_testCtx, "indirect_draw_instanced_triangle_list", "Draws an instanced triangle list", shaderPaths, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
506         addChild(new InstanceFactory<IndirectDrawInstanced>(m_testCtx, "indirect_draw_instanced_triangle_strip", "Draws an instanced triangle strip", shaderPaths, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
507 }
508
509 }       // DrawTests
510 }       // vkt