1 //
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
9 #include "libANGLE/queryconversions.h"
10
11 #include <vector>
12
13 #include "libANGLE/Context.h"
14 #include "common/utilities.h"
15
16 namespace gl
17 {
18
19 namespace
20 {
21
ExpandFloatToInteger(GLfloat value)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>
ClampToQueryRange(GLint64 value)28 QueryT ClampToQueryRange(GLint64 value)
29 {
30 const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min());
31 const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max());
32 return static_cast<QueryT>(clamp(value, min, max));
33 }
34
35 template <typename QueryT, typename NativeT>
36 QueryT CastStateValueToInt(GLenum pname, NativeT value)
37 {
38 GLenum queryType = GLTypeToGLenum<QueryT>::value;
39 GLenum nativeType = GLTypeToGLenum<NativeT>::value;
40
41 if (nativeType == GL_FLOAT)
42 {
43 // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
44 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
45 {
46 return ClampToQueryRange<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
47 }
48 else
49 {
50 return gl::iround<QueryT>(static_cast<GLfloat>(value));
51 }
52 }
53
54 // Clamp 64-bit int values when casting to int
55 if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT)
56 {
57 GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min());
58 GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
59 GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
60 return static_cast<QueryT>(clampedValue);
61 }
62
63 return static_cast<QueryT>(value);
64 }
65
66 template <typename QueryT, typename NativeT>
67 QueryT CastStateValue(GLenum pname, NativeT value)
68 {
69 GLenum queryType = GLTypeToGLenum<QueryT>::value;
70
71 switch (queryType)
72 {
73 case GL_INT:
74 return CastStateValueToInt<QueryT, NativeT>(pname, value);
75 case GL_INT_64_ANGLEX:
76 return CastStateValueToInt<QueryT, NativeT>(pname, value);
77 case GL_FLOAT:
78 return static_cast<QueryT>(value);
79 case GL_BOOL:
80 return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
81 default:
82 UNREACHABLE();
83 return 0;
84 }
85 }
86
87 } // anonymous namespace
88
89 template <typename QueryT>
CastStateValues(Context * context,GLenum nativeType,GLenum pname,unsigned int numParams,QueryT * outParams)90 void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
91 unsigned int numParams, QueryT *outParams)
92 {
93 if (nativeType == GL_INT)
94 {
95 std::vector<GLint> intParams(numParams, 0);
96 context->getIntegerv(pname, intParams.data());
97
98 for (unsigned int i = 0; i < numParams; ++i)
99 {
100 outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
101 }
102 }
103 else if (nativeType == GL_BOOL)
104 {
105 std::vector<GLboolean> boolParams(numParams, GL_FALSE);
106 context->getBooleanv(pname, boolParams.data());
107
108 for (unsigned int i = 0; i < numParams; ++i)
109 {
110 outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
111 }
112 }
113 else if (nativeType == GL_FLOAT)
114 {
115 std::vector<GLfloat> floatParams(numParams, 0.0f);
116 context->getFloatv(pname, floatParams.data());
117
118 for (unsigned int i = 0; i < numParams; ++i)
119 {
120 outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]);
121 }
122 }
123 else if (nativeType == GL_INT_64_ANGLEX)
124 {
125 std::vector<GLint64> int64Params(numParams, 0);
126 context->getInteger64v(pname, int64Params.data());
127
128 for (unsigned int i = 0; i < numParams; ++i)
129 {
130 outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
131 }
132 }
133 else UNREACHABLE();
134 }
135
136 // Explicit template instantiation (how we export template functions in different files)
137 // The calls below will make CastStateValues successfully link with the GL state query types
138 // The GL state query API types are: bool, int, uint, float, int64
139
140 template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
141 template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
142 template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
143 template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
144 template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
145
146 template <typename QueryT>
CastIndexedStateValues(Context * context,GLenum nativeType,GLenum pname,GLuint index,unsigned int numParams,QueryT * outParams)147 void CastIndexedStateValues(Context *context,
148 GLenum nativeType,
149 GLenum pname,
150 GLuint index,
151 unsigned int numParams,
152 QueryT *outParams)
153 {
154 if (nativeType == GL_INT)
155 {
156 std::vector<GLint> intParams(numParams, 0);
157 context->getIntegeri_v(pname, index, intParams.data());
158
159 for (unsigned int i = 0; i < numParams; ++i)
160 {
161 outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
162 }
163 }
164 else if (nativeType == GL_BOOL)
165 {
166 std::vector<GLboolean> boolParams(numParams, GL_FALSE);
167 context->getBooleani_v(pname, index, boolParams.data());
168
169 for (unsigned int i = 0; i < numParams; ++i)
170 {
171 outParams[i] =
172 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
173 }
174 }
175 else if (nativeType == GL_INT_64_ANGLEX)
176 {
177 std::vector<GLint64> int64Params(numParams, 0);
178 context->getInteger64i_v(pname, index, int64Params.data());
179
180 for (unsigned int i = 0; i < numParams; ++i)
181 {
182 outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
183 }
184 }
185 else
186 UNREACHABLE();
187 }
188
189 template void CastIndexedStateValues<GLboolean>(Context *,
190 GLenum,
191 GLenum,
192 GLuint index,
193 unsigned int,
194 GLboolean *);
195 template void CastIndexedStateValues<GLint>(Context *,
196 GLenum,
197 GLenum,
198 GLuint index,
199 unsigned int,
200 GLint *);
201 template void CastIndexedStateValues<GLuint>(Context *,
202 GLenum,
203 GLenum,
204 GLuint index,
205 unsigned int,
206 GLuint *);
207 template void CastIndexedStateValues<GLfloat>(Context *,
208 GLenum,
209 GLenum,
210 GLuint index,
211 unsigned int,
212 GLfloat *);
213 template void CastIndexedStateValues<GLint64>(Context *,
214 GLenum,
215 GLenum,
216 GLuint index,
217 unsigned int,
218 GLint64 *);
219 }
220