VirtualBox

Ignore:
Timestamp:
Oct 12, 2009 1:46:26 PM (15 years ago)
Author:
vboxsync
Message:

crOpenGL: most changes to extend FBO support to ARB version

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c

    r23094 r23694  
    3838    CRFramebufferObjectState *fbo = &ctx->framebufferobject;
    3939
    40     fbo->framebuffer = NULL;
     40    fbo->readFB = NULL;
     41    fbo->drawFB = NULL;
    4142    fbo->renderbuffer = NULL;
    4243    fbo->framebuffers = crAllocHashtable();
     
    7879    CRFramebufferObjectState *fbo = &ctx->framebufferobject;
    7980
    80     fbo->framebuffer = NULL;
     81    fbo->readFB = NULL;
     82    fbo->drawFB = NULL;
    8183    fbo->renderbuffer = NULL;
    8284
     
    108110    }
    109111    else fbo->renderbuffer = NULL;
     112}
     113
     114static void crStateCheckFBOAttachments(CRFramebufferObject *pFBO, GLuint rbo, GLenum target)
     115{
     116    CRFBOAttachmentPoint *ap;
     117    int u;
     118
     119    if (!pFBO)
     120        return;
     121
     122    for (u=0; u<CR_MAX_COLOR_ATTACHMENTS; ++u)
     123    {
     124        ap = &pFBO->color[u];
     125        if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
     126        {
     127            crStateFramebufferRenderbufferEXT(target, u+GL_COLOR_ATTACHMENT0_EXT, 0, 0);
     128#ifdef IN_GUEST
     129            pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     130#endif
     131        }
     132    }
     133
     134    ap = &pFBO->depth;
     135    if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
     136    {
     137        crStateFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT_EXT, 0, 0);
     138#ifdef IN_GUEST
     139        pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     140#endif
     141    }
     142    ap = &pFBO->stencil;
     143    if (ap->type==GL_RENDERBUFFER_EXT && ap->name==rbo)
     144    {
     145        crStateFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT_EXT, 0, 0);
     146#ifdef IN_GUEST
     147        pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     148#endif
     149    }
    110150}
    111151
     
    133173                }
    134174
    135                 /* check the attachments of current framebuffer */
    136                 if (fbo->framebuffer)
    137                 {
    138                     CRFBOAttachmentPoint *ap;
    139                     int u;
    140 
    141                     for (u=0; u<CR_MAX_COLOR_ATTACHMENTS; ++u)
    142                     {
    143                         ap = &fbo->framebuffer->color[u];
    144                         if (ap->type==GL_RENDERBUFFER_EXT && ap->name==renderbuffers[i])
    145                         {
    146                             crStateFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, u+GL_COLOR_ATTACHMENT0_EXT, 0, 0);
    147                         }
    148                     }
    149 
    150                     ap = &fbo->framebuffer->depth;
    151                     if (ap->type==GL_RENDERBUFFER_EXT && ap->name==renderbuffers[i])
    152                     {
    153                         crStateFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 0, 0);
    154                     }
    155                     ap = &g->framebufferobject.framebuffer->stencil;
    156                     if (ap->type==GL_RENDERBUFFER_EXT && ap->name==renderbuffers[i])
    157                     {
    158                         crStateFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, 0, 0);
    159                     }
    160                 }
     175                /* check the attachments of current framebuffers */
     176                crStateCheckFBOAttachments(fbo->readFB, renderbuffers[i], GL_READ_FRAMEBUFFER);
     177                crStateCheckFBOAttachments(fbo->drawFB, renderbuffers[i], GL_DRAW_FRAMEBUFFER);
    161178
    162179                crHashtableDelete(fbo->renderbuffers, renderbuffers[i], crStateFreeRBO);
     
    238255    fbo->readbuffer = GL_COLOR_ATTACHMENT0_EXT;
    239256    fbo->drawbuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
     257
     258#ifdef IN_GUEST
     259    fbo->status = GL_FRAMEBUFFER_UNDEFINED;
     260#endif
    240261}
    241262
     
    266287    CRContext *g = GetCurrentContext();
    267288    CRFramebufferObjectState *fbo = &g->framebufferobject;
     289    CRFramebufferObject *pFBO=NULL;
    268290
    269291    CRSTATE_FBO_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
    270     CRSTATE_FBO_CHECKERR(target!=GL_FRAMEBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
     292    CRSTATE_FBO_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
     293                         GL_INVALID_ENUM, "invalid target");
    271294
    272295    if (framebuffer)
    273296    {
    274         fbo->framebuffer = (CRFramebufferObject*) crHashtableSearch(fbo->framebuffers, framebuffer);
    275         if (!fbo->framebuffer)
    276         {
    277             fbo->framebuffer = (CRFramebufferObject*) crCalloc(sizeof(CRFramebufferObject));
    278             CRSTATE_FBO_CHECKERR(!fbo->framebuffer, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
    279             fbo->framebuffer->id = framebuffer;
    280             fbo->framebuffer->hwid = framebuffer;
    281             crStateInitFrameBuffer(fbo->framebuffer);
    282             crHashtableAdd(fbo->framebuffers, framebuffer, fbo->framebuffer);
    283         }
    284     }
    285     else fbo->framebuffer = NULL;
     297        pFBO = (CRFramebufferObject*) crHashtableSearch(fbo->framebuffers, framebuffer);
     298        if (!pFBO)
     299        {
     300            pFBO = (CRFramebufferObject*) crCalloc(sizeof(CRFramebufferObject));
     301            CRSTATE_FBO_CHECKERR(!pFBO, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
     302            pFBO->id = framebuffer;
     303            pFBO->hwid = framebuffer;
     304            crStateInitFrameBuffer(pFBO);
     305            crHashtableAdd(fbo->framebuffers, framebuffer, pFBO);
     306        }
     307    }
     308
     309    /* @todo: http://www.opengl.org/registry/specs/ARB/framebuffer_object.txt
     310     * FBO status might change when binding a different FBO here...but I doubt it happens.
     311     * So no status reset here until a proper check.
     312     */
     313
     314    switch (target)
     315    {
     316        case GL_FRAMEBUFFER_EXT:
     317            fbo->readFB = pFBO;
     318            fbo->drawFB = pFBO;
     319            break;
     320        case GL_READ_FRAMEBUFFER:
     321            fbo->readFB = pFBO;
     322            break;
     323        case GL_DRAW_FRAMEBUFFER:
     324            fbo->drawFB = pFBO;
     325            break;
     326    }
    286327}
    287328
     
    304345            if (fb)
    305346            {
    306                 if (fbo->framebuffer==fb)
     347                if (fbo->readFB==fb)
    307348                {
    308                     fbo->framebuffer = NULL;
     349                    fbo->readFB = NULL;
     350                }
     351                if (fbo->drawFB==fb)
     352                {
     353                    fbo->drawFB = NULL;
    309354                }
    310355                crHashtableDelete(fbo->framebuffers, framebuffers[i], crStateFreeFBO);
     
    336381    CRContext *g = GetCurrentContext();
    337382    CRFramebufferObjectState *fbo = &g->framebufferobject;
     383    CRFramebufferObject *pFBO;
    338384    GLuint maxtexsizelog2;
    339385
     
    341387
    342388    CRSTATE_FBO_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
    343     CRSTATE_FBO_CHECKERR(target!=GL_FRAMEBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
    344     CRSTATE_FBO_CHECKERR(!fbo->framebuffer, GL_INVALID_OPERATION, "no fbo bound");
    345     CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(fbo->framebuffer, attachment, ap), GL_INVALID_ENUM, "invalid attachment");
     389    CRSTATE_FBO_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
     390                         GL_INVALID_ENUM, "invalid target");
     391    pFBO = GL_READ_FRAMEBUFFER==target ? fbo->readFB : fbo->drawFB;
     392    CRSTATE_FBO_CHECKERR(!pFBO, GL_INVALID_OPERATION, "no fbo bound");
     393    CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(pFBO, attachment, ap), GL_INVALID_ENUM, "invalid attachment");
    346394
    347395    if (!texture)
     
    390438
    391439    *failed = GL_FALSE;
     440
     441#ifdef IN_GUEST
     442    if ((*ap)->type!=GL_TEXTURE || (*ap)->name!=texture || (*ap)->level!=level)
     443    {
     444        pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     445    }
     446#endif
    392447}
    393448
     
    481536    CRContext *g = GetCurrentContext();
    482537    CRFramebufferObjectState *fbo = &g->framebufferobject;
     538    CRFramebufferObject *pFBO;
    483539    CRFBOAttachmentPoint *ap;
    484540    CRRenderbufferObject *rb;
    485541
    486542    CRSTATE_FBO_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
    487     CRSTATE_FBO_CHECKERR(target!=GL_FRAMEBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
    488     CRSTATE_FBO_CHECKERR(!fbo->framebuffer, GL_INVALID_OPERATION, "no fbo bound");
    489     CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(fbo->framebuffer, attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
     543    CRSTATE_FBO_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
     544                         GL_INVALID_ENUM, "invalid target");
     545    pFBO = GL_READ_FRAMEBUFFER==target ? fbo->readFB : fbo->drawFB;
     546    CRSTATE_FBO_CHECKERR(!pFBO, GL_INVALID_OPERATION, "no fbo bound");
     547    CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(pFBO, attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
    490548
    491549    if (!renderbuffer)
    492550    {
     551#ifdef IN_GUEST
     552        if (ap->type!=GL_NONE)
     553        {
     554            pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     555        }
     556#endif
    493557        crStateInitFBOAttachmentPoint(ap);
    494558        return;
     
    498562    CRSTATE_FBO_CHECKERR(!rb, GL_INVALID_OPERATION, "rb doesn't exist");
    499563
     564#ifdef IN_GUEST
     565        if (ap->type!=GL_RENDERBUFFER_EXT || ap->name!=renderbuffer)
     566        {
     567            pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
     568        }
     569#endif
    500570    crStateInitFBOAttachmentPoint(ap);
    501571    ap->type = GL_RENDERBUFFER_EXT;
     
    508578    CRContext *g = GetCurrentContext();
    509579    CRFramebufferObjectState *fbo = &g->framebufferobject;
     580    CRFramebufferObject *pFBO;
    510581    CRFBOAttachmentPoint *ap;
    511582
    512583    CRSTATE_FBO_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
    513     CRSTATE_FBO_CHECKERR(target!=GL_FRAMEBUFFER_EXT, GL_INVALID_ENUM, "invalid target");
    514     CRSTATE_FBO_CHECKERR(!fbo->framebuffer, GL_INVALID_OPERATION, "no fbo bound");
    515     CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(fbo->framebuffer, attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
     584    CRSTATE_FBO_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
     585                         GL_INVALID_ENUM, "invalid target");
     586    pFBO = GL_READ_FRAMEBUFFER==target ? fbo->readFB : fbo->drawFB;
     587    CRSTATE_FBO_CHECKERR(!pFBO, GL_INVALID_OPERATION, "no fbo bound");
     588    CRSTATE_FBO_CHECKERR(!crStateGetFBOAttachmentPoint(pFBO, attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
    516589
    517590    switch (pname)
     
    634707        crHashtableWalk(to->framebufferobject.framebuffers, crStateSyncFramebuffersCB, to);
    635708
    636         diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.framebuffer?
    637             to->framebufferobject.framebuffer->hwid:0);
     709        if (to->framebufferobject.drawFB==to->framebufferobject.readFB)
     710        {
     711            diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.drawFB?
     712                to->framebufferobject.drawFB->hwid:0);
     713        }
     714        else
     715        {
     716            diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB?
     717                to->framebufferobject.drawFB->hwid:0);
     718
     719            diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB?
     720                to->framebufferobject.readFB->hwid:0);
     721        }
    638722
    639723        diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, to->framebufferobject.renderbuffer?
     
    642726    else
    643727    {
    644         if (to->framebufferobject.framebuffer!=from->framebufferobject.framebuffer)
    645         {
    646             diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.framebuffer?
    647                 to->framebufferobject.framebuffer->hwid:0);
     728        if (to->framebufferobject.drawFB!=from->framebufferobject.drawFB
     729            || to->framebufferobject.readFB!=from->framebufferobject.readFB)
     730        {
     731            if (to->framebufferobject.drawFB==to->framebufferobject.readFB)
     732            {
     733                diff_api.BindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->framebufferobject.drawFB?
     734                    to->framebufferobject.drawFB->hwid:0);
     735            }
     736            else
     737            {
     738                diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB?
     739                    to->framebufferobject.drawFB->hwid:0);
     740
     741                diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB?
     742                    to->framebufferobject.readFB->hwid:0);
     743            }
    648744        }
    649745
     
    671767    return pRBO ? pRBO->hwid : 0;
    672768}
     769
     770#ifdef IN_GUEST
     771DECLEXPORT(GLenum) STATE_APIENTRY crStateCheckFramebufferStatusEXT(GLenum target)
     772{
     773    GLenum status = GL_FRAMEBUFFER_UNDEFINED;
     774    CRContext *g = GetCurrentContext();
     775    CRFramebufferObjectState *fbo = &g->framebufferobject;
     776    CRFramebufferObject *pFBO=NULL;
     777
     778    switch (target)
     779    {
     780        case GL_FRAMEBUFFER_EXT:
     781            pFBO = fbo->drawFB;
     782            break;
     783        case GL_READ_FRAMEBUFFER:
     784            pFBO = fbo->readFB;
     785            break;
     786        case GL_DRAW_FRAMEBUFFER:
     787            pFBO = fbo->drawFB;
     788            break;
     789    }
     790
     791    if (pFBO) status = pFBO->status;
     792
     793    return status;
     794}
     795
     796DECLEXPORT(GLenum) STATE_APIENTRY crStateSetFramebufferStatus(GLenum target, GLenum status)
     797{
     798    CRContext *g = GetCurrentContext();
     799    CRFramebufferObjectState *fbo = &g->framebufferobject;
     800    CRFramebufferObject *pFBO=NULL;
     801
     802    switch (target)
     803    {
     804        case GL_FRAMEBUFFER_EXT:
     805            pFBO = fbo->drawFB;
     806            break;
     807        case GL_READ_FRAMEBUFFER:
     808            pFBO = fbo->readFB;
     809            break;
     810        case GL_DRAW_FRAMEBUFFER:
     811            pFBO = fbo->drawFB;
     812            break;
     813    }
     814
     815    if (pFBO) pFBO->status = status;
     816}
     817#endif
Note: See TracChangeset for help on using the changeset viewer.

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