VirtualBox

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

Last change on this file since 44125 was 44125, checked in by vboxsync, 12 years ago

crOpenGL: fix guest state bits

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