blob: 460e346eac00e2cf6627a3e2ea7e7f5991627598 [file] [log] [blame]
Jamie Madill55856b12014-01-02 13:59:50 -05001//
2// Copyright (c) 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
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/Context.h"
Jamie Madill55856b12014-01-02 13:59:50 -050010#include "common/utilities.h"
11
12namespace gl
13{
14
15// Helper class for converting a GL type to a GLenum:
16// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
17// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
18
19template <typename GLType>
20struct CastStateValueEnum { static GLenum mEnumForType; };
21
22template <> GLenum CastStateValueEnum<GLint>::mEnumForType = GL_INT;
23template <> GLenum CastStateValueEnum<GLuint>::mEnumForType = GL_UNSIGNED_INT;
24template <> GLenum CastStateValueEnum<GLboolean>::mEnumForType = GL_BOOL;
25template <> GLenum CastStateValueEnum<GLint64>::mEnumForType = GL_INT_64_ANGLEX;
26template <> GLenum CastStateValueEnum<GLfloat>::mEnumForType = GL_FLOAT;
27
28template <typename QueryT, typename NativeT>
29QueryT CastStateValueToInt(GLenum pname, NativeT value)
30{
31 GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
32 GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType;
33
34 if (nativeType == GL_FLOAT)
35 {
36 // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
37 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
38 {
39 return static_cast<QueryT>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) / 2.0f);
40 }
41 else
42 {
43 return gl::iround<QueryT>(value);
44 }
45 }
46
47 // Clamp 64-bit int values when casting to int
48 if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT)
49 {
50 GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min());
51 GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
52 GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
53 return static_cast<QueryT>(clampedValue);
54 }
55
56 return static_cast<QueryT>(value);
57}
58
59template <typename QueryT, typename NativeT>
60QueryT CastStateValue(GLenum pname, NativeT value)
61{
62 GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
63
64 switch (queryType)
65 {
66 case GL_INT: return CastStateValueToInt<QueryT, NativeT>(pname, value);
67 case GL_INT_64_ANGLEX: return CastStateValueToInt<QueryT, NativeT>(pname, value);
68 case GL_FLOAT: return static_cast<QueryT>(value);
69 case GL_BOOL: return (value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
70 default: UNREACHABLE(); return 0;
71 }
72}
73
74template <typename QueryT>
75void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
76 unsigned int numParams, QueryT *outParams)
77{
78 if (nativeType == GL_INT)
79 {
80 GLint *intParams = NULL;
81 intParams = new GLint[numParams];
82
83 context->getIntegerv(pname, intParams);
84
85 for (unsigned int i = 0; i < numParams; ++i)
86 {
87 outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
88 }
89
90 delete [] intParams;
91 }
92 else if (nativeType == GL_BOOL)
93 {
94 GLboolean *boolParams = NULL;
95 boolParams = new GLboolean[numParams];
96
97 context->getBooleanv(pname, boolParams);
98
99 for (unsigned int i = 0; i < numParams; ++i)
100 {
101 outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
102 }
103
104 delete [] boolParams;
105 }
106 else if (nativeType == GL_FLOAT)
107 {
108 GLfloat *floatParams = NULL;
109 floatParams = new GLfloat[numParams];
110
111 context->getFloatv(pname, floatParams);
112
113 for (unsigned int i = 0; i < numParams; ++i)
114 {
115 outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]);
116 }
117
118 delete [] floatParams;
119 }
120 else if (nativeType == GL_INT_64_ANGLEX)
121 {
122 GLint64 *int64Params = NULL;
123 int64Params = new GLint64[numParams];
124
125 context->getInteger64v(pname, int64Params);
126
127 for (unsigned int i = 0; i < numParams; ++i)
128 {
129 outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
130 }
131
132 delete [] int64Params;
133 }
134 else UNREACHABLE();
135}
136
137// Explicit template instantiation (how we export template functions in different files)
138// The calls below will make CastStateValues successfully link with the GL state query types
139// The GL state query API types are: bool, int, uint, float, int64
140
141template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
142template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
143template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
144template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
145template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
146
147}