1#ifndef _VKTPIPELINEREFERENCERENDERER_HPP
2#define _VKTPIPELINEREFERENCERENDERER_HPP
3/*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
6 *
7 * Copyright (c) 2015 The Khronos Group Inc.
8 * Copyright (c) 2015 Imagination Technologies Ltd.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 *      http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Reference renderer.
25 *//*--------------------------------------------------------------------*/
26
27#include "vkDefs.hpp"
28#include "vktPipelineVertexUtil.hpp"
29#include "tcuVector.hpp"
30#include "tcuVectorType.hpp"
31#include "tcuTexture.hpp"
32#include "tcuTextureUtil.hpp"
33#include "rrRenderState.hpp"
34#include "rrRenderer.hpp"
35#include <cstring>
36
37namespace vkt
38{
39
40namespace pipeline
41{
42
43tcu::Vec4	swizzle		(const tcu::Vec4& color, const tcu::UVec4& swizzle);
44
45class ColorVertexShader : public rr::VertexShader
46{
47public:
48	ColorVertexShader (void) : rr::VertexShader(2, 2)
49	{
50		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
51		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
52
53		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
54		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
55	}
56
57	virtual ~ColorVertexShader (void) {}
58
59	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
60								rr::VertexPacket* const*	packets,
61								const int					numPackets) const
62	{
63		tcu::Vec4 position;
64		tcu::Vec4 color;
65
66		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
67		{
68			rr::VertexPacket* const packet	= packets[packetNdx];
69
70			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
71			readVertexAttrib(color, inputs[1], packet->instanceNdx, packet->vertexNdx);
72
73			packet->outputs[0]	= position;
74			packet->outputs[1]	= color;
75			packet->position	= position;
76		}
77	}
78};
79
80class TexCoordVertexShader : public rr::VertexShader
81{
82public:
83	TexCoordVertexShader (void) : rr::VertexShader(2, 2)
84	{
85		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
86		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
87
88		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
89		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
90	}
91
92	virtual ~TexCoordVertexShader (void) {}
93
94	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
95								rr::VertexPacket* const*	packets,
96								const int					numPackets) const
97	{
98		tcu::Vec4 position;
99		tcu::Vec4 texCoord;
100
101		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
102		{
103			rr::VertexPacket* const packet	= packets[packetNdx];
104
105			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
106			readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx);
107
108			packet->outputs[0]	= position;
109			packet->outputs[1]	= texCoord;
110			packet->position	= position;
111		}
112	}
113};
114
115class ColorFragmentShader : public rr::FragmentShader
116{
117private:
118	const tcu::TextureFormat		m_colorFormat;
119	const tcu::TextureFormat		m_depthStencilFormat;
120
121public:
122	ColorFragmentShader (const tcu::TextureFormat& colorFormat,
123						 const tcu::TextureFormat& depthStencilFormat)
124		: rr::FragmentShader	(2, 1)
125		, m_colorFormat			(colorFormat)
126		, m_depthStencilFormat	(depthStencilFormat)
127	{
128		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
129
130		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
131		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
132		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
133							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
134							  : rr::GENERICVECTYPE_FLOAT;
135	}
136
137	virtual ~ColorFragmentShader (void) {}
138
139	virtual void shadeFragments (rr::FragmentPacket*				packets,
140								 const int							numPackets,
141								 const rr::FragmentShadingContext&	context) const
142	{
143		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
144		{
145			const rr::FragmentPacket& packet = packets[packetNdx];
146
147			if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS)
148			{
149				for (int fragNdx = 0; fragNdx < 4; fragNdx++)
150				{
151					const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
152					rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
153				}
154			}
155
156			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
157			{
158				const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx);
159				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor);
160			}
161		}
162	}
163};
164
165class CoordinateCaptureFragmentShader : public rr::FragmentShader
166{
167public:
168	CoordinateCaptureFragmentShader (void)
169		: rr::FragmentShader(2, 1)
170	{
171		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
172		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
173		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
174	}
175
176	virtual ~CoordinateCaptureFragmentShader (void)
177	{
178	}
179
180	virtual void shadeFragments (rr::FragmentPacket*				packets,
181								 const int							numPackets,
182								 const rr::FragmentShadingContext&	context) const
183	{
184		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
185		{
186			const rr::FragmentPacket& packet = packets[packetNdx];
187
188			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
189			{
190				const tcu::Vec4	vtxTexCoord	= rr::readVarying<float>(packet, context, 1, fragNdx);
191				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord);
192			}
193		}
194	}
195};
196
197class Program
198{
199public:
200	virtual ~Program (void) { }
201
202	virtual rr::Program getReferenceProgram (void) const = 0;
203};
204
205class CoordinateCaptureProgram : public Program
206{
207private:
208	TexCoordVertexShader			m_vertexShader;
209	CoordinateCaptureFragmentShader	m_fragmentShader;
210public:
211	CoordinateCaptureProgram (void)
212	{
213	}
214
215	virtual ~CoordinateCaptureProgram (void) { }
216
217	virtual rr::Program getReferenceProgram (void) const
218	{
219		return rr::Program(&m_vertexShader, &m_fragmentShader);
220	}
221};
222
223class ReferenceRenderer
224{
225public:
226								ReferenceRenderer		(int							surfaceWidth,
227														 int							surfaceHeight,
228														 int							numSamples,
229														 const tcu::TextureFormat&		colorFormat,
230														 const tcu::TextureFormat&		depthStencilFormat,
231														 const rr::Program* const		program);
232
233	virtual						~ReferenceRenderer		(void);
234
235	void						colorClear				(const tcu::Vec4& color);
236
237	void						draw					(const rr::RenderState&				renderState,
238														 const rr::PrimitiveType			primitive,
239														 const std::vector<Vertex4RGBA>&	vertexBuffer);
240
241	void						draw					(const rr::RenderState&				renderState,
242														 const rr::PrimitiveType			primitive,
243														 const std::vector<Vertex4Tex4>&	vertexBuffer);
244
245	tcu::PixelBufferAccess		getAccess				(void);
246	const rr::ViewportState		getViewportState		(void) const;
247
248private:
249	rr::Renderer				m_renderer;
250
251	const int					m_surfaceWidth;
252	const int					m_surfaceHeight;
253	const int					m_numSamples;
254
255	const tcu::TextureFormat	m_colorFormat;
256	const tcu::TextureFormat	m_depthStencilFormat;
257
258	tcu::TextureLevel			m_colorBuffer;
259	tcu::TextureLevel			m_resolveColorBuffer;
260	tcu::TextureLevel			m_depthStencilBuffer;
261
262	rr::RenderTarget*			m_renderTarget;
263	const rr::Program*			m_program;
264};
265
266rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
267rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
268rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
269rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
270tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
271rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);
272
273} // pipeline
274} // vkt
275
276#endif // _VKTPIPELINEREFERENCERENDERER_HPP
277