VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c@ 61571

Last change on this file since 61571 was 58895, checked in by vboxsync, 9 years ago

OpenGL/state_tracker: GL_FRAMEBUFFER is equivalent to GL_DRAW_FRAMEBUFFER

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 38.3 KB
Line 
1/* $Id: state_framebuffer.c 58895 2015-11-27 10:00:08Z vboxsync $ */
2
3/** @file
4 * VBox OpenGL: EXT_framebuffer_object state tracking
5 */
6
7/*
8 * Copyright (C) 2009-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "state.h"
20#include "state/cr_statetypes.h"
21#include "state/cr_statefuncs.h"
22#include "state_internals.h"
23#include "cr_mem.h"
24
25DECLEXPORT(void) STATE_APIENTRY
26crStateFramebufferObjectInit(CRContext *ctx)
27{
28 CRFramebufferObjectState *fbo = &ctx->framebufferobject;
29
30 fbo->readFB = NULL;
31 fbo->drawFB = NULL;
32 fbo->renderbuffer = NULL;
33 ctx->shared->bFBOResyncNeeded = GL_FALSE;
34}
35
36void STATE_APIENTRY crStateGenFramebuffersEXT(GLsizei n, GLuint *buffers)
37{
38 CRContext *g = GetCurrentContext();
39 crStateGenNames(g, g->shared->fbTable, n, buffers);
40}
41
42void STATE_APIENTRY crStateGenRenderbuffersEXT(GLsizei n, GLuint *buffers)
43{
44 CRContext *g = GetCurrentContext();
45 crStateGenNames(g, g->shared->rbTable, n, buffers);
46}
47
48void crStateRegFramebuffers(GLsizei n, GLuint *buffers)
49{
50 CRContext *g = GetCurrentContext();
51 crStateRegNames(g, g->shared->fbTable, n, buffers);
52}
53
54void crStateRegRenderbuffers(GLsizei n, GLuint *buffers)
55{
56 CRContext *g = GetCurrentContext();
57 crStateRegNames(g, g->shared->rbTable, n, buffers);
58}
59
60static void crStateInitFrameBuffer(CRFramebufferObject *fbo);
61
62static CRFramebufferObject *
63crStateFramebufferAllocate(CRContext *ctx, GLuint name)
64{
65 CRFramebufferObject *buffer = (CRFramebufferObject*) crCalloc(sizeof(CRFramebufferObject));
66 CRSTATE_CHECKERR_RET(!buffer, GL_OUT_OF_MEMORY, "crStateFramebufferAllocate", NULL);
67 buffer->id = name;
68#ifndef IN_GUEST
69 diff_api.GenFramebuffersEXT(1, &buffer->hwid);
70 if (!buffer->hwid)
71 {
72 crWarning("GenFramebuffersEXT failed!");
73 crFree(buffer);
74 return NULL;
75 }
76#else
77 buffer->hwid = name;
78#endif
79
80 crStateInitFrameBuffer(buffer);
81 crHashtableAdd(ctx->shared->fbTable, name, buffer);
82 CR_STATE_SHAREDOBJ_USAGE_INIT(buffer);
83
84 return buffer;
85}
86
87static CRRenderbufferObject *
88crStateRenderbufferAllocate(CRContext *ctx, GLuint name)
89{
90 CRRenderbufferObject *buffer = (CRRenderbufferObject*) crCalloc(sizeof(CRRenderbufferObject));
91 CRSTATE_CHECKERR_RET(!buffer, GL_OUT_OF_MEMORY, "crStateRenderbufferAllocate", NULL);
92 buffer->id = name;
93#ifndef IN_GUEST
94 diff_api.GenRenderbuffersEXT(1, &buffer->hwid);
95 if (!buffer->hwid)
96 {
97 crWarning("GenRenderbuffersEXT failed!");
98 crFree(buffer);
99 return NULL;
100 }
101#else
102 buffer->hwid = name;
103#endif
104
105 buffer->internalformat = GL_RGBA;
106 crHashtableAdd(ctx->shared->rbTable, name, buffer);
107 CR_STATE_SHAREDOBJ_USAGE_INIT(buffer);
108
109 return buffer;
110}
111
112void crStateFreeFBO(void *data)
113{
114 CRFramebufferObject *pObj = (CRFramebufferObject *)data;
115
116#ifndef IN_GUEST
117 if (diff_api.DeleteFramebuffersEXT)
118 {
119 diff_api.DeleteFramebuffersEXT(1, &pObj->hwid);
120 }
121#endif
122
123 crFree(pObj);
124}
125
126void crStateFreeRBO(void *data)
127{
128 CRRenderbufferObject *pObj = (CRRenderbufferObject *)data;
129
130#ifndef IN_GUEST
131 if (diff_api.DeleteRenderbuffersEXT)
132 {
133 diff_api.DeleteRenderbuffersEXT(1, &pObj->hwid);
134 }
135#endif
136
137 crFree(pObj);
138}
139
140DECLEXPORT(void) STATE_APIENTRY
141crStateFramebufferObjectDestroy(CRContext *ctx)
142{
143 CRFramebufferObjectState *fbo = &ctx->framebufferobject;
144
145 fbo->readFB = NULL;
146 fbo->drawFB = NULL;
147 fbo->renderbuffer = NULL;
148}
149
150DECLEXPORT(void) STATE_APIENTRY
151crStateBindRenderbufferEXT(GLenum target, GLuint renderbuffer)
152{
153 CRContext *g = GetCurrentContext();
154 CRFramebufferObjectState *fbo = &g->framebufferobject;
155
156 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
157 CRSTATE_CHECKERR(target!=GL_RENDERBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
158
159 if (renderbuffer)
160 {
161 fbo->renderbuffer = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffer);
162 if (!fbo->renderbuffer)
163 {
164 CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->rbTable, renderbuffer), GL_INVALID_OPERATION, "name is not a renderbuffer");
165 fbo->renderbuffer = crStateRenderbufferAllocate(g, renderbuffer);
166 }
167 CR_STATE_SHAREDOBJ_USAGE_SET(fbo->renderbuffer, g);
168 }
169 else fbo->renderbuffer = NULL;
170}
171
172static void crStateCheckFBOAttachments(CRFramebufferObject *pFBO, GLuint rbo, GLenum target)
173{
174 CRFBOAttachmentPoint *ap;
175 int u;
176
177 if (!pFBO)
178 return;
179
180 for (u=0; u<CR_MAX_COLOR_ATTACHMENTS; ++u)
181 {
182 ap = &pFBO->color[u];
183 if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
184 {
185 crStateFramebufferRenderbufferEXT(target, u+GL_COLOR_ATTACHMENT0_EXT, 0, 0);
186#ifdef IN_GUEST
187 pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
188#endif
189 }
190 }
191
192 ap = &pFBO->depth;
193 if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
194 {
195 crStateFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT_EXT, 0, 0);
196#ifdef IN_GUEST
197 pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
198#endif
199 }
200 ap = &pFBO->stencil;
201 if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
202 {
203 crStateFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT_EXT, 0, 0);
204#ifdef IN_GUEST
205 pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
206#endif
207 }
208}
209
210static void ctStateRenderbufferRefsCleanup(CRContext *g, GLuint fboId, CRRenderbufferObject *rbo)
211{
212 CRFramebufferObjectState *fbo = &g->framebufferobject;
213
214 if (fbo->renderbuffer==rbo)
215 {
216 fbo->renderbuffer = NULL;
217 }
218
219 /* check the attachments of current framebuffers */
220 crStateCheckFBOAttachments(fbo->readFB, fboId, GL_READ_FRAMEBUFFER);
221 crStateCheckFBOAttachments(fbo->drawFB, fboId, GL_DRAW_FRAMEBUFFER);
222
223 CR_STATE_SHAREDOBJ_USAGE_CLEAR(rbo, g);
224}
225
226DECLEXPORT(void) STATE_APIENTRY
227crStateDeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
228{
229 CRContext *g = GetCurrentContext();
230 CRFramebufferObjectState *fbo = &g->framebufferobject;
231 int i;
232
233 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
234 CRSTATE_CHECKERR(n<0, GL_INVALID_OPERATION, "n<0");
235
236 for (i = 0; i < n; i++)
237 {
238 if (renderbuffers[i])
239 {
240 CRRenderbufferObject *rbo;
241 rbo = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffers[i]);
242 if (rbo)
243 {
244 int j;
245
246 ctStateRenderbufferRefsCleanup(g, renderbuffers[i], rbo);
247 CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(rbo, j)
248 {
249 /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
250 * so on restore, we set mark bits as used.
251 * This is why g_pAvailableContexts[j] could be NULL
252 * also g_pAvailableContexts[0] will hold default context, which we should discard */
253 CRContext *ctx = g_pAvailableContexts[j];
254 if (j && ctx)
255 {
256 CRFramebufferObjectState *ctxFbo;
257 CRASSERT(ctx);
258 ctxFbo = &ctx->framebufferobject;
259 if (ctxFbo->renderbuffer==rbo)
260 crWarning("deleting RBO being used by another context %d", ctx->id);
261
262 ctStateRenderbufferRefsCleanup(ctx, renderbuffers[i], rbo);
263 }
264 else
265 CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(rbo, j);
266 }
267 crHashtableDelete(g->shared->rbTable, renderbuffers[i], crStateFreeRBO);
268 }
269 }
270 }
271}
272
273DECLEXPORT(void) STATE_APIENTRY
274crStateRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
275{
276 CRContext *g = GetCurrentContext();
277 CRFramebufferObjectState *fbo = &g->framebufferobject;
278 CRRenderbufferObject *rb = fbo->renderbuffer;
279
280 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
281 CRSTATE_CHECKERR(target!=GL_RENDERBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
282 CRSTATE_CHECKERR(!rb, GL_INVALID_OPERATION, "no bound renderbuffer");
283
284 rb->width = width;
285 rb->height = height;
286 rb->internalformat = internalformat;
287}
288
289DECLEXPORT(void) STATE_APIENTRY
290crStateGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
291{
292 CRContext *g = GetCurrentContext();
293 CRFramebufferObjectState *fbo = &g->framebufferobject;
294 CRRenderbufferObject *rb = fbo->renderbuffer;
295
296 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
297 CRSTATE_CHECKERR(target!=GL_RENDERBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
298 CRSTATE_CHECKERR(!rb, GL_INVALID_OPERATION, "no bound renderbuffer");
299
300 switch (pname)
301 {
302 case GL_RENDERBUFFER_WIDTH_EXT:
303 *params = rb->width;
304 break;
305 case GL_RENDERBUFFER_HEIGHT_EXT:
306 *params = rb->height;
307 break;
308 case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
309 *params = rb->internalformat;
310 break;
311 case GL_RENDERBUFFER_RED_SIZE_EXT:
312 case GL_RENDERBUFFER_GREEN_SIZE_EXT:
313 case GL_RENDERBUFFER_BLUE_SIZE_EXT:
314 case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
315 case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
316 case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
317 CRSTATE_CHECKERR(GL_TRUE, GL_INVALID_OPERATION, "unimplemented");
318 break;
319 default:
320 CRSTATE_CHECKERR(GL_TRUE, GL_INVALID_ENUM, "invalid pname");
321 }
322}
323
324static void crStateInitFBOAttachmentPoint(CRFBOAttachmentPoint *fboap)
325{
326 fboap->type = GL_NONE;
327 fboap->name = 0;
328 fboap->level = 0;
329 fboap->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
330 fboap->zoffset = 0;
331}
332
333static void crStateInitFrameBuffer(CRFramebufferObject *fbo)
334{
335 int i;
336
337 for (i=0; i<CR_MAX_COLOR_ATTACHMENTS; ++i)
338 crStateInitFBOAttachmentPoint(&fbo->color[i]);
339
340 crStateInitFBOAttachmentPoint(&fbo->depth);
341 crStateInitFBOAttachmentPoint(&fbo->stencil);
342
343 fbo->readbuffer = GL_COLOR_ATTACHMENT0_EXT;
344 fbo->drawbuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
345
346#ifdef IN_GUEST
347 fbo->status = GL_FRAMEBUFFER_UNDEFINED;
348#endif
349}
350
351static GLboolean crStateGetFBOAttachmentPoint(CRFramebufferObject *fb, GLenum attachment, CRFBOAttachmentPoint **ap)
352{
353 switch (attachment)
354 {
355 case GL_DEPTH_ATTACHMENT_EXT:
356 *ap = &fb->depth;
357 break;
358 case GL_STENCIL_ATTACHMENT_EXT:
359 *ap = &fb->stencil;
360 break;
361 default:
362 if (attachment>=GL_COLOR_ATTACHMENT0_EXT && attachment<=GL_COLOR_ATTACHMENT15_EXT)
363 {
364 *ap = &fb->color[attachment-GL_COLOR_ATTACHMENT0_EXT];
365 }
366 else return GL_FALSE;
367 }
368
369 return GL_TRUE;
370}
371
372DECLEXPORT(void) STATE_APIENTRY
373crStateBindFramebufferEXT(GLenum target, GLuint framebuffer)
374{
375 CRContext *g = GetCurrentContext();
376 CRFramebufferObjectState *fbo = &g->framebufferobject;
377 CRFramebufferObject *pFBO=NULL;
378
379 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
380 CRSTATE_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
381 GL_INVALID_ENUM, "invalid target");
382
383 if (framebuffer)
384 {
385 pFBO = (CRFramebufferObject*) crHashtableSearch(g->shared->fbTable, framebuffer);
386 if (!pFBO)
387 {
388 CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->fbTable, framebuffer), GL_INVALID_OPERATION, "name is not a framebuffer");
389 pFBO = crStateFramebufferAllocate(g, framebuffer);
390 }
391
392
393 CR_STATE_SHAREDOBJ_USAGE_SET(pFBO, g);
394 }
395
396 /* @todo: http://www.opengl.org/registry/specs/ARB/framebuffer_object.txt
397 * FBO status might change when binding a different FBO here...but I doubt it happens.
398 * So no status reset here until a proper check.
399 */
400
401 switch (target)
402 {
403 case GL_FRAMEBUFFER_EXT:
404 fbo->readFB = pFBO;
405 fbo->drawFB = pFBO;
406 break;
407 case GL_READ_FRAMEBUFFER:
408 fbo->readFB = pFBO;
409 break;
410 case GL_DRAW_FRAMEBUFFER:
411 fbo->drawFB = pFBO;
412 break;
413 }
414}
415
416static void ctStateFramebufferRefsCleanup(CRContext *g, CRFramebufferObject *fb)
417{
418 CRFramebufferObjectState *fbo = &g->framebufferobject;
419 if (fbo->readFB==fb)
420 {
421 fbo->readFB = NULL;
422 }
423 if (fbo->drawFB==fb)
424 {
425 fbo->drawFB = NULL;
426 }
427
428 CR_STATE_SHAREDOBJ_USAGE_CLEAR(fb, g);
429}
430
431DECLEXPORT(void) STATE_APIENTRY
432crStateDeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
433{
434 CRContext *g = GetCurrentContext();
435 int i;
436
437 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
438 CRSTATE_CHECKERR(n<0, GL_INVALID_OPERATION, "n<0");
439
440 for (i = 0; i < n; i++)
441 {
442 if (framebuffers[i])
443 {
444 CRFramebufferObject *fb;
445 fb = (CRFramebufferObject*) crHashtableSearch(g->shared->fbTable, framebuffers[i]);
446 if (fb)
447 {
448 int j;
449
450 ctStateFramebufferRefsCleanup(g, fb);
451
452 CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(fb, j)
453 {
454 /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
455 * so on restore, we set mark bits as used.
456 * This is why g_pAvailableContexts[j] could be NULL
457 * also g_pAvailableContexts[0] will hold default context, which we should discard */
458 CRContext *ctx = g_pAvailableContexts[j];
459 if (j && ctx)
460 {
461 CRFramebufferObjectState *ctxFbo;
462 CRASSERT(ctx);
463 ctxFbo = &ctx->framebufferobject;
464 if (ctxFbo->readFB==fb)
465 crWarning("deleting FBO being used as read buffer by another context %d", ctx->id);
466
467 if (ctxFbo->drawFB==fb)
468 crWarning("deleting FBO being used as draw buffer by another context %d", ctx->id);
469
470 ctStateFramebufferRefsCleanup(ctx, fb);
471 }
472 else
473 CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(fb, j);
474 }
475 crHashtableDelete(g->shared->fbTable, framebuffers[i], crStateFreeFBO);
476 }
477 }
478 }
479}
480
481/*@todo: move this function somewhere else*/
482/*return floor of base 2 log of x. log(0)==0*/
483unsigned int crLog2Floor(unsigned int x)
484{
485 x |= (x >> 1);
486 x |= (x >> 2);
487 x |= (x >> 4);
488 x |= (x >> 8);
489 x |= (x >> 16);
490 x -= ((x >> 1) & 0x55555555);
491 x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
492 x = (((x >> 4) + x) & 0x0f0f0f0f);
493 x += (x >> 8);
494 x += (x >> 16);
495 return (x & 0x0000003f) - 1;
496}
497
498static GLuint crStateFramebufferGet(CRFramebufferObjectState *fbo, GLenum target, CRFramebufferObject **apFBOs)
499{
500 /** @todo Since this function returns not more than one FBO, callers can be cleaned up. */
501 GLuint cPBOs = 0;
502 switch (target)
503 {
504 case GL_READ_FRAMEBUFFER:
505 cPBOs = 1;
506 apFBOs[0] = fbo->readFB;
507 break;
508 /* OpenGL glFramebufferTexture, glFramebufferRenderbuffer, glFramebufferRenderbuffer specs:
509 * "GL_FRAMEBUFFER is equivalent to GL_DRAW_FRAMEBUFFER."
510 */
511 case GL_FRAMEBUFFER:
512 case GL_DRAW_FRAMEBUFFER:
513 cPBOs = 1;
514 apFBOs[0] = fbo->drawFB;
515 break;
516 default:
517 crWarning("unexpected target value: 0x%x", target);
518 cPBOs = 0;
519 break;
520 }
521
522 return cPBOs;
523}
524
525static GLuint crStateFramebufferTextureCheck(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level,
526 CRFBOAttachmentPoint **aap, CRTextureObj **tobj)
527{
528 CRContext *g = GetCurrentContext();
529 CRFramebufferObjectState *fbo = &g->framebufferobject;
530 CRFramebufferObject *apFBOs[2];
531 GLuint cFBOs = 0, i;
532 GLuint maxtexsizelog2;
533
534 CRSTATE_CHECKERR_RET(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end", 0);
535 CRSTATE_CHECKERR_RET(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
536 GL_INVALID_ENUM, "invalid target", 0);
537
538 cFBOs = crStateFramebufferGet(fbo, target, apFBOs);
539 CRSTATE_CHECKERR_RET(!cFBOs, GL_INVALID_ENUM, "unexpected target", 0);
540 for (i = 0; i < cFBOs; ++i)
541 {
542 CRSTATE_CHECKERR_RET(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound", 0);
543 }
544
545 Assert(cFBOs);
546 Assert(cFBOs <= 2);
547
548 for (i = 0; i < cFBOs; ++i)
549 {
550 CRSTATE_CHECKERR_RET(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &aap[i]), GL_INVALID_ENUM, "invalid attachment", 0);
551 }
552
553 if (!texture)
554 {
555 return cFBOs;
556 }
557
558 switch (textarget)
559 {
560 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
561 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
562 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
563 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
564 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
565 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
566 maxtexsizelog2 = crLog2Floor(g->limits.maxCubeMapTextureSize);
567 *tobj = crStateTextureGet(GL_TEXTURE_CUBE_MAP_ARB, texture);
568 break;
569 case GL_TEXTURE_RECTANGLE_ARB:
570 maxtexsizelog2 = 0;
571 *tobj = crStateTextureGet(textarget, texture);
572 break;
573 case GL_TEXTURE_3D:
574 maxtexsizelog2 = crLog2Floor(g->limits.max3DTextureSize);
575 *tobj = crStateTextureGet(textarget, texture);
576 break;
577 case GL_TEXTURE_2D:
578 case GL_TEXTURE_1D:
579 maxtexsizelog2 = crLog2Floor(g->limits.maxTextureSize);
580 *tobj = crStateTextureGet(textarget, texture);
581 break;
582 default:
583 CRSTATE_CHECKERR_RET(GL_TRUE, GL_INVALID_OPERATION, "invalid textarget", 0);
584 }
585
586 CRSTATE_CHECKERR_RET(!*tobj, GL_INVALID_OPERATION, "invalid textarget/texture combo", 0);
587
588 if (GL_TEXTURE_RECTANGLE_ARB==textarget)
589 {
590 CRSTATE_CHECKERR_RET(level!=0, GL_INVALID_VALUE, "non zero mipmap level", 0);
591 }
592
593 CRSTATE_CHECKERR_RET(level<0, GL_INVALID_VALUE, "level<0", 0);
594 CRSTATE_CHECKERR_RET(level>maxtexsizelog2, GL_INVALID_VALUE, "level too big", 0);
595
596#ifdef IN_GUEST
597 for (i = 0; i < cFBOs; ++i)
598 {
599 if ((aap[i])->type!=GL_TEXTURE || (aap[i])->name!=texture || (aap[i])->level!=level)
600 {
601 apFBOs[i]->status = GL_FRAMEBUFFER_UNDEFINED;
602 }
603 }
604#endif
605
606 Assert(cFBOs);
607 Assert(cFBOs <= 2);
608
609 return cFBOs;
610}
611
612DECLEXPORT(void) STATE_APIENTRY
613crStateFramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
614{
615 CRContext *g = GetCurrentContext();
616 CRFramebufferObjectState *fbo = &g->framebufferobject;
617 CRFBOAttachmentPoint *aap[2];
618 GLuint cap, i;
619 CRTextureObj *tobj;
620
621 cap = crStateFramebufferTextureCheck(target, attachment, textarget, texture, level, aap, &tobj);
622 if (!cap) return;
623
624 if (!texture)
625 {
626 for (i = 0; i < cap; ++i)
627 {
628 crStateInitFBOAttachmentPoint(aap[i]);
629 }
630 return;
631 }
632
633 CRSTATE_CHECKERR(textarget!=GL_TEXTURE_1D, GL_INVALID_OPERATION, "textarget");
634
635 CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g);
636
637 for (i = 0; i < cap; ++i)
638 {
639 crStateInitFBOAttachmentPoint(aap[i]);
640 aap[i]->type = GL_TEXTURE;
641 aap[i]->name = texture;
642 aap[i]->level = level;
643 }
644}
645
646DECLEXPORT(void) STATE_APIENTRY
647crStateFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
648{
649 CRContext *g = GetCurrentContext();
650 CRFramebufferObjectState *fbo = &g->framebufferobject;
651 CRFBOAttachmentPoint *aap[2];
652 GLuint cap, i;
653 CRTextureObj *tobj;
654
655 cap = crStateFramebufferTextureCheck(target, attachment, textarget, texture, level, aap, &tobj);
656 if (!cap) return;
657
658 if (!texture)
659 {
660 for (i = 0; i < cap; ++i)
661 {
662 crStateInitFBOAttachmentPoint(aap[i]);
663 }
664 return;
665 }
666
667 CRSTATE_CHECKERR(GL_TEXTURE_1D==textarget || GL_TEXTURE_3D==textarget, GL_INVALID_OPERATION, "textarget");
668
669 CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g);
670
671 for (i = 0; i < cap; ++i)
672 {
673 crStateInitFBOAttachmentPoint(aap[i]);
674 aap[i]->type = GL_TEXTURE;
675 aap[i]->name = texture;
676 aap[i]->level = level;
677 if (textarget!=GL_TEXTURE_2D && textarget!=GL_TEXTURE_RECTANGLE_ARB)
678 {
679 aap[i]->face = textarget;
680 }
681 }
682}
683
684DECLEXPORT(void) STATE_APIENTRY
685crStateFramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
686{
687 CRContext *g = GetCurrentContext();
688 CRFramebufferObjectState *fbo = &g->framebufferobject;
689 CRFBOAttachmentPoint *aap[2];
690 GLuint cap, i;
691 CRTextureObj *tobj;
692
693 cap = crStateFramebufferTextureCheck(target, attachment, textarget, texture, level, aap, &tobj);
694 if (!cap) return;
695
696 if (!texture)
697 {
698 for (i = 0; i < cap; ++i)
699 {
700 crStateInitFBOAttachmentPoint(aap[i]);
701 }
702 return;
703 }
704
705 CRSTATE_CHECKERR(zoffset>(g->limits.max3DTextureSize-1), GL_INVALID_VALUE, "zoffset too big");
706 CRSTATE_CHECKERR(textarget!=GL_TEXTURE_3D, GL_INVALID_OPERATION, "textarget");
707
708 CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g);
709
710 for (i = 0; i < cap; ++i)
711 {
712 crStateInitFBOAttachmentPoint(aap[i]);
713 aap[i]->type = GL_TEXTURE;
714 aap[i]->name = texture;
715 aap[i]->level = level;
716 aap[i]->zoffset = zoffset;
717 }
718}
719
720DECLEXPORT(void) STATE_APIENTRY
721crStateFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
722{
723 CRContext *g = GetCurrentContext();
724 CRFramebufferObjectState *fbo = &g->framebufferobject;
725 CRFramebufferObject *apFBOs[2];
726 GLuint cFBOs, i;
727 CRFBOAttachmentPoint *aap[2];
728 CRRenderbufferObject *rb;
729
730 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
731 CRSTATE_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
732 GL_INVALID_ENUM, "invalid target");
733 cFBOs = crStateFramebufferGet(fbo, target, apFBOs);
734 CRSTATE_CHECKERR(!cFBOs, GL_INVALID_OPERATION, "no fbo bound");
735 for (i = 0; i < cFBOs; ++i)
736 {
737 CRSTATE_CHECKERR(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound");
738 }
739
740 for (i = 0; i < cFBOs; ++i)
741 {
742 CRSTATE_CHECKERR(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &aap[i]), GL_INVALID_ENUM, "invalid attachment");
743 }
744
745 if (!renderbuffer)
746 {
747 for (i = 0; i < cFBOs; ++i)
748 {
749#ifdef IN_GUEST
750 if (&aap[i]->type!=GL_NONE)
751 {
752 apFBOs[i]->status = GL_FRAMEBUFFER_UNDEFINED;
753 }
754#endif
755 crStateInitFBOAttachmentPoint(aap[i]);
756 }
757 return;
758 }
759
760 rb = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffer);
761 if (!rb)
762 {
763 CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->rbTable, renderbuffer), GL_INVALID_OPERATION, "rb doesn't exist");
764 rb = crStateRenderbufferAllocate(g, renderbuffer);
765 }
766
767 CR_STATE_SHAREDOBJ_USAGE_SET(rb, g);
768
769 for (i = 0; i < cFBOs; ++i)
770 {
771#ifdef IN_GUEST
772 if (aap[i]->type!=GL_RENDERBUFFER_EXT || aap[i]->name!=renderbuffer)
773 {
774 apFBOs[i]->status = GL_FRAMEBUFFER_UNDEFINED;
775 }
776#endif
777 crStateInitFBOAttachmentPoint(aap[i]);
778 aap[i]->type = GL_RENDERBUFFER_EXT;
779 aap[i]->name = renderbuffer;
780 }
781}
782
783DECLEXPORT(void) STATE_APIENTRY
784crStateGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params)
785{
786 CRContext *g = GetCurrentContext();
787 CRFramebufferObjectState *fbo = &g->framebufferobject;
788 CRFramebufferObject *apFBOs[2];
789 GLint cFBOs = 0, i;
790 CRFBOAttachmentPoint *ap;
791
792 CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
793 CRSTATE_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
794 GL_INVALID_ENUM, "invalid target");
795
796 cFBOs = crStateFramebufferGet(fbo, target, apFBOs);
797
798 CRSTATE_CHECKERR(!cFBOs, GL_INVALID_OPERATION, "no fbo bound");
799 for (i = 0; i < cFBOs; ++i)
800 {
801 CRSTATE_CHECKERR(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound");
802 }
803
804 if(cFBOs != 1)
805 {
806 crWarning("different FBPs attached to draw and read buffers, returning info for the read buffer");
807 }
808
809 for (i = 0; i < 1; ++i)
810 {
811 CRSTATE_CHECKERR(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
812
813 switch (pname)
814 {
815 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
816 *params = ap->type;
817 break;
818 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
819 CRSTATE_CHECKERR(ap->type!=GL_RENDERBUFFER_EXT && ap->type!=GL_TEXTURE, GL_INVALID_ENUM, "can't query object name when it's not bound")
820 *params = ap->name;
821 break;
822 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
823 CRSTATE_CHECKERR(ap->type!=GL_TEXTURE, GL_INVALID_ENUM, "not a texture");
824 *params = ap->level;
825 break;
826 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
827 CRSTATE_CHECKERR(ap->type!=GL_TEXTURE, GL_INVALID_ENUM, "not a texture");
828 *params = ap->face;
829 break;
830 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
831 CRSTATE_CHECKERR(ap->type!=GL_TEXTURE, GL_INVALID_ENUM, "not a texture");
832 *params = ap->zoffset;
833 break;
834 default:
835 CRSTATE_CHECKERR(GL_TRUE, GL_INVALID_ENUM, "invalid pname");
836 }
837 }
838}
839
840DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsFramebufferEXT( GLuint framebuffer )
841{
842 CRContext *g = GetCurrentContext();
843
844 FLUSH();
845
846 if (g->current.inBeginEnd) {
847 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
848 "glIsFramebufferEXT called in begin/end");
849 return GL_FALSE;
850 }
851
852 return framebuffer ? crHashtableIsKeyUsed(g->shared->fbTable, framebuffer) : GL_FALSE;
853}
854
855DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsRenderbufferEXT( GLuint renderbuffer )
856{
857 CRContext *g = GetCurrentContext();
858
859
860 FLUSH();
861
862 if (g->current.inBeginEnd) {
863 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
864 "glIsRenderbufferEXT called in begin/end");
865 return GL_FALSE;
866 }
867
868 return renderbuffer ? crHashtableIsKeyUsed(g->shared->rbTable, renderbuffer) : GL_FALSE;
869}
870
871DECLEXPORT(void) STATE_APIENTRY
872crStateGenerateMipmapEXT(GLenum target)
873{
874 /*@todo*/
875}
876
877static void crStateSyncRenderbuffersCB(unsigned long key, void *data1, void *data2)
878{
879 CRRenderbufferObject *pRBO = (CRRenderbufferObject*) data1;
880
881 diff_api.GenRenderbuffersEXT(1, &pRBO->hwid);
882
883 if (pRBO->width && pRBO->height)
884 {
885 diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, pRBO->hwid);
886 diff_api.RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, pRBO->internalformat, pRBO->width, pRBO->height);
887 }
888}
889
890static void crStateSyncAP(CRFBOAttachmentPoint *pAP, GLenum ap, CRContext *ctx)
891{
892 CRRenderbufferObject *pRBO;
893 CRTextureObj *tobj;
894
895 switch (pAP->type)
896 {
897 case GL_TEXTURE:
898 CRASSERT(pAP->name!=0);
899
900 tobj = (CRTextureObj *) crHashtableSearch(ctx->shared->textureTable, pAP->name);
901 if (tobj)
902 {
903 CRASSERT(!tobj->id || tobj->hwid);
904
905 switch (tobj->target)
906 {
907 case GL_TEXTURE_1D:
908 diff_api.FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, ap, tobj->target, crStateGetTextureObjHWID(tobj), pAP->level);
909 break;
910 case GL_TEXTURE_2D:
911 case GL_TEXTURE_RECTANGLE_ARB:
912 diff_api.FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ap, tobj->target, crStateGetTextureObjHWID(tobj), pAP->level);
913 break;
914 case GL_TEXTURE_CUBE_MAP_ARB:
915 diff_api.FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ap, pAP->face, crStateGetTextureObjHWID(tobj), pAP->level);
916 break;
917 case GL_TEXTURE_3D:
918 diff_api.FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, ap, tobj->target, crStateGetTextureObjHWID(tobj), pAP->level, pAP->zoffset);
919 break;
920 default:
921 crWarning("Unexpected textarget %d", tobj->target);
922 }
923 }
924 else
925 {
926 crWarning("Unknown texture id %d", pAP->name);
927 }
928 break;
929 case GL_RENDERBUFFER_EXT:
930 pRBO = (CRRenderbufferObject*) crHashtableSearch(ctx->shared->rbTable, pAP->name);
931 diff_api.FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, ap, GL_RENDERBUFFER_EXT, pRBO->hwid);
932 break;
933 case GL_NONE:
934 /* Intentionally left blank */
935 break;
936 default: crWarning("Invalid attachment point type %d (ap: %i)", pAP->type, ap);
937 }
938}
939
940static void crStateSyncFramebuffersCB(unsigned long key, void *data1, void *data2)
941{
942 CRFramebufferObject *pFBO = (CRFramebufferObject*) data1;
943 CRContext *ctx = (CRContext*) data2;
944 GLint i;
945
946 diff_api.GenFramebuffersEXT(1, &pFBO->hwid);
947
948 diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, pFBO->hwid);
949
950 for (i=0; i<CR_MAX_COLOR_ATTACHMENTS; ++i)
951 {
952 crStateSyncAP(&pFBO->color[i], GL_COLOR_ATTACHMENT0_EXT+i, ctx);
953 }
954
955 crStateSyncAP(&pFBO->depth, GL_DEPTH_ATTACHMENT_EXT, ctx);
956 crStateSyncAP(&pFBO->stencil, GL_STENCIL_ATTACHMENT_EXT, ctx);
957}
958
959DECLEXPORT(void) STATE_APIENTRY
960crStateFramebufferObjectSwitch(CRContext *from, CRContext *to)
961{
962 if (to->shared->bFBOResyncNeeded)
963 {
964 to->shared->bFBOResyncNeeded = GL_FALSE;
965
966 crHashtableWalk(to->shared->rbTable, crStateSyncRenderbuffersCB, NULL);
967 crHashtableWalk(to->shared->fbTable, crStateSyncFramebuffersCB, to);
968
969 if (to->framebufferobject.drawFB==to->framebufferobject.readFB)
970 {
971 diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.drawFB?
972 to->framebufferobject.drawFB->hwid:0);
973 }
974 else
975 {
976 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB?
977 to->framebufferobject.drawFB->hwid:0);
978
979 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB?
980 to->framebufferobject.readFB->hwid:0);
981 }
982
983 diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, to->framebufferobject.renderbuffer?
984 to->framebufferobject.renderbuffer->hwid:0);
985 }
986 else
987 {
988 if (to->framebufferobject.drawFB!=from->framebufferobject.drawFB
989 || to->framebufferobject.readFB!=from->framebufferobject.readFB)
990 {
991 if (to->framebufferobject.drawFB==to->framebufferobject.readFB)
992 {
993 diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.drawFB?
994 to->framebufferobject.drawFB->hwid:0);
995 }
996 else
997 {
998 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB?
999 to->framebufferobject.drawFB->hwid:0);
1000
1001 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB?
1002 to->framebufferobject.readFB->hwid:0);
1003 }
1004
1005 diff_api.DrawBuffer(to->framebufferobject.drawFB?to->framebufferobject.drawFB->drawbuffer[0]:to->buffer.drawBuffer);
1006 diff_api.ReadBuffer(to->framebufferobject.readFB?to->framebufferobject.readFB->readbuffer:to->buffer.readBuffer);
1007 }
1008
1009 if (to->framebufferobject.renderbuffer!=from->framebufferobject.renderbuffer)
1010 {
1011 diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, to->framebufferobject.renderbuffer?
1012 to->framebufferobject.renderbuffer->hwid:0);
1013 }
1014 }
1015}
1016
1017DECLEXPORT(void) STATE_APIENTRY
1018crStateFramebufferObjectDisableHW(CRContext *ctx, GLuint idDrawFBO, GLuint idReadFBO)
1019{
1020 GLenum idDrawBuffer = 0, idReadBuffer = 0;
1021
1022 if (ctx->framebufferobject.drawFB || idDrawFBO)
1023 {
1024 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
1025 idDrawBuffer = ctx->buffer.drawBuffer;
1026 }
1027
1028 if (ctx->framebufferobject.readFB || idReadFBO)
1029 {
1030 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
1031 idReadBuffer = ctx->buffer.readBuffer;
1032 }
1033
1034 if (idDrawBuffer)
1035 diff_api.DrawBuffer(idDrawBuffer);
1036 if (idReadBuffer)
1037 diff_api.ReadBuffer(idReadBuffer);
1038
1039 if (ctx->framebufferobject.renderbuffer)
1040 diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1041}
1042
1043DECLEXPORT(void) STATE_APIENTRY
1044crStateFramebufferObjectReenableHW(CRContext *fromCtx, CRContext *toCtx, GLuint idDrawFBO, GLuint idReadFBO)
1045{
1046 GLuint idReadBuffer = 0, idDrawBuffer = 0;
1047 if (!fromCtx)
1048 fromCtx = toCtx; /* <- in case fromCtx is zero, set it to toCtx to ensure framebuffer state gets re-enabled correctly */
1049
1050 if ((fromCtx->framebufferobject.drawFB) /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
1051 && fromCtx->framebufferobject.drawFB == toCtx->framebufferobject.drawFB) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
1052 {
1053 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, toCtx->framebufferobject.drawFB->hwid);
1054 idDrawBuffer = toCtx->framebufferobject.drawFB->drawbuffer[0];
1055 }
1056 else if (idDrawFBO && !toCtx->framebufferobject.drawFB)
1057 {
1058 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, idDrawFBO);
1059 idDrawBuffer = GL_COLOR_ATTACHMENT0;
1060 }
1061
1062 if ((fromCtx->framebufferobject.readFB) /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
1063 && fromCtx->framebufferobject.readFB == toCtx->framebufferobject.readFB) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
1064 {
1065 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, toCtx->framebufferobject.readFB->hwid);
1066 idReadBuffer = toCtx->framebufferobject.readFB->readbuffer;
1067 }
1068 else if (idReadFBO && !toCtx->framebufferobject.readFB)
1069 {
1070 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, idReadFBO);
1071 idReadBuffer = GL_COLOR_ATTACHMENT0;
1072 }
1073
1074 if (idDrawBuffer)
1075 diff_api.DrawBuffer(idDrawBuffer);
1076 if (idReadBuffer)
1077 diff_api.ReadBuffer(idReadBuffer);
1078
1079 if (fromCtx->framebufferobject.renderbuffer /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
1080 && fromCtx->framebufferobject.renderbuffer==toCtx->framebufferobject.renderbuffer) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
1081 {
1082 diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, toCtx->framebufferobject.renderbuffer->hwid);
1083 }
1084}
1085
1086
1087DECLEXPORT(GLuint) STATE_APIENTRY crStateGetFramebufferHWID(GLuint id)
1088{
1089 CRContext *g = GetCurrentContext();
1090 CRFramebufferObject *pFBO = (CRFramebufferObject*) crHashtableSearch(g->shared->fbTable, id);
1091#if 0 //def DEBUG_misha
1092 crDebug("FB id(%d) hw(%d)", id, pFBO ? pFBO->hwid : 0);
1093#endif
1094 return pFBO ? pFBO->hwid : 0;
1095}
1096
1097DECLEXPORT(GLuint) STATE_APIENTRY crStateGetRenderbufferHWID(GLuint id)
1098{
1099 CRContext *g = GetCurrentContext();
1100 CRRenderbufferObject *pRBO = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, id);
1101
1102 return pRBO ? pRBO->hwid : 0;
1103}
1104
1105static void crStateCheckFBOHWIDCB(unsigned long key, void *data1, void *data2)
1106{
1107 CRFramebufferObject *pFBO = (CRFramebufferObject *) data1;
1108 crCheckIDHWID_t *pParms = (crCheckIDHWID_t*) data2;
1109 (void) key;
1110
1111 if (pFBO->hwid==pParms->hwid)
1112 pParms->id = pFBO->id;
1113}
1114
1115static void crStateCheckRBOHWIDCB(unsigned long key, void *data1, void *data2)
1116{
1117 CRRenderbufferObject *pRBO = (CRRenderbufferObject *) data1;
1118 crCheckIDHWID_t *pParms = (crCheckIDHWID_t*) data2;
1119 (void) key;
1120
1121 if (pRBO->hwid==pParms->hwid)
1122 pParms->id = pRBO->id;
1123}
1124
1125DECLEXPORT(GLuint) STATE_APIENTRY crStateFBOHWIDtoID(GLuint hwid)
1126{
1127 CRContext *g = GetCurrentContext();
1128 crCheckIDHWID_t parms;
1129
1130 parms.id = hwid;
1131 parms.hwid = hwid;
1132
1133 crHashtableWalk(g->shared->fbTable, crStateCheckFBOHWIDCB, &parms);
1134 return parms.id;
1135}
1136
1137DECLEXPORT(GLuint) STATE_APIENTRY crStateRBOHWIDtoID(GLuint hwid)
1138{
1139 CRContext *g = GetCurrentContext();
1140 crCheckIDHWID_t parms;
1141
1142 parms.id = hwid;
1143 parms.hwid = hwid;
1144
1145 crHashtableWalk(g->shared->rbTable, crStateCheckRBOHWIDCB, &parms);
1146 return parms.id;
1147}
1148
1149#ifdef IN_GUEST
1150DECLEXPORT(GLenum) STATE_APIENTRY crStateCheckFramebufferStatusEXT(GLenum target)
1151{
1152 GLenum status = GL_FRAMEBUFFER_UNDEFINED;
1153 CRContext *g = GetCurrentContext();
1154 CRFramebufferObjectState *fbo = &g->framebufferobject;
1155 CRFramebufferObject *pFBO=NULL;
1156
1157 switch (target)
1158 {
1159 case GL_FRAMEBUFFER_EXT:
1160 pFBO = fbo->drawFB;
1161 break;
1162 case GL_READ_FRAMEBUFFER:
1163 pFBO = fbo->readFB;
1164 break;
1165 case GL_DRAW_FRAMEBUFFER:
1166 pFBO = fbo->drawFB;
1167 break;
1168 }
1169
1170 if (pFBO) status = pFBO->status;
1171
1172 return status;
1173}
1174
1175DECLEXPORT(GLenum) STATE_APIENTRY crStateSetFramebufferStatus(GLenum target, GLenum status)
1176{
1177 CRContext *g = GetCurrentContext();
1178 CRFramebufferObjectState *fbo = &g->framebufferobject;
1179 CRFramebufferObject *pFBO=NULL;
1180
1181 switch (target)
1182 {
1183 case GL_FRAMEBUFFER_EXT:
1184 pFBO = fbo->drawFB;
1185 break;
1186 case GL_READ_FRAMEBUFFER:
1187 pFBO = fbo->readFB;
1188 break;
1189 case GL_DRAW_FRAMEBUFFER:
1190 pFBO = fbo->drawFB;
1191 break;
1192 }
1193
1194 if (pFBO) pFBO->status = status;
1195
1196 return status;
1197}
1198#endif
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