summaryrefslogtreecommitdiff
path: root/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c')
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c111
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)