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
165template<typename TextureType>
166class SamplerFragmentShader : public rr::FragmentShader
167{
168private:
169	const tcu::TextureFormat		m_colorFormat;
170	const tcu::TextureFormatInfo	m_colorFormatInfo;
171	const TextureType				m_texture;
172	const tcu::Sampler				m_sampler;
173	const float						m_lod;
174	const tcu::Vec4					m_lookupScale;
175	const tcu::Vec4					m_lookupBias;
176	const tcu::UVec4				m_swizzle;
177
178public:
179	SamplerFragmentShader (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle)
180		: rr::FragmentShader	(2, 1)
181		, m_colorFormat			(colorFormat)
182		, m_colorFormatInfo		(tcu::getTextureFormatInfo(m_colorFormat))
183		, m_texture				(texture)
184		, m_sampler				(sampler)
185		, m_lod					(lod)
186		, m_lookupScale			(lookupScale)
187		, m_lookupBias			(lookupBias)
188		, m_swizzle				(swizzle)
189	{
190		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
191		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
192		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
193		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
194							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
195							  : rr::GENERICVECTYPE_FLOAT;
196	}
197
198	virtual ~SamplerFragmentShader (void)
199	{
200	}
201
202	static tcu::Vec4 sampleTexture (const tcu::Texture1D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
203	{
204		return texture.sample(sampler, texCoord.x(), lod);
205	}
206
207	static tcu::Vec4 sampleTexture (const tcu::Texture1DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
208	{
209		return texture.sample(sampler, texCoord.x(), texCoord.y(), lod);
210	}
211
212	static tcu::Vec4 sampleTexture (const tcu::Texture2D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
213	{
214		return texture.sample(sampler, texCoord.x(), texCoord.y(), lod);
215	}
216
217	static tcu::Vec4 sampleTexture (const tcu::Texture2DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
218	{
219		return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod);
220	}
221
222	static tcu::Vec4 sampleTexture (const tcu::Texture3D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
223	{
224		return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod);
225	}
226
227	static tcu::Vec4 sampleTexture (const tcu::TextureCube& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
228	{
229		return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod);
230	}
231
232	static tcu::Vec4 sampleTexture (const tcu::TextureCubeArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod)
233	{
234		return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), texCoord.w(), lod);
235	}
236
237	virtual void shadeFragments (rr::FragmentPacket*				packets,
238								 const int							numPackets,
239								 const rr::FragmentShadingContext&	context) const
240	{
241		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
242		{
243			const rr::FragmentPacket& packet = packets[packetNdx];
244
245			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
246			{
247				const tcu::Vec4	vtxTexCoord	= rr::readVarying<float>(packet, context, 1, fragNdx);
248				const tcu::Vec4	texColor	= sampleTexture(m_texture, m_sampler, vtxTexCoord, m_lod);
249				const tcu::Vec4	normColor	= texColor * m_lookupScale + m_lookupBias;
250				const tcu::Vec4 swizColor	= swizzle(normColor, m_swizzle);
251				const tcu::Vec4	color		= (swizColor + m_colorFormatInfo.lookupBias) / m_colorFormatInfo.lookupScale;
252				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
253			}
254		}
255	}
256};
257
258class Program
259{
260public:
261	virtual ~Program (void) { }
262
263	virtual rr::Program getReferenceProgram (void) const = 0;
264};
265
266template<typename TextureType>
267class SamplerProgram: public Program
268{
269private:
270	TexCoordVertexShader				m_vertexShader;
271	SamplerFragmentShader<TextureType>	m_fragmentShader;
272public:
273	SamplerProgram (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle)
274		: m_vertexShader	()
275		, m_fragmentShader	(colorFormat, texture, sampler, lod, lookupScale, lookupBias, swizzle)
276	{
277	}
278
279	virtual ~SamplerProgram (void) { }
280
281	virtual rr::Program getReferenceProgram (void) const
282	{
283		return rr::Program(&m_vertexShader, &m_fragmentShader);
284	}
285};
286
287class ReferenceRenderer
288{
289public:
290								ReferenceRenderer		(int							surfaceWidth,
291														 int							surfaceHeight,
292														 int							numSamples,
293														 const tcu::TextureFormat&		colorFormat,
294														 const tcu::TextureFormat&		depthStencilFormat,
295														 const rr::Program* const		program);
296
297	virtual						~ReferenceRenderer		(void);
298
299	void						colorClear				(const tcu::Vec4& color);
300
301	void						draw					(const rr::RenderState&				renderState,
302														 const rr::PrimitiveType			primitive,
303														 const std::vector<Vertex4RGBA>&	vertexBuffer);
304
305	void						draw					(const rr::RenderState&				renderState,
306														 const rr::PrimitiveType			primitive,
307														 const std::vector<Vertex4Tex4>&	vertexBuffer);
308
309	tcu::PixelBufferAccess		getAccess				(void);
310	const rr::ViewportState		getViewportState		(void) const;
311
312private:
313	rr::Renderer				m_renderer;
314
315	const int					m_surfaceWidth;
316	const int					m_surfaceHeight;
317	const int					m_numSamples;
318
319	const tcu::TextureFormat	m_colorFormat;
320	const tcu::TextureFormat	m_depthStencilFormat;
321
322	tcu::TextureLevel			m_colorBuffer;
323	tcu::TextureLevel			m_resolveColorBuffer;
324	tcu::TextureLevel			m_depthStencilBuffer;
325
326	rr::RenderTarget*			m_renderTarget;
327	const rr::Program*			m_program;
328};
329
330rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
331rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
332rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
333rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
334tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
335rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);
336
337} // pipeline
338} // vkt
339
340#endif // _VKTPIPELINEREFERENCERENDERER_HPP
341