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 
37 namespace vkt
38 {
39 
40 namespace pipeline
41 {
42 
43 tcu::Vec4	swizzle		(const tcu::Vec4& color, const tcu::UVec4& swizzle);
44 
45 class ColorVertexShader : public rr::VertexShader
46 {
47 public:
ColorVertexShader(void)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 
~ColorVertexShader(void)57 	virtual ~ColorVertexShader (void) {}
58 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const59 	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 
80 class TexCoordVertexShader : public rr::VertexShader
81 {
82 public:
TexCoordVertexShader(void)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 
~TexCoordVertexShader(void)92 	virtual ~TexCoordVertexShader (void) {}
93 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const94 	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 
115 class ColorFragmentShader : public rr::FragmentShader
116 {
117 private:
118 	const tcu::TextureFormat		m_colorFormat;
119 	const tcu::TextureFormat		m_depthStencilFormat;
120 
121 public:
ColorFragmentShader(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat)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 
~ColorFragmentShader(void)137 	virtual ~ColorFragmentShader (void) {}
138 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const139 	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 
165 template<typename TextureType>
166 class SamplerFragmentShader : public rr::FragmentShader
167 {
168 private:
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 
178 public:
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)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 
~SamplerFragmentShader(void)198 	virtual ~SamplerFragmentShader (void)
199 	{
200 	}
201 
sampleTexture(const tcu::Texture1D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::Texture1DArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::Texture2D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::Texture2DArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::Texture3D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::TextureCube & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
sampleTexture(const tcu::TextureCubeArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)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 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const237 	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 
258 class Program
259 {
260 public:
~Program(void)261 	virtual ~Program (void) { }
262 
263 	virtual rr::Program getReferenceProgram (void) const = 0;
264 };
265 
266 template<typename TextureType>
267 class SamplerProgram: public Program
268 {
269 private:
270 	TexCoordVertexShader				m_vertexShader;
271 	SamplerFragmentShader<TextureType>	m_fragmentShader;
272 public:
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)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 
~SamplerProgram(void)279 	virtual ~SamplerProgram (void) { }
280 
getReferenceProgram(void) const281 	virtual rr::Program getReferenceProgram (void) const
282 	{
283 		return rr::Program(&m_vertexShader, &m_fragmentShader);
284 	}
285 };
286 
287 class ReferenceRenderer
288 {
289 public:
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 
312 private:
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 
330 rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
331 rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
332 rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
333 rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
334 tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
335 rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);
336 
337 } // pipeline
338 } // vkt
339 
340 #endif // _VKTPIPELINEREFERENCERENDERER_HPP
341