1592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham/*------------------------------------------------------------------------
2592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * Vulkan Conformance Tests
3592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * ------------------------
4592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *
5592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * Copyright (c) 2016 The Khronos Group Inc.
6592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *
8592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * Licensed under the Apache License, Version 2.0 (the "License");
9592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * you may not use this file except in compliance with the License.
10592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * You may obtain a copy of the License at
11592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *
12592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *      http://www.apache.org/licenses/LICENSE-2.0
13592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *
14592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * Unless required by applicable law or agreed to in writing, software
15592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * distributed under the License is distributed on an "AS IS" BASIS,
16592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * See the License for the specific language governing permissions and
18592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * limitations under the License.
19592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *
20592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *//*!
21592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * \file
22592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham * \brief Simple Draw Tests
23592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham *//*--------------------------------------------------------------------*/
24592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
25592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "vktBasicDrawTests.hpp"
26592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
27592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "vktDrawBaseClass.hpp"
28592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "vkQueryUtil.hpp"
29592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "vktTestGroupUtil.hpp"
30592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
31592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "deDefs.h"
32592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "deRandom.hpp"
33592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "deString.h"
34592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
35592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "tcuTestCase.hpp"
36592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "tcuRGBA.hpp"
37592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "tcuTextureUtil.hpp"
38592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "tcuImageCompare.hpp"
39592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
40592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include "rrRenderer.hpp"
41592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
42592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include <string>
43592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham#include <sstream>
44592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
45592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamnamespace vkt
46592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
47592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamnamespace Draw
48592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
49592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamnamespace
50592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
51592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstatic const deUint32 SEED			= 0xc2a39fu;
52592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstatic const deUint32 INDEX_LIMIT	= 10000;
53592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham// To avoid too big and mostly empty structures
54592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstatic const deUint32 OFFSET_LIMIT	= 1000;
55592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham// Number of primitives to draw
56592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstatic const deUint32 PRIMITIVE_COUNT[] = {1, 3, 17, 45};
57592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
58592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamenum DrawCommandType
59592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
60592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DRAW_COMMAND_TYPE_DRAW,
61592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DRAW_COMMAND_TYPE_DRAW_INDEXED,
62592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DRAW_COMMAND_TYPE_DRAW_INDIRECT,
63592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT,
64592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
65592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DRAW_COMMAND_TYPE_DRAW_LAST
66592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
67592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
68592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamconst char* getDrawCommandTypeName (DrawCommandType command)
69592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
70592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	switch (command)
71592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
72592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case DRAW_COMMAND_TYPE_DRAW:					return "draw";
73592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case DRAW_COMMAND_TYPE_DRAW_INDEXED:			return "draw_indexed";
74592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case DRAW_COMMAND_TYPE_DRAW_INDIRECT:			return "draw_indirect";
75592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:	return "draw_indexed_indirect";
76592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		default:					DE_ASSERT(false);
77592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
78592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return "";
79592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
80592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
81592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamrr::PrimitiveType mapVkPrimitiveTopology (vk::VkPrimitiveTopology primitiveTopology)
82592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
83592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	switch (primitiveTopology)
84592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
85592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:						return rr::PRIMITIVETYPE_POINTS;
86592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:						return rr::PRIMITIVETYPE_LINES;
87592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:						return rr::PRIMITIVETYPE_LINE_STRIP;
88592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:					return rr::PRIMITIVETYPE_TRIANGLES;
89592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:					return rr::PRIMITIVETYPE_TRIANGLE_FAN;
90592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:					return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
91592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:		return rr::PRIMITIVETYPE_LINES_ADJACENCY;
92592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:		return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
93592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:	return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
94592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:	return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
95592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		default:
96592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			DE_ASSERT(false);
97592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
98592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return rr::PRIMITIVETYPE_LAST;
99592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
100592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
101592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct DrawParamsBase
102592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
103592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<PositionColorVertex>	vertices;
104592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkPrimitiveTopology				topology;
105592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
106592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawParamsBase ()
107592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
108592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
109592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawParamsBase (const vk::VkPrimitiveTopology top)
110592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: topology	(top)
111592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
112592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
113592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
114592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct IndexedParamsBase
115592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
116592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<deUint32>	indexes;
117592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkIndexType	indexType;
118592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
119592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	IndexedParamsBase (const vk::VkIndexType indexT)
120592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: indexType	(indexT)
121592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
122592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
123592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
124592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham// Structs to store draw parameters
125592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct DrawParams : DrawParamsBase
126592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
127592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// vkCmdDraw parameters is like a single VkDrawIndirectCommand
128592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkDrawIndirectCommand	params;
129592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
130592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawParams (const vk::VkPrimitiveTopology top, const deUint32 vertexC, const deUint32 instanceC, const deUint32 firstV, const deUint32 firstI)
131592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: DrawParamsBase	(top)
132592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
133592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.vertexCount		= vertexC;
134592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.instanceCount	= instanceC;
135592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.firstVertex		= firstV;
136592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.firstInstance	= firstI;
137592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
138592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
139592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
140592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct DrawIndexedParams : DrawParamsBase, IndexedParamsBase
141592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
142592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// vkCmdDrawIndexed parameters is like a single VkDrawIndexedIndirectCommand
143592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkDrawIndexedIndirectCommand	params;
144592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
145592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawIndexedParams (const vk::VkPrimitiveTopology top, const vk::VkIndexType indexT, const deUint32 indexC, const deUint32 instanceC, const deUint32 firstIdx, const deInt32 vertexO, const deUint32 firstIns)
146592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: DrawParamsBase	(top)
147592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		, IndexedParamsBase	(indexT)
148592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
149592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.indexCount		= indexC;
150592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.instanceCount	= instanceC;
151592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.firstIndex		= firstIdx;
152592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.vertexOffset		= vertexO;
153592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		params.firstInstance	= firstIns;
154592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
155592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
156592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
157592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct DrawIndirectParams : DrawParamsBase
158592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
159592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<vk::VkDrawIndirectCommand>	commands;
160592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
161592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawIndirectParams (const vk::VkPrimitiveTopology top)
162592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: DrawParamsBase	(top)
163592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
164592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
165592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void addCommand (const deUint32 vertexC, const deUint32 instanceC, const deUint32 firstV, const deUint32 firstI)
166592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
167592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VkDrawIndirectCommand	cmd;
168592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.vertexCount				= vertexC;
169592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.instanceCount			= instanceC;
170592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.firstVertex				= firstV;
171592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.firstInstance			= firstI;
172592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
173592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		commands.push_back(cmd);
174592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
175592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
176592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
177592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct DrawIndexedIndirectParams : DrawParamsBase, IndexedParamsBase
178592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
179592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<vk::VkDrawIndexedIndirectCommand>	commands;
180592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
181592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawIndexedIndirectParams (const vk::VkPrimitiveTopology top, const vk::VkIndexType indexT)
182592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: DrawParamsBase	(top)
183592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		, IndexedParamsBase	(indexT)
184592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
185592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
186592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void addCommand (const deUint32 indexC, const deUint32 instanceC, const deUint32 firstIdx, const deInt32 vertexO, const deUint32 firstIns)
187592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
188592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VkDrawIndexedIndirectCommand	cmd;
189592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.indexCount						= indexC;
190592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.instanceCount					= instanceC;
191592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.firstIndex						= firstIdx;
192592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.vertexOffset					= vertexO;
193592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		cmd.firstInstance					= firstIns;
194592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
195592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		commands.push_back(cmd);
196592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
197592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
198592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
199592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham// Reference renderer shaders
200592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamclass PassthruVertShader : public rr::VertexShader
201592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
202592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahampublic:
203592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	PassthruVertShader (void)
204592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	: rr::VertexShader (2, 1)
205592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
206592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
207592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
208592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
209592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
210592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
211592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
212592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
213592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
214592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
215592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
216592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham																	 packets[packetNdx]->instanceNdx,
217592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham																	 packets[packetNdx]->vertexNdx);
218592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
219592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::Vec4 color = rr::readVertexAttribFloat(inputs[1],
220592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham														packets[packetNdx]->instanceNdx,
221592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham														packets[packetNdx]->vertexNdx);
222592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
223592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			packets[packetNdx]->outputs[0] = color;
224592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
225592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
226592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
227592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
228592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamclass PassthruFragShader : public rr::FragmentShader
229592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
230592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahampublic:
231592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	PassthruFragShader (void)
232592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: rr::FragmentShader(1, 1)
233592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
234592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
235592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
236592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
237592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
238592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
239592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
240592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
241592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
242592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			rr::FragmentPacket& packet = packets[packetNdx];
243592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
244592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			{
245592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				tcu::Vec4 color = rr::readVarying<float>(packet, context, 0, fragNdx);
246592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
247592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			}
248592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
249592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
250592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
251592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
252114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowskiinline bool imageCompare (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& reference, const tcu::ConstPixelBufferAccess& result, const vk::VkPrimitiveTopology topology)
253114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski{
254114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	if (topology == vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
255114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	{
256114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski		return tcu::intThresholdPositionDeviationCompare(
257114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski			log, "Result", "Image comparison result", reference, result,
258114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski			tcu::UVec4(4u),					// color threshold
259114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski			tcu::IVec3(1, 1, 0),			// position deviation tolerance
260114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski			true,							// don't check the pixels at the boundary
261114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski			tcu::COMPARE_LOG_RESULT);
262114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	}
263114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	else
2644203a1b6ef4e91b23a5907060b68844c5921802cSlawomir Cygan		return tcu::fuzzyCompare(log, "Result", "Image comparison result", reference, result, 0.053f, tcu::COMPARE_LOG_RESULT);
265114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski}
266114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski
267592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamclass DrawTestInstanceBase : public TestInstance
268592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
269592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahampublic:
270592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham									DrawTestInstanceBase	(Context& context);
271592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual							~DrawTestInstanceBase	(void) = 0;
272592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void							initialize				(const DrawParamsBase& data);
273592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void							initPipeline			(const vk::VkDevice device);
274592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void							beginRenderPass			(void);
275592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
276592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Specialize this function for each type
277592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual tcu::TestStatus			iterate					(void) = 0;
278592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamprotected:
279592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Specialize this function for each type
280592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual void					generateDrawData		(void) = 0;
281592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	void							generateRefImage		(const tcu::PixelBufferAccess& access, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
282592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
283592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DrawParamsBase											m_data;
284592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::DeviceInterface&								m_vk;
285592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkPipeline>								m_pipeline;
286592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkPipelineLayout>							m_pipelineLayout;
287592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkFormat											m_colorAttachmentFormat;
288592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::SharedPtr<Image>									m_colorTargetImage;
289592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkImageView>								m_colorTargetView;
290592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkRenderPass>								m_renderPass;
291592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkFramebuffer>								m_framebuffer;
292592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	PipelineCreateInfo::VertexInputState					m_vertexInputState;
293592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::SharedPtr<Buffer>									m_vertexBuffer;
294592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkCommandPool>								m_cmdPool;
295592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkCommandBuffer>							m_cmdBuffer;
296592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
297592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	enum
298592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
299592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		WIDTH = 256,
300592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		HEIGHT = 256
301592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
302592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
303592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
304592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestInstanceBase::DrawTestInstanceBase (Context& context)
305592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	: vkt::TestInstance			(context)
306592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	, m_vk						(context.getDeviceInterface())
307592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	, m_colorAttachmentFormat	(vk::VK_FORMAT_R8G8B8A8_UNORM)
308592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
309592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
310592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
311592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestInstanceBase::~DrawTestInstanceBase (void)
312592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
313592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
314592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
315592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstanceBase::initialize (const DrawParamsBase& data)
316592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
317592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data	= data;
318592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
319592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDevice	device				= m_context.getDevice();
320592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32		queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
321592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
3225d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang	const vk::VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
3235d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang
3245d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang	if (features.geometryShader == VK_FALSE &&
3255d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		(m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
3265d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		 m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
3275d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		 m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ||
3285d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		 m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY)
3295d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		)
3305d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang	{
3315d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang		TCU_THROW(NotSupportedError, "Geometry Not Supported");
3325d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang	}
3335d30c13f5033fa9ea86ee795ce96d2d2e27027d2Yanjun Zhang
334592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
335592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_pipelineLayout						= vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
336592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
337592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkExtent3D targetImageExtent	= { WIDTH, HEIGHT, 1 };
338592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
339592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
340592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
341592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_colorTargetImage						= Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
342592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
343592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
344592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_colorTargetView						= vk::createImageView(m_vk, device, &colorTargetViewInfo);
345592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
346592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	RenderPassCreateInfo renderPassCreateInfo;
347592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
348592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_SAMPLE_COUNT_1_BIT,
349592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
350592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_ATTACHMENT_STORE_OP_STORE,
351592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
352592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_ATTACHMENT_STORE_OP_STORE,
353592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_IMAGE_LAYOUT_GENERAL,
354592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															 vk::VK_IMAGE_LAYOUT_GENERAL));
355592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
356592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkAttachmentReference colorAttachmentReference =
357592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
358592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,
359592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL
360592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
361592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
362592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
363592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   0,
364592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   0,
365592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   DE_NULL,
366592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   1,
367592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   &colorAttachmentReference,
368592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   DE_NULL,
369592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   AttachmentReference(),
370592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   0,
371592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham													   DE_NULL));
372592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
373592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_renderPass		= vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
374592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
375592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<vk::VkImageView> colorAttachments(1);
376592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	colorAttachments[0] = *m_colorTargetView;
377592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
378592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
379592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
380592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_framebuffer		= vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
381592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
382592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
383592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
384592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,
385592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		(deUint32)sizeof(tcu::Vec4) * 2,
386592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_VERTEX_INPUT_RATE_VERTEX,
387592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
388592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
389592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
390592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
391592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
392592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u,
393592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u,
394592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
395592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u
396592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		},
397592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
398592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			1u,
399592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u,
400592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
401592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			(deUint32)(sizeof(float)* 4),
402592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
403592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
404592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
405592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
406592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															  &vertexInputBindingDescription,
407592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															  2,
408592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham															  vertexInputAttributeDescriptions);
409592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
410592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDeviceSize dataSize = m_data.vertices.size() * sizeof(PositionColorVertex);
411592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
412592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
413592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
414592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deUint8* ptr = reinterpret_cast<deUint8*>(m_vertexBuffer->getBoundMemory().getHostPtr());
415592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deMemcpy(ptr, &(m_data.vertices[0]), static_cast<size_t>(dataSize));
416592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
417592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::flushMappedMemoryRange(m_vk,
418592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham							   device,
419592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham							   m_vertexBuffer->getBoundMemory().getMemory(),
420592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham							   m_vertexBuffer->getBoundMemory().getOffset(),
421114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski							   VK_WHOLE_SIZE);
422592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
423592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
42455dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi	m_cmdPool	= vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
42555dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi	m_cmdBuffer	= vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
426592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
427592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	initPipeline(device);
428592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
429592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
430592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstanceBase::initPipeline (const vk::VkDevice device)
431592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
432592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::Unique<vk::VkShaderModule>	vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("vert"), 0));
433592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::Unique<vk::VkShaderModule>	fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("frag"), 0));
434592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
435592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
436592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
437592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkViewport viewport;
438592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.x				= 0;
439592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.y				= 0;
440592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.width			= static_cast<float>(WIDTH);
441592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.height			= static_cast<float>(HEIGHT);
442592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.minDepth		= 0.0f;
443592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	viewport.maxDepth		= 1.0f;
444592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
445592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkRect2D scissor;
446592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	scissor.offset.x		= 0;
447592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	scissor.offset.y		= 0;
448592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	scissor.extent.width	= WIDTH;
449592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	scissor.extent.height	= HEIGHT;
450592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
451592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
452592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
453592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
454592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
455592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_data.topology));
456592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
457592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport), std::vector<vk::VkRect2D>(1, scissor)));
458592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
459592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
460592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
461592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
462592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
463592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
464592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
465592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstanceBase::beginRenderPass (void)
466592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
467592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
468592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const CmdBufferBeginInfo beginInfo;
469592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
470592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
471592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
472592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
473592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
474592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
475592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
476592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
477592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
478592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkMemoryBarrier memBarrier =
479592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
480592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
481592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,
482592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_ACCESS_TRANSFER_WRITE_BIT,
483592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
484592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
485592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
486592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
487592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
488592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
489592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
490592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
491592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
492592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
493592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
494592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
495592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
496592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstanceBase::generateRefImage (const tcu::PixelBufferAccess& access, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
497592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
498592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const PassthruVertShader				vertShader;
499592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const PassthruFragShader				fragShader;
500592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::Program						program			(&vertShader, &fragShader);
501592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::MultisamplePixelBufferAccess	colorBuffer		= rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(access);
502592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::RenderTarget					renderTarget	(colorBuffer);
503592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::RenderState					renderState		((rr::ViewportState(colorBuffer)));
504592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::Renderer						renderer;
505592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
506592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const rr::VertexAttrib	vertexAttribs[] =
507592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
508592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertices[0]),
509592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &colors[0])
510592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
511592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
512592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	renderer.draw(rr::DrawCommand(renderState,
513592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham								  renderTarget,
514592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham								  program,
515592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham								  DE_LENGTH_OF_ARRAY(vertexAttribs),
516592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham								  &vertexAttribs[0],
517592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham								  rr::PrimitiveList(mapVkPrimitiveTopology(m_data.topology), (deUint32)vertices.size(), 0)));
518592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
519592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
520592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
521592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamclass DrawTestInstance : public DrawTestInstanceBase
522592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
523592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahampublic:
524592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham							DrawTestInstance		(Context& context, const T& data);
525592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual					~DrawTestInstance		(void);
526592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual void			generateDrawData		(void);
527592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual tcu::TestStatus	iterate					(void);
528592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamprivate:
529592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	T						m_data;
530592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
531592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
532592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
533592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestInstance<T>::DrawTestInstance (Context& context, const T& data)
534592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	: DrawTestInstanceBase	(context)
535592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	, m_data				(data)
536592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
537592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	generateDrawData();
538592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	initialize(m_data);
539592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
540592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
541592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
542592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestInstance<T>::~DrawTestInstance (void)
543592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
544592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
545592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
546592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
547592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstance<T>::generateDrawData (void)
548592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
549592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DE_FATAL("Using the general case of this function is forbidden!");
550592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
551592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
552592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
553592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestStatus DrawTestInstance<T>::iterate (void)
554592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
555592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	DE_FATAL("Using the general case of this function is forbidden!");
556592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return tcu::TestStatus::fail("");
557592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
558592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
559592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
560592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamclass DrawTestCase : public TestCase
561592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
562592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	public:
563592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham									DrawTestCase		(tcu::TestContext& context, const char* name, const char* desc, const T data);
564592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham									~DrawTestCase		(void);
565592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual	void					initPrograms		(vk::SourceCollections& programCollection) const;
566592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual void					initShaderSources	(void);
567592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	virtual TestInstance*			createInstance		(Context& context) const;
568592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
569592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamprivate:
570592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	T													m_data;
571592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::string											m_vertShaderSource;
572592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::string											m_fragShaderSource;
573592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
574592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
575592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
576592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestCase<T>::DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const T data)
577592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	: vkt::TestCase	(context, name, desc)
578592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	, m_data		(data)
579592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
580592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	initShaderSources();
581592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
582592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
583592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
584592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamDrawTestCase<T>::~DrawTestCase	(void)
585592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
586592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
587592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
588592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
589592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestCase<T>::initPrograms (vk::SourceCollections& programCollection) const
590592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
591592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
592592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
593592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
594592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
595592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
596592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestCase<T>::initShaderSources (void)
597592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
598592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::stringstream vertShader;
599592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vertShader	<< "#version 430\n"
600592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "layout(location = 0) in vec4 in_position;\n"
601592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "layout(location = 1) in vec4 in_color;\n"
602592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "layout(location = 0) out vec4 out_color;\n"
603592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
604592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "out gl_PerVertex {\n"
605114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    vec4  gl_Position;\n"
606114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    float gl_PointSize;\n"
607592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "};\n"
608592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "void main() {\n"
609114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    gl_PointSize = 1.0;\n"
610114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    gl_Position  = in_position;\n"
611114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    out_color    = in_color;\n"
612592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "}\n";
613592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
614592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vertShaderSource = vertShader.str();
615592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
616592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::stringstream fragShader;
617592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	fragShader	<< "#version 430\n"
618592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "layout(location = 0) in vec4 in_color;\n"
619592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "layout(location = 0) out vec4 out_color;\n"
620592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "void main()\n"
621592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "{\n"
622114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski				<< "    out_color = in_color;\n"
623592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				<< "}\n";
624592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
625592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_fragShaderSource = fragShader.str();
626592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
627592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
628592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<typename T>
629592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor AbrahamTestInstance* DrawTestCase<T>::createInstance (Context& context) const
630592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
631592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return new DrawTestInstance<T>(context, m_data);
632592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
633592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
634592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham// Specialized cases
635592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
636592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstance<DrawParams>::generateDrawData (void)
637592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
638592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::Random		rnd			(SEED ^ m_data.params.firstVertex ^ m_data.params.vertexCount);
639592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
640592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32	vectorSize	= m_data.params.firstVertex + m_data.params.vertexCount;
641592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
642592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Initialize the vector
643592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.vertices = std::vector<PositionColorVertex>(vectorSize, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
644592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
645592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Fill only the used indexes
646592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (deUint32 vertexIdx = m_data.params.firstVertex; vertexIdx < vectorSize; ++vertexIdx)
647592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
648592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_data.vertices[vertexIdx] = PositionColorVertex(
649592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0),										// Coord
650592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0)));	// Color
651592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
652592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
653592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
654592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
655592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestStatus DrawTestInstance<DrawParams>::iterate (void)
656592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
657592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TestLog			&log				= m_context.getTestContext().getLog();
658592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkQueue		queue				= m_context.getUniversalQueue();
659592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
660592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	beginRenderPass();
661592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
662592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDeviceSize	vertexBufferOffset	= 0;
663592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
664592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
665592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
666592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
667592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdDraw(*m_cmdBuffer, m_data.params.vertexCount, m_data.params.instanceCount, m_data.params.firstVertex, m_data.params.firstInstance);
668592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdEndRenderPass(*m_cmdBuffer);
669592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.endCommandBuffer(*m_cmdBuffer);
670592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
671592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkSubmitInfo	submitInfo =
672592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
673592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
674592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*				pNext;
675592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					waitSemaphoreCount;
676592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const VkSemaphore*		pWaitSemaphores;
677592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		(const vk::VkPipelineStageFlags*)DE_NULL,
678592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1,											// deUint32					commandBufferCount;
679592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&m_cmdBuffer.get(),							// const VkCommandBuffer*	pCommandBuffers;
680592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					signalSemaphoreCount;
681592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL										// const VkSemaphore*		pSignalSemaphores;
682592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
683592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
684592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
685592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Validation
686592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
687592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
688592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
689592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<tcu::Vec4>	vertices;
690592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<tcu::Vec4>	colors;
691592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
692592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<PositionColorVertex>::const_iterator vertex = m_data.vertices.begin() + m_data.params.firstVertex; vertex != m_data.vertices.end(); ++vertex)
693592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
694592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vertices.push_back(vertex->position);
695592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		colors.push_back(vertex->color);
696592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
697592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	generateRefImage(refImage.getAccess(), vertices, colors);
698592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
699592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueWaitIdle(queue));
700592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
701592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
702592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
703592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
704592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
705592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	qpTestResult res = QP_TEST_RESULT_PASS;
706592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
707114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	if (!imageCompare(log, refImage.getAccess(), renderedFrame, m_data.topology))
708592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		res = QP_TEST_RESULT_FAIL;
709114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski
710592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return tcu::TestStatus(res, qpGetTestResultName(res));
711592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
712592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
713592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
714592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstance<DrawIndexedParams>::generateDrawData (void)
715592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
716592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::Random		rnd			(SEED ^ m_data.params.firstIndex ^ m_data.params.indexCount);
717592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32	indexSize	= m_data.params.firstIndex + m_data.params.indexCount;
718592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
719592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Initialize the vector with zeros
720592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.indexes = std::vector<deUint32>(indexSize, 0);
721592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
722592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deUint32		highestIndex	= 0;	// Store to highest index to calculate the vertices size
723592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Fill the indexes from firstIndex
724592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (deUint32 idx = 0; idx < m_data.params.indexCount; ++idx)
725592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
726592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32	vertexIdx	= rnd.getInt(m_data.params.vertexOffset, INDEX_LIMIT);
727592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		highestIndex = (vertexIdx > highestIndex) ? vertexIdx : highestIndex;
728592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
729592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_data.indexes[m_data.params.firstIndex + idx]	= vertexIdx;
730592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
731592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
732592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Fill up the vertex coordinates with zeros until the highestIndex including the vertexOffset
733592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.vertices = std::vector<PositionColorVertex>(m_data.params.vertexOffset + highestIndex + 1, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
734592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
735592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Generate random vertex only where you have index pointing at
736592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<deUint32>::const_iterator indexIt = m_data.indexes.begin() + m_data.params.firstIndex; indexIt != m_data.indexes.end(); ++indexIt)
737592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
738592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		// Get iterator to the vertex position  with the vertexOffset
739592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<PositionColorVertex>::iterator vertexIt = m_data.vertices.begin() + m_data.params.vertexOffset + *indexIt;
740592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
741592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		tcu::VecAccess<float, 4, 4>	positionAccess = vertexIt->position.xyzw();
742592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
743592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
744592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		tcu::VecAccess<float, 4, 4>	colorAccess = vertexIt->color.xyzw();
745592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
746592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
747592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
748592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
749592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
750592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestStatus DrawTestInstance<DrawIndexedParams>::iterate (void)
751592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
752592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TestLog				&log				= m_context.getTestContext().getLog();
753592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::DeviceInterface&	vk					= m_context.getDeviceInterface();
754592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDevice			vkDevice			= m_context.getDevice();
755592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
756592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkQueue			queue				= m_context.getUniversalQueue();
757592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Allocator&				allocator			= m_context.getDefaultAllocator();
758592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
759592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	beginRenderPass();
760592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
761592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDeviceSize	vertexBufferOffset = 0;
762592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBuffer	vertexBuffer = m_vertexBuffer->object();
763592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
764592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
765592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
766592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
767592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32	bufferSize	= (deUint32)(m_data.indexes.size() * sizeof(deUint32));
768592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
769592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkBuffer>	indexBuffer;
770592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
771592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBufferCreateInfo	bufferCreateInfo =
772592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
773592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
774592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*			pNext;
775592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0u,											// VkBufferCreateFlags	flags;
776592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		bufferSize,									// VkDeviceSize			size;
777592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
778592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
779592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1u,											// deUint32				queueFamilyIndexCount;
780592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
781592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
782592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
783592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	indexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
784592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
785592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::MovePtr<vk::Allocation>	indexAlloc;
786592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
787592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	indexAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), vk::MemoryRequirement::HostVisible);
788592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexAlloc->getMemory(), indexAlloc->getOffset()));
789592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
790592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deMemcpy(indexAlloc->getHostPtr(), &(m_data.indexes[0]), bufferSize);
791592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
7926bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet	vk::flushMappedMemoryRange(m_vk, vkDevice, indexAlloc->getMemory(), indexAlloc->getOffset(), bufferSize);
7936bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet
794592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindIndexBuffer(*m_cmdBuffer, *indexBuffer, 0u, m_data.indexType);
795592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdDrawIndexed(*m_cmdBuffer, m_data.params.indexCount, m_data.params.instanceCount, m_data.params.firstIndex, m_data.params.vertexOffset, m_data.params.firstInstance);
796592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdEndRenderPass(*m_cmdBuffer);
797592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.endCommandBuffer(*m_cmdBuffer);
798592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
799592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkSubmitInfo	submitInfo =
800592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
801592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
802592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*				pNext;
803592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					waitSemaphoreCount;
804592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const VkSemaphore*		pWaitSemaphores;
805592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		(const vk::VkPipelineStageFlags*)DE_NULL,
806592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1,											// deUint32					commandBufferCount;
807592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&m_cmdBuffer.get(),							// const VkCommandBuffer*	pCommandBuffers;
808592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					signalSemaphoreCount;
809592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL										// const VkSemaphore*		pSignalSemaphores;
810592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
811592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
812592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
813592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Validation
814592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TextureLevel	refImage	(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
815592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
816592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
817592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<tcu::Vec4>	vertices;
818592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	std::vector<tcu::Vec4>	colors;
819592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
820592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<deUint32>::const_iterator it = m_data.indexes.begin() + m_data.params.firstIndex; it != m_data.indexes.end(); ++it)
821592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
822592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32 idx = m_data.params.vertexOffset + *it;
823592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vertices.push_back(m_data.vertices[idx].position);
824592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		colors.push_back(m_data.vertices[idx].color);
825592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
826592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	generateRefImage(refImage.getAccess(), vertices, colors);
827592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
828592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueWaitIdle(queue));
829592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
830592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
831592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
832592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
833592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
834592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	qpTestResult res = QP_TEST_RESULT_PASS;
835592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
836114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	if (!imageCompare(log, refImage.getAccess(), renderedFrame, m_data.topology))
837592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		res = QP_TEST_RESULT_FAIL;
838114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski
839592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return tcu::TestStatus(res, qpGetTestResultName(res));
840592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
841592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
842592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
843592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstance<DrawIndirectParams>::generateDrawData (void)
844592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
845592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::Random	rnd(SEED ^ m_data.commands[0].vertexCount ^ m_data.commands[0].firstVertex);
846592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
847592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deUint32 lastIndex	= 0;
848592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
849592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Find the interval which will be used
850592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
851592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
852592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const deUint32	index = it->firstVertex + it->vertexCount;
853592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		lastIndex	= (index > lastIndex) ? index : lastIndex;
854592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
855592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
856592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Initialize with zeros
857592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.vertices = std::vector<PositionColorVertex>(lastIndex, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
858592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
859592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Generate random vertices only where necessary
860592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
861592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
862592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<PositionColorVertex>::iterator vertexStart = m_data.vertices.begin() + it->firstVertex;
863592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
864592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 idx = 0; idx < it->vertexCount; ++idx)
865592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
866592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			std::vector<PositionColorVertex>::iterator vertexIt = vertexStart + idx;
867592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
868592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::VecAccess<float, 4, 4> positionAccess = vertexIt->position.xyzw();
869592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
870592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
871592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::VecAccess<float, 4, 4> colorAccess = vertexIt->color.xyzw();
872592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
873592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
874592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
875592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
876592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
877592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
878592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestStatus DrawTestInstance<DrawIndirectParams>::iterate (void)
879592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
880592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TestLog						&log				= m_context.getTestContext().getLog();
881592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::DeviceInterface&			vk					= m_context.getDeviceInterface();
882592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDevice					vkDevice			= m_context.getDevice();
883592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Allocator&						allocator			= m_context.getDefaultAllocator();
884592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkQueue					queue				= m_context.getUniversalQueue();
885592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
886592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkPhysicalDeviceFeatures	features			= m_context.getDeviceFeatures();
887592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
888592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	beginRenderPass();
889592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
890592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDeviceSize	vertexBufferOffset	= 0;
891592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
892592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
893592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
894592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
895592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
896592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkBuffer>		indirectBuffer;
897592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::MovePtr<vk::Allocation>	indirectAlloc;
898592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
899592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
900592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const vk::VkDeviceSize	indirectInfoSize	= m_data.commands.size() * sizeof(vk::VkDrawIndirectCommand);
901592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
902592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const vk::VkBufferCreateInfo	indirectCreateInfo =
903592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
904592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
905592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			DE_NULL,									// const void*			pNext;
906592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u,											// VkBufferCreateFlags	flags;
907592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			indirectInfoSize,							// VkDeviceSize			size;
908592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,	// VkBufferUsageFlags	usage;
909592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
910592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			1u,											// deUint32				queueFamilyIndexCount;
911592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
912592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		};
913592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
914592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		indirectBuffer	= createBuffer(vk, vkDevice, &indirectCreateInfo);
915592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		indirectAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indirectBuffer), vk::MemoryRequirement::HostVisible);
916592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		VK_CHECK(vk.bindBufferMemory(vkDevice, *indirectBuffer, indirectAlloc->getMemory(), indirectAlloc->getOffset()));
917592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
918592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deMemcpy(indirectAlloc->getHostPtr(), &(m_data.commands[0]), (size_t)indirectInfoSize);
9196bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet
9206bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet		vk::flushMappedMemoryRange(m_vk, vkDevice, indirectAlloc->getMemory(), indirectAlloc->getOffset(), indirectInfoSize);
921592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
922592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
923592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// If multiDrawIndirect not supported execute single calls
924592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	if (m_data.commands.size() > 1 && !(features.multiDrawIndirect))
925592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
926592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 cmdIdx = 0; cmdIdx < m_data.commands.size(); ++cmdIdx)
927592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
928592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			const deUint32	offset	= (deUint32)(indirectAlloc->getOffset() + cmdIdx * sizeof(vk::VkDrawIndirectCommand));
929592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			m_vk.cmdDrawIndirect(*m_cmdBuffer, *indirectBuffer, offset, 1, sizeof(vk::VkDrawIndirectCommand));
930592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
931592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
932592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	else
933592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
934592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_vk.cmdDrawIndirect(*m_cmdBuffer, *indirectBuffer, indirectAlloc->getOffset(), (deUint32)m_data.commands.size(), sizeof(vk::VkDrawIndirectCommand));
935592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
936592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
937592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdEndRenderPass(*m_cmdBuffer);
938592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.endCommandBuffer(*m_cmdBuffer);
939592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
940592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkSubmitInfo	submitInfo =
941592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
942592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
943592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*				pNext;
944592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					waitSemaphoreCount;
945592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const VkSemaphore*		pWaitSemaphores;
946592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		(const vk::VkPipelineStageFlags*)DE_NULL,
947592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1,											// deUint32					commandBufferCount;
948592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&m_cmdBuffer.get(),							// const VkCommandBuffer*	pCommandBuffers;
949592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					signalSemaphoreCount;
950592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL										// const VkSemaphore*		pSignalSemaphores;
951592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
952592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
953592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
954592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Validation
955592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
956592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
957592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
958592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
959592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
960592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<tcu::Vec4>	vertices;
961592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<tcu::Vec4>	colors;
962592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
963592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<PositionColorVertex>::const_iterator	firstIt	= m_data.vertices.begin() + it->firstVertex;
964592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<PositionColorVertex>::const_iterator	lastIt	= firstIt + it->vertexCount;
965592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
966592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (std::vector<PositionColorVertex>::const_iterator vertex = firstIt; vertex != lastIt; ++vertex)
967592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
968592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vertices.push_back(vertex->position);
969592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			colors.push_back(vertex->color);
970592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
971592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		generateRefImage(refImage.getAccess(), vertices, colors);
972592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
973592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
974592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueWaitIdle(queue));
975592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
976592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
977592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
978592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
979592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
980592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	qpTestResult res = QP_TEST_RESULT_PASS;
981592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
982114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	if (!imageCompare(log, refImage.getAccess(), renderedFrame, m_data.topology))
983592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		res = QP_TEST_RESULT_FAIL;
984114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski
985592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return tcu::TestStatus(res, qpGetTestResultName(res));
986592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
987592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
988592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
989592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid DrawTestInstance<DrawIndexedIndirectParams>::generateDrawData (void)
990592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
991592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::Random		rnd			(SEED ^ m_data.commands[0].firstIndex ^ m_data.commands[0].indexCount);
992592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
993592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deUint32		lastIndex	= 0;
994592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
995592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Get the maximum range of indexes
996592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
997592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
998592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const deUint32	index		= it->firstIndex + it->indexCount;
999592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham						lastIndex	= (index > lastIndex) ? index : lastIndex;
1000592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1001592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1002592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Initialize the vector with zeros
1003592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.indexes = std::vector<deUint32>(lastIndex, 0);
1004592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1005592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deUint32	highestIndex	= 0;
1006592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1007592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Generate random indexes for the ranges
1008592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
1009592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1010592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 idx = 0; idx < it->indexCount; ++idx)
1011592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1012592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			const deUint32	vertexIdx	= rnd.getInt(it->vertexOffset, INDEX_LIMIT);
1013592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			const deUint32	maxIndex	= vertexIdx + it->vertexOffset;
1014592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1015592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			highestIndex = (maxIndex > highestIndex) ? maxIndex : highestIndex;
1016592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			m_data.indexes[it->firstIndex + idx] = vertexIdx;
1017592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1018592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1019592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1020592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Initialize the vertex vector
1021592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_data.vertices = std::vector<PositionColorVertex>(highestIndex + 1, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
1022592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1023592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Generate random vertices in the used locations
1024592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator cmdIt = m_data.commands.begin(); cmdIt != m_data.commands.end(); ++cmdIt)
1025592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1026592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32	firstIdx	= cmdIt->firstIndex;
1027592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32	lastIdx		= firstIdx + cmdIt->indexCount;
1028592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1029592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 idx = firstIdx; idx < lastIdx; ++idx)
1030592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1031592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			std::vector<PositionColorVertex>::iterator	vertexIt = m_data.vertices.begin() + cmdIt->vertexOffset + m_data.indexes[idx];
1032592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1033592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::VecAccess<float, 4, 4> positionAccess = vertexIt->position.xyzw();
1034592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
1035592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1036592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			tcu::VecAccess<float, 4, 4> colorAccess = vertexIt->color.xyzw();
1037592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
1038592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1039592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1040592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1041592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1042592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtemplate<>
1043592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestStatus DrawTestInstance<DrawIndexedIndirectParams>::iterate (void)
1044592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1045592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TestLog						&log				= m_context.getTestContext().getLog();
1046592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::DeviceInterface&			vk					= m_context.getDeviceInterface();
1047592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDevice					vkDevice			= m_context.getDevice();
1048592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1049592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkQueue					queue				= m_context.getUniversalQueue();
1050592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Allocator&						allocator			= m_context.getDefaultAllocator();
1051592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkPhysicalDeviceFeatures	features			= m_context.getDeviceFeatures();
1052592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1053592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	beginRenderPass();
1054592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1055592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkDeviceSize	vertexBufferOffset	= 0;
1056592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
1057592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1058592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1059592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1060592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1061592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkBuffer>		indirectBuffer;
1062592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::MovePtr<vk::Allocation>	indirectAlloc;
1063592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1064592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1065592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const vk::VkDeviceSize	indirectInfoSize	= m_data.commands.size() * sizeof(vk::VkDrawIndexedIndirectCommand);
1066592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1067592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const vk::VkBufferCreateInfo	indirectCreateInfo =
1068592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1069592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1070592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			DE_NULL,									// const void*			pNext;
1071592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			0u,											// VkBufferCreateFlags	flags;
1072592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			indirectInfoSize,							// VkDeviceSize			size;
1073592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,	// VkBufferUsageFlags	usage;
1074592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1075592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			1u,											// deUint32				queueFamilyIndexCount;
1076592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1077592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		};
1078592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1079592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		indirectBuffer	= createBuffer(vk, vkDevice, &indirectCreateInfo);
1080592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		indirectAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indirectBuffer), vk::MemoryRequirement::HostVisible);
1081592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		VK_CHECK(vk.bindBufferMemory(vkDevice, *indirectBuffer, indirectAlloc->getMemory(), indirectAlloc->getOffset()));
1082592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1083592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deMemcpy(indirectAlloc->getHostPtr(), &(m_data.commands[0]), (size_t)indirectInfoSize);
10846bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet
10856bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet		vk::flushMappedMemoryRange(m_vk, vkDevice, indirectAlloc->getMemory(), indirectAlloc->getOffset(), indirectInfoSize);
1086592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1087592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1088592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const deUint32	bufferSize = (deUint32)(m_data.indexes.size() * sizeof(deUint32));
1089592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1090592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::Move<vk::VkBuffer>			indexBuffer;
1091592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1092592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkBufferCreateInfo	bufferCreateInfo =
1093592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1094592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1095592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*			pNext;
1096592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0u,											// VkBufferCreateFlags	flags;
1097592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		bufferSize,									// VkDeviceSize			size;
1098592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
1099592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1100592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1u,											// deUint32				queueFamilyIndexCount;
1101592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1102592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
1103592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1104592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	indexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
1105592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1106592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::MovePtr<vk::Allocation>	indexAlloc;
1107592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1108592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	indexAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), vk::MemoryRequirement::HostVisible);
1109592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexAlloc->getMemory(), indexAlloc->getOffset()));
1110592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1111592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	deMemcpy(indexAlloc->getHostPtr(), &(m_data.indexes[0]), bufferSize);
1112592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
11136bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet	vk::flushMappedMemoryRange(m_vk, vkDevice, indexAlloc->getMemory(), indexAlloc->getOffset(), bufferSize);
11146bc94f82bfc311caad84898c40c2d20b3992fe0cGary Sweet
1115592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdBindIndexBuffer(*m_cmdBuffer, *indexBuffer, 0u, m_data.indexType);
1116592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1117592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// If multiDrawIndirect not supported execute single calls
1118592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	if (m_data.commands.size() > 1 && !(features.multiDrawIndirect))
1119592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1120592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 cmdIdx = 0; cmdIdx < m_data.commands.size(); ++cmdIdx)
1121592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1122592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			const deUint32	offset	= (deUint32)(indirectAlloc->getOffset() + cmdIdx * sizeof(vk::VkDrawIndexedIndirectCommand));
1123592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, *indirectBuffer, offset, 1, sizeof(vk::VkDrawIndexedIndirectCommand));
1124592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1125592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1126592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	else
1127592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1128592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, *indirectBuffer, indirectAlloc->getOffset(), (deUint32)m_data.commands.size(), sizeof(vk::VkDrawIndexedIndirectCommand));
1129592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1130592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1131592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.cmdEndRenderPass(*m_cmdBuffer);
1132592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	m_vk.endCommandBuffer(*m_cmdBuffer);
1133592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1134592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	vk::VkSubmitInfo	submitInfo =
1135592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1136592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
1137592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const void*				pNext;
1138592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					waitSemaphoreCount;
1139592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL,									// const VkSemaphore*		pWaitSemaphores;
1140592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		(const vk::VkPipelineStageFlags*)DE_NULL,
1141592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		1,											// deUint32					commandBufferCount;
1142592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		&m_cmdBuffer.get(),							// const VkCommandBuffer*	pCommandBuffers;
1143592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		0,											// deUint32					signalSemaphoreCount;
1144592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		DE_NULL										// const VkSemaphore*		pSignalSemaphores;
1145592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	};
1146592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
1147592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1148592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	// Validation
1149592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
1150592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
1151592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1152592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator cmd = m_data.commands.begin(); cmd != m_data.commands.end(); ++cmd)
1153592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1154592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<tcu::Vec4>	vertices;
1155592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::vector<tcu::Vec4>	colors;
1156592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1157592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		for (deUint32 idx = 0; idx < cmd->indexCount; ++idx)
1158592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1159592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			const deUint32 vertexIndex = cmd->vertexOffset + m_data.indexes[cmd->firstIndex + idx];
1160592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			vertices.push_back(m_data.vertices[vertexIndex].position);
1161592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			colors.push_back(m_data.vertices[vertexIndex].color);
1162592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1163592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		generateRefImage(refImage.getAccess(), vertices, colors);
1164592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1165592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1166592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	VK_CHECK(m_vk.queueWaitIdle(queue));
1167592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1168592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
1169592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
1170592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1171592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1172592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	qpTestResult res = QP_TEST_RESULT_PASS;
1173592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1174114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski	if (!imageCompare(log, refImage.getAccess(), renderedFrame, m_data.topology))
1175592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		res = QP_TEST_RESULT_FAIL;
1176114a1ba56e07d60347ca817f4d6c83b10c4e5071Maciej Jesionowski
1177592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return tcu::TestStatus(res, qpGetTestResultName(res));
1178592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1179592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1180592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtypedef DrawTestCase<DrawParams>				DrawCase;
1181592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtypedef DrawTestCase<DrawIndexedParams>			IndexedCase;
1182592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtypedef DrawTestCase<DrawIndirectParams>		IndirectCase;
1183592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtypedef DrawTestCase<DrawIndexedIndirectParams>	IndexedIndirectCase;
1184592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1185592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamstruct TestCaseParams
1186592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1187592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const DrawCommandType			command;
1188592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkPrimitiveTopology	topology;
1189592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1190592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	TestCaseParams (const DrawCommandType cmd, const vk::VkPrimitiveTopology top)
1191592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		: command	(cmd)
1192592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		, topology	(top)
1193592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{}
1194592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham};
1195592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1196592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}	// anonymous
1197592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1198592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid populateSubGroup (tcu::TestCaseGroup* testGroup, const TestCaseParams caseParams)
1199592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1200592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	de::Random						rnd			(SEED ^ deStringHash(testGroup->getName()));
1201592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	tcu::TestContext&				testCtx		= testGroup->getTestContext();
1202592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const DrawCommandType			command		= caseParams.command;
1203592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	const vk::VkPrimitiveTopology	topology	= caseParams.topology;
1204592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1205592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (deUint32 primitiveCountIdx = 0; primitiveCountIdx < DE_LENGTH_OF_ARRAY(PRIMITIVE_COUNT); ++primitiveCountIdx)
1206592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1207592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const deUint32 primitives = PRIMITIVE_COUNT[primitiveCountIdx];
1208592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1209592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32	multiplier	= 1;
1210592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		deUint32	offset		= 0;
1211592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		// Calculated by Vulkan 23.1
1212592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		switch (topology)
1213592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1214592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:													break;
1215592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:						multiplier = 2;				break;
1216592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:													break;
1217592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:					multiplier = 3;				break;
1218592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:												break;
1219592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:									offset = 1;	break;
1220592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:		multiplier = 4;	offset = 1;	break;
1221592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:						offset = 1;	break;
1222592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:	multiplier = 6;				break;
1223592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:	multiplier = 2;				break;
1224592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			default:														DE_FATAL("Unsupported topology.");
1225592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1226592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1227592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const deUint32	vertexCount		= multiplier * primitives + offset;
1228592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		std::string		name			= de::toString(primitives);
1229592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1230592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		switch (command)
1231592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		{
1232592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case DRAW_COMMAND_TYPE_DRAW:
1233592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			{
1234592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	firstPrimitive	= rnd.getInt(0, primitives);
1235592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	firstVertex		= multiplier * firstPrimitive;
1236592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new DrawCase(testCtx, name.c_str(), "vkCmdDraw testcase.",
1237592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham					DrawParams(topology, vertexCount, 1, firstVertex, 0))
1238592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				);
1239592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				break;
1240592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			}
1241592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case DRAW_COMMAND_TYPE_DRAW_INDEXED:
1242592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			{
1243592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	firstIndex			= rnd.getInt(0, OFFSET_LIMIT);
1244592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	vertexOffset		= rnd.getInt(0, OFFSET_LIMIT);
1245592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new IndexedCase(testCtx, name.c_str(), "vkCmdDrawIndexed testcase.",
1246592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham					DrawIndexedParams(topology, vk::VK_INDEX_TYPE_UINT32, vertexCount, 1, firstIndex, vertexOffset, 0))
1247592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				);
1248592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				break;
1249592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			}
1250592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case DRAW_COMMAND_TYPE_DRAW_INDIRECT:
1251592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			{
1252592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	firstVertex		= rnd.getInt(0, OFFSET_LIMIT);
1253592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1254592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				DrawIndirectParams	params	= DrawIndirectParams(topology);
1255592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1256592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				params.addCommand(vertexCount, 1, 0, 0);
1257592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new IndirectCase(testCtx, (name + "_single_command").c_str(), "vkCmdDrawIndirect testcase.", params));
1258592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1259592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				params.addCommand(vertexCount, 1, firstVertex, 0);
1260592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new IndirectCase(testCtx, (name + "_multi_command").c_str(), "vkCmdDrawIndirect testcase.", params));
1261592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				break;
1262592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			}
1263592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:
1264592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			{
1265592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	firstIndex		= rnd.getInt(vertexCount, OFFSET_LIMIT);
1266592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				deUint32	vertexOffset	= rnd.getInt(vertexCount, OFFSET_LIMIT);
1267592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1268592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				DrawIndexedIndirectParams	params	= DrawIndexedIndirectParams(topology, vk::VK_INDEX_TYPE_UINT32);
1269592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				params.addCommand(vertexCount, 1, 0, 0, 0);
1270592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new IndexedIndirectCase(testCtx, (name + "_single_command").c_str(), "vkCmdDrawIndexedIndirect testcase.", params));
1271592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1272592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				params.addCommand(vertexCount, 1, firstIndex, vertexOffset, 0);
1273592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				testGroup->addChild(new IndexedIndirectCase(testCtx, (name + "_multi_command").c_str(), "vkCmdDrawIndexedIndirect testcase.", params));
1274592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				break;
1275592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			}
1276592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham			default:
1277592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham				DE_FATAL("Unsupported draw command.");
1278592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		}
1279592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1280592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1281592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1282592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid createTopologyGroups (tcu::TestCaseGroup* testGroup, const DrawCommandType cmdType)
1283592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1284592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (deUint32 idx = 0; idx != vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++idx)
1285592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1286592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const vk::VkPrimitiveTopology	topology	= vk::VkPrimitiveTopology(idx);
1287592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const std::string				groupName	= de::toLower(getPrimitiveTopologyName(topology)).substr(22);
1288592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		addTestGroup(testGroup, groupName, "Testcases with a specific topology.", populateSubGroup, TestCaseParams(cmdType, topology));
1289592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1290592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1291592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1292592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamvoid createDrawTests (tcu::TestCaseGroup* testGroup)
1293592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1294592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	for (deUint32 idx = 0; idx < DRAW_COMMAND_TYPE_DRAW_LAST; ++idx)
1295592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	{
1296592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		const DrawCommandType	command	= DrawCommandType(idx);
1297592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham		addTestGroup(testGroup, getDrawCommandTypeName(command), "Group for testing a specific draw command.", createTopologyGroups, command);
1298592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	}
1299592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1300592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1301592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abrahamtcu::TestCaseGroup*	createBasicDrawTests (tcu::TestContext& testCtx)
1302592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham{
1303592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham	return createTestGroup(testCtx, "basic_draw", "Basic drawing tests", createDrawTests);
1304592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}
1305592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham
1306592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}	// DrawTests
1307592743bcc9d2bc40bf0b371ad4431f701fc9cd1aGabor Abraham}	// vkt
1308