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 Fragment operation test utilities.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "glsFragmentOpUtil.hpp"
     25 #include "gluRenderContext.hpp"
     26 #include "gluShaderProgram.hpp"
     27 #include "gluDrawUtil.hpp"
     28 #include "glwFunctions.hpp"
     29 #include "glwEnums.hpp"
     30 
     31 namespace deqp
     32 {
     33 namespace gls
     34 {
     35 namespace FragmentOpUtil
     36 {
     37 
     38 template<typename T>
     39 inline T triQuadInterpolate (const T values[4], float xFactor, float yFactor)
     40 {
     41 	if (xFactor + yFactor < 1.0f)
     42 		return values[0] + (values[2]-values[0])*xFactor		+ (values[1]-values[0])*yFactor;
     43 	else
     44 		return values[3] + (values[1]-values[3])*(1.0f-xFactor)	+ (values[2]-values[3])*(1.0f-yFactor);
     45 }
     46 
     47 // GLSL ES 1.0 shaders
     48 static const char* s_glsl1VertSrc =
     49 	"attribute highp vec4 a_position;\n"
     50 	"attribute mediump vec4 a_color;\n"
     51 	"varying mediump vec4 v_color;\n"
     52 	"void main()\n"
     53 	"{\n"
     54 	"	gl_Position = a_position;\n"
     55 	"	v_color = a_color;\n"
     56 	"}\n";
     57 static const char* s_glsl1FragSrc =
     58 	"varying mediump vec4 v_color;\n"
     59 	"void main()\n"
     60 	"{\n"
     61 	"	gl_FragColor = v_color;\n"
     62 	"}\n";
     63 
     64 // GLSL ES 3.0 shaders
     65 static const char* s_glsl3VertSrc =
     66 	"#version 300 es\n"
     67 	"in highp vec4 a_position;\n"
     68 	"in mediump vec4 a_color;\n"
     69 	"out mediump vec4 v_color;\n"
     70 	"void main()\n"
     71 	"{\n"
     72 	"	gl_Position = a_position;\n"
     73 	"	v_color = a_color;\n"
     74 	"}\n";
     75 static const char* s_glsl3FragSrc =
     76 	"#version 300 es\n"
     77 	"in mediump vec4 v_color;\n"
     78 	"layout(location = 0) out mediump vec4 o_color;\n"
     79 	"void main()\n"
     80 	"{\n"
     81 	"	o_color = v_color;\n"
     82 	"}\n";
     83 
     84 // GLSL 3.3 shaders
     85 static const char* s_glsl33VertSrc =
     86 	"#version 330 core\n"
     87 	"in vec4 a_position;\n"
     88 	"in vec4 a_color;\n"
     89 	"in vec4 a_color1;\n"
     90 	"out vec4 v_color;\n"
     91 	"out vec4 v_color1;\n"
     92 	"void main()\n"
     93 	"{\n"
     94 	"	gl_Position	= a_position;\n"
     95 	"	v_color		= a_color;\n"
     96 	"	v_color1	= a_color1;\n"
     97 	"}\n";
     98 static const char* s_glsl33FragSrc =
     99 	"#version 330 core\n"
    100 	"in vec4 v_color;\n"
    101 	"in vec4 v_color1;\n"
    102 	"layout(location = 0, index = 0) out vec4 o_color;\n"
    103 	"layout(location = 0, index = 1) out vec4 o_color1;\n"
    104 	"void main()\n"
    105 	"{\n"
    106 	"	o_color  = v_color;\n"
    107 	"	o_color1 = v_color1;\n"
    108 	"}\n";
    109 
    110 static const char* getVertSrc (glu::GLSLVersion glslVersion)
    111 {
    112 	if (glslVersion == glu::GLSL_VERSION_100_ES)
    113 		return s_glsl1VertSrc;
    114 	else if (glslVersion == glu::GLSL_VERSION_300_ES)
    115 		return s_glsl3VertSrc;
    116 	else if (glslVersion == glu::GLSL_VERSION_330)
    117 		return s_glsl33VertSrc;
    118 
    119 	DE_ASSERT(DE_FALSE);
    120 	return 0;
    121 }
    122 
    123 static const char* getFragSrc (glu::GLSLVersion glslVersion)
    124 {
    125 	if (glslVersion == glu::GLSL_VERSION_100_ES)
    126 		return s_glsl1FragSrc;
    127 	else if (glslVersion == glu::GLSL_VERSION_300_ES)
    128 		return s_glsl3FragSrc;
    129 	else if (glslVersion == glu::GLSL_VERSION_330)
    130 		return s_glsl33FragSrc;
    131 
    132 	DE_ASSERT(DE_FALSE);
    133 	return 0;
    134 }
    135 
    136 QuadRenderer::QuadRenderer (const glu::RenderContext& context, glu::GLSLVersion glslVersion)
    137 	: m_context			(context)
    138 	, m_program			(DE_NULL)
    139 	, m_positionLoc		(0)
    140 	, m_colorLoc		(-1)
    141 	, m_color1Loc		(-1)
    142 	, m_blendFuncExt	(!glu::glslVersionIsES(glslVersion) && (glslVersion >= glu::GLSL_VERSION_330))
    143 {
    144 	DE_ASSERT(glslVersion == glu::GLSL_VERSION_100_ES ||
    145 			  glslVersion == glu::GLSL_VERSION_300_ES ||
    146 			  glslVersion == glu::GLSL_VERSION_330);
    147 
    148 	const glw::Functions&	gl		= context.getFunctions();
    149 	const char*				vertSrc	= getVertSrc(glslVersion);
    150 	const char*				fragSrc	= getFragSrc(glslVersion);
    151 
    152 	m_program = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(vertSrc, fragSrc));
    153 	if (!m_program->isOk())
    154 	{
    155 		delete m_program;
    156 		throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);
    157 	}
    158 
    159 	m_positionLoc	= gl.getAttribLocation(m_program->getProgram(), "a_position");
    160 	m_colorLoc		= gl.getAttribLocation(m_program->getProgram(), "a_color");
    161 
    162 	if (m_blendFuncExt)
    163 		m_color1Loc = gl.getAttribLocation(m_program->getProgram(), "a_color1");
    164 
    165 	if (m_positionLoc < 0 || m_colorLoc < 0 || (m_blendFuncExt && m_color1Loc < 0))
    166 	{
    167 		delete m_program;
    168 		throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
    169 	}
    170 }
    171 
    172 QuadRenderer::~QuadRenderer (void)
    173 {
    174 	delete m_program;
    175 }
    176 
    177 void QuadRenderer::render (const Quad& quad) const
    178 {
    179 	const float position[] =
    180 	{
    181 		quad.posA.x(), quad.posA.y(), quad.depth[0], 1.0f,
    182 		quad.posA.x(), quad.posB.y(), quad.depth[1], 1.0f,
    183 		quad.posB.x(), quad.posA.y(), quad.depth[2], 1.0f,
    184 		quad.posB.x(), quad.posB.y(), quad.depth[3], 1.0f
    185 	};
    186 	const deUint8 indices[] = { 0, 2, 1, 1, 2, 3 };
    187 
    188 	DE_STATIC_ASSERT(sizeof(tcu::Vec4) == sizeof(float)*4);
    189 	DE_STATIC_ASSERT(sizeof(quad.color) == sizeof(float)*4*4);
    190 	DE_STATIC_ASSERT(sizeof(quad.color1) == sizeof(float)*4*4);
    191 
    192 	std::vector<glu::VertexArrayBinding> vertexArrays;
    193 
    194 	vertexArrays.push_back(glu::va::Float(m_positionLoc,	4, 4, 0, &position[0]));
    195 	vertexArrays.push_back(glu::va::Float(m_colorLoc,		4, 4, 0, (const float*)&quad.color[0]));
    196 
    197 	if (m_blendFuncExt)
    198 		vertexArrays.push_back(glu::va::Float(m_color1Loc,	4, 4, 0, (const float*)&quad.color1[0]));
    199 
    200 	m_context.getFunctions().useProgram(m_program->getProgram());
    201 	glu::draw(m_context, m_program->getProgram(),
    202 			  (int)vertexArrays.size(), &vertexArrays[0],
    203 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
    204 }
    205 
    206 ReferenceQuadRenderer::ReferenceQuadRenderer (void)
    207 	: m_fragmentBufferSize(0)
    208 {
    209 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_fragmentDepths); i++)
    210 		m_fragmentDepths[i] = 0.0f;
    211 }
    212 
    213 void ReferenceQuadRenderer::flushFragmentBuffer (const rr::MultisamplePixelBufferAccess&	colorBuffer,
    214 												 const rr::MultisamplePixelBufferAccess&	depthBuffer,
    215 												 const rr::MultisamplePixelBufferAccess&	stencilBuffer,
    216 												 rr::FaceType								faceType,
    217 												 const rr::FragmentOperationState&			state)
    218 {
    219 	m_fragmentProcessor.render(colorBuffer, depthBuffer, stencilBuffer, &m_fragmentBuffer[0], m_fragmentBufferSize, faceType, state);
    220 	m_fragmentBufferSize = 0;
    221 }
    222 
    223 void ReferenceQuadRenderer::render (const tcu::PixelBufferAccess&			colorBuffer,
    224 									const tcu::PixelBufferAccess&			depthBuffer,
    225 									const tcu::PixelBufferAccess&			stencilBuffer,
    226 									const IntegerQuad&						quad,
    227 									const rr::FragmentOperationState&		state)
    228 {
    229 	bool			flipX			= quad.posA.x() > quad.posB.x();
    230 	bool			flipY			= quad.posA.y() > quad.posB.y();
    231 	rr::FaceType	faceType		= flipX == flipY ? rr::FACETYPE_FRONT : rr::FACETYPE_BACK;
    232 	int				xFirst			= flipX ? quad.posB.x() : quad.posA.x();
    233 	int				xLast			= flipX ? quad.posA.x() : quad.posB.x();
    234 	int				yFirst			= flipY ? quad.posB.y() : quad.posA.y();
    235 	int				yLast			= flipY ? quad.posA.y() : quad.posB.y();
    236 	float			width			= (float)(xLast - xFirst + 1);
    237 	float			height			= (float)(yLast - yFirst + 1);
    238 
    239 	for (int y = yFirst; y <= yLast; y++)
    240 	{
    241 		// Interpolation factor for y.
    242 		float yRatio = (0.5f + (float)(y - yFirst)) / height;
    243 		if (flipY)
    244 			yRatio = 1.0f - yRatio;
    245 
    246 		for (int x = xFirst; x <= xLast; x++)
    247 		{
    248 			// Interpolation factor for x.
    249 			float xRatio = (0.5f + (float)(x - xFirst)) / width;
    250 			if (flipX)
    251 				xRatio = 1.0f - xRatio;
    252 
    253 			tcu::Vec4	color	= triQuadInterpolate(quad.color, xRatio, yRatio);
    254 			tcu::Vec4	color1	= triQuadInterpolate(quad.color1, xRatio, yRatio);
    255 			float		depth	= triQuadInterpolate(quad.depth, xRatio, yRatio);
    256 
    257 			// Interpolated color and depth.
    258 
    259 			DE_STATIC_ASSERT(MAX_FRAGMENT_BUFFER_SIZE == DE_LENGTH_OF_ARRAY(m_fragmentBuffer));
    260 
    261 			if (m_fragmentBufferSize >= MAX_FRAGMENT_BUFFER_SIZE)
    262 				flushFragmentBuffer(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer),
    263 									rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer),
    264 									rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer), faceType, state);
    265 
    266 			m_fragmentDepths[m_fragmentBufferSize] = depth;
    267 			m_fragmentBuffer[m_fragmentBufferSize] = rr::Fragment(tcu::IVec2(x, y), rr::GenericVec4(color), rr::GenericVec4(color1), 1u /* coverage mask */, &m_fragmentDepths[m_fragmentBufferSize]);
    268 			m_fragmentBufferSize++;
    269 		}
    270 	}
    271 
    272 	flushFragmentBuffer(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer),
    273 						rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer),
    274 						rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer), faceType, state);
    275 }
    276 
    277 tcu::PixelBufferAccess getMultisampleAccess(const tcu::PixelBufferAccess& original)
    278 {
    279 	return tcu::PixelBufferAccess(original.getFormat(),
    280 								  1,
    281 								  original.getWidth(),
    282 								  original.getHeight(),
    283 								  original.getFormat().getPixelSize(),
    284 								  original.getRowPitch(),
    285 								  original.getDataPtr());
    286 }
    287 
    288 tcu::ConstPixelBufferAccess getMultisampleAccess(const tcu::ConstPixelBufferAccess& original)
    289 {
    290 	return tcu::ConstPixelBufferAccess(original.getFormat(),
    291 									   1,
    292 									   original.getWidth(),
    293 									   original.getHeight(),
    294 									   original.getFormat().getPixelSize(),
    295 									   original.getRowPitch(),
    296 									   original.getDataPtr());
    297 }
    298 
    299 } // FragmentOpUtil
    300 } // gls
    301 } // deqp
    302