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 ColorVertexShaderDualSource : public rr::VertexShader
81{
82public:
83	ColorVertexShaderDualSource (void) : rr::VertexShader(3, 3)
84	{
85		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
86		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
87		m_inputs[2].type	= rr::GENERICVECTYPE_FLOAT;
88
89		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
90		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
91		m_outputs[2].type	= rr::GENERICVECTYPE_FLOAT;
92	}
93
94	virtual ~ColorVertexShaderDualSource (void) {}
95
96	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
97								rr::VertexPacket* const*	packets,
98								const int					numPackets) const
99	{
100		tcu::Vec4 position;
101		tcu::Vec4 color0;
102		tcu::Vec4 color1;
103
104		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
105		{
106			rr::VertexPacket* const packet	= packets[packetNdx];
107
108			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
109			readVertexAttrib(color0, inputs[1], packet->instanceNdx, packet->vertexNdx);
110			readVertexAttrib(color1, inputs[2], packet->instanceNdx, packet->vertexNdx);
111
112			packet->outputs[0]	= position;
113			packet->outputs[1]	= color0;
114			packet->outputs[2]	= color1;
115			packet->position	= position;
116		}
117	}
118};
119
120class TexCoordVertexShader : public rr::VertexShader
121{
122public:
123	TexCoordVertexShader (void) : rr::VertexShader(2, 2)
124	{
125		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
126		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
127
128		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
129		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
130	}
131
132	virtual ~TexCoordVertexShader (void) {}
133
134	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
135								rr::VertexPacket* const*	packets,
136								const int					numPackets) const
137	{
138		tcu::Vec4 position;
139		tcu::Vec4 texCoord;
140
141		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
142		{
143			rr::VertexPacket* const packet	= packets[packetNdx];
144
145			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
146			readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx);
147
148			packet->outputs[0]	= position;
149			packet->outputs[1]	= texCoord;
150			packet->position	= position;
151		}
152	}
153};
154
155class ColorFragmentShader : public rr::FragmentShader
156{
157private:
158	const tcu::TextureFormat		m_colorFormat;
159	const tcu::TextureFormat		m_depthStencilFormat;
160	const bool						m_disableVulkanDepthRange;
161
162public:
163	ColorFragmentShader (const tcu::TextureFormat&	colorFormat,
164						 const tcu::TextureFormat&	depthStencilFormat,
165						 const bool					disableVulkanDepthRange = false)
166		: rr::FragmentShader		(2, 1)
167		, m_colorFormat				(colorFormat)
168		, m_depthStencilFormat		(depthStencilFormat)
169		, m_disableVulkanDepthRange	(disableVulkanDepthRange)
170	{
171		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
172
173		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
174		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
175		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
176							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
177							  : rr::GENERICVECTYPE_FLOAT;
178	}
179
180	virtual ~ColorFragmentShader (void) {}
181
182	virtual void shadeFragments (rr::FragmentPacket*				packets,
183								 const int							numPackets,
184								 const rr::FragmentShadingContext&	context) const
185	{
186		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
187		{
188			const rr::FragmentPacket& packet = packets[packetNdx];
189
190			// Reference renderer uses OpenGL depth range of -1..1, and does the viewport depth transform using
191			// formula (position.z+1)/2. For Vulkan the depth range is 0..1 and the vertex depth is mapped as is, so
192			// the values gets overridden here, unless depth clip control extension changes the depth clipping to use
193			// the OpenGL depth range.
194			if (!m_disableVulkanDepthRange && (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS))
195			{
196				for (int fragNdx = 0; fragNdx < 4; fragNdx++)
197				{
198					const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
199					rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
200				}
201			}
202
203			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
204			{
205				const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx);
206				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor);
207			}
208		}
209	}
210};
211
212class ColorFragmentShaderDualSource : public rr::FragmentShader
213{
214private:
215	const tcu::TextureFormat		m_colorFormat;
216	const tcu::TextureFormat		m_depthStencilFormat;
217
218public:
219	ColorFragmentShaderDualSource (const tcu::TextureFormat& colorFormat,
220								   const tcu::TextureFormat& depthStencilFormat)
221		: rr::FragmentShader	(3, 1)
222		, m_colorFormat			(colorFormat)
223		, m_depthStencilFormat	(depthStencilFormat)
224	{
225		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
226
227		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
228		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
229		m_inputs[2].type	= rr::GENERICVECTYPE_FLOAT;
230
231		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
232							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
233							  : rr::GENERICVECTYPE_FLOAT;
234	}
235
236	virtual ~ColorFragmentShaderDualSource (void) {}
237
238	virtual void shadeFragments (rr::FragmentPacket*				packets,
239								 const int							numPackets,
240								 const rr::FragmentShadingContext&	context) const
241	{
242		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
243		{
244			const rr::FragmentPacket& packet = packets[packetNdx];
245
246			if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS)
247			{
248				for (int fragNdx = 0; fragNdx < 4; fragNdx++)
249				{
250					const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
251					rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
252				}
253			}
254
255			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
256			{
257				const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 1, fragNdx);
258				const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 2, fragNdx);
259				rr::writeFragmentOutputDualSource(context, packetNdx, fragNdx, 0, vtxColor0, vtxColor1);
260			}
261		}
262	}
263};
264
265class CoordinateCaptureFragmentShader : public rr::FragmentShader
266{
267public:
268	CoordinateCaptureFragmentShader (void)
269		: rr::FragmentShader(2, 1)
270	{
271		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
272		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
273		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
274	}
275
276	virtual ~CoordinateCaptureFragmentShader (void)
277	{
278	}
279
280	virtual void shadeFragments (rr::FragmentPacket*				packets,
281								 const int							numPackets,
282								 const rr::FragmentShadingContext&	context) const
283	{
284		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
285		{
286			const rr::FragmentPacket& packet = packets[packetNdx];
287
288			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
289			{
290				const tcu::Vec4	vtxTexCoord	= rr::readVarying<float>(packet, context, 1, fragNdx);
291				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord);
292			}
293		}
294	}
295};
296
297class Program
298{
299public:
300	virtual ~Program (void) { }
301
302	virtual rr::Program getReferenceProgram (void) const = 0;
303};
304
305class CoordinateCaptureProgram : public Program
306{
307private:
308	TexCoordVertexShader			m_vertexShader;
309	CoordinateCaptureFragmentShader	m_fragmentShader;
310public:
311	CoordinateCaptureProgram (void)
312	{
313	}
314
315	virtual ~CoordinateCaptureProgram (void) { }
316
317	virtual rr::Program getReferenceProgram (void) const
318	{
319		return rr::Program(&m_vertexShader, &m_fragmentShader);
320	}
321};
322
323class ReferenceRenderer
324{
325public:
326								ReferenceRenderer		(int							surfaceWidth,
327														 int							surfaceHeight,
328														 int							numSamples,
329														 const tcu::TextureFormat&		colorFormat,
330														 const tcu::TextureFormat&		depthStencilFormat,
331														 const rr::Program* const		program);
332
333	virtual						~ReferenceRenderer		(void);
334
335	void						colorClear				(const tcu::Vec4& color);
336
337	void						draw					(const rr::RenderState&				renderState,
338														 const rr::PrimitiveType			primitive,
339														 const std::vector<Vertex4RGBA>&	vertexBuffer);
340
341	void						draw					(const rr::RenderState&					renderState,
342														 const rr::PrimitiveType				primitive,
343														 const std::vector<Vertex4RGBARGBA>&	vertexBuffer);
344
345	void						draw					(const rr::RenderState&				renderState,
346														 const rr::PrimitiveType			primitive,
347														 const std::vector<Vertex4Tex4>&	vertexBuffer);
348
349	tcu::PixelBufferAccess		getAccess				(void);
350	tcu::PixelBufferAccess		getDepthStencilAccess	(void);
351	const rr::ViewportState		getViewportState		(void) const;
352
353private:
354	rr::Renderer				m_renderer;
355
356	const int					m_surfaceWidth;
357	const int					m_surfaceHeight;
358	const int					m_numSamples;
359
360	const tcu::TextureFormat	m_colorFormat;
361	const tcu::TextureFormat	m_depthStencilFormat;
362
363	tcu::TextureLevel			m_colorBuffer;
364	tcu::TextureLevel			m_resolveColorBuffer;
365	tcu::TextureLevel			m_depthStencilBuffer;
366	tcu::TextureLevel			m_resolveDepthStencilBuffer;
367
368	rr::RenderTarget*			m_renderTarget;
369	const rr::Program*			m_program;
370};
371
372rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
373rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
374rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
375rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
376tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
377rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);
378
379} // pipeline
380} // vkt
381
382#endif // _VKTPIPELINEREFERENCERENDERER_HPP
383