From: divverent Date: Mon, 30 Jan 2012 21:39:54 +0000 (+0000) Subject: properly handle !vid.support.arb_texture_non_power_of_two in DDS upload (fixes segfau... X-Git-Tag: xonotic-v0.8.0~96^2~351 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ce130c7da8ce2c1cdf5e19d1823276c5ca5e83b5;p=xonotic%2Fdarkplaces.git properly handle !vid.support.arb_texture_non_power_of_two in DDS upload (fixes segfault with dpsoftrast in xonotic effects-low.cfg) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11662 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_textures.c b/gl_textures.c index cf6c768e..8dc1cae6 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -2167,7 +2167,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen unsigned char *dds; fs_offset_t ddsfilesize; unsigned int ddssize; - qboolean force_swdecode = (r_texture_dds_swdecode.integer > 1); + qboolean force_swdecode, npothack; if (cls.state == ca_dedicated) return NULL; @@ -2344,9 +2344,17 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen } force_swdecode = false; + npothack = + (!vid.support.arb_texture_non_power_of_two && + ( + (dds_width & (dds_width - 1)) + || + (dds_height & (dds_height - 1)) + ) + ); if(bytesperblock) { - if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc) + if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && !npothack) { if(r_texture_dds_swdecode.integer > 1) force_swdecode = true; @@ -2624,6 +2632,12 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen glt->tiledepth = 1; glt->miplevels = dds_miplevels; + if(npothack) + { + for (glt->tilewidth = 1;glt->tilewidth < mipwidth;glt->tilewidth <<= 1); + for (glt->tileheight = 1;glt->tileheight < mipheight;glt->tileheight <<= 1); + } + // texture uploading can take a while, so make sure we're sending keepalives CL_KeepaliveMessage(false); @@ -2678,9 +2692,19 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen for (mip = 0;mip <= dds_miplevels;mip++) // <= to include the not-counted "largest" miplevel { + unsigned char *upload_mippixels = mippixels; + int upload_mipwidth = mipwidth; + int upload_mipheight = mipheight; mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel; if (mippixels + mipsize > mippixels_start + mipsize_total) break; + if(npothack) + { + upload_mipwidth = (glt->tilewidth >> mip); + upload_mipheight = (glt->tileheight >> mip); + upload_mippixels = Mem_Alloc(tempmempool, 4 * upload_mipwidth * upload_mipheight); + Image_Resample32(mippixels, mipwidth, mipheight, 1, upload_mippixels, upload_mipwidth, upload_mipheight, 1, r_lerpimages.integer); + } switch(vid.renderpath) { case RENDERPATH_GL11: @@ -2690,11 +2714,11 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen case RENDERPATH_GLES2: if (bytesperblock) { - qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, glt->glinternalformat, mipwidth, mipheight, 0, mipsize, mippixels);CHECKGLERROR + qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, mipsize, upload_mippixels);CHECKGLERROR } else { - qglTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, mipwidth, mipheight, 0, glt->glformat, glt->gltype, mippixels);CHECKGLERROR + qglTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, glt->glformat, glt->gltype, upload_mippixels);CHECKGLERROR } break; case RENDERPATH_D3D9: @@ -2703,7 +2727,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen D3DLOCKED_RECT d3dlockedrect; if (IDirect3DTexture9_LockRect((IDirect3DTexture9*)glt->d3dtexture, mip, &d3dlockedrect, NULL, 0) == D3D_OK && d3dlockedrect.pBits) { - memcpy(d3dlockedrect.pBits, mippixels, mipsize); + memcpy(d3dlockedrect.pBits, upload_mippixels, mipsize); IDirect3DTexture9_UnlockRect((IDirect3DTexture9*)glt->d3dtexture, mip); } break; @@ -2720,11 +2744,13 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen if (bytesperblock) Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); else - DPSOFTRAST_Texture_UpdateFull(glt->texnum, mippixels); + DPSOFTRAST_Texture_UpdateFull(glt->texnum, upload_mippixels); // DPSOFTRAST calculates its own mipmaps mip = dds_miplevels; break; } + if(upload_mippixels != mippixels) + Mem_Free(upload_mippixels); mippixels += mipsize; if (mipwidth <= 1 && mipheight <= 1) {