Home | History | Annotate | Download | only in pipeline
      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:
     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 
     80 class TexCoordVertexShader : public rr::VertexShader
     81 {
     82 public:
     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 
    115 class ColorFragmentShader : public rr::FragmentShader
    116 {
    117 private:
    118 	const tcu::TextureFormat		m_colorFormat;
    119 	const tcu::TextureFormat		m_depthStencilFormat;
    120 
    121 public:
    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 
    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:
    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 
    258 class Program
    259 {
    260 public:
    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:
    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 
    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