void * PACKSPU_APIENTRY
packspu_MapBufferARB( GLenum target, GLenum access )
{
    GET_CONTEXT(ctx);
    void *buffer;
    CRBufferObject *pBufObj;

    CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
    buffer = crStateMapBufferARB(target, access);

#ifdef CR_ARB_pixel_buffer_object
    if (buffer)
    {
        pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
        CRASSERT(pBufObj);

        if (pBufObj->bResyncOnRead && 
            access != GL_WRITE_ONLY_ARB)
        {
            /*fetch data from host side*/
            packspu_GetHostBufferSubDataARB(target, 0, pBufObj->size, buffer);
        }
    }
#endif

    return buffer;
}
예제 #2
0
void STATE_APIENTRY
crStateGetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferPointervARB called in begin/end");
        return;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetBufferPointervARB(target)");
        return;
    }

    if (pname != GL_BUFFER_MAP_POINTER_ARB) {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetBufferPointervARB(pname)");
        return;
    }

    *params = obj->pointer;
}
예제 #3
0
void STATE_APIENTRY
crStateBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;
    CRStateBits *sb = GetCurrentBits();
    CRBufferObjectBits *bb = &sb->bufferobject;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferSubDataARB called in begin/end");
        return;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glBufferSubDataARB(target)");
        return;
    }

    if (obj->id == 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferSubDataARB");
        return;
    }

    if (obj->pointer) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferSubDataARB(buffer is mapped)");
        return;
    }

    if (size < 0 || offset < 0 || (unsigned int)offset + size > obj->size) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferSubDataARB(bad offset and/or size)");
        return;
    }

    if (b->retainBufferData && obj->data) {
        crMemcpy((char *) obj->data + offset, data, size);
    }

    DIRTY(bb->dirty, g->neg_bitid);
    DIRTY(obj->dirty, g->neg_bitid);
    /* grow dirty region */
    if (offset + size > obj->dirtyStart + obj->dirtyLength)
        obj->dirtyLength = offset + size;
    if (offset < obj->dirtyStart)
        obj->dirtyStart = offset;
}
예제 #4
0
GLboolean STATE_APIENTRY
crStateUnmapBufferARB(GLenum target)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;
    CRStateBits *sb = GetCurrentBits();
    CRBufferObjectBits *bb = &sb->bufferobject;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glUnmapBufferARB called in begin/end");
        return GL_FALSE;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glUnmapBufferARB(target)");
        return GL_FALSE;
    }

    if (obj->id == 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glUnmapBufferARB");
        return GL_FALSE;
    }

    if (!obj->pointer) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glUnmapBufferARB");
        return GL_FALSE;
    }

    obj->pointer = NULL;

    if (obj->access != GL_READ_ONLY_ARB) {
        /* the data was most likely modified */
        DIRTY(bb->dirty, g->neg_bitid);
        DIRTY(obj->dirty, g->neg_bitid);
        obj->dirtyStart = 0;
        obj->dirtyLength = obj->size;
    }

    return GL_TRUE;
}
void PACKSPU_APIENTRY packspu_GetBufferSubDataARB( GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data )
{
    GET_CONTEXT(ctx);

#ifdef CR_ARB_pixel_buffer_object
    CRBufferObject *pBufObj;

    pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);

    if (pBufObj && pBufObj->bResyncOnRead)
    {
        packspu_GetHostBufferSubDataARB(target, offset, size, data);
        return;
    }
#endif
    
    crStateGetBufferSubDataARB(target, offset, size, data);
}
예제 #6
0
void * STATE_APIENTRY
crStateMapBufferARB(GLenum target, GLenum access)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glMapBufferARB called in begin/end");
        return NULL;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMapBufferARB(target)");
        return NULL;
    }

    if (obj->id == 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glMapBufferARB");
        return GL_FALSE;
    }

    switch (access) {
        case GL_READ_ONLY_ARB:
        case GL_WRITE_ONLY_ARB:
        case GL_READ_WRITE_ARB:
            obj->access = access;
            break;
        default:
            crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
                                     "glMapBufferARB(access)");
            return NULL;
    }

    if (b->retainBufferData && obj->data)
        obj->pointer = obj->data;

    return obj->pointer;
}
예제 #7
0
void STATE_APIENTRY
crStateGetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferSubDataARB called in begin/end");
        return;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetBufferSubDataARB(target)");
        return;
    }

    if (obj->id == 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferSubDataARB");
        return;
    }

    if (obj->pointer) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferSubDataARB(buffer is mapped)");
        return;
    }

    if (size < 0 || offset < 0 || (unsigned int)offset + size > obj->size) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferSubDataARB(bad offset and/or size)");
        return;
    }

    if (b->retainBufferData && obj->data) {
        crMemcpy(data, (char *) obj->data + offset, size);
    }
}
GLboolean PACKSPU_APIENTRY
packspu_UnmapBufferARB( GLenum target )
{
    GET_CONTEXT(ctx);

#if CR_ARB_vertex_buffer_object
    CRBufferObject *bufObj;

    bufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);

    /* send new buffer contents to server */
    crPackBufferDataARB( target, bufObj->size, bufObj->pointer, bufObj->usage );
#endif

    CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
    crStateUnmapBufferARB( target );

    return GL_TRUE;
}
예제 #9
0
void STATE_APIENTRY
crStateGetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glGetBufferParameterivARB called in begin/end");
        return;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetBufferParameterivARB(target)");
        return;
    }

    switch (pname) {
        case GL_BUFFER_SIZE_ARB:
            *params = obj->size;
            break;
        case GL_BUFFER_USAGE_ARB:
            *params = obj->usage;
            break;
        case GL_BUFFER_ACCESS_ARB:
            *params = obj->access;
            break;
        case GL_BUFFER_MAPPED_ARB:
            *params = (obj->pointer != NULL);
            break;
        default:
            crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
                                     "glGetBufferParameterivARB(pname)");
            return;
    }
}
예제 #10
0
void STATE_APIENTRY
crStateBindBufferARB (GLenum target, GLuint buffer)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &(g->bufferobject);
    CRStateBits *sb = GetCurrentBits();
    CRBufferObjectBits *bb = &(sb->bufferobject);
    CRBufferObject *oldObj, *newObj;

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBindBufferARB called in begin/end");
        return;
    }

    FLUSH();

    oldObj = crStateGetBoundBufferObject(target, b);
    if (!oldObj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glBindBufferARB(target)");
        return;
    }

    if (buffer == 0) {
        newObj = b->nullBuffer;
    }
    else {
        newObj = (CRBufferObject *) crHashtableSearch(g->shared->buffersTable, buffer);
        if (!newObj) {
            CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->buffersTable, buffer), GL_INVALID_OPERATION, "name is not a buffer object");
            newObj = AllocBufferObject(buffer);
            CRSTATE_CHECKERR(!newObj, GL_OUT_OF_MEMORY, "glBindBuffer");
#ifndef IN_GUEST
            diff_api.GenBuffersARB(1, &newObj->hwid);
            if (!newObj->hwid)
            {
                crWarning("GenBuffersARB failed!");
                crFree(newObj);
                return;
            }
#endif
            crHashtableAdd( g->shared->buffersTable, buffer, newObj );
        }

        CR_STATE_SHAREDOBJ_USAGE_SET(newObj, g);
    }

    newObj->refCount++;
    oldObj->refCount--;

    switch (target)
    {
        case GL_ARRAY_BUFFER_ARB:
            b->arrayBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->arrayBinding, g->neg_bitid);
            break;
        case GL_ELEMENT_ARRAY_BUFFER_ARB:
            b->elementsBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->elementsBinding, g->neg_bitid);
            break;
#ifdef CR_ARB_pixel_buffer_object
        case GL_PIXEL_PACK_BUFFER_ARB:
            b->packBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->packBinding, g->neg_bitid);
            break;
        case GL_PIXEL_UNPACK_BUFFER_ARB:
            b->unpackBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->unpackBinding, g->neg_bitid);
            break;
#endif
        default: /*can't get here*/
            CRASSERT(false);
            return;
    }

    if (oldObj->refCount <= 0) {
        /*we shouldn't reach this point*/
        CRASSERT(false);
        crHashtableDelete(g->shared->buffersTable, (unsigned long) oldObj->id, crStateFreeBufferObject);
    }

#ifdef IN_GUEST
    if (target == GL_PIXEL_PACK_BUFFER_ARB)
    {
        newObj->bResyncOnRead = GL_TRUE;
    }
#endif
}
예제 #11
0
void STATE_APIENTRY
crStateBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;
    CRBufferObject *obj;
    CRStateBits *sb = GetCurrentBits();
    CRBufferObjectBits *bb = &sb->bufferobject;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferDataARB called in begin/end");
        return;
    }

    if (size < 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
                                 "glBufferDataARB(size < 0)");
        return;
    }

    switch (usage) {
        case GL_STREAM_DRAW_ARB:
        case GL_STREAM_READ_ARB:
        case GL_STREAM_COPY_ARB:
        case GL_STATIC_DRAW_ARB:
        case GL_STATIC_READ_ARB:
        case GL_STATIC_COPY_ARB:
        case GL_DYNAMIC_DRAW_ARB:
        case GL_DYNAMIC_READ_ARB:
        case GL_DYNAMIC_COPY_ARB:
            /* OK */
            break;
        default:
            crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
                                     "glBufferDataARB(usage)");
            return;
    }

    obj = crStateGetBoundBufferObject(target, b);
    if (!obj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glBufferDataARB(target)");
        return;
    }

    if (obj->id == 0) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glBufferDataARB");
        return;
    }

    if (obj->pointer) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBufferDataARB(buffer is mapped)");
        return;
    }

    obj->usage = usage;
    obj->size = size;

    /* The user of the state tracker should set the retainBufferData field
     * during context initialization, if needed.
     */
    if (b->retainBufferData) {
        if (obj->data) {
            crFree(obj->data);
        }

        obj->data = crAlloc(size);
        if (!obj->data) {
            crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBufferDataARB");
            return;
        }
        if (data)
            crMemcpy(obj->data, data, size);
    }

    DIRTY(bb->dirty, g->neg_bitid);
    DIRTY(obj->dirty, g->neg_bitid);
    obj->dirtyStart = 0;
    obj->dirtyLength = size;
}