• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ColorVertexShaderDualSource : public rr::VertexShader
81 {
82 public:
ColorVertexShaderDualSource(void)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 
~ColorVertexShaderDualSource(void)94 	virtual ~ColorVertexShaderDualSource (void) {}
95 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const96 	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 
120 class TexCoordVertexShader : public rr::VertexShader
121 {
122 public:
TexCoordVertexShader(void)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 
~TexCoordVertexShader(void)132 	virtual ~TexCoordVertexShader (void) {}
133 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const134 	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 
155 class ColorFragmentShader : public rr::FragmentShader
156 {
157 private:
158 	const tcu::TextureFormat		m_colorFormat;
159 	const tcu::TextureFormat		m_depthStencilFormat;
160 	const bool						m_disableVulkanDepthRange;
161 
162 public:
ColorFragmentShader(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat,const bool disableVulkanDepthRange=false)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 
~ColorFragmentShader(void)180 	virtual ~ColorFragmentShader (void) {}
181 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const182 	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 
212 class ColorFragmentShaderDualSource : public rr::FragmentShader
213 {
214 private:
215 	const tcu::TextureFormat		m_colorFormat;
216 	const tcu::TextureFormat		m_depthStencilFormat;
217 
218 public:
ColorFragmentShaderDualSource(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat)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 
~ColorFragmentShaderDualSource(void)236 	virtual ~ColorFragmentShaderDualSource (void) {}
237 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const238 	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 
265 class CoordinateCaptureFragmentShader : public rr::FragmentShader
266 {
267 public:
CoordinateCaptureFragmentShader(void)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 
~CoordinateCaptureFragmentShader(void)276 	virtual ~CoordinateCaptureFragmentShader (void)
277 	{
278 	}
279 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const280 	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 
297 class Program
298 {
299 public:
~Program(void)300 	virtual ~Program (void) { }
301 
302 	virtual rr::Program getReferenceProgram (void) const = 0;
303 };
304 
305 class CoordinateCaptureProgram : public Program
306 {
307 private:
308 	TexCoordVertexShader			m_vertexShader;
309 	CoordinateCaptureFragmentShader	m_fragmentShader;
310 public:
CoordinateCaptureProgram(void)311 	CoordinateCaptureProgram (void)
312 	{
313 	}
314 
~CoordinateCaptureProgram(void)315 	virtual ~CoordinateCaptureProgram (void) { }
316 
getReferenceProgram(void) const317 	virtual rr::Program getReferenceProgram (void) const
318 	{
319 		return rr::Program(&m_vertexShader, &m_fragmentShader);
320 	}
321 };
322 
323 class ReferenceRenderer
324 {
325 public:
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 
353 private:
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 
372 rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
373 rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
374 rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
375 rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
376 tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
377 rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);
378 
379 } // pipeline
380 } // vkt
381 
382 #endif // _VKTPIPELINEREFERENCERENDERER_HPP
383