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