diff options
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c')
| -rw-r--r-- | src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c | 111 |
1 files changed, 93 insertions, 18 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c index 951a0e55..5da27393 100644 --- a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c +++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c @@ -250,10 +250,8 @@ crStateTextureInitTextureObj(CRContext *ctx, CRTextureObj *tobj, RESET(tobj->paramsBit[i], ctx->bitid); } -#ifndef IN_GUEST CR_STATE_SHAREDOBJ_USAGE_INIT(tobj); CR_STATE_SHAREDOBJ_USAGE_SET(tobj, ctx); -#endif } @@ -620,9 +618,29 @@ crStateDeleteTextureObject(CRTextureObj *tobj) crFree(tobj); } -void STATE_APIENTRY crStateGenTextures(GLsizei n, GLuint *textures) +void crStateRegNames(CRContext *g, CRHashTable *table, GLsizei n, GLuint *names) +{ + GLint i; + for (i = 0; i < n; i++) + { + if (names[i]) + { + GLboolean isNewKey = crHashtableAllocRegisterKey(table, names[i]); + CRASSERT(isNewKey); + } + else + crWarning("RegNames: requested to register a null name"); + } +} + +void crStateRegTextures(GLsizei n, GLuint *names) { CRContext *g = GetCurrentContext(); + crStateRegNames(g, g->shared->textureTable, n, names); +} + +void crStateGenNames(CRContext *g, CRHashTable *table, GLsizei n, GLuint *names) +{ GLint start; FLUSH(); @@ -630,23 +648,23 @@ void STATE_APIENTRY crStateGenTextures(GLsizei n, GLuint *textures) if (g->current.inBeginEnd) { crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, - "glGenTextures called in Begin/End"); + "crStateGenNames called in Begin/End"); return; } if (n < 0) { crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, - "Negative n passed to glGenTextures: %d", n); + "Negative n passed to crStateGenNames: %d", n); return; } - start = crHashtableAllocKeys(g->shared->textureTable, n); + start = crHashtableAllocKeys(table, n); if (start) { GLint i; for (i = 0; i < n; i++) - textures[i] = (GLuint) (start + i); + names[i] = (GLuint) (start + i); } else { @@ -654,6 +672,12 @@ void STATE_APIENTRY crStateGenTextures(GLsizei n, GLuint *textures) } } +void STATE_APIENTRY crStateGenTextures(GLsizei n, GLuint *textures) +{ + CRContext *g = GetCurrentContext(); + crStateGenNames(g, g->shared->textureTable, n, textures); +} + static void crStateTextureCheckFBOAPs(GLenum target, GLuint texture) { GLuint u; @@ -730,6 +754,7 @@ static void crStateCleanupTextureRefs(CRContext *g, CRTextureObj *tObj) #endif } + CR_STATE_SHAREDOBJ_USAGE_CLEAR(tObj, g); } void STATE_APIENTRY crStateDeleteTextures(GLsizei n, const GLuint *textures) @@ -760,15 +785,39 @@ void STATE_APIENTRY crStateDeleteTextures(GLsizei n, const GLuint *textures) { GLuint name = textures[i]; CRTextureObj *tObj; + if (!name) + continue; + GET_TOBJ(tObj, g, name); - if (name && tObj) + if (tObj) { + GLuint j; + crStateCleanupTextureRefs(g, tObj); + CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(tObj, 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) + crStateCleanupTextureRefs(ctx, tObj); + else + CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(tObj, j); + } + /* on the host side, ogl texture object is deleted by a separate cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures); * in crServerDispatchDeleteTextures, we just delete a state object here, which crStateDeleteTextureObject does */ crHashtableDelete(g->shared->textureTable, name, (CRHashtableCallback)crStateDeleteTextureObject); } + else + { + /* call crHashtableDelete in any way, to ensure the allocated key is freed */ + Assert(crHashtableIsKeyUsed(g->shared->textureTable, name)); + crHashtableDelete(g->shared->textureTable, name, NULL); + } } DIRTY(tb->dirty, g->neg_bitid); @@ -858,8 +907,17 @@ DECLEXPORT(void) crStateSetTextureUsed(GLuint texture, GLboolean used) GET_TOBJ(tobj, g, texture); if (!tobj) { - crWarning("crStateSetTextureUsed: failed to fined a HW name for texture(%d)!", texture); - return; +#ifdef IN_GUEST + if (used) + { + tobj = crStateTextureAllocate_t(g, texture); + } + else +#endif + { + crWarning("crStateSetTextureUsed: failed to fined a HW name for texture(%d)!", texture); + return; + } } if (used) @@ -870,8 +928,6 @@ DECLEXPORT(void) crStateSetTextureUsed(GLuint texture, GLboolean used) CRTextureBits *tb = &(sb->texture); CRTextureState *t = &(g->texture); - CR_STATE_SHAREDOBJ_USAGE_CLEAR(tobj, g); - crStateCleanupTextureRefs(g, tobj); if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(tobj)) @@ -953,12 +1009,11 @@ void STATE_APIENTRY crStateBindTexture(GLenum target, GLuint texture) GET_TOBJ(tobj, g, texture); if (!tobj) { + Assert(crHashtableIsKeyUsed(g->shared->textureTable, texture)); tobj = crStateTextureAllocate_t(g, texture); } -#ifndef IN_GUEST CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g); -#endif /* Check the targets */ if (tobj->target == GL_NONE) @@ -3204,10 +3259,28 @@ void STATE_APIENTRY crStatePrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities) { - UNUSED(n); - UNUSED(textures); + CRContext *g = GetCurrentContext(); + CRTextureObj *tobj; + GLsizei i; UNUSED(priorities); - /* TODO: */ + + for (i = 0; i < n; ++i) + { + GLuint tex = textures[i]; + GET_TOBJ(tobj, g, tex); + if (!tobj) + { + Assert(crHashtableIsKeyUsed(g->shared->textureTable, tex)); + tobj = crStateTextureAllocate_t(g, tex); + } + + /* so far the code just ensures the tex object is created to make + * the crserverlib code be able to pass it to host ogl */ + + /* TODO: store texture priorities in the state data to be able to restore it properly + * on save state load */ + } + return; } @@ -3259,7 +3332,9 @@ DECLEXPORT(GLuint) STATE_APIENTRY crStateTextureHWIDtoID(GLuint hwid) DECLEXPORT(GLuint) STATE_APIENTRY crStateGetTextureHWID(GLuint id) { CRContext *g = GetCurrentContext(); - CRTextureObj *tobj = GET_TOBJ(tobj, g, id); + CRTextureObj *tobj; + + GET_TOBJ(tobj, g, id); #ifdef DEBUG_misha if (id) |
