diff options
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c')
| -rw-r--r-- | src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c | 218 |
1 files changed, 125 insertions, 93 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c index 5a3d2e49..bd6a1e20 100644 --- a/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c +++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c @@ -22,16 +22,25 @@ static CRBufferObject *AllocBufferObject(GLuint name) b->usage = GL_STATIC_DRAW_ARB; b->access = GL_READ_WRITE_ARB; b->bResyncOnRead = GL_FALSE; -#ifndef IN_GUEST CR_STATE_SHAREDOBJ_USAGE_INIT(b); -#endif } return b; } -GLboolean crStateIsBufferBound(GLenum target) +void STATE_APIENTRY crStateGenBuffersARB(GLsizei n, GLuint *buffers) +{ + CRContext *g = GetCurrentContext(); + crStateGenNames(g, g->shared->buffersTable, n, buffers); +} + +void crStateRegBuffers(GLsizei n, GLuint *buffers) { CRContext *g = GetCurrentContext(); + crStateRegNames(g, g->shared->buffersTable, n, buffers); +} + +GLboolean crStateIsBufferBoundForCtx(CRContext *g, GLenum target) +{ CRBufferObjectState *b = &(g->bufferobject); switch (target) @@ -51,6 +60,12 @@ GLboolean crStateIsBufferBound(GLenum target) } } +GLboolean crStateIsBufferBound(GLenum target) +{ + CRContext *g = GetCurrentContext(); + return crStateIsBufferBoundForCtx(g, target); +} + CRBufferObject *crStateGetBoundBufferObject(GLenum target, CRBufferObjectState *b) { switch (target) @@ -70,6 +85,21 @@ CRBufferObject *crStateGetBoundBufferObject(GLenum target, CRBufferObjectState * } } +DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsBufferARB( GLuint buffer ) +{ + CRContext *g = GetCurrentContext(); + + FLUSH(); + + if (g->current.inBeginEnd) { + crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, + "glIsBufferARB called in begin/end"); + return GL_FALSE; + } + + return buffer ? crHashtableIsKeyUsed(g->shared->buffersTable, buffer) : GL_FALSE; +} + void crStateBufferObjectInit (CRContext *ctx) { CRStateBits *sb = GetCurrentBits(); @@ -93,7 +123,7 @@ void crStateBufferObjectInit (CRContext *ctx) b->nullBuffer = AllocBufferObject(0); b->arrayBuffer = b->nullBuffer; b->elementsBuffer = b->nullBuffer; - b->nullBuffer->refCount = 3; + b->nullBuffer->refCount += 2; #ifdef CR_ARB_pixel_buffer_object b->packBuffer = b->nullBuffer; b->unpackBuffer = b->nullBuffer; @@ -184,17 +214,22 @@ crStateBindBufferARB (GLenum target, GLuint buffer) 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); - if (!newObj) { - crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBindBuffer"); + 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 ); } -#ifndef IN_GUEST CR_STATE_SHAREDOBJ_USAGE_SET(newObj, g); -#endif } newObj->refCount++; @@ -243,127 +278,124 @@ crStateBindBufferARB (GLenum target, GLuint buffer) #endif } -void STATE_APIENTRY -crStateDeleteBuffersARB(GLsizei n, const GLuint *buffers) +static void ctStateBuffersRefsCleanup(CRContext *ctx, CRBufferObject *obj, CRbitvalue *neg_bitid) { - CRContext *g = GetCurrentContext(); - CRBufferObjectState *b = &(g->bufferobject); + CRBufferObjectState *b = &(ctx->bufferobject); CRStateBits *sb = GetCurrentBits(); CRBufferObjectBits *bb = &(sb->bufferobject); - int i; + int j, k; - FLUSH(); - - if (g->current.inBeginEnd) { - crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, - "glDeleteBuffersARB called in Begin/End"); - return; + if (obj == b->arrayBuffer) + { + b->arrayBuffer = b->nullBuffer; + b->arrayBuffer->refCount++; + DIRTY(bb->dirty, neg_bitid); + DIRTY(bb->arrayBinding, neg_bitid); } - - if (n < 0) { - crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, - "glDeleteBuffersARB(n < 0)"); - return; + if (obj == b->elementsBuffer) + { + b->elementsBuffer = b->nullBuffer; + b->elementsBuffer->refCount++; + DIRTY(bb->dirty, neg_bitid); + DIRTY(bb->elementsBinding, neg_bitid); } - - for (i = 0; i < n; i++) { - if (buffers[i]) { - CRBufferObject *obj = (CRBufferObject *) - crHashtableSearch(g->shared->buffersTable, buffers[i]); - if (obj) { - if (obj == b->arrayBuffer) - { - b->arrayBuffer = b->nullBuffer; - b->arrayBuffer->refCount++; - DIRTY(bb->dirty, g->neg_bitid); - DIRTY(bb->arrayBinding, g->neg_bitid); - } - else if (obj == b->elementsBuffer) - { - b->elementsBuffer = b->nullBuffer; - b->elementsBuffer->refCount++; - DIRTY(bb->dirty, g->neg_bitid); - DIRTY(bb->elementsBinding, g->neg_bitid); - } #ifdef CR_ARB_pixel_buffer_object - else if (obj == b->packBuffer) - { - b->packBuffer = b->nullBuffer; - b->packBuffer->refCount++; - DIRTY(bb->dirty, g->neg_bitid); - DIRTY(bb->packBinding, g->neg_bitid); - } - else if (obj == b->unpackBuffer) - { - b->unpackBuffer = b->nullBuffer; - b->unpackBuffer->refCount++; - DIRTY(bb->dirty, g->neg_bitid); - DIRTY(bb->unpackBinding, g->neg_bitid); - } + if (obj == b->packBuffer) + { + b->packBuffer = b->nullBuffer; + b->packBuffer->refCount++; + DIRTY(bb->dirty, neg_bitid); + DIRTY(bb->packBinding, neg_bitid); + } + if (obj == b->unpackBuffer) + { + b->unpackBuffer = b->nullBuffer; + b->unpackBuffer->refCount++; + DIRTY(bb->dirty, neg_bitid); + DIRTY(bb->unpackBinding, neg_bitid); + } #endif - /* @todo check bindings with the vertex arrays */ - crHashtableDelete(g->shared->buffersTable, buffers[i], crStateFreeBufferObject); +#ifdef CR_ARB_vertex_buffer_object + for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j) + { + CRClientPointer *cp = crStateGetClientPointerByIndex(j, &ctx->client.array); + if (obj == cp->buffer) + { + cp->buffer = b->nullBuffer; + ++b->nullBuffer->refCount; + } + } + + for (k=0; k<ctx->client.vertexArrayStackDepth; ++k) + { + CRVertexArrays *pArray = &ctx->client.vertexArrayStack[k]; + for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j) + { + CRClientPointer *cp = crStateGetClientPointerByIndex(j, pArray); + if (obj == cp->buffer) + { + cp->buffer = b->nullBuffer; + ++b->nullBuffer->refCount; } } } -} +#endif + CR_STATE_SHAREDOBJ_USAGE_CLEAR(obj, ctx); +} void STATE_APIENTRY -crStateGenBuffersARB(GLsizei n, GLuint * buffers) +crStateDeleteBuffersARB(GLsizei n, const GLuint *buffers) { CRContext *g = GetCurrentContext(); - CRBufferObjectState *b = &(g->bufferobject); - GLint start; + int i; FLUSH(); if (g->current.inBeginEnd) { crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, - "glGenBuffersARB called in Begin/End"); + "glDeleteBuffersARB called in Begin/End"); return; } if (n < 0) { crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, - "glGenBuffersARB(n < 0)"); + "glDeleteBuffersARB(n < 0)"); return; } - start = crHashtableAllocKeys(g->shared->buffersTable, n); - if (start) { - GLint i; - for (i = 0; i < n; i++) - buffers[i] = (GLuint) (start + i); - } - else { - crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glGenBuffersARB"); - } -} - + for (i = 0; i < n; i++) { + if (buffers[i]) { + CRBufferObject *obj = (CRBufferObject *) + crHashtableSearch(g->shared->buffersTable, buffers[i]); + if (obj) { + int j; -GLboolean STATE_APIENTRY -crStateIsBufferARB(GLuint buffer) -{ - CRContext *g = GetCurrentContext(); - CRBufferObjectState *b = &g->bufferobject; + ctStateBuffersRefsCleanup(g, obj, g->neg_bitid); - FLUSH(); + CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(obj, j) + { + /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info, + * so on restore, we set mark bits as used. + * This is why g_pAvailableContexts[j] could be NULL + * also g_pAvailableContexts[0] will hold default context, which we should discard */ + CRContext *ctx = g_pAvailableContexts[j]; + if (j && ctx) + { + ctStateBuffersRefsCleanup(ctx, obj, g->neg_bitid); /* <- yes, use g->neg_bitid, i.e. neg_bitid of the current context to ensure others bits get dirtified, + * but not the current context ones*/ + } + else + CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(obj, j); + } - if (g->current.inBeginEnd) { - crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, - "glIsBufferARB called in begin/end"); - return GL_FALSE; + crHashtableDelete(g->shared->buffersTable, buffers[i], crStateFreeBufferObject); + } + } } - - if (buffer && crHashtableSearch(g->shared->buffersTable, buffer)) - return GL_TRUE; - else - return GL_FALSE; } - void STATE_APIENTRY crStateBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage) { |
