queryconversions.cpp (12646B)
1 // 2 // Copyright 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // queryconversions.cpp: Implementation of state query cast conversions 8 9 #include "libANGLE/queryconversions.h" 10 11 #include <vector> 12 13 #include "common/utilities.h" 14 #include "libANGLE/Context.h" 15 16 namespace gl 17 { 18 19 namespace 20 { 21 22 GLint64 ExpandFloatToInteger(GLfloat value) 23 { 24 return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0); 25 } 26 27 template <typename QueryT, typename NativeT> 28 QueryT CastFromStateValueToInt(GLenum pname, NativeT value) 29 { 30 GLenum nativeType = GLTypeToGLenum<NativeT>::value; 31 32 if (nativeType == GL_FLOAT) 33 { 34 // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from 35 // Table 4.5 36 switch (pname) 37 { 38 case GL_DEPTH_RANGE: 39 case GL_COLOR_CLEAR_VALUE: 40 case GL_DEPTH_CLEAR_VALUE: 41 case GL_BLEND_COLOR: 42 // GLES1 emulation: 43 // Also, several GLES1.x values need to be converted to integer with 44 // ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data 45 // Conversions". 46 case GL_ALPHA_TEST_REF: 47 case GL_CURRENT_COLOR: 48 return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value))); 49 default: 50 return clampCast<QueryT>(std::round(value)); 51 } 52 } 53 54 return clampCast<QueryT>(value); 55 } 56 57 template <typename NativeT, typename QueryT> 58 NativeT CastQueryValueToInt(GLenum pname, QueryT value) 59 { 60 GLenum queryType = GLTypeToGLenum<QueryT>::value; 61 62 if (queryType == GL_FLOAT) 63 { 64 // ARM devices cast float to uint differently than Intel. 65 // Basically, any negative floating point number becomes 0 66 // when converted to unsigned int. Instead, convert to a signed 67 // int and then convert to unsigned int to "preserve the value" 68 // E.g. common case for tests is to pass in -1 as an invalid query 69 // value. If cast to a unsigned int it becomes 0 (GL_NONE) and is now 70 // a valid enum and negative tests fail. But converting to int 71 // and then to final unsigned int gives us 4294967295 (0xffffffff) 72 // which is what we want. 73 return static_cast<NativeT>(static_cast<GLint64>(std::round(value))); 74 } 75 76 return static_cast<NativeT>(value); 77 } 78 79 } // anonymous namespace 80 81 GLint CastMaskValue(GLuint value) 82 { 83 return clampCast<GLint>(value); 84 } 85 86 template <typename QueryT, typename InternalT> 87 QueryT CastFromGLintStateValue(GLenum pname, InternalT value) 88 { 89 return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value)); 90 } 91 92 template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value); 93 template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value); 94 template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value); 95 template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value); 96 template GLuint CastFromGLintStateValue<GLuint, GLint>(GLenum pname, GLint value); 97 template GLfloat CastFromGLintStateValue<GLfloat, GLint>(GLenum pname, GLint value); 98 template GLint CastFromGLintStateValue<GLint, GLint>(GLenum pname, GLint value); 99 template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value); 100 template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value); 101 template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value); 102 103 template <typename QueryT, typename NativeT> 104 QueryT CastFromStateValue(GLenum pname, NativeT value) 105 { 106 GLenum queryType = GLTypeToGLenum<QueryT>::value; 107 108 switch (queryType) 109 { 110 case GL_INT: 111 case GL_INT_64_ANGLEX: 112 case GL_UNSIGNED_INT: 113 case GL_UINT_64_ANGLEX: 114 return CastFromStateValueToInt<QueryT, NativeT>(pname, value); 115 case GL_FLOAT: 116 return static_cast<QueryT>(value); 117 case GL_BOOL: 118 return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE); 119 default: 120 UNREACHABLE(); 121 return 0; 122 } 123 } 124 template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value); 125 template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value); 126 template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value); 127 template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value); 128 template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value); 129 template GLfloat CastFromStateValue<GLfloat, GLuint>(GLenum pname, GLuint value); 130 template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value); 131 template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value); 132 template GLuint CastFromStateValue<GLuint, GLfloat>(GLenum pname, GLfloat value); 133 template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value); 134 template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value); 135 template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value); 136 template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value); 137 template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value); 138 template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value); 139 template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value); 140 141 template <typename NativeT, typename QueryT> 142 NativeT CastQueryValueTo(GLenum pname, QueryT value) 143 { 144 GLenum nativeType = GLTypeToGLenum<NativeT>::value; 145 146 switch (nativeType) 147 { 148 case GL_INT: 149 case GL_INT_64_ANGLEX: 150 case GL_UNSIGNED_INT: 151 case GL_UINT_64_ANGLEX: 152 return CastQueryValueToInt<NativeT, QueryT>(pname, value); 153 case GL_FLOAT: 154 return static_cast<NativeT>(value); 155 case GL_BOOL: 156 return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE); 157 default: 158 UNREACHABLE(); 159 return 0; 160 } 161 } 162 163 template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value); 164 template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value); 165 template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value); 166 template GLint CastQueryValueTo<GLint, GLuint>(GLenum pname, GLuint value); 167 template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value); 168 template GLfloat CastQueryValueTo<GLfloat, GLuint>(GLenum pname, GLuint value); 169 template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value); 170 template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value); 171 template GLuint CastQueryValueTo<GLuint, GLuint>(GLenum pname, GLuint value); 172 template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value); 173 174 template <typename QueryT> 175 void CastStateValues(const Context *context, 176 GLenum nativeType, 177 GLenum pname, 178 unsigned int numParams, 179 QueryT *outParams) 180 { 181 if (nativeType == GL_INT) 182 { 183 std::vector<GLint> intParams(numParams, 0); 184 context->getIntegervImpl(pname, intParams.data()); 185 186 for (unsigned int i = 0; i < numParams; ++i) 187 { 188 outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]); 189 } 190 } 191 else if (nativeType == GL_BOOL) 192 { 193 std::vector<GLboolean> boolParams(numParams, GL_FALSE); 194 context->getBooleanvImpl(pname, boolParams.data()); 195 196 for (unsigned int i = 0; i < numParams; ++i) 197 { 198 outParams[i] = 199 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1)); 200 } 201 } 202 else if (nativeType == GL_FLOAT) 203 { 204 std::vector<GLfloat> floatParams(numParams, 0.0f); 205 context->getFloatvImpl(pname, floatParams.data()); 206 207 for (unsigned int i = 0; i < numParams; ++i) 208 { 209 outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]); 210 } 211 } 212 else if (nativeType == GL_INT_64_ANGLEX) 213 { 214 std::vector<GLint64> int64Params(numParams, 0); 215 context->getInteger64vImpl(pname, int64Params.data()); 216 217 for (unsigned int i = 0; i < numParams; ++i) 218 { 219 outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]); 220 } 221 } 222 else 223 { 224 WARN() << "Application querying parameter that does not exist."; 225 } 226 } 227 228 // Explicit template instantiation (how we export template functions in different files) 229 // The calls below will make CastStateValues successfully link with the GL state query types 230 // The GL state query API types are: bool, int, uint, float, int64, uint64 231 232 template void CastStateValues<GLboolean>(const Context *, 233 GLenum, 234 GLenum, 235 unsigned int, 236 GLboolean *); 237 template void CastStateValues<GLint>(const Context *, GLenum, GLenum, unsigned int, GLint *); 238 template void CastStateValues<GLuint>(const Context *, GLenum, GLenum, unsigned int, GLuint *); 239 template void CastStateValues<GLfloat>(const Context *, GLenum, GLenum, unsigned int, GLfloat *); 240 template void CastStateValues<GLint64>(const Context *, GLenum, GLenum, unsigned int, GLint64 *); 241 242 template <typename QueryT> 243 void CastIndexedStateValues(Context *context, 244 GLenum nativeType, 245 GLenum pname, 246 GLuint index, 247 unsigned int numParams, 248 QueryT *outParams) 249 { 250 if (nativeType == GL_INT) 251 { 252 std::vector<GLint> intParams(numParams, 0); 253 context->getIntegeri_v(pname, index, intParams.data()); 254 255 for (unsigned int i = 0; i < numParams; ++i) 256 { 257 outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]); 258 } 259 } 260 else if (nativeType == GL_BOOL) 261 { 262 std::vector<GLboolean> boolParams(numParams, GL_FALSE); 263 context->getBooleani_v(pname, index, boolParams.data()); 264 265 for (unsigned int i = 0; i < numParams; ++i) 266 { 267 outParams[i] = 268 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1)); 269 } 270 } 271 else if (nativeType == GL_INT_64_ANGLEX) 272 { 273 std::vector<GLint64> int64Params(numParams, 0); 274 context->getInteger64i_v(pname, index, int64Params.data()); 275 276 for (unsigned int i = 0; i < numParams; ++i) 277 { 278 outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]); 279 } 280 } 281 else 282 UNREACHABLE(); 283 } 284 285 template void CastIndexedStateValues<GLboolean>(Context *, 286 GLenum, 287 GLenum, 288 GLuint index, 289 unsigned int, 290 GLboolean *); 291 template void CastIndexedStateValues<GLint>(Context *, 292 GLenum, 293 GLenum, 294 GLuint index, 295 unsigned int, 296 GLint *); 297 template void CastIndexedStateValues<GLuint>(Context *, 298 GLenum, 299 GLenum, 300 GLuint index, 301 unsigned int, 302 GLuint *); 303 template void CastIndexedStateValues<GLfloat>(Context *, 304 GLenum, 305 GLenum, 306 GLuint index, 307 unsigned int, 308 GLfloat *); 309 template void CastIndexedStateValues<GLint64>(Context *, 310 GLenum, 311 GLenum, 312 GLuint index, 313 unsigned int, 314 GLint64 *); 315 } // namespace gl