• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Draw Indexed Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDrawIndexedTest.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 enum
41 {
42 	VERTEX_OFFSET = 13
43 };
44 
45 namespace vkt
46 {
47 namespace Draw
48 {
49 namespace
50 {
51 class DrawIndexed : public DrawTestsBaseClass
52 {
53 public:
54 	typedef		TestSpecBase	TestSpec;
55 
56 								DrawIndexed				(Context &context, TestSpec testSpec);
57 	virtual		tcu::TestStatus iterate					(void);
58 protected:
59 	std::vector<deUint32>		m_indexes;
60 	de::SharedPtr<Buffer>		m_indexBuffer;
61 };
62 
63 class DrawInstancedIndexed : public DrawIndexed
64 {
65 public:
66 								DrawInstancedIndexed	(Context &context, TestSpec testSpec);
67 	virtual		tcu::TestStatus	iterate					(void);
68 };
69 
DrawIndexed(Context & context,TestSpec testSpec)70 DrawIndexed::DrawIndexed (Context &context, TestSpec testSpec)
71 	: DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], testSpec.topology)
72 {
73 	switch (m_topology)
74 	{
75 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
76 			m_indexes.push_back(0);
77 			m_indexes.push_back(0);
78 			m_indexes.push_back(2);
79 			m_indexes.push_back(0);
80 			m_indexes.push_back(6);
81 			m_indexes.push_back(6);
82 			m_indexes.push_back(0);
83 			m_indexes.push_back(7);
84 			break;
85 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
86 			m_indexes.push_back(0);
87 			m_indexes.push_back(0);
88 			m_indexes.push_back(2);
89 			m_indexes.push_back(0);
90 			m_indexes.push_back(6);
91 			m_indexes.push_back(5);
92 			m_indexes.push_back(0);
93 			m_indexes.push_back(7);
94 			break;
95 
96 		case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
97 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
98 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
99 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
100 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
101 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
102 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
103 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
104 		case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
105 		case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
106 			DE_FATAL("Topology not implemented");
107 			break;
108 		default:
109 			DE_FATAL("Unknown topology");
110 			break;
111 	}
112 
113 	for (int unusedIdx = 0; unusedIdx < VERTEX_OFFSET; unusedIdx++)
114 	{
115 		m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
116 	}
117 
118 	int vertexIndex = VERTEX_OFFSET;
119 
120 	m_data.push_back(VertexElementData(tcu::Vec4(	-0.3f,	 0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
121 	m_data.push_back(VertexElementData(tcu::Vec4(	-1.0f,	 1.0f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
122 	m_data.push_back(VertexElementData(tcu::Vec4(	-0.3f,	-0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
123 	m_data.push_back(VertexElementData(tcu::Vec4(	 1.0f,	-1.0f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
124 	m_data.push_back(VertexElementData(tcu::Vec4(	-0.3f,	-0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
125 	m_data.push_back(VertexElementData(tcu::Vec4(	 0.3f,	 0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
126 	m_data.push_back(VertexElementData(tcu::Vec4(	 0.3f,	-0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
127 	m_data.push_back(VertexElementData(tcu::Vec4(	 0.3f,	 0.3f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), vertexIndex++));
128 
129 	m_data.push_back(VertexElementData(tcu::Vec4(	-1.0f,	 1.0f,	1.0f,	1.0f), tcu::RGBA::blue().toVec(), -1));
130 
131 	initialize();
132 };
133 
iterate(void)134 tcu::TestStatus DrawIndexed::iterate (void)
135 {
136 	tcu::TestLog &log			= m_context.getTestContext().getLog();
137 	const vk::VkQueue queue		= m_context.getUniversalQueue();
138 
139 	beginRenderPass();
140 
141 	const vk::VkDeviceSize dataSize = m_indexes.size() * sizeof(deUint32);
142 	m_indexBuffer = Buffer::createAndAlloc(	m_vk, m_context.getDevice(),
143 											BufferCreateInfo(dataSize,
144 															 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT),
145 											m_context.getDefaultAllocator(),
146 											vk::MemoryRequirement::HostVisible);
147 
148 	deUint8* ptr = reinterpret_cast<deUint8*>(m_indexBuffer->getBoundMemory().getHostPtr());
149 
150 	deMemcpy(ptr, &m_indexes[0], static_cast<size_t>(dataSize));
151 
152 	vk::flushMappedMemoryRange(m_vk, m_context.getDevice(),
153 							   m_indexBuffer->getBoundMemory().getMemory(),
154 							   m_indexBuffer->getBoundMemory().getOffset(),
155 							   dataSize);
156 
157 	const vk::VkDeviceSize vertexBufferOffset = 0;
158 	const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
159 	const vk::VkBuffer indexBuffer = m_indexBuffer->object();
160 
161 	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
162 	m_vk.cmdBindIndexBuffer(*m_cmdBuffer, indexBuffer, 0, vk::VK_INDEX_TYPE_UINT32);
163 
164 	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
165 
166 	m_vk.cmdDrawIndexed(*m_cmdBuffer, 6, 1, 2, VERTEX_OFFSET, 0);
167 
168 	m_vk.cmdEndRenderPass(*m_cmdBuffer);
169 	m_vk.endCommandBuffer(*m_cmdBuffer);
170 
171 	vk::VkSubmitInfo submitInfo =
172 	{
173 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
174 		DE_NULL,							// const void*				pNext;
175 		0,										// deUint32					waitSemaphoreCount;
176 		DE_NULL,								// const VkSemaphore*		pWaitSemaphores;
177 		(const vk::VkPipelineStageFlags*)DE_NULL,
178 		1,										// deUint32					commandBufferCount;
179 		&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
180 		0,										// deUint32					signalSemaphoreCount;
181 		DE_NULL								// const VkSemaphore*		pSignalSemaphores;
182 	};
183 
184 	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
185 
186 	VK_CHECK(m_vk.queueWaitIdle(queue));
187 
188 	// Validation
189 	tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
190 								  referenceFrame.allocLevel(0);
191 
192 	const deInt32 frameWidth	= referenceFrame.getWidth();
193 	const deInt32 frameHeight	= referenceFrame.getHeight();
194 
195 	tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
196 
197 	ReferenceImageCoordinates refCoords;
198 
199 	for (int y = 0; y < frameHeight; y++)
200 	{
201 		const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
202 
203 		for (int x = 0; x < frameWidth; x++)
204 		{
205 			const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
206 
207 			if ((yCoord >= refCoords.bottom &&
208 				 yCoord <= refCoords.top	&&
209 				 xCoord >= refCoords.left	&&
210 				 xCoord <= refCoords.right))
211 				referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
212 		}
213 	}
214 
215 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
216 	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
217 		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
218 
219 	qpTestResult res = QP_TEST_RESULT_PASS;
220 
221 	if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
222 		referenceFrame.getLevel(0), renderedFrame, 0.05f,
223 		tcu::COMPARE_LOG_RESULT)) {
224 		res = QP_TEST_RESULT_FAIL;
225 	}
226 
227 	return tcu::TestStatus(res, qpGetTestResultName(res));
228 };
229 
DrawInstancedIndexed(Context & context,TestSpec testSpec)230 DrawInstancedIndexed::DrawInstancedIndexed (Context &context, TestSpec testSpec)
231 	: DrawIndexed	(context, testSpec)
232 {
233 }
234 
iterate(void)235 tcu::TestStatus DrawInstancedIndexed::iterate (void)
236 {
237 	tcu::TestLog &log		= m_context.getTestContext().getLog();
238 	const vk::VkQueue queue = m_context.getUniversalQueue();
239 
240 	beginRenderPass();
241 
242 	const vk::VkDeviceSize dataSize = m_indexes.size() * sizeof(deUint32);
243 	m_indexBuffer = Buffer::createAndAlloc(	m_vk, m_context.getDevice(),
244 											BufferCreateInfo(dataSize,
245 															 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT),
246 											m_context.getDefaultAllocator(),
247 											vk::MemoryRequirement::HostVisible);
248 
249 	deUint8* ptr = reinterpret_cast<deUint8*>(m_indexBuffer->getBoundMemory().getHostPtr());
250 
251 	deMemcpy(ptr, &m_indexes[0], static_cast<size_t>(dataSize));
252 	vk::flushMappedMemoryRange(m_vk, m_context.getDevice(),
253 							   m_indexBuffer->getBoundMemory().getMemory(),
254 							   m_indexBuffer->getBoundMemory().getOffset(),
255 							   dataSize);
256 
257 	const vk::VkDeviceSize vertexBufferOffset = 0;
258 	const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
259 	const vk::VkBuffer indexBuffer = m_indexBuffer->object();
260 
261 	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
262 	m_vk.cmdBindIndexBuffer(*m_cmdBuffer, indexBuffer, 0, vk::VK_INDEX_TYPE_UINT32);
263 	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
264 
265 	switch (m_topology)
266 	{
267 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
268 			m_vk.cmdDrawIndexed(*m_cmdBuffer, 6, 4, 2, VERTEX_OFFSET, 2);
269 			break;
270 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
271 			m_vk.cmdDrawIndexed(*m_cmdBuffer, 4, 4, 2, VERTEX_OFFSET, 2);
272 			break;
273 		case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
274 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
275 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
276 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
277 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
278 		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
279 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
280 		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
281 		case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
282 		case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
283 			DE_FATAL("Topology not implemented");
284 			break;
285 		default:
286 			DE_FATAL("Unknown topology");
287 			break;
288 	}
289 
290 	m_vk.cmdEndRenderPass(*m_cmdBuffer);
291 	m_vk.endCommandBuffer(*m_cmdBuffer);
292 
293 	vk::VkSubmitInfo submitInfo =
294 	{
295 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
296 		DE_NULL,							// const void*				pNext;
297 		0,										// deUint32					waitSemaphoreCount;
298 		DE_NULL,								// const VkSemaphore*		pWaitSemaphores;
299 		(const vk::VkPipelineStageFlags*)DE_NULL,
300 		1,										// deUint32					commandBufferCount;
301 		&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
302 		0,										// deUint32					signalSemaphoreCount;
303 		DE_NULL								// const VkSemaphore*		pSignalSemaphores;
304 	};
305 	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
306 
307 	VK_CHECK(m_vk.queueWaitIdle(queue));
308 
309 	// Validation
310 	VK_CHECK(m_vk.queueWaitIdle(queue));
311 
312 	tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
313 	referenceFrame.allocLevel(0);
314 
315 	const deInt32 frameWidth = referenceFrame.getWidth();
316 	const deInt32 frameHeight = referenceFrame.getHeight();
317 
318 	tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
319 
320 	ReferenceImageInstancedCoordinates refInstancedCoords;
321 
322 	for (int y = 0; y < frameHeight; y++)
323 	{
324 		const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
325 
326 		for (int x = 0; x < frameWidth; x++)
327 		{
328 			const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
329 
330 			if ((yCoord >= refInstancedCoords.bottom	&&
331 				 yCoord <= refInstancedCoords.top		&&
332 				 xCoord >= refInstancedCoords.left		&&
333 				 xCoord <= refInstancedCoords.right))
334 				referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
335 		}
336 	}
337 
338 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
339 	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
340 		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
341 
342 	qpTestResult res = QP_TEST_RESULT_PASS;
343 
344 	if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
345 		referenceFrame.getLevel(0), renderedFrame, 0.05f,
346 		tcu::COMPARE_LOG_RESULT)) {
347 		res = QP_TEST_RESULT_FAIL;
348 	}
349 
350 	return tcu::TestStatus(res, qpGetTestResultName(res));
351 
352 }
353 
354 }	// anonymous
355 
DrawIndexedTests(tcu::TestContext & testCtx)356 DrawIndexedTests::DrawIndexedTests (tcu::TestContext &testCtx)
357 	: TestCaseGroup	(testCtx, "indexed_draw", "drawing indexed geometry")
358 {
359 	/* Left blank on purpose */
360 }
361 
~DrawIndexedTests(void)362 DrawIndexedTests::~DrawIndexedTests (void) {}
363 
init(void)364 void DrawIndexedTests::init (void)
365 {
366 	{
367 		DrawIndexed::TestSpec testSpec;
368 		testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetch.vert";
369 		testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag";
370 
371 		testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
372 		addChild(new InstanceFactory<DrawIndexed>(m_testCtx, "draw_indexed_triangle_list", "Draws indexed triangle list", testSpec));
373 		testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
374 		addChild(new InstanceFactory<DrawIndexed>(m_testCtx, "draw_indexed_triangle_strip", "Draws indexed triangle strip", testSpec));
375 	}
376 	{
377 		DrawInstancedIndexed::TestSpec testSpec;
378 		testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchInstancedFirstInstance.vert";
379 		testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag";
380 
381 		testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
382 		addChild(new InstanceFactory<DrawInstancedIndexed>(m_testCtx, "draw_instanced_indexed_triangle_list", "Draws indexed triangle list", testSpec));
383 		testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
384 		addChild(new InstanceFactory<DrawInstancedIndexed>(m_testCtx, "draw_instanced_indexed_triangle_strip", "Draws indexed triangle strip", testSpec));
385 	}
386 }
387 
388 }	// DrawTests
389 }	// vkt
390