Polymost: Refactor all GL internal texture format decision making into uploadtexture().

This directly achieves the following:
* Eliminated codedup.
* Recently introduced GL ES performance downsampling now applies to model skins.
* Replaces the alpha/art format distinction with {RGB/no alpha, RGBA/one-bit alpha (ART transparency), RGBA/full alpha}.
* Cleanly allows multiple fallback formats for each type.
* Ready for further commits.

git-svn-id: https://svn.eduke32.com/eduke32@5642 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2016-02-29 06:34:20 +00:00
parent aec2da83cd
commit 506e89fefb
3 changed files with 91 additions and 62 deletions

View file

@ -29,7 +29,7 @@ struct glfiltermodes {
extern struct glfiltermodes glfiltermodes[NUMGLFILTERMODES]; extern struct glfiltermodes glfiltermodes[NUMGLFILTERMODES];
//void phex(char v, char *s); //void phex(char v, char *s);
void uploadtexture(int32_t doalloc, vec2_t siz, int32_t intexfmt, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth); void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth);
void polymost_drawsprite(int32_t snum); void polymost_drawsprite(int32_t snum);
void polymost_drawmaskwall(int32_t damaskwallcnt); void polymost_drawmaskwall(int32_t damaskwallcnt);
void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
@ -157,12 +157,20 @@ enum {
DAMETH_NODOWNSIZE = 4096, DAMETH_NODOWNSIZE = 4096,
DAMETH_HI = 8192, DAMETH_HI = 8192,
DAMETH_NOFIX = 16384, DAMETH_NOFIX = 16384,
DAMETH_NOTEXCOMPRESS = 32768,
DAMETH_HASALPHA = 65536,
DAMETH_ONEBITALPHA = 131072,
}; };
#define DAMETH_NARROW_MASKPROPS(dameth) (((dameth)&(~DAMETH_TRANS1))|(((dameth)&DAMETH_TRANS1)>>1)) #define DAMETH_NARROW_MASKPROPS(dameth) (((dameth)&(~DAMETH_TRANS1))|(((dameth)&DAMETH_TRANS1)>>1))
EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_MASKPROPS) == DAMETH_MASK); EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_MASKPROPS) == DAMETH_MASK);
EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_CLAMPED) == DAMETH_CLAMPED); EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_CLAMPED) == DAMETH_CLAMPED);
#define TO_DAMETH_NODOWNSIZE(hicr_flags) (((hicr_flags)&HICR_NODOWNSIZE)<<8)
EDUKE32_STATIC_ASSERT(TO_DAMETH_NODOWNSIZE(HICR_NODOWNSIZE) == DAMETH_NODOWNSIZE);
#define TO_DAMETH_NOTEXCOMPRESS(hicr_flags) (((hicr_flags)&HICR_NOTEXCOMPRESS)<<15)
EDUKE32_STATIC_ASSERT(TO_DAMETH_NOTEXCOMPRESS(HICR_NOTEXCOMPRESS) == DAMETH_NOTEXCOMPRESS);
// Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>? // Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>?
static inline int polymost_want_npotytex(int32_t dameth, int32_t ysiz) static inline int polymost_want_npotytex(int32_t dameth, int32_t ysiz)
{ {

View file

@ -739,7 +739,7 @@ static inline int32_t hicfxmask(int32_t pal)
//Note: even though it says md2model, it works for both md2model&md3model //Note: even though it says md2model, it works for both md2model&md3model
int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf) int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
{ {
int32_t i, bpl, osizx, osizy, texfmt = GL_RGBA, intexfmt = GL_RGBA; int32_t i, bpl, osizx, osizy;
char *skinfile, hasalpha, fn[BMAX_PATH]; char *skinfile, hasalpha, fn[BMAX_PATH];
GLuint *texidx = NULL; GLuint *texidx = NULL;
mdskinmap_t *sk, *skzero = NULL; mdskinmap_t *sk, *skzero = NULL;
@ -850,7 +850,7 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
{ {
osizx = cachead.xdim; osizx = cachead.xdim;
osizy = cachead.ydim; osizy = cachead.ydim;
hasalpha = (cachead.flags & CACHEAD_HASALPHA) ? 1 : 0; hasalpha = !!(cachead.flags & CACHEAD_HASALPHA);
if (pal < (MAXPALOOKUPS - RESERVEDPALS)) if (pal < (MAXPALOOKUPS - RESERVEDPALS))
m->usesalpha = hasalpha; m->usesalpha = hasalpha;
//kclose(filh); // FIXME: uncomment when cache1d.c is fixed //kclose(filh); // FIXME: uncomment when cache1d.c is fixed
@ -889,18 +889,15 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
bglBindTexture(GL_TEXTURE_2D, *texidx); bglBindTexture(GL_TEXTURE_2D, *texidx);
//gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr); //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr);
#if !defined EDUKE32_GLES
if (glinfo.texcompr && glusetexcompr && !(sk->flags & HICR_NOTEXCOMPRESS))
intexfmt = hasalpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB;
else
#endif
if (!hasalpha)
intexfmt = GL_RGB;
if (glinfo.bgra) int32_t const texfmt = glinfo.bgra ? GL_BGRA : GL_RGBA;
texfmt = GL_BGRA;
uploadtexture((doalloc&1), siz, texfmt, (coltype *)fptr, siz,
DAMETH_HI |
TO_DAMETH_NODOWNSIZE(sk->flags) |
TO_DAMETH_NOTEXCOMPRESS(sk->flags) |
(hasalpha ? DAMETH_HASALPHA : 0));
uploadtexture((doalloc&1), siz, intexfmt, texfmt, (coltype *)fptr, siz, DAMETH_HI | (sk->flags & HICR_NODOWNSIZE ? DAMETH_NODOWNSIZE : 0));
Bfree((void *)fptr); Bfree((void *)fptr);
} }

View file

@ -134,14 +134,6 @@ int32_t r_parallaxskypanning = 0;
#define MIN_CACHETIME_PRINT 10 #define MIN_CACHETIME_PRINT 10
#ifdef EDUKE32_GLES
int32_t texfmt_art = GL_RGB5_A1;
int32_t texfmt_alpha = GL_RGBA4;
#else
int32_t texfmt_art = GL_RGBA;
int32_t texfmt_alpha = GL_RGBA;
#endif
// this was faster in MSVC but slower with GCC... currently unknown on ARM where both // this was faster in MSVC but slower with GCC... currently unknown on ARM where both
// the FPU and possibly the optimization path in the compiler need improvement // the FPU and possibly the optimization path in the compiler need improvement
#if 0 #if 0
@ -646,14 +638,62 @@ static void fixtransparency(coltype *dapic, vec2_t dasiz, vec2_t dasiz2, int32_t
} }
} }
void uploadtexture(int32_t doalloc, vec2_t siz, int32_t intexfmt, int32_t texfmt, #if defined EDUKE32_GLES
// sorted first in increasing order of size, then in decreasing order of quality
static int32_t const texfmts_rgb_mask[] = { GL_RGB5_A1, GL_RGBA, 0 };
static int32_t const texfmts_rgb[] = { GL_RGB565, GL_RGB5_A1, GL_RGB, GL_RGBA, 0 };
static int32_t const texfmts_rgba[] = { GL_RGBA4, GL_RGBA, 0 } ;
static int32_t const *texfmt_rgb_mask = texfmts_rgb_mask;
static int32_t const *texfmt_rgb = texfmts_rgb;
static int32_t const *texfmt_rgba = texfmts_rgba;
static int32_t polymost_glTexImage2D_error(int32_t * intexfmt, int32_t const **intexfmt_master)
{
GLenum err;
while ((err = bglGetError()) != GL_NO_ERROR)
{
if ((*intexfmt = *++*intexfmt_master) == 0)
{
initprintf("No texture formats supported (error 0x%X).\n", err);
Bfflush(NULL);
uninitengine();
Bexit(565);
}
return 1;
}
return 0;
}
#else
# define polymost_glTexImage2D_error(...) (0)
#endif
void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt,
coltype *pic, vec2_t tsiz, int32_t dameth) coltype *pic, vec2_t tsiz, int32_t dameth)
{ {
const int hi = !!(dameth & DAMETH_HI); const int hi = !!(dameth & DAMETH_HI);
const int nodownsize = !!(dameth & DAMETH_NODOWNSIZE); const int nodownsize = !!(dameth & DAMETH_NODOWNSIZE);
const int nomiptransfix = !!(dameth & DAMETH_NOFIX); const int nomiptransfix = !!(dameth & DAMETH_NOFIX);
const int hasalpha = !!(dameth & DAMETH_HASALPHA) && (dameth & DAMETH_MASKPROPS) != DAMETH_NOMASK;
dameth &= ~(DAMETH_HI|DAMETH_NODOWNSIZE|DAMETH_NOFIX); dameth &= ~(DAMETH_HI|DAMETH_NODOWNSIZE|DAMETH_NOFIX|DAMETH_NOTEXCOMPRESS|DAMETH_HASALPHA|DAMETH_ONEBITALPHA);
#if !defined EDUKE32_GLES
const int texcompress_ok = !(dameth & DAMETH_NOTEXCOMPRESS);
int32_t intexfmt;
if (glinfo.texcompr && glusetexcompr && texcompress_ok)
intexfmt = hasalpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB;
else
intexfmt = hasalpha ? GL_RGBA : GL_RGB;
#else
const int onebitalpha = !!(dameth & DAMETH_ONEBITALPHA);
int32_t const ** intexfmt_master = hasalpha ? (onebitalpha ? &texfmt_rgb_mask : &texfmt_rgba) : &texfmt_rgb;
int32_t intexfmt = **intexfmt_master;
#endif
if (gltexmaxsize <= 0) if (gltexmaxsize <= 0)
{ {
@ -679,20 +719,15 @@ void uploadtexture(int32_t doalloc, vec2_t siz, int32_t intexfmt, int32_t texfmt
if (!miplevel) if (!miplevel)
{ {
redo: BuildGLErrorCheck(); // XXX
if (doalloc&1) do
bglTexImage2D(GL_TEXTURE_2D,0,intexfmt,siz.x,siz.y,0,texfmt,GL_UNSIGNED_BYTE,pic); //loading 1st time
else
bglTexSubImage2D(GL_TEXTURE_2D,0,0,0,siz.x,siz.y,texfmt,GL_UNSIGNED_BYTE,pic); //overwrite old texture
if (bglGetError() != GL_NO_ERROR)
{ {
if (intexfmt == GL_RGB5_A1) if (doalloc&1)
texfmt_art = intexfmt = GL_RGB; bglTexImage2D(GL_TEXTURE_2D,0,intexfmt,siz.x,siz.y,0,texfmt,GL_UNSIGNED_BYTE,pic); //loading 1st time
else if (intexfmt == GL_RGBA4) else
texfmt_alpha = intexfmt = GL_RGBA; bglTexSubImage2D(GL_TEXTURE_2D,0,0,0,siz.x,siz.y,texfmt,GL_UNSIGNED_BYTE,pic); //overwrite old texture
goto redo;
} }
while (polymost_glTexImage2D_error(&intexfmt, intexfmt_master));
} }
vec2_t siz2 = siz; vec2_t siz2 = siz;
@ -746,20 +781,15 @@ redo:
if (j >= miplevel) if (j >= miplevel)
{ {
redo_mip: BuildGLErrorCheck(); // XXX
if (doalloc & 1) // loading 1st time do
bglTexImage2D(GL_TEXTURE_2D, j - miplevel, intexfmt, siz3.x, siz3.y, 0, texfmt, GL_UNSIGNED_BYTE, pic);
else // overwrite old texture
bglTexSubImage2D(GL_TEXTURE_2D, j - miplevel, 0, 0, siz3.x, siz3.y, texfmt, GL_UNSIGNED_BYTE, pic);
if (bglGetError() != GL_NO_ERROR)
{ {
if (intexfmt == GL_RGB5_A1) if (doalloc & 1) // loading 1st time
texfmt_art = intexfmt = GL_RGB; bglTexImage2D(GL_TEXTURE_2D, j - miplevel, intexfmt, siz3.x, siz3.y, 0, texfmt, GL_UNSIGNED_BYTE, pic);
else if (intexfmt == GL_RGBA4) else // overwrite old texture
texfmt_alpha = intexfmt = GL_RGBA; bglTexSubImage2D(GL_TEXTURE_2D, j - miplevel, 0, 0, siz3.x, siz3.y, texfmt, GL_UNSIGNED_BYTE, pic);
goto redo_mip;
} }
while (polymost_glTexImage2D_error(&intexfmt, intexfmt_master));
} }
siz2 = siz3; siz2 = siz3;
@ -971,8 +1001,9 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
npoty = PTH_NPOTWALL; npoty = PTH_NPOTWALL;
} }
uploadtexture(doalloc, siz, hasalpha && texfmt_art == GL_RGBA ? GL_RGB : texfmt_art, uploadtexture(doalloc, siz, GL_RGBA, pic, tsiz,
GL_RGBA, pic, tsiz, dameth | DAMETH_NOFIX); dameth | DAMETH_NOFIX | DAMETH_NOTEXCOMPRESS |
(hasalpha ? (DAMETH_HASALPHA|DAMETH_ONEBITALPHA) : 0));
Bfree(pic); Bfree(pic);
@ -1008,7 +1039,7 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
coltype *pic = NULL; coltype *pic = NULL;
char *fn; char *fn;
int32_t picfillen, intexfmt = GL_RGBA, filh; int32_t picfillen, filh;
int32_t startticks=0, willprint=0; int32_t startticks=0, willprint=0;
@ -1246,24 +1277,17 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y)
hicr->flags |= (HICR_NODOWNSIZE + HICR_NOTEXCOMPRESS); hicr->flags |= (HICR_NODOWNSIZE + HICR_NOTEXCOMPRESS);
#if !defined EDUKE32_GLES
if (glinfo.texcompr && glusetexcompr && !(hicr->flags & HICR_NOTEXCOMPRESS))
intexfmt = (hasalpha == 255) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB;
else
if (hasalpha == 255) intexfmt = GL_RGB;
#else
if (hasalpha == 255) intexfmt = texfmt_art;
else intexfmt = texfmt_alpha;
#endif
if ((doalloc&3)==1) if ((doalloc&3)==1)
bglGenTextures(1, &pth->glpic); //# of textures (make OpenGL allocate structure) bglGenTextures(1, &pth->glpic); //# of textures (make OpenGL allocate structure)
bglBindTexture(GL_TEXTURE_2D,pth->glpic); bglBindTexture(GL_TEXTURE_2D,pth->glpic);
fixtransparency(pic,tsiz,siz,dameth); fixtransparency(pic,tsiz,siz,dameth);
uploadtexture(doalloc,siz,intexfmt,texfmt,pic,tsiz, uploadtexture(doalloc,siz,texfmt,pic,tsiz,
dameth | DAMETH_HI | DAMETH_NOFIX | (hicr->flags & HICR_NODOWNSIZE ? DAMETH_NODOWNSIZE : 0)); dameth | DAMETH_HI | DAMETH_NOFIX |
TO_DAMETH_NODOWNSIZE(hicr->flags) |
TO_DAMETH_NOTEXCOMPRESS(hicr->flags) |
(hasalpha != 255 ? DAMETH_HASALPHA : 0));
} }
// precalculate scaling parameters for replacement // precalculate scaling parameters for replacement