Merge "Fix missing SSBO binding in EGL robustness tests"
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawSimpleTest.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
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 Simple Draw Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawSimpleTest.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDrawTestCaseUtil.hpp"
29
30 #include "vktDrawBaseClass.hpp"
31
32 #include "tcuTestLog.hpp"
33 #include "tcuResource.hpp"
34 #include "tcuImageCompare.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuRGBA.hpp"
37
38 #include "vkDefs.hpp"
39
40 namespace vkt
41 {
42 namespace Draw
43 {
44 namespace
45 {
46 class SimpleDraw : public DrawTestsBaseClass
47 {
48 public:
49         typedef TestSpecBase    TestSpec;
50                                                         SimpleDraw                              (Context &context, TestSpec testSpec);
51         virtual tcu::TestStatus iterate                                 (void);
52 };
53
54 class SimpleDrawInstanced : public SimpleDraw
55 {
56 public:
57         typedef TestSpec                TestSpec;
58                                                         SimpleDrawInstanced             (Context &context, TestSpec testSpec);
59         tcu::TestStatus                 iterate                                 (void);
60 };
61
62 SimpleDraw::SimpleDraw (Context &context, TestSpec testSpec)
63         : DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], testSpec.topology)
64 {
65         m_data.push_back(VertexElementData(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
66         m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
67
68         int refVertexIndex = 2;
69
70         switch (m_topology)
71         {
72                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
73                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
74                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
75                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
76                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
77                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
78                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
79                         break;
80                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
81                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
82                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
83                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
84                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
85                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
86                         break;
87                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
88                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
89                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
90                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
91                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
92                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
93                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
94                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
95                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
96                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
97                         DE_FATAL("Topology not implemented");
98                         break;
99                 default:
100                         DE_FATAL("Unknown topology");
101                         break;
102         }
103
104         m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
105
106         initialize();
107 }
108
109 tcu::TestStatus SimpleDraw::iterate (void)
110 {
111         tcu::TestLog &log                                                       = m_context.getTestContext().getLog();
112         const vk::VkQueue queue                                         = m_context.getUniversalQueue();
113
114         beginRenderPass();
115
116         const vk::VkDeviceSize vertexBufferOffset       = 0;
117         const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
118
119         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
120         m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
121
122         switch (m_topology)
123         {
124                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
125                         m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 2, 0);
126                         break;
127                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
128                         m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 2, 0);
129                         break;
130                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
131                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
132                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
133                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
134                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
135                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
136                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
137                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
138                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
139                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
140                         DE_FATAL("Topology not implemented");
141                         break;
142                 default:
143                         DE_FATAL("Unknown topology");
144                         break;
145         }
146
147         m_vk.cmdEndRenderPass(*m_cmdBuffer);
148         m_vk.endCommandBuffer(*m_cmdBuffer);
149
150         vk::VkSubmitInfo submitInfo =
151         {
152                 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
153                 DE_NULL,                                                        // const void*                          pNext;
154                 0,                                                                              // deUint32                                     waitSemaphoreCount;
155                 DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
156                 (const vk::VkPipelineStageFlags*)DE_NULL,
157                 1,                                                                              // deUint32                                     commandBufferCount;
158                 &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
159                 0,                                                                              // deUint32                                     signalSemaphoreCount;
160                 DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
161         };
162         VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
163
164         VK_CHECK(m_vk.queueWaitIdle(queue));
165
166         // Validation
167         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
168
169         referenceFrame.allocLevel(0);
170
171         const deInt32 frameWidth        = referenceFrame.getWidth();
172         const deInt32 frameHeight       = referenceFrame.getHeight();
173
174         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
175
176         ReferenceImageCoordinates refCoords;
177
178         for (int y = 0; y < frameHeight; y++)
179         {
180                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
181
182                 for (int x = 0; x < frameWidth; x++)
183                 {
184                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
185
186                         if ((yCoord >= refCoords.bottom &&
187                                  yCoord <= refCoords.top        &&
188                                  xCoord >= refCoords.left       &&
189                                  xCoord <= refCoords.right))
190                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
191                 }
192         }
193
194         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
195         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
196                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
197
198         qpTestResult res = QP_TEST_RESULT_PASS;
199
200         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
201                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
202                 tcu::COMPARE_LOG_RESULT)) {
203                 res = QP_TEST_RESULT_FAIL;
204         }
205
206         return tcu::TestStatus(res, qpGetTestResultName(res));
207
208 }
209
210 SimpleDrawInstanced::SimpleDrawInstanced (Context &context, TestSpec testSpec)
211         : SimpleDraw    (context, testSpec) {}
212
213 tcu::TestStatus SimpleDrawInstanced::iterate (void)
214 {
215         tcu::TestLog &log               = m_context.getTestContext().getLog();
216
217         const vk::VkQueue queue = m_context.getUniversalQueue();
218
219         beginRenderPass();
220
221         const vk::VkDeviceSize vertexBufferOffset = 0;
222         const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
223
224         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
225
226         m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
227
228         switch (m_topology)
229         {
230                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
231                         m_vk.cmdDraw(*m_cmdBuffer, 6, 4, 2, 2);
232                         break;
233                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
234                         m_vk.cmdDraw(*m_cmdBuffer, 4, 4, 2, 2);
235                         break;
236                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
237                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
238                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
239                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
240                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
241                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
242                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
243                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
244                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
245                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
246                         DE_FATAL("Topology not implemented");
247                         break;
248                 default:
249                         DE_FATAL("Unknown topology");
250                         break;
251         }
252
253         m_vk.cmdEndRenderPass(*m_cmdBuffer);
254         m_vk.endCommandBuffer(*m_cmdBuffer);
255
256         vk::VkSubmitInfo submitInfo =
257         {
258                 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
259                 DE_NULL,                                                        // const void*                          pNext;
260                 0,                                                                              // deUint32                                     waitSemaphoreCount;
261                 DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
262                 (const vk::VkPipelineStageFlags*)DE_NULL,
263                 1,                                                                              // deUint32                                     commandBufferCount;
264                 &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
265                 0,                                                                              // deUint32                                     signalSemaphoreCount;
266                 DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
267         };
268         VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
269
270         VK_CHECK(m_vk.queueWaitIdle(queue));
271
272         // Validation
273         VK_CHECK(m_vk.queueWaitIdle(queue));
274
275         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
276
277         referenceFrame.allocLevel(0);
278
279         const deInt32 frameWidth        = referenceFrame.getWidth();
280         const deInt32 frameHeight       = referenceFrame.getHeight();
281
282         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
283
284         ReferenceImageInstancedCoordinates refInstancedCoords;
285
286         for (int y = 0; y < frameHeight; y++)
287         {
288                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
289
290                 for (int x = 0; x < frameWidth; x++)
291                 {
292                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
293
294                         if ((yCoord >= refInstancedCoords.bottom        &&
295                                  yCoord <= refInstancedCoords.top               &&
296                                  xCoord >= refInstancedCoords.left              &&
297                                  xCoord <= refInstancedCoords.right))
298                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
299                 }
300         }
301
302         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
303         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
304                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
305
306         qpTestResult res = QP_TEST_RESULT_PASS;
307
308         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
309                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
310                 tcu::COMPARE_LOG_RESULT)) {
311                 res = QP_TEST_RESULT_FAIL;
312         }
313
314         return tcu::TestStatus(res, qpGetTestResultName(res));
315 }
316
317 }       // anonymous
318
319 SimpleDrawTests::SimpleDrawTests (tcu::TestContext &testCtx)
320 : TestCaseGroup (testCtx, "simple_draw", "drawing simple geometry")
321 {
322         /* Left blank on purpose */
323 }
324
325 SimpleDrawTests::~SimpleDrawTests (void) {}
326
327
328 void SimpleDrawTests::init (void)
329 {
330         {
331                 SimpleDraw::TestSpec testSpec;
332                 testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetch.vert";
333                 testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag";
334
335                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
336                 addChild(new InstanceFactory<SimpleDraw>(m_testCtx, "simple_draw_triangle_list", "Draws triangle list", testSpec));
337                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
338                 addChild(new InstanceFactory<SimpleDraw>(m_testCtx, "simple_draw_triangle_strip", "Draws triangle strip", testSpec));
339         }
340         {
341                 SimpleDrawInstanced::TestSpec testSpec;
342                 testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchInstancedFirstInstance.vert";
343                 testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag";
344
345                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
346                 addChild(new InstanceFactory<SimpleDrawInstanced>(m_testCtx, "simple_draw_instanced_triangle_list", "Draws an instanced triangle list", testSpec));
347                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
348                 addChild(new InstanceFactory<SimpleDrawInstanced>(m_testCtx, "simple_draw_instanced_triangle_strip", "Draws an instanced triangle strip", testSpec));
349         }
350 }
351
352 }       // DrawTests
353 }       // vkt