1abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*------------------------------------------------------------------------
2abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Vulkan Conformance Tests
3abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * ------------------------
4abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
5abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2014 The Android Open Source Project
6abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc.
7abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
8abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License");
9abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * you may not use this file except in compliance with the License.
10abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * You may obtain a copy of the License at
11abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
12abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *      http://www.apache.org/licenses/LICENSE-2.0
13abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
14abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Unless required by applicable law or agreed to in writing, software
15abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS,
16abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * See the License for the specific language governing permissions and
18abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * limitations under the License.
19abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
20abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*!
21abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \file
22abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Tessellation Winding Tests
23abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/
24abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
25abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationWindingTests.hpp"
26abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTestCaseUtil.hpp"
27abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationUtil.hpp"
28abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
29abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuTestLog.hpp"
30abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuRGBA.hpp"
31abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
32abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkDefs.hpp"
33abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkQueryUtil.hpp"
34abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkBuilderUtil.hpp"
35abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkImageUtil.hpp"
36abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkTypeUtil.hpp"
37abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkStrUtil.hpp"
38abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
39abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deUniquePtr.hpp"
40abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
41abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace vkt
42abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
43abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace tessellation
44abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
45abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
46abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiusing namespace vk;
47abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
48abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace
49abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
50abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
51abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::string getCaseName (const TessPrimitiveType primitiveType, const Winding winding)
52abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
53abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::ostringstream str;
54abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	str << getTessPrimitiveTypeShaderName(primitiveType) << "_" << getWindingShaderName(winding);
55abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return str.str();
56abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
57abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
58abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline VkFrontFace mapFrontFace (const Winding winding)
59abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
60abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (winding)
61abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
62abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case WINDING_CCW:	return VK_FRONT_FACE_COUNTER_CLOCKWISE;
63abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case WINDING_CW:	return VK_FRONT_FACE_CLOCKWISE;
64abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
65abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
66abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return VK_FRONT_FACE_LAST;
67abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
68abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
69abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
70abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Returns true when the image passes the verification.
71abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool verifyResultImage (tcu::TestLog&						log,
72abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						const tcu::ConstPixelBufferAccess	image,
73abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						const TessPrimitiveType				primitiveType,
74abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						const Winding						winding,
75abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						const Winding						frontFaceWinding)
76abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
77abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const int totalNumPixels	= image.getWidth()*image.getHeight();
78abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const int badPixelTolerance = (primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 5*de::max(image.getWidth(), image.getHeight()) : 0);
79abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
80abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const tcu::Vec4 white = tcu::RGBA::white().toVec();
81abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const tcu::Vec4 red   = tcu::RGBA::red().toVec();
82abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
83abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	int numWhitePixels = 0;
84abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	int numRedPixels   = 0;
85abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int y = 0; y < image.getHeight();	y++)
86abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int x = 0; x < image.getWidth();	x++)
87abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
88abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		numWhitePixels += image.getPixel(x, y) == white ? 1 : 0;
89abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		numRedPixels   += image.getPixel(x, y) == red   ? 1 : 0;
90abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
91abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
92abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(numWhitePixels + numRedPixels <= totalNumPixels);
93abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
94abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	log << tcu::TestLog::Message << "Note: got " << numWhitePixels << " white and " << numRedPixels << " red pixels" << tcu::TestLog::EndMessage;
95abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
96abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const int otherPixels = totalNumPixels - numWhitePixels - numRedPixels;
97abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (otherPixels > badPixelTolerance)
98abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
99abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		log << tcu::TestLog::Message
100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "Failure: Got " << otherPixels << " other than white or red pixels (maximum tolerance " << badPixelTolerance << ")"
101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< tcu::TestLog::EndMessage;
102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return false;
103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (frontFaceWinding == winding)
106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			if (de::abs(numWhitePixels - totalNumPixels/2) > badPixelTolerance)
110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			{
111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				log << tcu::TestLog::Message << "Failure: wrong number of white pixels; expected approximately " << totalNumPixels/2 << tcu::TestLog::EndMessage;
112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				return false;
113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			}
114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else if (primitiveType == TESSPRIMITIVETYPE_QUADS)
116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			if (numWhitePixels != totalNumPixels)
118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			{
119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				log << tcu::TestLog::Message << "Failure: expected only white pixels (full-viewport quad)" << tcu::TestLog::EndMessage;
120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				return false;
121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			}
122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else
124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (numWhitePixels != 0)
129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			log << tcu::TestLog::Message << "Failure: expected only red pixels (everything culled)" << tcu::TestLog::EndMessage;
131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return false;
132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return true;
136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass WindingTest : public TestCase
139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic:
141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								WindingTest		(tcu::TestContext&			testCtx,
142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski												 const TessPrimitiveType	primitiveType,
143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski												 const Winding				winding);
144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	void						initPrograms	(SourceCollections&			programCollection) const;
146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	TestInstance*				createInstance	(Context&					context) const;
147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate:
149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const TessPrimitiveType		m_primitiveType;
150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Winding				m_winding;
151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski};
152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiWindingTest::WindingTest (tcu::TestContext&			testCtx,
154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						  const TessPrimitiveType	primitiveType,
155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						  const Winding				winding)
156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	: TestCase			(testCtx, getCaseName(primitiveType, winding), "")
157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	, m_primitiveType	(primitiveType)
158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	, m_winding			(winding)
159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid WindingTest::initPrograms (SourceCollections& programCollection) const
163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Vertex shader - no inputs
165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation control shader
177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(vertices = 1) out;\n"
183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelInner[0] = 5.0;\n"
187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelInner[1] = 5.0;\n"
188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[0] = 5.0;\n"
190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[1] = 5.0;\n"
191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[2] = 5.0;\n"
192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[3] = 5.0;\n"
193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation evaluation shader
199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(" << getTessPrimitiveTypeShaderName(m_primitiveType) << ", "
205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						 << getWindingShaderName(m_winding) << ") in;\n"
206abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
207abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
208abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
209abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_Position = vec4(gl_TessCoord.xy*2.0 - 1.0, 0.0, 1.0);\n"
210abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
211abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
212abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
213abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
214abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
215abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Fragment shader
216abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
217abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
218abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
219abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
220abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out mediump vec4 o_color;\n"
221abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
222abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
223abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
224abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    o_color = vec4(1.0);\n"
225abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
226abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
227abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
228abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
229abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
230abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
231abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass WindingTestInstance : public TestInstance
232abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
233abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic:
234abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								WindingTestInstance (Context&					context,
235abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													 const TessPrimitiveType	primitiveType,
236abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													 const Winding				winding);
237abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
238abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	tcu::TestStatus				iterate				(void);
239abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
240abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate:
241abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const TessPrimitiveType		m_primitiveType;
242abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Winding				m_winding;
243abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski};
244abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
245abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiWindingTestInstance::WindingTestInstance (Context&					context,
246abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const TessPrimitiveType	primitiveType,
247abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const Winding				winding)
248abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	: TestInstance		(context)
249abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	, m_primitiveType	(primitiveType)
250abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	, m_winding			(winding)
251abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
252abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
253abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
254abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus WindingTestInstance::iterate (void)
255abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
256abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const DeviceInterface&	vk					= m_context.getDeviceInterface();
257abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDevice			device				= m_context.getDevice();
258abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkQueue			queue				= m_context.getUniversalQueue();
259abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
260abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	Allocator&				allocator			= m_context.getDefaultAllocator();
261abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
262abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Color attachment
263abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
264abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const tcu::IVec2			  renderSize				 = tcu::IVec2(64, 64);
265abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFormat				  colorFormat				 = VK_FORMAT_R8G8B8A8_UNORM;
266abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
267abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Image					  colorAttachmentImage		 (vk, device, allocator,
268abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1u),
269abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 MemoryRequirement::Any);
270abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
271abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Color output buffer: image will be copied here for verification
272abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
273abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDeviceSize	colorBufferSizeBytes = renderSize.x()*renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
274abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Buffer		colorBuffer			 (vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
275abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
276abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Pipeline
277abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
278abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkImageView>		colorAttachmentView(makeImageView                       (vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange));
279abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkRenderPass>		renderPass         (makeRenderPass                      (vk, device, colorFormat));
280abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkFramebuffer>		framebuffer        (makeFramebuffer                     (vk, device, *renderPass, *colorAttachmentView, renderSize.x(), renderSize.y(), 1u));
281abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkPipelineLayout>	pipelineLayout     (makePipelineLayoutWithoutDescriptors(vk, device));
282abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
283abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
284abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
285abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Front face is static state, so we have to create two pipelines.
286abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
287abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkPipeline> pipelineCounterClockwise(GraphicsPipelineBuilder()
288abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setRenderSize	 (renderSize)
289abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setCullModeFlags(cullMode)
290abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setFrontFace	 (VK_FRONT_FACE_COUNTER_CLOCKWISE)
291abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_VERTEX_BIT,				   m_context.getBinaryCollection().get("vert"), DE_NULL)
292abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,    m_context.getBinaryCollection().get("tesc"), DE_NULL)
293abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get("tese"), DE_NULL)
294abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT,				   m_context.getBinaryCollection().get("frag"), DE_NULL)
295abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.build			 (vk, device, *pipelineLayout, *renderPass));
296abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
297abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkPipeline> pipelineClockwise(GraphicsPipelineBuilder()
298abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setRenderSize   (renderSize)
299abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setCullModeFlags(cullMode)
300abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setFrontFace    (VK_FRONT_FACE_CLOCKWISE)
301abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_VERTEX_BIT,				   m_context.getBinaryCollection().get("vert"), DE_NULL)
302abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,	   m_context.getBinaryCollection().get("tesc"), DE_NULL)
303abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get("tese"), DE_NULL)
304abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader		 (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT,				   m_context.getBinaryCollection().get("frag"), DE_NULL)
305abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.build			 (vk, device, *pipelineLayout, *renderPass));
306abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
307abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const struct // not static
308abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
309abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		Winding		frontFaceWinding;
310abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VkPipeline	pipeline;
311abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	} testCases[] =
312abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
313abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ WINDING_CCW,	*pipelineCounterClockwise },
314abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ WINDING_CW,	*pipelineClockwise		  },
315abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
316abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
317abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	tcu::TestLog& log = m_context.getTestContext().getLog();
318abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	log << tcu::TestLog::Message << "Pipeline uses " << getCullModeFlagsStr(cullMode) << tcu::TestLog::EndMessage;
319abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
320abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	bool success = true;
321abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
322abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Draw commands
323abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
324abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkCommandPool>   cmdPool  (makeCommandPool  (vk, device, queueFamilyIndex));
325abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkCommandBuffer> cmdBuffer(makeCommandBuffer(vk, device, *cmdPool));
326abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
327abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCases); ++caseNdx)
328abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
329abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const Winding frontFaceWinding = testCases[caseNdx].frontFaceWinding;
330abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
331abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		log << tcu::TestLog::Message << "Setting " << getFrontFaceName(mapFrontFace(frontFaceWinding)) << tcu::TestLog::EndMessage;
332abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
333abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Reset the command buffer and begin.
334abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		beginCommandBuffer(vk, *cmdBuffer);
335abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
336abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Change color attachment image layout
337abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
338abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// State is slightly different on the first iteration.
339abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageLayout currentLayout = (caseNdx == 0 ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3406e5ef4c51158771e71f72c70980b4dbd78f011f2Pyry Haulos			const VkAccessFlags srcFlags	  = (caseNdx == 0 ? (VkAccessFlags)0          : (VkAccessFlags)VK_ACCESS_TRANSFER_READ_BIT);
341abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
342abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
343abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				srcFlags, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
344abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				currentLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
345abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				*colorAttachmentImage, colorImageSubresourceRange);
346abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
347abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u,
348abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
349abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
350abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
351abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Begin render pass
352abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
353abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkRect2D renderArea = {
354abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				makeOffset2D(0, 0),
355abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				makeExtent2D(renderSize.x(), renderSize.y()),
356abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			};
357abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const tcu::Vec4 clearColor = tcu::RGBA::red().toVec();
358abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
359abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
360abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
361abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
362abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, testCases[caseNdx].pipeline);
363abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
364abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Process a single abstract vertex.
365abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
366abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		endRenderPass(vk, *cmdBuffer);
367abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
368abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Copy render result to a host-visible buffer
369abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
370abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageMemoryBarrier colorAttachmentPreCopyBarrier = makeImageMemoryBarrier(
371abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
372abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
373abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				*colorAttachmentImage, colorImageSubresourceRange);
374abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
375abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
376abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentPreCopyBarrier);
377abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
378abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
3791d185cb7ef57f375fcdf78cb50a7b4b5e3e4923ePyry Haulos			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(renderSize.x(), renderSize.y(), 1), makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
380abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorAttachmentImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &copyRegion);
381abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
382abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
383abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
384abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
385abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
386abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
387abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 1u, &postCopyBarrier, 0u, DE_NULL);
388abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
389abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
390abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		endCommandBuffer(vk, *cmdBuffer);
391abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
392abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
393abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
394abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// Log rendered image
395abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const Allocation& colorBufferAlloc = colorBuffer.getAllocation();
396abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			invalidateMappedMemoryRange(vk, device, colorBufferAlloc.getMemory(), colorBufferAlloc.getOffset(), colorBufferSizeBytes);
397abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
398abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc.getHostPtr());
399abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
400abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
401abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// Verify case result
402abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			success = success && verifyResultImage(log, imagePixelAccess, m_primitiveType, m_winding, frontFaceWinding);
403abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
404abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}  // for windingNdx
405abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
406abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return (success ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Failure"));
407abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
408abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
409abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestInstance* WindingTest::createInstance (Context& context) const
410abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
411abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER);
412abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
413abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return new WindingTestInstance(context, m_primitiveType, m_winding);
414abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
415abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
416abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // anonymous
417abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
418abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! These tests correspond to dEQP-GLES31.functional.tessellation.winding.*
419abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCaseGroup* createWindingTests (tcu::TestContext& testCtx)
420abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
421abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "winding", "Test the cw and ccw input layout qualifiers"));
422abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
423abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	static const TessPrimitiveType primitivesNoIsolines[] =
424abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
425abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		TESSPRIMITIVETYPE_TRIANGLES,
426abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		TESSPRIMITIVETYPE_QUADS,
427abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
428abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
429abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitivesNoIsolines); ++primitiveTypeNdx)
430abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int windingNdx = 0; windingNdx < WINDING_LAST; ++windingNdx)
431abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		group->addChild(new WindingTest(testCtx, primitivesNoIsolines[primitiveTypeNdx], (Winding)windingNdx));
432abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
433abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return group.release();
434abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
435abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
436abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // tessellation
437abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // vkt
438