1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.0 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 FBO test utilities. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fFboTestUtil.hpp" 25 #include "sglrContextUtil.hpp" 26 #include "sglrGLContext.hpp" 27 #include "sglrReferenceContext.hpp" 28 #include "gluTextureUtil.hpp" 29 #include "tcuTextureUtil.hpp" 30 #include "deStringUtil.hpp" 31 #include "deMath.h" 32 #include "glwEnums.hpp" 33 #include "glwFunctions.hpp" 34 35 #include <limits> 36 37 namespace deqp 38 { 39 namespace gles3 40 { 41 namespace Functional 42 { 43 namespace FboTestUtil 44 { 45 46 using std::string; 47 using std::vector; 48 using tcu::Vec2; 49 using tcu::Vec3; 50 using tcu::Vec4; 51 using tcu::IVec2; 52 using tcu::IVec3; 53 using tcu::IVec4; 54 55 static rr::GenericVecType mapDataTypeToGenericVecType(glu::DataType type) 56 { 57 switch (type) 58 { 59 case glu::TYPE_FLOAT_VEC4: return rr::GENERICVECTYPE_FLOAT; 60 case glu::TYPE_INT_VEC4: return rr::GENERICVECTYPE_INT32; 61 case glu::TYPE_UINT_VEC4: return rr::GENERICVECTYPE_UINT32; 62 default: 63 DE_ASSERT(DE_FALSE); 64 return rr::GENERICVECTYPE_LAST; 65 } 66 } 67 68 template <typename T> 69 static tcu::Vector<T, 4> castVectorSaturate (const tcu::Vec4& in) 70 { 71 return tcu::Vector<T, 4>((in.x() + 0.5f >= std::numeric_limits<T>::max()) ? (std::numeric_limits<T>::max()) : ((in.x() - 0.5f <= std::numeric_limits<T>::min()) ? (std::numeric_limits<T>::min()) : (T(in.x()))), 72 (in.y() + 0.5f >= std::numeric_limits<T>::max()) ? (std::numeric_limits<T>::max()) : ((in.y() - 0.5f <= std::numeric_limits<T>::min()) ? (std::numeric_limits<T>::min()) : (T(in.y()))), 73 (in.z() + 0.5f >= std::numeric_limits<T>::max()) ? (std::numeric_limits<T>::max()) : ((in.z() - 0.5f <= std::numeric_limits<T>::min()) ? (std::numeric_limits<T>::min()) : (T(in.z()))), 74 (in.w() + 0.5f >= std::numeric_limits<T>::max()) ? (std::numeric_limits<T>::max()) : ((in.w() - 0.5f <= std::numeric_limits<T>::min()) ? (std::numeric_limits<T>::min()) : (T(in.w())))); 75 } 76 77 FlatColorShader::FlatColorShader (glu::DataType outputType) 78 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 79 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 80 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 81 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 82 << sglr::pdec::Uniform("u_color", glu::TYPE_FLOAT_VEC4) 83 << sglr::pdec::VertexSource( 84 "#version 300 es\n" 85 "in highp vec4 a_position;\n" 86 "void main (void)\n" 87 "{\n" 88 " gl_Position = a_position;\n" 89 "}\n") 90 << sglr::pdec::FragmentSource( 91 string( 92 "#version 300 es\n" 93 "uniform highp vec4 u_color;\n" 94 "layout(location = 0) out highp ") + glu::getDataTypeName(outputType) + " o_color;\n" 95 "void main (void)\n" 96 "{\n" 97 " o_color = " + glu::getDataTypeName(outputType) + "(u_color);\n" 98 "}\n")) 99 , m_outputType(outputType) 100 { 101 } 102 103 void FlatColorShader::setColor (sglr::Context& context, deUint32 program, const tcu::Vec4& color) 104 { 105 deInt32 location = context.getUniformLocation(program, "u_color"); 106 107 context.useProgram(program); 108 context.uniform4fv(location, 1, color.getPtr()); 109 } 110 111 void FlatColorShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 112 { 113 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 114 { 115 rr::VertexPacket& packet = *packets[packetNdx]; 116 117 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 118 } 119 } 120 121 void FlatColorShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 122 { 123 const tcu::Vec4 color (m_uniforms[0].value.f4); 124 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 125 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 126 127 DE_UNREF(packets); 128 129 if (m_outputType == glu::TYPE_FLOAT_VEC4) 130 { 131 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 132 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 133 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 134 } 135 else if (m_outputType == glu::TYPE_INT_VEC4) 136 { 137 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 138 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 139 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 140 } 141 else if (m_outputType == glu::TYPE_UINT_VEC4) 142 { 143 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 144 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 145 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 146 } 147 else 148 DE_ASSERT(DE_FALSE); 149 } 150 151 GradientShader::GradientShader (glu::DataType outputType) 152 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 153 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 154 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 155 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 156 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 157 << sglr::pdec::Uniform("u_gradientMin", glu::TYPE_FLOAT_VEC4) 158 << sglr::pdec::Uniform("u_gradientMax", glu::TYPE_FLOAT_VEC4) 159 << sglr::pdec::VertexSource( 160 "#version 300 es\n" 161 "in highp vec4 a_position;\n" 162 "in highp vec4 a_coord;\n" 163 "out highp vec4 v_coord;\n" 164 "void main (void)\n" 165 "{\n" 166 " gl_Position = a_position;\n" 167 " v_coord = a_coord;\n" 168 "}\n") 169 << sglr::pdec::FragmentSource( 170 string( 171 "#version 300 es\n" 172 "in highp vec4 v_coord;\n" 173 "uniform highp vec4 u_gradientMin;\n" 174 "uniform highp vec4 u_gradientMax;\n" 175 "layout(location = 0) out highp ") + glu::getDataTypeName(outputType) + " o_color;\n" 176 "void main (void)\n" 177 "{\n" 178 " highp float x = v_coord.x;\n" 179 " highp float y = v_coord.y;\n" 180 " highp float f0 = (x + y) * 0.5;\n" 181 " highp float f1 = 0.5 + (x - y) * 0.5;\n" 182 " highp vec4 fv = vec4(f0, f1, 1.0f-f0, 1.0f-f1);\n" 183 " o_color = " + glu::getDataTypeName(outputType) + "(u_gradientMin + (u_gradientMax-u_gradientMin)*fv);\n" 184 "}\n")) 185 , m_outputType(outputType) 186 { 187 } 188 189 void GradientShader::setGradient (sglr::Context& ctx, deUint32 program, const tcu::Vec4& gradientMin, const tcu::Vec4& gradientMax) 190 { 191 ctx.useProgram(program); 192 ctx.uniform4fv(ctx.getUniformLocation(program, "u_gradientMin"), 1, gradientMin.getPtr()); 193 ctx.uniform4fv(ctx.getUniformLocation(program, "u_gradientMax"), 1, gradientMax.getPtr()); 194 } 195 196 void GradientShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 197 { 198 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 199 { 200 rr::VertexPacket& packet = *packets[packetNdx]; 201 202 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 203 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 204 } 205 } 206 207 void GradientShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 208 { 209 const tcu::Vec4 gradientMin(m_uniforms[0].value.f4); 210 const tcu::Vec4 gradientMax(m_uniforms[1].value.f4); 211 212 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 213 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 214 { 215 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 216 const float x = coord.x(); 217 const float y = coord.y(); 218 const float f0 = (x + y) * 0.5f; 219 const float f1 = 0.5f + (x - y) * 0.5f; 220 const tcu::Vec4 fv = Vec4(f0, f1, 1.0f-f0, 1.0f-f1); 221 222 const tcu::Vec4 color = gradientMin + (gradientMax-gradientMin) * fv; 223 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 224 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 225 226 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 227 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 228 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 229 else 230 DE_ASSERT(DE_FALSE); 231 } 232 } 233 234 static string genTexFragmentShader (const vector<glu::DataType>& samplerTypes, glu::DataType outputType) 235 { 236 const char* precision = "highp"; 237 std::ostringstream src; 238 239 src << "#version 300 es\n" 240 << "layout(location = 0) out highp " << glu::getDataTypeName(outputType) << " o_color0;\n"; 241 242 src << "in highp vec2 v_coord;\n"; 243 244 for (int samplerNdx = 0; samplerNdx < (int)samplerTypes.size(); samplerNdx++) 245 { 246 src << "uniform " << precision << " " << glu::getDataTypeName(samplerTypes[samplerNdx]) << " u_sampler" << samplerNdx << ";\n"; 247 src << "uniform " << precision << " vec4 u_texScale" << samplerNdx << ";\n"; 248 src << "uniform " << precision << " vec4 u_texBias" << samplerNdx << ";\n"; 249 } 250 251 // Output scale & bias 252 src << "uniform " << precision << " vec4 u_outScale0;\n" 253 << "uniform " << precision << " vec4 u_outBias0;\n"; 254 255 src << "\n" 256 << "void main (void)\n" 257 << "{\n" 258 << " " << precision << " vec4 out0 = vec4(0.0);\n"; 259 260 // Texture input fetch and combine. 261 for (int inNdx = 0; inNdx < (int)samplerTypes.size(); inNdx++) 262 src << "\tout0 += vec4(" 263 << "texture(u_sampler" << inNdx << ", v_coord)) * u_texScale" << inNdx << " + u_texBias" << inNdx << ";\n"; 264 265 // Write output. 266 src << " o_color0 = " << glu::getDataTypeName(outputType) << "(out0 * u_outScale0 + u_outBias0);\n"; 267 268 src << "}\n"; 269 270 return src.str(); 271 } 272 273 static sglr::pdec::ShaderProgramDeclaration genTexture2DShaderDecl (const DataTypes& samplerTypes, glu::DataType outputType) 274 { 275 sglr::pdec::ShaderProgramDeclaration decl; 276 277 decl << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT); 278 decl << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT); 279 decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT); 280 decl << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)); 281 282 decl << sglr::pdec::VertexSource( 283 "#version 300 es\n" 284 "in highp vec4 a_position;\n" 285 "in highp vec2 a_coord;\n" 286 "out highp vec2 v_coord;\n" 287 "void main(void)\n" 288 "{\n" 289 " gl_Position = a_position;\n" 290 " v_coord = a_coord;\n" 291 "}\n"); 292 decl << sglr::pdec::FragmentSource(genTexFragmentShader(samplerTypes.vec, outputType)); 293 294 decl << sglr::pdec::Uniform("u_outScale0", glu::TYPE_FLOAT_VEC4); 295 decl << sglr::pdec::Uniform("u_outBias0", glu::TYPE_FLOAT_VEC4); 296 297 for (size_t ndx = 0; ndx < samplerTypes.vec.size(); ++ndx) 298 { 299 decl << sglr::pdec::Uniform(std::string("u_sampler") + de::toString(ndx), samplerTypes.vec[ndx]); 300 decl << sglr::pdec::Uniform(std::string("u_texScale") + de::toString(ndx), glu::TYPE_FLOAT_VEC4); 301 decl << sglr::pdec::Uniform(std::string("u_texBias") + de::toString(ndx), glu::TYPE_FLOAT_VEC4); 302 } 303 304 return decl; 305 } 306 307 Texture2DShader::Texture2DShader (const DataTypes& samplerTypes, glu::DataType outputType, const Vec4& outScale, const Vec4& outBias) 308 : sglr::ShaderProgram (genTexture2DShaderDecl(samplerTypes, outputType)) 309 , m_outScale (outScale) 310 , m_outBias (outBias) 311 , m_outputType (outputType) 312 { 313 m_inputs.resize(samplerTypes.vec.size()); 314 315 // Initialize units. 316 for (int ndx = 0; ndx < (int)m_inputs.size(); ndx++) 317 { 318 m_inputs[ndx].unitNdx = ndx; 319 m_inputs[ndx].scale = Vec4(1.0f); 320 m_inputs[ndx].bias = Vec4(0.0f); 321 } 322 } 323 324 void Texture2DShader::setUnit (int inputNdx, int unitNdx) 325 { 326 m_inputs[inputNdx].unitNdx = unitNdx; 327 } 328 329 void Texture2DShader::setTexScaleBias (int inputNdx, const Vec4& scale, const Vec4& bias) 330 { 331 m_inputs[inputNdx].scale = scale; 332 m_inputs[inputNdx].bias = bias; 333 } 334 335 void Texture2DShader::setOutScaleBias (const Vec4& scale, const Vec4& bias) 336 { 337 m_outScale = scale; 338 m_outBias = bias; 339 } 340 341 void Texture2DShader::setUniforms (sglr::Context& gl, deUint32 program) const 342 { 343 gl.useProgram(program); 344 345 for (int texNdx = 0; texNdx < (int)m_inputs.size(); texNdx++) 346 { 347 string samplerName = string("u_sampler") + de::toString(texNdx); 348 string scaleName = string("u_texScale") + de::toString(texNdx); 349 string biasName = string("u_texBias") + de::toString(texNdx); 350 351 gl.uniform1i(gl.getUniformLocation(program, samplerName.c_str()), m_inputs[texNdx].unitNdx); 352 gl.uniform4fv(gl.getUniformLocation(program, scaleName.c_str()), 1, m_inputs[texNdx].scale.getPtr()); 353 gl.uniform4fv(gl.getUniformLocation(program, biasName.c_str()), 1, m_inputs[texNdx].bias.getPtr()); 354 } 355 356 gl.uniform4fv(gl.getUniformLocation(program, "u_outScale0"), 1, m_outScale.getPtr()); 357 gl.uniform4fv(gl.getUniformLocation(program, "u_outBias0"), 1, m_outBias.getPtr()); 358 } 359 360 void Texture2DShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 361 { 362 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 363 { 364 rr::VertexPacket& packet = *packets[packetNdx]; 365 366 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 367 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 368 } 369 } 370 371 void Texture2DShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 372 { 373 const tcu::Vec4 outScale (m_uniforms[0].value.f4); 374 const tcu::Vec4 outBias (m_uniforms[1].value.f4); 375 376 tcu::Vec2 texCoords[4]; 377 tcu::Vec4 colors[4]; 378 379 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 380 { 381 // setup tex coords 382 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 383 { 384 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 385 texCoords[fragNdx] = tcu::Vec2(coord.x(), coord.y()); 386 } 387 388 // clear result 389 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 390 colors[fragNdx] = tcu::Vec4(0.0f); 391 392 // sample each texture 393 for (int ndx = 0; ndx < (int)m_inputs.size(); ndx++) 394 { 395 const sglr::rc::Texture2D* tex = m_uniforms[2 + ndx*3].sampler.tex2D; 396 const tcu::Vec4 scale (m_uniforms[2 + ndx*3 + 1].value.f4); 397 const tcu::Vec4 bias (m_uniforms[2 + ndx*3 + 2].value.f4); 398 tcu::Vec4 tmpColors[4]; 399 400 tex->sample4(tmpColors, texCoords); 401 402 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 403 colors[fragNdx] += tmpColors[fragNdx] * scale + bias; 404 } 405 406 // write out 407 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 408 { 409 const tcu::Vec4 color = colors[fragNdx] * outScale + outBias; 410 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 411 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 412 413 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 414 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 415 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 416 else 417 DE_ASSERT(DE_FALSE); 418 } 419 } 420 } 421 422 TextureCubeShader::TextureCubeShader (glu::DataType samplerType, glu::DataType outputType) 423 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 424 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 425 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 426 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 427 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 428 << sglr::pdec::Uniform("u_coordMat", glu::TYPE_FLOAT_MAT3) 429 << sglr::pdec::Uniform("u_sampler0", samplerType) 430 << sglr::pdec::Uniform("u_scale", glu::TYPE_FLOAT_VEC4) 431 << sglr::pdec::Uniform("u_bias", glu::TYPE_FLOAT_VEC4) 432 << sglr::pdec::VertexSource( 433 "#version 300 es\n" 434 "in highp vec4 a_position;\n" 435 "in mediump vec2 a_coord;\n" 436 "uniform mat3 u_coordMat;\n" 437 "out mediump vec3 v_coord;\n" 438 "void main (void)\n" 439 "{\n" 440 " gl_Position = a_position;\n" 441 " v_coord = u_coordMat * vec3(a_coord, 1.0);\n" 442 "}\n") 443 << sglr::pdec::FragmentSource( 444 string("") + 445 "#version 300 es\n" 446 "uniform highp " + glu::getDataTypeName(samplerType) + " u_sampler0;\n" 447 "uniform highp vec4 u_scale;\n" 448 "uniform highp vec4 u_bias;\n" 449 "in mediump vec3 v_coord;\n" 450 "layout(location = 0) out highp " + glu::getDataTypeName(outputType) + " o_color;\n" 451 "void main (void)\n" 452 "{\n" 453 " o_color = " + glu::getDataTypeName(outputType) + "(vec4(texture(u_sampler0, v_coord)) * u_scale + u_bias);\n" 454 "}\n")) 455 , m_texScale (1.0f) 456 , m_texBias (0.0f) 457 , m_outputType (outputType) 458 { 459 } 460 461 void TextureCubeShader::setFace (tcu::CubeFace face) 462 { 463 static const float s_cubeTransforms[][3*3] = 464 { 465 // Face -X: (x, y, 1) -> (-1, -(2*y-1), +(2*x-1)) 466 { 0.0f, 0.0f, -1.0f, 467 0.0f, -2.0f, 1.0f, 468 2.0f, 0.0f, -1.0f }, 469 // Face +X: (x, y, 1) -> (+1, -(2*y-1), -(2*x-1)) 470 { 0.0f, 0.0f, 1.0f, 471 0.0f, -2.0f, 1.0f, 472 -2.0f, 0.0f, 1.0f }, 473 // Face -Y: (x, y, 1) -> (+(2*x-1), -1, -(2*y-1)) 474 { 2.0f, 0.0f, -1.0f, 475 0.0f, 0.0f, -1.0f, 476 0.0f, -2.0f, 1.0f }, 477 // Face +Y: (x, y, 1) -> (+(2*x-1), +1, +(2*y-1)) 478 { 2.0f, 0.0f, -1.0f, 479 0.0f, 0.0f, 1.0f, 480 0.0f, 2.0f, -1.0f }, 481 // Face -Z: (x, y, 1) -> (-(2*x-1), -(2*y-1), -1) 482 { -2.0f, 0.0f, 1.0f, 483 0.0f, -2.0f, 1.0f, 484 0.0f, 0.0f, -1.0f }, 485 // Face +Z: (x, y, 1) -> (+(2*x-1), -(2*y-1), +1) 486 { 2.0f, 0.0f, -1.0f, 487 0.0f, -2.0f, 1.0f, 488 0.0f, 0.0f, 1.0f } 489 }; 490 DE_ASSERT(de::inBounds<int>(face, 0, tcu::CUBEFACE_LAST)); 491 m_coordMat = tcu::Mat3(s_cubeTransforms[face]); 492 } 493 494 void TextureCubeShader::setTexScaleBias (const Vec4& scale, const Vec4& bias) 495 { 496 m_texScale = scale; 497 m_texBias = bias; 498 } 499 500 void TextureCubeShader::setUniforms (sglr::Context& gl, deUint32 program) const 501 { 502 gl.useProgram(program); 503 504 gl.uniform1i(gl.getUniformLocation(program, "u_sampler0"), 0); 505 gl.uniformMatrix3fv(gl.getUniformLocation(program, "u_coordMat"), 1, GL_FALSE, m_coordMat.getColumnMajorData().getPtr()); 506 gl.uniform4fv(gl.getUniformLocation(program, "u_scale"), 1, m_texScale.getPtr()); 507 gl.uniform4fv(gl.getUniformLocation(program, "u_bias"), 1, m_texBias.getPtr()); 508 } 509 510 void TextureCubeShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 511 { 512 tcu::Mat3 texCoordMat = tcu::Mat3(m_uniforms[0].value.m3); 513 514 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 515 { 516 rr::VertexPacket& packet = *packets[packetNdx]; 517 tcu::Vec2 a_coord = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx).xy(); 518 tcu::Vec3 v_coord = texCoordMat * tcu::Vec3(a_coord.x(), a_coord.y(), 1.0f); 519 520 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 521 packet.outputs[0] = tcu::Vec4(v_coord.x(), v_coord.y(), v_coord.z(), 0.0f); 522 } 523 } 524 525 void TextureCubeShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 526 { 527 const tcu::Vec4 texScale (m_uniforms[2].value.f4); 528 const tcu::Vec4 texBias (m_uniforms[3].value.f4); 529 530 tcu::Vec3 texCoords[4]; 531 tcu::Vec4 colors[4]; 532 533 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 534 { 535 const sglr::rc::TextureCube* tex = m_uniforms[1].sampler.texCube; 536 537 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 538 { 539 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 540 texCoords[fragNdx] = tcu::Vec3(coord.x(), coord.y(), coord.z()); 541 } 542 543 tex->sample4(colors, texCoords); 544 545 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 546 { 547 const tcu::Vec4 color = colors[fragNdx] * texScale + texBias; 548 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 549 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 550 551 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 552 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 553 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 554 else 555 DE_ASSERT(DE_FALSE); 556 } 557 } 558 } 559 560 Texture2DArrayShader::Texture2DArrayShader (glu::DataType samplerType, glu::DataType outputType) 561 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 562 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 563 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 564 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 565 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 566 << sglr::pdec::Uniform("u_sampler0", samplerType) 567 << sglr::pdec::Uniform("u_scale", glu::TYPE_FLOAT_VEC4) 568 << sglr::pdec::Uniform("u_bias", glu::TYPE_FLOAT_VEC4) 569 << sglr::pdec::Uniform("u_layer", glu::TYPE_INT) 570 << sglr::pdec::VertexSource( 571 "#version 300 es\n" 572 "in highp vec4 a_position;\n" 573 "in highp vec2 a_coord;\n" 574 "out highp vec2 v_coord;\n" 575 "void main (void)\n" 576 "{\n" 577 " gl_Position = a_position;\n" 578 " v_coord = a_coord;\n" 579 "}\n") 580 << sglr::pdec::FragmentSource( 581 string("") + 582 "#version 300 es\n" 583 "uniform highp " + glu::getDataTypeName(samplerType) + " u_sampler0;\n" 584 "uniform highp vec4 u_scale;\n" 585 "uniform highp vec4 u_bias;\n" 586 "uniform highp int u_layer;\n" 587 "in highp vec2 v_coord;\n" 588 "layout(location = 0) out highp " + glu::getDataTypeName(outputType) + " o_color;\n" 589 "void main (void)\n" 590 "{\n" 591 " o_color = " + glu::getDataTypeName(outputType) + "(vec4(texture(u_sampler0, vec3(v_coord, u_layer))) * u_scale + u_bias);\n" 592 "}\n")) 593 , m_texScale (1.0f) 594 , m_texBias (0.0f) 595 , m_layer (0) 596 , m_outputType (outputType) 597 { 598 } 599 600 void Texture2DArrayShader::setLayer (int layer) 601 { 602 m_layer = layer; 603 } 604 605 void Texture2DArrayShader::setTexScaleBias (const Vec4& scale, const Vec4& bias) 606 { 607 m_texScale = scale; 608 m_texBias = bias; 609 } 610 611 void Texture2DArrayShader::setUniforms (sglr::Context& gl, deUint32 program) const 612 { 613 gl.useProgram(program); 614 615 gl.uniform1i (gl.getUniformLocation(program, "u_sampler0"), 0); 616 gl.uniform1i (gl.getUniformLocation(program, "u_layer"), m_layer); 617 gl.uniform4fv (gl.getUniformLocation(program, "u_scale"), 1, m_texScale.getPtr()); 618 gl.uniform4fv (gl.getUniformLocation(program, "u_bias"), 1, m_texBias.getPtr()); 619 } 620 621 void Texture2DArrayShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 622 { 623 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 624 { 625 rr::VertexPacket& packet = *packets[packetNdx]; 626 627 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 628 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 629 } 630 } 631 632 void Texture2DArrayShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 633 { 634 const tcu::Vec4 texScale (m_uniforms[1].value.f4); 635 const tcu::Vec4 texBias (m_uniforms[2].value.f4); 636 const int layer = m_uniforms[3].value.i; 637 638 tcu::Vec3 texCoords[4]; 639 tcu::Vec4 colors[4]; 640 641 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 642 { 643 const sglr::rc::Texture2DArray* tex = m_uniforms[0].sampler.tex2DArray; 644 645 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 646 { 647 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 648 texCoords[fragNdx] = tcu::Vec3(coord.x(), coord.y(), float(layer)); 649 } 650 651 tex->sample4(colors, texCoords); 652 653 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 654 { 655 const tcu::Vec4 color = colors[fragNdx] * texScale + texBias; 656 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 657 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 658 659 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 660 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 661 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 662 else 663 DE_ASSERT(DE_FALSE); 664 } 665 } 666 } 667 668 Texture3DShader::Texture3DShader (glu::DataType samplerType, glu::DataType outputType) 669 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 670 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 671 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 672 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 673 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 674 << sglr::pdec::Uniform("u_sampler0", samplerType) 675 << sglr::pdec::Uniform("u_scale", glu::TYPE_FLOAT_VEC4) 676 << sglr::pdec::Uniform("u_bias", glu::TYPE_FLOAT_VEC4) 677 << sglr::pdec::Uniform("u_depth", glu::TYPE_FLOAT) 678 << sglr::pdec::VertexSource( 679 "#version 300 es\n" 680 "in highp vec4 a_position;\n" 681 "in highp vec2 a_coord;\n" 682 "out highp vec2 v_coord;\n" 683 "void main (void)\n" 684 "{\n" 685 " gl_Position = a_position;\n" 686 " v_coord = a_coord;\n" 687 "}\n") 688 << sglr::pdec::FragmentSource( 689 string("") + 690 "#version 300 es\n" 691 "uniform highp " + glu::getDataTypeName(samplerType) + " u_sampler0;\n" 692 "uniform highp vec4 u_scale;\n" 693 "uniform highp vec4 u_bias;\n" 694 "uniform highp float u_depth;\n" 695 "in highp vec2 v_coord;\n" 696 "layout(location = 0) out highp " + glu::getDataTypeName(outputType) + " o_color;\n" 697 "void main (void)\n" 698 "{\n" 699 " o_color = " + glu::getDataTypeName(outputType) + "(vec4(texture(u_sampler0, vec3(v_coord, u_depth))) * u_scale + u_bias);\n" 700 "}\n")) 701 , m_texScale (1.0f) 702 , m_texBias (0.0f) 703 , m_depth (0.0f) 704 , m_outputType (outputType) 705 { 706 } 707 708 void Texture3DShader::setDepth (float depth) 709 { 710 m_depth = depth; 711 } 712 713 void Texture3DShader::setTexScaleBias (const Vec4& scale, const Vec4& bias) 714 { 715 m_texScale = scale; 716 m_texBias = bias; 717 } 718 719 void Texture3DShader::setUniforms (sglr::Context& gl, deUint32 program) const 720 { 721 gl.useProgram(program); 722 723 gl.uniform1i (gl.getUniformLocation(program, "u_sampler0"), 0); 724 gl.uniform1f (gl.getUniformLocation(program, "u_depth"), m_depth); 725 gl.uniform4fv (gl.getUniformLocation(program, "u_scale"), 1, m_texScale.getPtr()); 726 gl.uniform4fv (gl.getUniformLocation(program, "u_bias"), 1, m_texBias.getPtr()); 727 } 728 729 void Texture3DShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 730 { 731 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 732 { 733 rr::VertexPacket& packet = *packets[packetNdx]; 734 735 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 736 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 737 } 738 } 739 740 void Texture3DShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 741 { 742 const tcu::Vec4 texScale (m_uniforms[1].value.f4); 743 const tcu::Vec4 texBias (m_uniforms[2].value.f4); 744 const float depth = m_uniforms[3].value.f; 745 746 tcu::Vec3 texCoords[4]; 747 tcu::Vec4 colors[4]; 748 749 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 750 { 751 const sglr::rc::Texture3D* tex = m_uniforms[0].sampler.tex3D; 752 753 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 754 { 755 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 756 texCoords[fragNdx] = tcu::Vec3(coord.x(), coord.y(), depth); 757 } 758 759 tex->sample4(colors, texCoords); 760 761 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 762 { 763 const tcu::Vec4 color = colors[fragNdx] * texScale + texBias; 764 const tcu::IVec4 icolor = castVectorSaturate<deInt32>(color); 765 const tcu::UVec4 uicolor = castVectorSaturate<deUint32>(color); 766 767 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 768 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 769 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 770 else 771 DE_ASSERT(DE_FALSE); 772 } 773 } 774 } 775 776 DepthGradientShader::DepthGradientShader (glu::DataType outputType) 777 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 778 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 779 << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT) 780 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 781 << sglr::pdec::FragmentOutput(mapDataTypeToGenericVecType(outputType)) 782 << sglr::pdec::Uniform("u_maxGradient", glu::TYPE_FLOAT) 783 << sglr::pdec::Uniform("u_minGradient", glu::TYPE_FLOAT) 784 << sglr::pdec::Uniform("u_color", glu::TYPE_FLOAT_VEC4) 785 << sglr::pdec::VertexSource( 786 "#version 300 es\n" 787 "in highp vec4 a_position;\n" 788 "in highp vec4 a_coord;\n" 789 "out highp vec4 v_coord;\n" 790 "void main (void)\n" 791 "{\n" 792 " gl_Position = a_position;\n" 793 " v_coord = a_coord;\n" 794 "}\n") 795 << sglr::pdec::FragmentSource( 796 string( 797 "#version 300 es\n" 798 "in highp vec4 v_coord;\n" 799 "uniform highp float u_minGradient;\n" 800 "uniform highp float u_maxGradient;\n" 801 "uniform highp vec4 u_color;\n" 802 "layout(location = 0) out highp ") + glu::getDataTypeName(outputType) + " o_color;\n" 803 "void main (void)\n" 804 "{\n" 805 " highp float x = v_coord.x;\n" 806 " highp float y = v_coord.y;\n" 807 " highp float f0 = (x + y) * 0.5;\n" 808 " gl_FragDepth = u_minGradient + (u_maxGradient-u_minGradient)*f0;\n" 809 " o_color = " + glu::getDataTypeName(outputType) + "(u_color);\n" 810 "}\n")) 811 , m_outputType (outputType) 812 , u_minGradient (getUniformByName("u_minGradient")) 813 , u_maxGradient (getUniformByName("u_maxGradient")) 814 , u_color (getUniformByName("u_color")) 815 { 816 } 817 818 void DepthGradientShader::setUniforms (sglr::Context& ctx, deUint32 program, const float gradientMin, const float gradientMax, const tcu::Vec4& color) 819 { 820 ctx.useProgram(program); 821 ctx.uniform1fv(ctx.getUniformLocation(program, "u_minGradient"), 1, &gradientMin); 822 ctx.uniform1fv(ctx.getUniformLocation(program, "u_maxGradient"), 1, &gradientMax); 823 ctx.uniform4fv(ctx.getUniformLocation(program, "u_color"), 1, color.getPtr()); 824 } 825 826 void DepthGradientShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 827 { 828 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 829 { 830 rr::VertexPacket& packet = *packets[packetNdx]; 831 832 packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx); 833 packet.outputs[0] = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx); 834 } 835 } 836 837 void DepthGradientShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 838 { 839 const float gradientMin (u_minGradient.value.f); 840 const float gradientMax (u_maxGradient.value.f); 841 const tcu::Vec4 color (u_color.value.f4); 842 const tcu::IVec4 icolor (castVectorSaturate<deInt32>(color)); 843 const tcu::UVec4 uicolor (castVectorSaturate<deUint32>(color)); 844 845 // running this shader without a depth buffer does not make any sense 846 DE_ASSERT(context.fragmentDepths); 847 848 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 849 for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 850 { 851 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 852 const float x = coord.x(); 853 const float y = coord.y(); 854 const float f0 = (x + y) * 0.5f; 855 856 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, gradientMin + (gradientMax-gradientMin) * f0); 857 858 if (m_outputType == glu::TYPE_FLOAT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 859 else if (m_outputType == glu::TYPE_INT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, icolor); 860 else if (m_outputType == glu::TYPE_UINT_VEC4) rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, uicolor); 861 else 862 DE_ASSERT(DE_FALSE); 863 } 864 } 865 866 void clearColorBuffer (sglr::Context& ctx, const tcu::TextureFormat& format, const tcu::Vec4& value) 867 { 868 const tcu::TextureChannelClass fmtClass = tcu::getTextureChannelClass(format.type); 869 870 switch (fmtClass) 871 { 872 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 873 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 874 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 875 ctx.clearBufferfv(GL_COLOR, 0, value.getPtr()); 876 break; 877 878 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 879 ctx.clearBufferuiv(GL_COLOR, 0, value.asUint().getPtr()); 880 break; 881 882 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 883 ctx.clearBufferiv(GL_COLOR, 0, value.asInt().getPtr()); 884 break; 885 886 default: 887 DE_ASSERT(DE_FALSE); 888 } 889 } 890 891 void readPixels (sglr::Context& ctx, tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias) 892 { 893 tcu::TextureFormat readFormat = getFramebufferReadFormat(format); 894 glu::TransferFormat transferFmt = glu::getTransferFormat(readFormat); 895 int alignment = 4; // \note GL_PACK_ALIGNMENT = 4 is assumed. 896 int rowSize = deAlign32(readFormat.getPixelSize()*width, alignment); 897 vector<deUint8> data (rowSize*height); 898 899 ctx.readPixels(x, y, width, height, transferFmt.format, transferFmt.dataType, &data[0]); 900 901 // Convert to surface. 902 tcu::ConstPixelBufferAccess src(readFormat, width, height, 1, rowSize, 0, &data[0]); 903 904 dst.setSize(width, height); 905 tcu::PixelBufferAccess dstAccess = dst.getAccess(); 906 907 for (int yo = 0; yo < height; yo++) 908 for (int xo = 0; xo < width; xo++) 909 dstAccess.setPixel(src.getPixel(xo, yo) * scale + bias, xo, yo); 910 } 911 912 static const char* getFboIncompleteReasonName (deUint32 reason) 913 { 914 switch (reason) 915 { 916 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; 917 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; 918 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; 919 case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED"; 920 case GL_FRAMEBUFFER_COMPLETE: return "GL_FRAMEBUFFER_COMPLETE"; 921 default: return "UNKNOWN"; 922 } 923 } 924 925 FboIncompleteException::FboIncompleteException (deUint32 reason, const char* file, int line) 926 : TestError ("Framebuffer is not complete", getFboIncompleteReasonName(reason), file, line) 927 , m_reason (reason) 928 { 929 } 930 931 const char* getFormatName (deUint32 format) 932 { 933 switch (format) 934 { 935 case GL_RGB565: return "rgb565"; 936 case GL_RGB5_A1: return "rgb5_a1"; 937 case GL_RGBA4: return "rgba4"; 938 case GL_DEPTH_COMPONENT16: return "depth_component16"; 939 case GL_STENCIL_INDEX8: return "stencil_index8"; 940 case GL_RGBA32F: return "rgba32f"; 941 case GL_RGBA32I: return "rgba32i"; 942 case GL_RGBA32UI: return "rgba32ui"; 943 case GL_RGBA16F: return "rgba16f"; 944 case GL_RGBA16I: return "rgba16i"; 945 case GL_RGBA16UI: return "rgba16ui"; 946 case GL_RGBA8: return "rgba8"; 947 case GL_RGBA8I: return "rgba8i"; 948 case GL_RGBA8UI: return "rgba8ui"; 949 case GL_SRGB8_ALPHA8: return "srgb8_alpha8"; 950 case GL_RGB10_A2: return "rgb10_a2"; 951 case GL_RGB10_A2UI: return "rgb10_a2ui"; 952 case GL_RGBA8_SNORM: return "rgba8_snorm"; 953 case GL_RGB8: return "rgb8"; 954 case GL_R11F_G11F_B10F: return "r11f_g11f_b10f"; 955 case GL_RGB32F: return "rgb32f"; 956 case GL_RGB32I: return "rgb32i"; 957 case GL_RGB32UI: return "rgb32ui"; 958 case GL_RGB16F: return "rgb16f"; 959 case GL_RGB16I: return "rgb16i"; 960 case GL_RGB16UI: return "rgb16ui"; 961 case GL_RGB8_SNORM: return "rgb8_snorm"; 962 case GL_RGB8I: return "rgb8i"; 963 case GL_RGB8UI: return "rgb8ui"; 964 case GL_SRGB8: return "srgb8"; 965 case GL_RGB9_E5: return "rgb9_e5"; 966 case GL_RG32F: return "rg32f"; 967 case GL_RG32I: return "rg32i"; 968 case GL_RG32UI: return "rg32ui"; 969 case GL_RG16F: return "rg16f"; 970 case GL_RG16I: return "rg16i"; 971 case GL_RG16UI: return "rg16ui"; 972 case GL_RG8: return "rg8"; 973 case GL_RG8I: return "rg8i"; 974 case GL_RG8UI: return "rg8ui"; 975 case GL_RG8_SNORM: return "rg8_snorm"; 976 case GL_R32F: return "r32f"; 977 case GL_R32I: return "r32i"; 978 case GL_R32UI: return "r32ui"; 979 case GL_R16F: return "r16f"; 980 case GL_R16I: return "r16i"; 981 case GL_R16UI: return "r16ui"; 982 case GL_R8: return "r8"; 983 case GL_R8I: return "r8i"; 984 case GL_R8UI: return "r8ui"; 985 case GL_R8_SNORM: return "r8_snorm"; 986 case GL_DEPTH_COMPONENT32F: return "depth_component32f"; 987 case GL_DEPTH_COMPONENT24: return "depth_component24"; 988 case GL_DEPTH32F_STENCIL8: return "depth32f_stencil8"; 989 case GL_DEPTH24_STENCIL8: return "depth24_stencil8"; 990 991 default: 992 TCU_FAIL("Unknown format"); 993 } 994 } 995 996 glu::DataType getFragmentOutputType (const tcu::TextureFormat& format) 997 { 998 switch (tcu::getTextureChannelClass(format.type)) 999 { 1000 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1001 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1002 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1003 return glu::TYPE_FLOAT_VEC4; 1004 1005 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1006 return glu::TYPE_UINT_VEC4; 1007 1008 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1009 return glu::TYPE_INT_VEC4; 1010 1011 default: 1012 DE_FATAL("Unknown format"); 1013 return glu::TYPE_LAST; 1014 } 1015 } 1016 1017 tcu::TextureFormat getFramebufferReadFormat (const tcu::TextureFormat& format) 1018 { 1019 switch (tcu::getTextureChannelClass(format.type)) 1020 { 1021 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1022 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT); 1023 1024 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1025 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1026 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1027 1028 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1029 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32); 1030 1031 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1032 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32); 1033 1034 default: 1035 DE_FATAL("Unknown format"); 1036 return tcu::TextureFormat(); 1037 } 1038 } 1039 1040 static int calculateU8ConversionError (int srcBits) 1041 { 1042 if (srcBits > 0) 1043 { 1044 const int clampedBits = de::clamp<int>(srcBits, 0, 8); 1045 const int srcMaxValue = de::max((1<<clampedBits) - 1, 1); 1046 const int error = int(deFloatCeil(255.0f * 2.0f / float(srcMaxValue))); 1047 1048 return de::clamp<int>(error, 0, 255); 1049 } 1050 else 1051 return 1; 1052 } 1053 1054 tcu::RGBA getFormatThreshold (const tcu::TextureFormat& format) 1055 { 1056 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format); 1057 1058 return tcu::RGBA(calculateU8ConversionError(bits.x()), 1059 calculateU8ConversionError(bits.y()), 1060 calculateU8ConversionError(bits.z()), 1061 calculateU8ConversionError(bits.w())); 1062 } 1063 1064 tcu::RGBA getFormatThreshold (deUint32 glFormat) 1065 { 1066 const tcu::TextureFormat format = glu::mapGLInternalFormat(glFormat); 1067 1068 return getFormatThreshold(format); 1069 } 1070 1071 static int getToSRGB8ConversionError (int srcBits) 1072 { 1073 // \note These are pre-computed based on simulation results. 1074 static const int errors[] = 1075 { 1076 1, // 0 bits - rounding 1077 255, // 1 bits 1078 157, // 2 bits 1079 106, // 3 bits 1080 74, // 4 bits 1081 51, // 5 bits 1082 34, // 6 bits 1083 22, // 7 bits 1084 13, // 8 bits 1085 7, // 9 bits 1086 4, // 10 bits 1087 3, // 11 bits 1088 2, // 12 bits 1089 // 1 from this on 1090 }; 1091 1092 DE_ASSERT(srcBits >= 0); 1093 if (srcBits < DE_LENGTH_OF_ARRAY(errors)) 1094 return errors[srcBits]; 1095 else 1096 return 1; 1097 } 1098 1099 tcu::RGBA getToSRGBConversionThreshold (const tcu::TextureFormat& src, const tcu::TextureFormat& dst) 1100 { 1101 // Only SRGB8 and SRGB8_ALPHA8 formats are supported. 1102 DE_ASSERT(dst.type == tcu::TextureFormat::UNORM_INT8 && tcu::isSRGB(dst)); 1103 1104 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(src); 1105 const bool dstHasAlpha = dst.order == tcu::TextureFormat::sRGBA; 1106 1107 return tcu::RGBA(getToSRGB8ConversionError(bits.x()), 1108 getToSRGB8ConversionError(bits.y()), 1109 getToSRGB8ConversionError(bits.z()), 1110 dstHasAlpha ? calculateU8ConversionError(bits.w()) : 0); 1111 } 1112 1113 } // FboTestUtil 1114 } // Functional 1115 } // gles3 1116 } // deqp 1117