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