From 2b286dab9187e2d2f4bce1c51f83a396f28c57c9 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 28 Dec 2009 14:03:46 +0000 Subject: [PATCH] exposed two more fields in rtexture_t, now texnum is always non-zero but there is a dirty flag, and there is a gltexturetypeenum for use by binding code eliminated internal flags GLTEXF_UPLOAD and GLTEXF_DESTROYED git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9723 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_textures.c | 59 ++++++++++++++++----------------------------------- r_textures.h | 4 +++- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/gl_textures.c b/gl_textures.c index 249ced51..e81ae041 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -28,12 +28,8 @@ int gl_filter_mag = GL_LINEAR; static mempool_t *texturemempool; // note: this must not conflict with TEXF_ flags in r_textures.h -// cleared when a texture is uploaded -#define GLTEXF_UPLOAD 0x00010000 // bitmask for mismatch checking #define GLTEXF_IMPORTANTBITS (0) -// set when image is uploaded and freed -#define GLTEXF_DESTROYED 0x00040000 // dynamic texture (treat texnum == 0 differently) #define GLTEXF_DYNAMIC 0x00080000 @@ -91,13 +87,13 @@ static int cubemapside[6] = typedef struct gltexture_s { - // this field is exposed to the R_GetTexture macro, for speed reasons - // (must be identical in rtexture_t) + // this portion of the struct is exposed to the R_GetTexture macro for + // speed reasons, must be identical in rtexture_t! int texnum; // GL texture slot number + qboolean dirty; // indicates that R_RealGetTexture should be called + int gltexturetypeenum; // used by R_Mesh_TexBind // dynamic texture stuff [11/22/2007 Black] - // used to hold the texture number of dirty textures - int dirtytexnum; updatecallback_t updatecallback; void *updatacallback_data; // --- [11/22/2007 Black] @@ -250,10 +246,10 @@ void R_MarkDirtyTexture(rtexture_t *rt) { } // dont do anything if the texture is already dirty (and make sure this *is* a dynamic texture after all!) - if( !glt->dirtytexnum && glt->flags & GLTEXF_DYNAMIC ) { - glt->dirtytexnum = glt->texnum; + if (glt->flags & GLTEXF_DYNAMIC) + { // mark it as dirty, so R_RealGetTexture gets called - glt->texnum = 0; + glt->dirty = true; } } @@ -266,14 +262,10 @@ void R_MakeTextureDynamic(rtexture_t *rt, updatecallback_t updatecallback, void glt->flags |= GLTEXF_DYNAMIC; glt->updatecallback = updatecallback; glt->updatacallback_data = data; - glt->dirtytexnum = 0; } static void R_UpdateDynamicTexture(gltexture_t *glt) { - glt->texnum = glt->dirtytexnum; - // reset dirtytexnum again (not dirty anymore) - glt->dirtytexnum = 0; - // TODO: now assert that t->texnum != 0 ? + glt->dirty = false; if( glt->updatecallback ) { glt->updatecallback( (rtexture_t*) glt, glt->updatacallback_data ); } @@ -300,7 +292,7 @@ void R_FreeTexture(rtexture_t *rt) else Host_Error("R_FreeTexture: texture \"%s\" not linked in pool", glt->identifier); - if (!(glt->flags & GLTEXF_UPLOAD)) + if (glt->texnum) { CHECKGLERROR qglDeleteTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR @@ -406,7 +398,7 @@ static void GL_TextureMode_f (void) for (glt = pool->gltchain;glt;glt = glt->chain) { // only update already uploaded images - if (!(glt->flags & (GLTEXF_UPLOAD | TEXF_FORCENEAREST | TEXF_FORCELINEAR))) + if (glt->texnum && !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR))) { oldbindtexnum = R_Mesh_TexBound(0, gltexturetypebindingenums[glt->texturetype]); qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR @@ -530,7 +522,7 @@ void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean print for (glt = pool->gltchain;glt;glt = glt->chain) { glsize = R_CalcTexelDataSize(glt); - isloaded = !(glt->flags & GLTEXF_UPLOAD); + isloaded = glt->texnum != 0; pooltotal++; pooltotalt += glsize; pooltotalp += glt->inputdatasize; @@ -662,7 +654,7 @@ void R_Textures_Frame (void) for (glt = pool->gltchain;glt;glt = glt->chain) { // only update already uploaded images - if ((glt->flags & (GLTEXF_UPLOAD | TEXF_MIPMAP)) == TEXF_MIPMAP) + if (glt->texnum && (glt->flags & TEXF_MIPMAP) == TEXF_MIPMAP) { oldbindtexnum = R_Mesh_TexBound(0, gltexturetypebindingenums[glt->texturetype]); @@ -821,7 +813,9 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int prevbuffer = colorconvertbuffer; } - if ((glt->flags & (TEXF_MIPMAP | TEXF_PICMIP | GLTEXF_UPLOAD)) == 0 && glt->inputwidth == glt->tilewidth && glt->inputheight == glt->tileheight && glt->inputdepth == glt->tiledepth && (fragx != 0 || fragy != 0 || fragwidth != glt->tilewidth || fragheight != glt->tileheight)) + // upload the image - preferring to do only complete uploads (drivers do not really like partial updates) + + if ((glt->flags & (TEXF_MIPMAP | TEXF_PICMIP)) == 0 && glt->inputwidth == glt->tilewidth && glt->inputheight == glt->tileheight && glt->inputdepth == glt->tiledepth && (fragx != 0 || fragy != 0 || fragwidth != glt->tilewidth || fragheight != glt->tileheight)) { // update a portion of the image switch(glt->texturetype) @@ -842,9 +836,6 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int if (fragx || fragy || fragz || glt->inputwidth != fragwidth || glt->inputheight != fragheight || glt->inputdepth != fragdepth) Host_Error("R_Upload: partial update not allowed on initial upload or in combination with PICMIP or MIPMAP\n"); - // upload the image for the first time - glt->flags &= ~GLTEXF_UPLOAD; - // cubemaps contain multiple images and thus get processed a bit differently if (glt->texturetype != GLTEXTURETYPE_CUBEMAP) { @@ -944,21 +935,6 @@ int R_RealGetTexture(rtexture_t *rt) glt = (gltexture_t *)rt; if (glt->flags & GLTEXF_DYNAMIC) R_UpdateDynamicTexture(glt); - if (glt->flags & GLTEXF_UPLOAD) - { - CHECKGLERROR - qglGenTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR - R_Upload(glt, glt->inputtexels, 0, 0, 0, glt->inputwidth, glt->inputheight, glt->inputdepth); - if (glt->inputtexels) - { - Mem_Free(glt->inputtexels); - glt->inputtexels = NULL; - glt->flags |= GLTEXF_DESTROYED; - } - else if (glt->flags & GLTEXF_DESTROYED) - Con_Printf("R_GetTexture: Texture %s already uploaded and destroyed. Can not upload original image again. Uploaded blank texture.\n", glt->identifier); - } - return glt->texnum; } else @@ -1055,7 +1031,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden glt->inputwidth = width; glt->inputheight = height; glt->inputdepth = depth; - glt->flags = flags | GLTEXF_UPLOAD; + glt->flags = flags; glt->textype = texinfo; glt->texturetype = texturetype; glt->inputdatasize = size; @@ -1066,8 +1042,9 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden glt->bytesperpixel = texinfo->internalbytesperpixel; glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1; glt->texnum = 0; + glt->dirty = false; + glt->gltexturetypeenum = gltexturetypeenums[glt->texturetype]; // init the dynamic texture attributes, too [11/22/2007 Black] - glt->dirtytexnum = 0; glt->updatecallback = NULL; glt->updatacallback_data = NULL; diff --git a/r_textures.h b/r_textures.h index 503163f8..63ce2222 100644 --- a/r_textures.h +++ b/r_textures.h @@ -49,6 +49,8 @@ typedef struct rtexture_s { // this is exposed (rather than private) for speed reasons only int texnum; + qboolean dirty; + int gltexturetypeenum; // exposed for use in R_Mesh_TexBind } rtexture_t; @@ -102,7 +104,7 @@ void R_FlushTexture(rtexture_t *rt); // returns the renderer dependent texture slot number (call this before each // use, as a texture might not have been precached) -#define R_GetTexture(rt) ((rt) ? ((rt)->texnum > 0 ? (rt)->texnum : R_RealGetTexture(rt)) : r_texture_white->texnum) +#define R_GetTexture(rt) ((rt) ? ((rt)->dirty ? R_RealGetTexture(rt) : (rt)->texnum) : r_texture_white->texnum) int R_RealGetTexture (rtexture_t *rt); // returns width of texture, as was specified when it was uploaded -- 2.39.2