VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_occlude.c@ 76793

Last change on this file since 76793 was 76793, checked in by vboxsync, 6 years ago

3D: Validation of glDeleteQueries arguments

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.7 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "state.h"
8#include "state/cr_statetypes.h"
9#include "state/cr_statefuncs.h"
10#include "state_internals.h"
11#include "cr_mem.h"
12
13#if !defined(IN_GUEST)
14#include "cr_unpack.h"
15#endif
16
17void
18crStateOcclusionInit(CRContext *ctx)
19{
20 CROcclusionState *o = &ctx->occlusion;
21
22 o->objects = crAllocHashtable();
23 o->currentQueryObject = 0;
24}
25
26
27void
28crStateOcclusionDestroy(CRContext *ctx)
29{
30 CROcclusionState *o = &(ctx->occlusion);
31 crFreeHashtable(o->objects, crFree);
32}
33
34
35static CROcclusionObject *
36NewQueryObject(GLenum target, GLuint id)
37{
38 CROcclusionObject *q = (CROcclusionObject *) crAlloc(sizeof(CROcclusionObject));
39 if (q) {
40 q->target = target;
41 q->name = id;
42 q->passedCounter = 0;
43 q->active = GL_FALSE;
44 }
45 return q;
46}
47
48
49void STATE_APIENTRY
50crStateDeleteQueriesARB(GLsizei n, const GLuint *ids)
51{
52 CRContext *g = GetCurrentContext();
53 CROcclusionState *o = &(g->occlusion);
54 /*CRStateBits *sb = GetCurrentBits();*/
55 /*CROcclusionBits *bb = &(sb->occlusion);*/
56 int i;
57
58 FLUSH();
59
60 if (g->current.inBeginEnd) {
61 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
62 "glDeleteQueriesARB called in Begin/End");
63 return;
64 }
65
66 if (n <= 0 || n >= INT32_MAX / sizeof(GLuint))
67 {
68 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
69 "glDeleteQueriesARB: parameter 'n' is out of range");
70 return;
71 }
72
73#if !defined(IN_GUEST)
74 if (!DATA_POINTER_CHECK(n * sizeof(GLuint)))
75 {
76 crError("glDeleteQueriesARB: parameter 'n' is out of range");
77 return;
78 }
79#endif
80
81 for (i = 0; i < n; i++) {
82 if (ids[i]) {
83 CROcclusionObject *q = (CROcclusionObject *)
84 crHashtableSearch(o->objects, ids[i]);
85 if (q) {
86 crHashtableDelete(o->objects, ids[i], crFree);
87 }
88 }
89 }
90}
91
92
93void STATE_APIENTRY
94crStateGenQueriesARB(GLsizei n, GLuint * queries)
95{
96 CRContext *g = GetCurrentContext();
97 CROcclusionState *o = &(g->occlusion);
98 GLint start;
99
100 FLUSH();
101
102 if (g->current.inBeginEnd) {
103 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
104 "glGenQueriesARB called in Begin/End");
105 return;
106 }
107
108 if (n < 0) {
109 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
110 "glGenQueriesARB(n < 0)");
111 return;
112 }
113
114 start = crHashtableAllocKeys(o->objects, n);
115 if (start) {
116 GLint i;
117 for (i = 0; i < n; i++)
118 queries[i] = (GLuint) (start + i);
119 }
120 else {
121 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glGenQueriesARB");
122 }
123}
124
125
126GLboolean STATE_APIENTRY
127crStateIsQueryARB(GLuint id)
128{
129 CRContext *g = GetCurrentContext();
130 CROcclusionState *o = &(g->occlusion);
131
132 FLUSH();
133
134 if (g->current.inBeginEnd) {
135 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
136 "glIsQueryARB called in begin/end");
137 return GL_FALSE;
138 }
139
140 if (id && crHashtableIsKeyUsed(o->objects, id))
141 return GL_TRUE;
142 else
143 return GL_FALSE;
144}
145
146
147void STATE_APIENTRY
148crStateGetQueryivARB(GLenum target, GLenum pname, GLint *params)
149{
150 CRContext *g = GetCurrentContext();
151 CROcclusionState *o = &(g->occlusion);
152 (void)target;
153
154 FLUSH();
155
156 if (g->current.inBeginEnd) {
157 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
158 "glGetGetQueryivARB called in begin/end");
159 return;
160 }
161
162 switch (pname) {
163 case GL_QUERY_COUNTER_BITS_ARB:
164 *params = 8 * sizeof(GLuint);
165 break;
166 case GL_CURRENT_QUERY_ARB:
167 *params = o->currentQueryObject;
168 break;
169 default:
170 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
171 "glGetGetQueryivARB(pname)");
172 return;
173 }
174}
175
176
177void STATE_APIENTRY
178crStateGetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
179{
180 CRContext *g = GetCurrentContext();
181 CROcclusionState *o = &(g->occlusion);
182 CROcclusionObject *q;
183
184 FLUSH();
185
186 if (g->current.inBeginEnd) {
187 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
188 "glGetGetQueryObjectivARB called in begin/end");
189 return;
190 }
191
192 q = (CROcclusionObject *) crHashtableSearch(o->objects, id);
193 if (!q || q->active) {
194 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
195 "glGetQueryObjectivARB");
196 return;
197 }
198
199 switch (pname) {
200 case GL_QUERY_RESULT_ARB:
201 *params = q->passedCounter;
202 break;
203 case GL_QUERY_RESULT_AVAILABLE_ARB:
204 *params = GL_TRUE;
205 break;
206 default:
207 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
208 "glGetQueryObjectivARB(pname)");
209 return;
210 }
211}
212
213
214void STATE_APIENTRY
215crStateGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
216{
217 CRContext *g = GetCurrentContext();
218 CROcclusionState *o = &(g->occlusion);
219 CROcclusionObject *q;
220
221 FLUSH();
222
223 if (g->current.inBeginEnd) {
224 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
225 "glGetGetQueryObjectuivARB called in begin/end");
226 return;
227 }
228
229 q = (CROcclusionObject *) crHashtableSearch(o->objects, id);
230 if (!q || q->active) {
231 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
232 "glGetQueryObjectuivARB");
233 return;
234 }
235
236 switch (pname) {
237 case GL_QUERY_RESULT_ARB:
238 *params = q->passedCounter;
239 break;
240 case GL_QUERY_RESULT_AVAILABLE_ARB:
241 /* XXX revisit when we have a hardware implementation! */
242 *params = GL_TRUE;
243 break;
244 default:
245 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
246 "glGetQueryObjectuivARB(pname)");
247 return;
248 }
249}
250
251
252void STATE_APIENTRY
253crStateBeginQueryARB(GLenum target, GLuint id)
254{
255 CRContext *g = GetCurrentContext();
256 CROcclusionState *o = &(g->occlusion);
257 CROcclusionObject *q;
258
259 FLUSH();
260
261 if (g->current.inBeginEnd) {
262 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
263 "glGetGetQueryObjectuivARB called in begin/end");
264 return;
265 }
266
267 if (target != GL_SAMPLES_PASSED_ARB) {
268 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
269 "glBeginQueryARB(target)");
270 return;
271 }
272
273 if (o->currentQueryObject) {
274 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
275 "glBeginQueryARB(target)");
276 return;
277 }
278
279 q = (CROcclusionObject *) crHashtableSearch(o->objects, id);
280 if (q && q->active) {
281 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glBeginQueryARB");
282 return;
283 }
284 else if (!q) {
285 q = NewQueryObject(target, id);
286 if (!q) {
287 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBeginQueryARB");
288 return;
289 }
290 crHashtableAdd(o->objects, id, q);
291 }
292
293 q->active = GL_TRUE;
294 q->passedCounter = 0;
295 q->active = GL_TRUE;
296 q->passedCounter = 0;
297 o->currentQueryObject = id;
298}
299
300
301void STATE_APIENTRY
302crStateEndQueryARB(GLenum target)
303{
304 CRContext *g = GetCurrentContext();
305 CROcclusionState *o = &(g->occlusion);
306 CROcclusionObject *q;
307
308 FLUSH();
309
310 if (g->current.inBeginEnd) {
311 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
312 "glGetGetQueryObjectuivARB called in begin/end");
313 return;
314 }
315
316 if (target != GL_SAMPLES_PASSED_ARB) {
317 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEndQueryARB(target)");
318 return;
319 }
320
321 q = (CROcclusionObject *) crHashtableSearch(o->objects, o->currentQueryObject);
322 if (!q || !q->active) {
323 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
324 "glEndQueryARB with glBeginQueryARB");
325 return;
326 }
327
328 q->passedCounter = 0;
329 q->active = GL_FALSE;
330 o->currentQueryObject = 0;
331}
332
333
334void crStateOcclusionDiff(CROcclusionBits *bb, CRbitvalue *bitID,
335 CRContext *fromCtx, CRContext *toCtx)
336{
337 /* Apparently, no occlusion state differencing needed */
338 (void)bb; (void)bitID; (void)fromCtx; (void)toCtx;
339}
340
341
342/*
343 * XXX this function might need some testing/fixing.
344 */
345void crStateOcclusionSwitch(CROcclusionBits *bb, CRbitvalue *bitID,
346 CRContext *fromCtx, CRContext *toCtx)
347{
348 /* Apparently, no occlusion state switching needed */
349 /* Note: we better not do a switch while we're inside a glBeginQuery/
350 * glEndQuery sequence.
351 */
352 (void)bb; (void)bitID; (void)fromCtx; (void)toCtx;
353 CRASSERT(!fromCtx->occlusion.currentQueryObject);
354}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette