Home | History | Annotate | Download | only in glshared
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL (ES) Module
      3  * -----------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief sglr-rsg adaptation.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "glsRandomShaderProgram.hpp"
     25 #include "rsgShader.hpp"
     26 
     27 namespace deqp
     28 {
     29 namespace gls
     30 {
     31 
     32 using std::vector;
     33 
     34 static rr::GenericVecType mapToGenericVecType (const rsg::VariableType& varType)
     35 {
     36 	if (varType.isFloatOrVec())
     37 		return rr::GENERICVECTYPE_FLOAT;
     38 	else if (varType.isIntOrVec())
     39 		return rr::GENERICVECTYPE_INT32;
     40 	else
     41 	{
     42 		DE_ASSERT(false);
     43 		return rr::GENERICVECTYPE_LAST;
     44 	}
     45 }
     46 
     47 static glu::DataType mapToBasicType (const rsg::VariableType& varType)
     48 {
     49 	if (varType.isFloatOrVec() || varType.isIntOrVec() || varType.isBoolOrVec())
     50 	{
     51 		const glu::DataType		scalarType		= varType.isFloatOrVec()	? glu::TYPE_FLOAT	:
     52 												  varType.isIntOrVec()		? glu::TYPE_INT		:
     53 												  varType.isBoolOrVec()		? glu::TYPE_BOOL	: glu::TYPE_LAST;
     54 		const int				numComps		= varType.getNumElements();
     55 
     56 		DE_ASSERT(de::inRange(numComps, 1, 4));
     57 		return glu::DataType(scalarType + numComps - 1);
     58 	}
     59 	else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_2D)
     60 		return glu::TYPE_SAMPLER_2D;
     61 	else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_CUBE)
     62 		return glu::TYPE_SAMPLER_CUBE;
     63 	else
     64 	{
     65 		DE_ASSERT(false);
     66 		return glu::TYPE_LAST;
     67 	}
     68 }
     69 
     70 static void generateProgramDeclaration (sglr::pdec::ShaderProgramDeclaration& decl, const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms)
     71 {
     72 	decl << sglr::pdec::VertexSource(vertexShader.getSource())
     73 		 << sglr::pdec::FragmentSource(fragmentShader.getSource());
     74 
     75 	for (vector<rsg::ShaderInput*>::const_iterator vtxInIter = vertexShader.getInputs().begin(); vtxInIter != vertexShader.getInputs().end(); ++vtxInIter)
     76 	{
     77 		const rsg::ShaderInput*	vertexInput	= *vtxInIter;
     78 		decl << sglr::pdec::VertexAttribute(vertexInput->getVariable()->getName(), mapToGenericVecType(vertexInput->getVariable()->getType()));
     79 	}
     80 
     81 	for (vector<rsg::ShaderInput*>::const_iterator fragInIter = fragmentShader.getInputs().begin(); fragInIter != fragmentShader.getInputs().end(); ++fragInIter)
     82 	{
     83 		const rsg::ShaderInput*	fragInput	= *fragInIter;
     84 		decl << sglr::pdec::VertexToFragmentVarying(mapToGenericVecType(fragInput->getVariable()->getType()));
     85 	}
     86 
     87 	for (int uniformNdx = 0; uniformNdx < numUnifiedUniforms; uniformNdx++)
     88 	{
     89 		const rsg::ShaderInput*	uniform	= unifiedUniforms[uniformNdx];
     90 		decl << sglr::pdec::Uniform(uniform->getVariable()->getName(), mapToBasicType(uniform->getVariable()->getType()));
     91 	}
     92 
     93 	decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);
     94 }
     95 
     96 static sglr::pdec::ShaderProgramDeclaration generateProgramDeclaration (const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms)
     97 {
     98 	sglr::pdec::ShaderProgramDeclaration decl;
     99 	generateProgramDeclaration(decl, vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms);
    100 	return decl;
    101 }
    102 
    103 static const rsg::Variable* findShaderOutputByName (const rsg::Shader& shader, const char* name)
    104 {
    105 	vector<const rsg::Variable*> outputs;
    106 	shader.getOutputs(outputs);
    107 
    108 	for (vector<const rsg::Variable*>::const_iterator iter = outputs.begin(); iter != outputs.end(); ++iter)
    109 	{
    110 		if (deStringEqual((*iter)->getName(), name))
    111 			return *iter;
    112 	}
    113 
    114 	return DE_NULL;
    115 }
    116 
    117 static const rsg::Variable* findShaderOutputByLocation (const rsg::Shader& shader, int location)
    118 {
    119 	vector<const rsg::Variable*> outputs;
    120 	shader.getOutputs(outputs);
    121 
    122 	for (vector<const rsg::Variable*>::const_iterator iter = outputs.begin(); iter != outputs.end(); iter++)
    123 	{
    124 		if ((*iter)->getLayoutLocation() == location)
    125 			return *iter;
    126 	}
    127 
    128 	return DE_NULL;
    129 }
    130 
    131 RandomShaderProgram::RandomShaderProgram (const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms)
    132 	: sglr::ShaderProgram	(generateProgramDeclaration(vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms))
    133 	, m_vertexShader		(vertexShader)
    134 	, m_fragmentShader		(fragmentShader)
    135 	, m_numUnifiedUniforms	(numUnifiedUniforms)
    136 	, m_unifiedUniforms		(unifiedUniforms)
    137 	, m_positionVar			(findShaderOutputByName(vertexShader, "gl_Position"))
    138 	, m_fragColorVar		(findShaderOutputByLocation(fragmentShader, 0))
    139 	, m_execCtx				(m_sampler2DMap, m_samplerCubeMap)
    140 {
    141 	TCU_CHECK_INTERNAL(m_positionVar && m_positionVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT && m_positionVar->getType().getNumElements() == 4);
    142 	TCU_CHECK_INTERNAL(m_fragColorVar && m_fragColorVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT && m_fragColorVar->getType().getNumElements() == 4);
    143 
    144 	// Build list of vertex outputs.
    145 	for (vector<rsg::ShaderInput*>::const_iterator fragInIter = fragmentShader.getInputs().begin(); fragInIter != fragmentShader.getInputs().end(); ++fragInIter)
    146 	{
    147 		const rsg::ShaderInput*	fragInput		= *fragInIter;
    148 		const rsg::Variable*	vertexOutput	= findShaderOutputByName(vertexShader, fragInput->getVariable()->getName());
    149 
    150 		TCU_CHECK_INTERNAL(vertexOutput);
    151 		m_vertexOutputs.push_back(vertexOutput);
    152 	}
    153 }
    154 
    155 void RandomShaderProgram::refreshUniforms (void) const
    156 {
    157 	DE_ASSERT(m_numUnifiedUniforms == (int)m_uniforms.size());
    158 
    159 	for (int uniformNdx = 0; uniformNdx < m_numUnifiedUniforms; uniformNdx++)
    160 	{
    161 		const rsg::Variable*		uniformVar	= m_unifiedUniforms[uniformNdx]->getVariable();
    162 		const rsg::VariableType&	uniformType	= uniformVar->getType();
    163 		const sglr::UniformSlot&	uniformSlot	= m_uniforms[uniformNdx];
    164 
    165 		m_execCtx.getValue(uniformVar) = rsg::ConstValueAccess(uniformType, (const rsg::Scalar*)&uniformSlot.value).value();
    166 	}
    167 }
    168 
    169 void RandomShaderProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
    170 {
    171 	// \todo [2013-12-13 pyry] Do only when necessary.
    172 	refreshUniforms();
    173 
    174 	int packetOffset = 0;
    175 
    176 	while (packetOffset < numPackets)
    177 	{
    178 		const int	numToExecute	= de::min(numPackets-packetOffset, (int)rsg::EXEC_VEC_WIDTH);
    179 
    180 		// Fetch attributes.
    181 		for (int attribNdx = 0; attribNdx < (int)m_vertexShader.getInputs().size(); ++attribNdx)
    182 		{
    183 			const rsg::Variable*		attribVar		= m_vertexShader.getInputs()[attribNdx]->getVariable();
    184 			const rsg::VariableType&	attribType		= attribVar->getType();
    185 			const int					numComponents	= attribType.getNumElements();
    186 			rsg::ExecValueAccess		access			= m_execCtx.getValue(attribVar);
    187 
    188 			DE_ASSERT(attribType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
    189 
    190 			for (int ndx = 0; ndx < numToExecute; ndx++)
    191 			{
    192 				const int				packetNdx	= ndx+packetOffset;
    193 				const rr::VertexPacket*	packet		= packets[packetNdx];
    194 				const tcu::Vec4			attribValue	= rr::readVertexAttribFloat(inputs[attribNdx], packet->instanceNdx, packet->vertexNdx);
    195 
    196 										access.component(0).asFloat(ndx) = attribValue[0];
    197 				if (numComponents >= 2)	access.component(1).asFloat(ndx) = attribValue[1];
    198 				if (numComponents >= 3)	access.component(2).asFloat(ndx) = attribValue[2];
    199 				if (numComponents >= 4)	access.component(3).asFloat(ndx) = attribValue[3];
    200 			}
    201 		}
    202 
    203 		m_vertexShader.execute(m_execCtx);
    204 
    205 		// Store position
    206 		{
    207 			const rsg::ExecConstValueAccess	access	= m_execCtx.getValue(m_positionVar);
    208 
    209 			for (int ndx = 0; ndx < numToExecute; ndx++)
    210 			{
    211 				const int			packetNdx	= ndx+packetOffset;
    212 				rr::VertexPacket*	packet		= packets[packetNdx];
    213 
    214 				packet->position[0] = access.component(0).asFloat(ndx);
    215 				packet->position[1] = access.component(1).asFloat(ndx);
    216 				packet->position[2] = access.component(2).asFloat(ndx);
    217 				packet->position[3] = access.component(3).asFloat(ndx);
    218 			}
    219 		}
    220 
    221 		// Other varyings
    222 		for (int varNdx = 0; varNdx < (int)m_vertexOutputs.size(); varNdx++)
    223 		{
    224 			const rsg::Variable*			var				= m_vertexOutputs[varNdx];
    225 			const rsg::VariableType&		varType			= var->getType();
    226 			const int						numComponents	= varType.getNumElements();
    227 			const rsg::ExecConstValueAccess	access			= m_execCtx.getValue(var);
    228 
    229 			DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
    230 
    231 			for (int ndx = 0; ndx < numToExecute; ndx++)
    232 			{
    233 				const int				packetNdx	= ndx+packetOffset;
    234 				rr::VertexPacket* const	packet		= packets[packetNdx];
    235 				float* const			dst			= packet->outputs[varNdx].getAccess<float>();
    236 
    237 										dst[0] = access.component(0).asFloat(ndx);
    238 				if (numComponents >= 2) dst[1] = access.component(1).asFloat(ndx);
    239 				if (numComponents >= 3) dst[2] = access.component(2).asFloat(ndx);
    240 				if (numComponents >= 4) dst[3] = access.component(3).asFloat(ndx);
    241 			}
    242 		}
    243 
    244 		packetOffset += numToExecute;
    245 	}
    246 }
    247 
    248 void RandomShaderProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
    249 {
    250 	const rsg::ExecConstValueAccess	fragColorAccess	= m_execCtx.getValue(m_fragColorVar);
    251 	int								packetOffset	= 0;
    252 
    253 	DE_STATIC_ASSERT(rsg::EXEC_VEC_WIDTH % rr::NUM_FRAGMENTS_PER_PACKET == 0);
    254 
    255 	while (packetOffset < numPackets)
    256 	{
    257 		const int	numPacketsToExecute	= de::min(numPackets-packetOffset, (int)rsg::EXEC_VEC_WIDTH / (int)rr::NUM_FRAGMENTS_PER_PACKET);
    258 
    259 		// Interpolate varyings.
    260 		for (int varNdx = 0; varNdx < (int)m_fragmentShader.getInputs().size(); ++varNdx)
    261 		{
    262 			const rsg::Variable*		var				= m_fragmentShader.getInputs()[varNdx]->getVariable();
    263 			const rsg::VariableType&	varType			= var->getType();
    264 			const int					numComponents	= varType.getNumElements();
    265 			rsg::ExecValueAccess		access			= m_execCtx.getValue(var);
    266 
    267 			DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
    268 
    269 			for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++)
    270 			{
    271 				const rr::FragmentPacket&	packet		= packets[packetOffset+packetNdx];
    272 
    273 				for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
    274 				{
    275 					const tcu::Vec4		varValue	= rr::readVarying<float>(packet, context, varNdx, fragNdx);
    276 					const int			dstNdx		= packetNdx*rr::NUM_FRAGMENTS_PER_PACKET + fragNdx;
    277 
    278 											access.component(0).asFloat(dstNdx) = varValue[0];
    279 					if (numComponents >= 2)	access.component(1).asFloat(dstNdx) = varValue[1];
    280 					if (numComponents >= 3)	access.component(2).asFloat(dstNdx) = varValue[2];
    281 					if (numComponents >= 4)	access.component(3).asFloat(dstNdx) = varValue[3];
    282 				}
    283 			}
    284 		}
    285 
    286 		m_fragmentShader.execute(m_execCtx);
    287 
    288 		// Store color
    289 		for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++)
    290 		{
    291 			for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
    292 			{
    293 				const int		srcNdx	= packetNdx*rr::NUM_FRAGMENTS_PER_PACKET + fragNdx;
    294 				const tcu::Vec4 color	(fragColorAccess.component(0).asFloat(srcNdx),
    295 										 fragColorAccess.component(1).asFloat(srcNdx),
    296 										 fragColorAccess.component(2).asFloat(srcNdx),
    297 										 fragColorAccess.component(3).asFloat(srcNdx));
    298 
    299 				rr::writeFragmentOutput(context, packetOffset+packetNdx, fragNdx, 0, color);
    300 			}
    301 		}
    302 
    303 		packetOffset += numPacketsToExecute;
    304 	}
    305 }
    306 
    307 } // gls
    308 } // deqp
    309