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, 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 Table 4.5
35 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
36 {
37 return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
38 }
39 else
40 {
41 return clampCast<QueryT>(std::round(value));
42 }
43 }
44
45 return clampCast<QueryT>(value);
46 }
47
48 template <typename NativeT, typename QueryT>
49 NativeT CastQueryValueToInt(GLenum pname, QueryT value)
50 {
51 GLenum queryType = GLTypeToGLenum<QueryT>::value;
52
53 if (queryType == GL_FLOAT)
54 {
55 return static_cast<NativeT>(std::round(value));
56 }
57
58 return static_cast<NativeT>(value);
59 }
60
61 } // anonymous namespace
62
63 // ES 3.10 Section 2.2.2
64 // When querying bitmasks(such as SAMPLE_MASK_VALUE or STENCIL_WRITEMASK) with GetIntegerv, the
65 // mask value is treated as a signed integer, so that mask values with the high bit set will not be
66 // clamped when returned as signed integers.
CastMaskValue(const Context * context,GLuint value)67 GLint CastMaskValue(const Context *context, GLuint value)
68 {
69 return (context->getClientVersion() >= Version(3, 1) ? static_cast<GLint>(value)
70 : clampCast<GLint>(value));
71 }
72
73 template <typename QueryT, typename InternalT>
74 QueryT CastFromGLintStateValue(GLenum pname, InternalT value)
75 {
76 return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value));
77 }
78
79 template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value);
80 template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value);
81 template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value);
82 template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value);
83 template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value);
84 template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value);
85 template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value);
86
87 template <typename QueryT, typename NativeT>
88 QueryT CastFromStateValue(GLenum pname, NativeT value)
89 {
90 GLenum queryType = GLTypeToGLenum<QueryT>::value;
91
92 switch (queryType)
93 {
94 case GL_INT:
95 case GL_INT_64_ANGLEX:
96 case GL_UNSIGNED_INT:
97 case GL_UINT_64_ANGLEX:
98 return CastFromStateValueToInt<QueryT, NativeT>(pname, value);
99 case GL_FLOAT:
100 return static_cast<QueryT>(value);
101 case GL_BOOL:
102 return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
103 default:
104 UNREACHABLE();
105 return 0;
106 }
107 }
108 template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value);
109 template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value);
110 template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value);
111 template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value);
112 template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value);
113 template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
114 template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
115 template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value);
116 template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value);
117 template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value);
118 template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value);
119 template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value);
120 template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value);
121 template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value);
122
123 template <typename NativeT, typename QueryT>
124 NativeT CastQueryValueTo(GLenum pname, QueryT value)
125 {
126 GLenum nativeType = GLTypeToGLenum<NativeT>::value;
127
128 switch (nativeType)
129 {
130 case GL_INT:
131 case GL_INT_64_ANGLEX:
132 case GL_UNSIGNED_INT:
133 case GL_UINT_64_ANGLEX:
134 return CastQueryValueToInt<NativeT, QueryT>(pname, value);
135 case GL_FLOAT:
136 return static_cast<NativeT>(value);
137 case GL_BOOL:
138 return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE);
139 default:
140 UNREACHABLE();
141 return 0;
142 }
143 }
144
145 template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value);
146 template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value);
147 template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value);
148 template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value);
149 template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value);
150 template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
151 template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
152
153 template <typename QueryT>
CastStateValues(Context * context,GLenum nativeType,GLenum pname,unsigned int numParams,QueryT * outParams)154 void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
155 unsigned int numParams, QueryT *outParams)
156 {
157 if (nativeType == GL_INT)
158 {
159 std::vector<GLint> intParams(numParams, 0);
160 context->getIntegervImpl(pname, intParams.data());
161
162 for (unsigned int i = 0; i < numParams; ++i)
163 {
164 outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
165 }
166 }
167 else if (nativeType == GL_BOOL)
168 {
169 std::vector<GLboolean> boolParams(numParams, GL_FALSE);
170 context->getBooleanvImpl(pname, boolParams.data());
171
172 for (unsigned int i = 0; i < numParams; ++i)
173 {
174 outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
175 }
176 }
177 else if (nativeType == GL_FLOAT)
178 {
179 std::vector<GLfloat> floatParams(numParams, 0.0f);
180 context->getFloatvImpl(pname, floatParams.data());
181
182 for (unsigned int i = 0; i < numParams; ++i)
183 {
184 outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]);
185 }
186 }
187 else if (nativeType == GL_INT_64_ANGLEX)
188 {
189 std::vector<GLint64> int64Params(numParams, 0);
190 context->getInteger64v(pname, int64Params.data());
191
192 for (unsigned int i = 0; i < numParams; ++i)
193 {
194 outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
195 }
196 }
197 else UNREACHABLE();
198 }
199
200 // Explicit template instantiation (how we export template functions in different files)
201 // The calls below will make CastStateValues successfully link with the GL state query types
202 // The GL state query API types are: bool, int, uint, float, int64, uint64
203
204 template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
205 template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
206 template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
207 template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
208 template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
209
210 template <typename QueryT>
CastIndexedStateValues(Context * context,GLenum nativeType,GLenum pname,GLuint index,unsigned int numParams,QueryT * outParams)211 void CastIndexedStateValues(Context *context,
212 GLenum nativeType,
213 GLenum pname,
214 GLuint index,
215 unsigned int numParams,
216 QueryT *outParams)
217 {
218 if (nativeType == GL_INT)
219 {
220 std::vector<GLint> intParams(numParams, 0);
221 context->getIntegeri_v(pname, index, intParams.data());
222
223 for (unsigned int i = 0; i < numParams; ++i)
224 {
225 outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
226 }
227 }
228 else if (nativeType == GL_BOOL)
229 {
230 std::vector<GLboolean> boolParams(numParams, GL_FALSE);
231 context->getBooleani_v(pname, index, boolParams.data());
232
233 for (unsigned int i = 0; i < numParams; ++i)
234 {
235 outParams[i] =
236 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
237 }
238 }
239 else if (nativeType == GL_INT_64_ANGLEX)
240 {
241 std::vector<GLint64> int64Params(numParams, 0);
242 context->getInteger64i_v(pname, index, int64Params.data());
243
244 for (unsigned int i = 0; i < numParams; ++i)
245 {
246 outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
247 }
248 }
249 else
250 UNREACHABLE();
251 }
252
253 template void CastIndexedStateValues<GLboolean>(Context *,
254 GLenum,
255 GLenum,
256 GLuint index,
257 unsigned int,
258 GLboolean *);
259 template void CastIndexedStateValues<GLint>(Context *,
260 GLenum,
261 GLenum,
262 GLuint index,
263 unsigned int,
264 GLint *);
265 template void CastIndexedStateValues<GLuint>(Context *,
266 GLenum,
267 GLenum,
268 GLuint index,
269 unsigned int,
270 GLuint *);
271 template void CastIndexedStateValues<GLfloat>(Context *,
272 GLenum,
273 GLenum,
274 GLuint index,
275 unsigned int,
276 GLfloat *);
277 template void CastIndexedStateValues<GLint64>(Context *,
278 GLenum,
279 GLenum,
280 GLuint index,
281 unsigned int,
282 GLint64 *);
283 }
284