From ded870ff9ce1f5b3b156cd33c04c67618feeba99 Mon Sep 17 00:00:00 2001 From: eihrul Date: Mon, 16 Jan 2012 21:33:09 +0000 Subject: [PATCH] flip dpsoftrast's texture memory layout so it matches the framebuffer orientation (allows r_viewfbo and r_bloom to work) however, r_viewfbo and r_bloom in combination are still broken on GPUs/dpsoftrast without non-power-of-2 textures due to not matching the position DP's bloom expects them to be located at git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11649 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::merge=e362fefcd05e3d1c5a8e5987916085de5cc368c5 --- dpsoftrast.c | 40 +++++++++++++++++++++++++--------------- gl_rmain.c | 39 ++++++++++++++++++++++----------------- vid_shared.c | 2 +- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/dpsoftrast.c b/dpsoftrast.c index a79a9d36..a646db35 100644 --- a/dpsoftrast.c +++ b/dpsoftrast.c @@ -748,12 +748,12 @@ void DPSOFTRAST_Texture_UpdatePartial(int index, int mip, const unsigned char *p DPSOFTRAST_Flush(); if (pixels) { - dst = texture->bytes + (blocky * texture->mipmap[0][2] + blockx) * 4; + dst = texture->bytes + texture->mipmap[0][1] +(-blocky * texture->mipmap[0][2] + blockx) * 4; while (blockheight > 0) { + dst -= texture->mipmap[0][2] * 4; memcpy(dst, pixels, blockwidth * 4); pixels += blockwidth * 4; - dst += texture->mipmap[0][2] * 4; blockheight--; } } @@ -766,7 +766,16 @@ void DPSOFTRAST_Texture_UpdateFull(int index, const unsigned char *pixels) if (texture->binds) DPSOFTRAST_Flush(); if (pixels) - memcpy(texture->bytes, pixels, texture->mipmap[0][1]); + { + int i, stride = texture->mipmap[0][2]*4; + unsigned char *dst = texture->bytes + texture->mipmap[0][1]; + for (i = texture->mipmap[0][3];i > 0;i--) + { + dst -= stride; + memcpy(dst, pixels, stride); + pixels += stride; + } + } DPSOFTRAST_Texture_CalculateMipmaps(index); } int DPSOFTRAST_Texture_GetWidth(int index, int mip) @@ -1269,9 +1278,10 @@ void DPSOFTRAST_CopyRectangleToTexture(int index, int mip, int tx, int ty, int s if (th > sh) th = sh; if (tw < 1 || th < 1) return; - sy1 = sheight - 1 - sy1; + sy1 = sheight - sy1 - th; + ty1 = theight - ty1 - th; for (y = 0;y < th;y++) - memcpy(tpixels + ((ty1 + y) * twidth + tx1), spixels + ((sy1 - y) * swidth + sx1), tw*4); + memcpy(tpixels + ((ty1 + y) * twidth + tx1), spixels + ((sy1 + y) * swidth + sx1), tw*4); if (texture->mipmaps > 1) DPSOFTRAST_Texture_CalculateMipmaps(index); } @@ -2293,7 +2303,7 @@ static void DPSOFTRAST_Texture2DBGRA8(DPSOFTRAST_Texture *texture, int mip, floa const unsigned char * RESTRICT pixel[4]; int width = texture->mipmap[mip][2], height = texture->mipmap[mip][3]; int wrapmask[2] = { width-1, height-1 }; - pixelbase = (unsigned char *)texture->bytes + texture->mipmap[mip][0]; + pixelbase = (unsigned char *)texture->bytes + texture->mipmap[mip][0] + texture->mipmap[mip][1] - 4*width; if(texture->filter & DPSOFTRAST_TEXTURE_FILTER_LINEAR) { unsigned int tc[2] = { x * (width<<12) - 2048, y * (height<<12) - 2048}; @@ -2316,10 +2326,10 @@ static void DPSOFTRAST_Texture2DBGRA8(DPSOFTRAST_Texture *texture, int mip, floa tci1[0] &= wrapmask[0]; tci1[1] &= wrapmask[1]; } - pixel[0] = pixelbase + 4 * (tci[1]*width+tci[0]); - pixel[1] = pixelbase + 4 * (tci[1]*width+tci1[0]); - pixel[2] = pixelbase + 4 * (tci1[1]*width+tci[0]); - pixel[3] = pixelbase + 4 * (tci1[1]*width+tci1[0]); + pixel[0] = pixelbase + 4 * (tci[0] - tci[1]*width); + pixel[1] = pixelbase + 4 * (tci[0] - tci[1]*width); + pixel[2] = pixelbase + 4 * (tci[0] - tci1[1]*width); + pixel[3] = pixelbase + 4 * (tci[0] - tci1[1]*width); c[0] = (pixel[0][0]*lerp[0]+pixel[1][0]*lerp[1]+pixel[2][0]*lerp[2]+pixel[3][0]*lerp[3])>>24; c[1] = (pixel[0][1]*lerp[0]+pixel[1][1]*lerp[1]+pixel[2][1]*lerp[2]+pixel[3][1]*lerp[3])>>24; c[2] = (pixel[0][2]*lerp[0]+pixel[1][2]*lerp[1]+pixel[2][2]*lerp[2]+pixel[3][2]*lerp[3])>>24; @@ -2338,7 +2348,7 @@ static void DPSOFTRAST_Texture2DBGRA8(DPSOFTRAST_Texture *texture, int mip, floa tci[0] &= wrapmask[0]; tci[1] &= wrapmask[1]; } - pixel[0] = pixelbase + 4 * (tci[1]*width+tci[0]); + pixel[0] = pixelbase + 4 * (tci[0] - tci[1]*width); c[0] = pixel[0][0]; c[1] = pixel[0][1]; c[2] = pixel[0][2]; @@ -2382,7 +2392,7 @@ static void DPSOFTRAST_Draw_Span_Texture2DVarying(DPSOFTRAST_State_Thread *threa return; } mip = triangle->mip[texunitindex]; - pixelbase = (unsigned char *)texture->bytes + texture->mipmap[mip][0]; + pixelbase = (unsigned char *)texture->bytes + texture->mipmap[mip][0] + texture->mipmap[mip][1] - 4*texture->mipmap[mip][2]; // if this mipmap of the texture is 1 pixel, just fill it with that color if (texture->mipmap[mip][1] == 4) { @@ -2404,7 +2414,7 @@ static void DPSOFTRAST_Draw_Span_Texture2DVarying(DPSOFTRAST_State_Thread *threa flags = texture->flags; tcscale[0] = texture->mipmap[mip][2]; tcscale[1] = texture->mipmap[mip][3]; - tciwidth = texture->mipmap[mip][2]; + tciwidth = -texture->mipmap[mip][2]; tcimin[0] = 0; tcimin[1] = 0; tcimax[0] = texture->mipmap[mip][2]-1; @@ -2569,7 +2579,7 @@ static void DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(DPSOFTRAST_State_Thread * return; } mip = triangle->mip[texunitindex]; - pixelbase = (const unsigned char *)texture->bytes + texture->mipmap[mip][0]; + pixelbase = (const unsigned char *)texture->bytes + texture->mipmap[mip][0] + texture->mipmap[mip][1] - 4*texture->mipmap[mip][2]; // if this mipmap of the texture is 1 pixel, just fill it with that color if (texture->mipmap[mip][1] == 4) { @@ -2591,7 +2601,7 @@ static void DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(DPSOFTRAST_State_Thread * if (filter) endtc = _mm_sub_ps(endtc, _mm_set1_ps(0.5f)); endsubtc = _mm_cvtps_epi32(_mm_mul_ps(endtc, _mm_set1_ps(65536.0f))); - tcoffset = _mm_add_epi32(_mm_slli_epi32(_mm_shuffle_epi32(tcsize, _MM_SHUFFLE(0, 0, 0, 0)), 18), _mm_set1_epi32(4)); + tcoffset = _mm_add_epi32(_mm_slli_epi32(_mm_sub_epi32(_mm_setzero_si128(), _mm_shuffle_epi32(tcsize, _MM_SHUFFLE(0, 0, 0, 0))), 18), _mm_set1_epi32(4)); tcmax = _mm_packs_epi32(tcmask, tcmask); for (x = startx;x < endx;) { diff --git a/gl_rmain.c b/gl_rmain.c index 5a3b3293..d1902817 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -6168,6 +6168,14 @@ static void R_Bloom_StartFrame(void) r_fb.screentexcoord2f[6] = 0; r_fb.screentexcoord2f[7] = 0; + if(r_fb.fbo) + { + for (i = 1;i < 8;i += 2) + { + r_fb.screentexcoord2f[i] += 1 - (float)(viewheight + r_refdef.view.y) / (float)r_fb.screentextureheight; + } + } + // set up a texcoord array for the reduced resolution bloom image // (which will be additive blended over the screen image) r_fb.bloomtexcoord2f[0] = 0; @@ -6191,20 +6199,17 @@ static void R_Bloom_StartFrame(void) case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: + for (i = 0;i < 4;i++) { - int i; - for (i = 0;i < 4;i++) - { - r_fb.screentexcoord2f[i*2+0] += 0.5f / (float)r_fb.screentexturewidth; - r_fb.screentexcoord2f[i*2+1] += 0.5f / (float)r_fb.screentextureheight; - r_fb.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_fb.bloomtexturewidth; - r_fb.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_fb.bloomtextureheight; - } + r_fb.screentexcoord2f[i*2+0] += 0.5f / (float)r_fb.screentexturewidth; + r_fb.screentexcoord2f[i*2+1] += 0.5f / (float)r_fb.screentextureheight; + r_fb.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_fb.bloomtexturewidth; + r_fb.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_fb.bloomtextureheight; } break; } - R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, r_refdef.view.x, (r_fb.bloomfbo[0] ? r_fb.bloomtextureheight : vid.height) - r_fb.bloomheight - r_refdef.view.y, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL); + R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, 0, 0, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL); if (r_fb.fbo) r_refdef.view.clear = true; @@ -6318,14 +6323,14 @@ static void R_Bloom_MakeTexture(void) xoffset /= (float)r_fb.bloomtexturewidth; yoffset /= (float)r_fb.bloomtextureheight; // compute a texcoord array with the specified x and y offset - r_fb.offsettexcoord2f[0] = xoffset+0; - r_fb.offsettexcoord2f[1] = yoffset+(float)r_fb.bloomheight / (float)r_fb.bloomtextureheight; - r_fb.offsettexcoord2f[2] = xoffset+(float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth; - r_fb.offsettexcoord2f[3] = yoffset+(float)r_fb.bloomheight / (float)r_fb.bloomtextureheight; - r_fb.offsettexcoord2f[4] = xoffset+(float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth; - r_fb.offsettexcoord2f[5] = yoffset+0; - r_fb.offsettexcoord2f[6] = xoffset+0; - r_fb.offsettexcoord2f[7] = yoffset+0; + r_fb.offsettexcoord2f[0] = xoffset+r_fb.bloomtexcoord2f[0]; + r_fb.offsettexcoord2f[1] = yoffset+r_fb.bloomtexcoord2f[1]; + r_fb.offsettexcoord2f[2] = xoffset+r_fb.bloomtexcoord2f[2]; + r_fb.offsettexcoord2f[3] = yoffset+r_fb.bloomtexcoord2f[3]; + r_fb.offsettexcoord2f[4] = xoffset+r_fb.bloomtexcoord2f[4]; + r_fb.offsettexcoord2f[5] = yoffset+r_fb.bloomtexcoord2f[5]; + r_fb.offsettexcoord2f[6] = xoffset+r_fb.bloomtexcoord2f[6]; + r_fb.offsettexcoord2f[7] = yoffset+r_fb.bloomtexcoord2f[7]; // this r value looks like a 'dot' particle, fading sharply to // black at the edges // (probably not realistic but looks good enough) diff --git a/vid_shared.c b/vid_shared.c index 7bea96c2..0859617f 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -2041,7 +2041,7 @@ void VID_Soft_SharedSetup(void) vid.support.arb_vertex_buffer_object = true; vid.support.ext_blend_subtract = true; vid.support.ext_draw_range_elements = true; - vid.support.ext_framebuffer_object = false; // FIXME actually dpsoftrast has code for this, but everything is downside up then + vid.support.ext_framebuffer_object = true; vid.support.ext_texture_3d = true; //vid.support.ext_texture_compression_s3tc = true; vid.support.ext_texture_filter_anisotropic = true; -- 2.39.2