From 9e2bbec47f402f584536434dbdf3353fb817b8e7 Mon Sep 17 00:00:00 2001 From: Rodolfo Osvaldo Bogado Date: Wed, 3 Feb 2010 03:52:50 +0000 Subject: [PATCH] a lot of modifications here :) first fixed scaling when updating backbuffer to make it friendly with encoders, now frame dumping must work without errors in any codec. clean screenshot and frame dumping code now is more correct, faster and stable. improve safe texture cache, improving the distribution of the hash algorithm, including tlut hash in the final hash of the texture, and making use of a 64 bit hash to make it more accurate. clean a lot of code and corrected some missused vertex formats when drawing full screen quads. and biggest change last: implemented pseudo antialiasing: a image post-process algorithm that mimics antialiazing and is fare more easier to implement in this scenario. you can change the intensity of the effect changing the values of the antialiasing combo. the right value depends on the game. for example mkwii looks awesome with 8x. please try all the changes and let me know the results. if something is broken, please let me know and will fix it asap. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5000 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/VideoCommon/Src/TextureDecoder.cpp | 41 +++--- Source/Core/VideoCommon/Src/TextureDecoder.h | 4 +- Source/Core/VideoCommon/Src/VideoConfig.cpp | 10 +- .../Plugin_VideoDX9/Src/D3DTexture.cpp | 5 +- .../Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp | 80 ++++++++--- Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h | 14 +- .../Plugin_VideoDX9/Src/Debugger/Debugger.cpp | 8 +- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 83 ++++++++++- .../Plugin_VideoDX9/Src/PixelShaderCache.h | 2 + Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 136 +++++++++--------- .../Plugin_VideoDX9/Src/TextureCache.cpp | 48 +++++-- .../Plugin_VideoDX9/Src/TextureCache.h | 2 +- .../Plugin_VideoDX9/Src/TextureConverter.cpp | 6 +- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 60 ++++++-- .../Plugin_VideoDX9/Src/VertexShaderCache.h | 1 + .../Plugin_VideoOGL/Src/TextureMngr.cpp | 24 ++-- .../Plugins/Plugin_VideoOGL/Src/TextureMngr.h | 2 +- 17 files changed, 354 insertions(+), 172 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp index 45ebaedbc6..d49633609c 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp @@ -88,32 +88,27 @@ int TexDecoder_GetTextureSizeInBytes(int width, int height, int format) return (width * height * TexDecoder_GetTexelSizeInNibbles(format)) / 2; } -u32 TexDecoder_GetTlutHash(const u8* src, int len) +u64 TexDecoder_GetTlutHash(const u8* src, int len) { //char str[40000], st[20]; str[0]='\0';for (int i=0;i> 11) & 0x1F); int red2 = Convert5To8((c2 >> 11) & 0x1F); int colors[4]; + colors[0] = makecol(red1, green1, blue1, 255); + colors[1] = makecol(red2, green2, blue2, 255); if (c1 > c2) { int blue3 = ((blue2 - blue1) >> 1) - ((blue2 - blue1) >> 3); int green3 = ((green2 - green1) >> 1) - ((green2 - green1) >> 3); - int red3 = ((red2 - red1) >> 1) - ((red2 - red1) >> 3); - colors[0] = makecol(red1, green1, blue1, 255); - colors[1] = makecol(red2, green2, blue2, 255); + int red3 = ((red2 - red1) >> 1) - ((red2 - red1) >> 3); colors[2] = makecol(red1 + red3, green1 + green3, blue1 + blue3, 255); colors[3] = makecol(red2 - red3, green2 - green3, blue2 - blue3, 255); } else { - colors[0] = makecol(red1, green1, blue1, 255); // Color 1 - colors[1] = makecol(red2, green2, blue2, 255); // Color 2 colors[2] = makecol((red1 + red2 + 1) / 2, // Average (green1 + green2 + 1) / 2, (blue1 + blue2 + 1) / 2, 255); diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.h b/Source/Core/VideoCommon/Src/TextureDecoder.h index 068be12118..c1647dc6f6 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.h +++ b/Source/Core/VideoCommon/Src/TextureDecoder.h @@ -89,8 +89,8 @@ PC_TexFormat GetPC_TexFormat(int texformat, int tlutfmt); void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth, int texformat, int tlutaddr, int tlutfmt); -u32 TexDecoder_GetSafeTextureHash(const u8 *src, int width, int height, int texformat, u32 seed=0); -u32 TexDecoder_GetTlutHash(const u8* src, int len); +u64 TexDecoder_GetSafeTextureHash(const u8 *src, int width, int height, int texformat, u32 seed=0); +u64 TexDecoder_GetTlutHash(const u8* src, int len); void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 52f3c39357..f2eb12076e 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -258,8 +258,12 @@ void ComputeDrawRectangle(int backbuffer_width, int backbuffer_height, bool flip int XOffset = (int)(FloatXOffset + 0.5f); int YOffset = (int)(FloatYOffset + 0.5f); + int iWhidth = (int)ceil(FloatGLWidth); + int iHeight = (int)ceil(FloatGLHeight); + iWhidth -= iWhidth % 4; + iHeight -= iHeight % 4; rc->left = XOffset; - rc->top = flip ? (int)(YOffset + ceil(FloatGLHeight)) : YOffset; - rc->right = XOffset + (int)ceil(FloatGLWidth); - rc->bottom = flip ? YOffset : (int)(YOffset + ceil(FloatGLHeight)); + rc->top = flip ? (int)(YOffset + iHeight) : YOffset; + rc->right = XOffset + iWhidth; + rc->bottom = flip ? YOffset : (int)(YOffset + iHeight); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp index e3ae4c4c85..fb1ababed1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp @@ -17,6 +17,7 @@ #include "D3DBase.h" #include "D3DTexture.h" +#include "Math.h" namespace D3D { @@ -120,7 +121,7 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int } break; case D3DFMT_DXT1: - memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8); + memcpy(Lock.pBits,buffer,(size_t)(ceilf(((float)width)/4.0f) * ceilf(((float)height)/4.0f) * 8)); break; default: PanicAlert("D3D: Invalid texture format %i", fmt); @@ -239,7 +240,7 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w } break; case D3DFMT_DXT1: - memcpy(Lock.pBits, buffer, (width/4) * (height/4) * 8); + memcpy(Lock.pBits, buffer, (size_t)(ceilf(((float)width)/4.0f) * ceilf(((float)height)/4.0f) * 8)); break; } pTexture->UnlockRect(level); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp index 69b224e16a..440492615d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp @@ -20,6 +20,7 @@ #include "D3DBase.h" #include "D3DUtil.h" #include "Render.h" +#include namespace D3D { @@ -342,7 +343,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2) { - struct Q2DVertex { float x,y,z,rhw; u32 color; float u, v; } coords[4] = { + struct Q2DVertex { float x,y,z,rhw;u32 color;float u,v,w,h; } coords[4] = { {x1-0.5f, y1-0.5f, 0, 1, color, u1, v1}, {x2-0.5f, y1-0.5f, 0, 1, color, u2, v1}, {x2-0.5f, y2-0.5f, 0, 1, color, u2, v2}, @@ -350,6 +351,7 @@ void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v }; dev->SetPixelShader(0); dev->SetVertexShader(0); + dev->SetVertexDeclaration(NULL); dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); @@ -359,43 +361,79 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture, const RECT *rSource, int SourceWidth, int SourceHeight, - const RECT *rDest, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader) { - float u1=((float)rSource->left)/(float) SourceWidth; - float u2=((float)rSource->right)/(float) SourceWidth; - float v1=((float)rSource->top)/(float) SourceHeight; - float v2=((float)rSource->bottom)/(float) SourceHeight; + float sw = 1.0f /(float) SourceWidth; + float sh = 1.0f /(float) SourceHeight; + float u1=((float)rSource->left + 0.5f) * sw; + float u2=((float)rSource->right + 0.5f) * sw; + float v1=((float)rSource->top + 0.5f) * sh; + float v2=((float)rSource->bottom + 0.5f) * sh; - struct Q2DVertex { float x,y,z,rhw,u,v; } coords[4] = { - {(float)rDest->left - 0.5f, (float)rDest->top- 0.5f, 0.0f, 1.0f, u1, v1}, - {(float)rDest->right- 0.5f, (float)rDest->top- 0.5f, 0.0f,1.0f, u2, v1}, - {(float)rDest->right- 0.5f, (float)rDest->bottom- 0.5f, 0.0f,1.0f, u2, v2}, - {(float)rDest->left- 0.5f, (float)rDest->bottom- 0.5f, 0.0f,1.0f, u1, v2} + struct Q2DVertex { float x,y,z,rhw,u,v,w,h; } coords[4] = { + {-1.0f, 1.0f, 0.0f,1.0f, u1, v1, sw, sh}, + { 1.0f, 1.0f, 0.0f,1.0f, u2, v1, sw, sh}, + { 1.0f,-1.0f, 0.0f,1.0f, u2, v2, sw, sh}, + {-1.0f,-1.0f, 0.0f,1.0f, u1, v2, sw, sh} }; - dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); dev->SetVertexShader(Vshader); dev->SetPixelShader(PShader); D3D::SetTexture(0, texture); + dev->SetVertexDeclaration(NULL); + dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX2); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); } -void drawClearQuad(const RECT *rDest, u32 Color,float z, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader) + +void drawFSAATexQuad(IDirect3DTexture9 *texture, + IDirect3DTexture9 *Depthtexture, + const RECT *rSource, + int SourceWidth, + int SourceHeight, + IDirect3DPixelShader9 *PShader, + IDirect3DVertexShader9 *Vshader, + int Intensity, + float DepthRange) { - struct Q2DVertex { float x,y,z,rhw;u32 Color; } coords[4] = { - {(float)rDest->left-0.5f, (float)rDest->top-0.5f, z, 1.0f, Color}, - {(float)rDest->right-0.5f, (float)rDest->top-0.5f, z,1.0f, Color}, - {(float)rDest->right-0.5f, (float)rDest->bottom-0.5f, z,1.0f, Color}, - {(float)rDest->left-0.5f, (float)rDest->bottom-0.5f, z,1.0f, Color} + float sw = 1.0f /(float) SourceWidth; + float sh = 1.0f /(float) SourceHeight; + float u1=((float)rSource->left + 0.5f) * sw; + float u2=((float)rSource->right + 0.5f) * sw; + float v1=((float)rSource->top + 0.5f) * sh; + float v2=((float)rSource->bottom + 0.5f) * sh; + float FinalIntensity = 4.0f / pow(10.0,Intensity); + + struct Q2DVertex { float x,y,z,rhw;float u,v,w,h,dr1,dr2; } coords[4] = { + {-1.0f, 1.0f, 0.0f,1.0f,u1, v1, sw, sh,FinalIntensity,DepthRange}, + { 1.0f, 1.0f, 0.0f,1.0f,u2, v1, sw, sh,FinalIntensity,DepthRange}, + { 1.0f,-1.0f, 0.0f,1.0f,u2, v2, sw, sh,FinalIntensity,DepthRange}, + {-1.0f,-1.0f, 0.0f,1.0f,u1, v2, sw, sh,FinalIntensity,DepthRange} + }; + dev->SetVertexShader(Vshader); + dev->SetPixelShader(PShader); + D3D::SetTexture(0, texture); + D3D::SetTexture(1, Depthtexture); + dev->SetVertexDeclaration(NULL); + dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3); + dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); + RestoreShaders(); +} + +void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader) +{ + struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = { + {-1.0f, 1.0f, z, 1.0f, Color}, + { 1.0f, 1.0f, z, 1.0f, Color}, + { 1.0f, -1.0f, z, 1.0f, Color}, + {-1.0f, -1.0f, z, 1.0f, Color} }; - dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); dev->SetVertexShader(Vshader); dev->SetPixelShader(PShader); D3D::SetTexture(0, 0); + dev->SetVertexDeclaration(NULL); + dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h index f7abe3218e..7902b17851 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h @@ -62,12 +62,18 @@ namespace D3D const RECT *rSource, int SourceWidth, int SourceHeight, - const RECT *rDest, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader); - void drawClearQuad(const RECT *rDest, u32 Color,float z, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader); + void drawFSAATexQuad(IDirect3DTexture9 *texture, + IDirect3DTexture9 *Depthtexture, + const RECT *rSource, + int SourceWidth, + int SourceHeight, + IDirect3DPixelShader9 *PShader, + IDirect3DVertexShader9 *Vshader, + int Intensity, + float DepthRange); + void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader); void SaveRenderStates(); void RestoreRenderStates(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp index c0b50286a9..8ed95c638d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp @@ -18,7 +18,7 @@ #include "IniFile.h" #include "Debugger.h" -#include "FileUtil.h" +#include "FileUtil.h" #include "VideoConfig.h" #include "../Globals.h" @@ -76,7 +76,7 @@ void GFXDebuggerDX9::OnClose(wxCloseEvent& event) void GFXDebuggerDX9::SaveSettings() const { IniFile file; - file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); + file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); // TODO: make this work when we close the entire program too, currently on total close we get // weird values, perhaps because of some conflict with the rendering window @@ -101,13 +101,13 @@ void GFXDebuggerDX9::SaveSettings() const //file.Set("VideoWindow", "ConfBits", g_Config.iLog); - file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); + file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); } void GFXDebuggerDX9::LoadSettings() { IniFile file; - file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); + file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); int x = 100, y = 100, w = 100, h = 100; file.Get("VideoWindow", "x", &x, GetPosition().x); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 7893cb1c59..c31ed4f7c5 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -47,6 +47,8 @@ static LPDIRECT3DPIXELSHADER9 s_ColorCopyProgram = 0; static LPDIRECT3DPIXELSHADER9 s_ClearProgram = 0; static LPDIRECT3DPIXELSHADER9 s_ClearZProgram = 0; static LPDIRECT3DPIXELSHADER9 s_DepthMatrixProgram = 0; +static LPDIRECT3DPIXELSHADER9 s_FSAAProgram = 0; +static LPDIRECT3DPIXELSHADER9 s_FSAAColorMatrixProgram = 0; LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram() { @@ -68,6 +70,16 @@ LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram() return s_ClearProgram; } +LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetFSAAProgram() +{ + return s_FSAAProgram; +} + +LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetFSAAColorMatrixProgram() +{ + return s_FSAAColorMatrixProgram; +} + void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4) { if (lastPSconstants[const_number][0] != f1 || lastPSconstants[const_number][1] != f2 || @@ -122,7 +134,7 @@ void PixelShaderCache::Init() sprintf(pprog, "uniform sampler samp0 : register(s0);\n" "void main(\n" "out float4 ocol0 : COLOR0,\n" - " in float3 uv0 : TEXCOORD0){\n" + "in float4 uv0 : TEXCOORD0){\n" "ocol0 = tex2D(samp0,uv0.xy);\n" "}\n"); s_ColorCopyProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); @@ -131,7 +143,7 @@ void PixelShaderCache::Init() "uniform float4 cColMatrix[5] : register(c%d);\n" "void main(\n" "out float4 ocol0 : COLOR0,\n" - " in float3 uv0 : TEXCOORD0){\n" + " in float4 uv0 : TEXCOORD0){\n" "float4 texcol = tex2D(samp0,uv0.xy);\n" "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n" "}\n",C_COLORMATRIX); @@ -141,13 +153,73 @@ void PixelShaderCache::Init() "uniform float4 cColMatrix[5] : register(c%d);\n" "void main(\n" "out float4 ocol0 : COLOR0,\n" - " in float3 uv0 : TEXCOORD0){\n" + " in float4 uv0 : TEXCOORD0){\n" "float4 texcol = tex2D(samp0,uv0.xy);\n" "float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n" "texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n" "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n" "}\n",C_COLORMATRIX); s_DepthMatrixProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); + + sprintf(pprog, "uniform sampler samp0 : register(s0);\n" + "uniform sampler samp1 : register(s1);\n" + "void main(\n" + "out float4 ocol0 : COLOR0,\n" + " in float4 incol0 : COLOR0,\n" + "in float4 uv0 : TEXCOORD0,\n" + "in float4 uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3,\n" + "in float4 uv4 : TEXCOORD4,\n" + "in float2 uv5 : TEXCOORD5,\n" + "in float2 uv6 : TEXCOORD6,\n" + "in float2 uv7 : TEXCOORD7){\n" + "float3 P1 = float3(tex2D(samp1,uv0.xy).x,tex2D(samp1,uv1.xy).x,tex2D(samp1,uv2.xy).x);\n" + "float3 P2 = float3(tex2D(samp1,uv3.xy).x,tex2D(samp1,uv4.xy).x,tex2D(samp1,uv5).x);\n" + "float3 P3 = float3(P1.z,tex2D(samp1,uv6).x,P2.z);\n" + "float3 P4 = float3(P1.x,tex2D(samp1,uv7).r,P2.x);\n" + "float3 P5 = float3(1.0f,2.0f,1.0f);\n" + "float3 T = float3(dot(P3,P5) - dot(P4,P5),dot(P1,P5) - dot(P2,P5),0.0f);\n" + "if (dot(T,T) > incol0.x)\n" + "{\n" + "ocol0 = (tex2D(samp0,uv0.wz) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.wz))*0.25f;// + tex2D(samp0,uv4.xy) + tex2D(samp0,uv5) + tex2D(samp0,uv6) + tex2D(samp0,uv7) + tex2D(samp0,uv4.wz)) / 9.0f;\n" + "} else {\n" + "ocol0 = tex2D(samp0,uv4.wz);\n" + "}\n" + "}\n"); + s_FSAAProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); + + sprintf(pprog, "uniform sampler samp0 : register(s0);\n" + "uniform sampler samp1 : register(s1);\n" + "uniform float4 cColMatrix[5] : register(c%d);\n" + "void main(\n" + "out float4 ocol0 : COLOR0,\n" + " in float4 incol0 : COLOR0,\n" + "in float4 uv0 : TEXCOORD0,\n" + "in float4 uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3,\n" + "in float4 uv4 : TEXCOORD4,\n" + "in float2 uv5 : TEXCOORD5,\n" + "in float2 uv6 : TEXCOORD6,\n" + "in float2 uv7 : TEXCOORD7){\n" + "float3 P1 = float3(tex2D(samp1,uv0.xy).x,tex2D(samp1,uv1.xy).x,tex2D(samp1,uv2.xy).x);\n" + "float3 P2 = float3(tex2D(samp1,uv3.xy).x,tex2D(samp1,uv4.xy).x,tex2D(samp1,uv5).x);\n" + "float3 P3 = float3(P1.z,tex2D(samp1,uv6).x,P2.z);\n" + "float3 P4 = float3(P1.x,tex2D(samp1,uv7).r,P2.x);\n" + "float3 P5 = float3(1.0f,2.0f,1.0f);\n" + "float3 T = float3(dot(P3,P5) - dot(P4,P5),dot(P1,P5) - dot(P2,P5),0.0f);\n" + "float4 texcol = float4(0.0f,0.0f,0.0f,0.0f);\n" + "if (dot(T,T) > incol0.x)\n" + "{\n" + "texcol = (tex2D(samp0,uv0.wz) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.wz))*0.25f;// + tex2D(samp0,uv4.xy) + tex2D(samp0,uv5) + tex2D(samp0,uv6) + tex2D(samp0,uv7) + tex2D(samp0,uv4.wz)) / 9.0f;\n" + "} else {\n" + "texcol = tex2D(samp0,uv4.wz);\n" + "}\n" + "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n" + "}\n",C_COLORMATRIX); + s_FSAAColorMatrixProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); + Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) @@ -182,7 +254,10 @@ void PixelShaderCache::Shutdown() s_DepthMatrixProgram = NULL; if (s_ClearProgram) s_ClearProgram->Release(); s_ClearProgram = NULL; - + if (s_FSAAProgram) s_FSAAProgram->Release(); + s_FSAAProgram = NULL; + if (s_FSAAColorMatrixProgram) s_FSAAColorMatrixProgram->Release(); + s_FSAAColorMatrixProgram = NULL; Clear(); g_ps_disk_cache.Sync(); g_ps_disk_cache.Close(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index 8b4ab8d8fb..5cf64e1a3a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -66,6 +66,8 @@ public: static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(); static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(); static LPDIRECT3DPIXELSHADER9 GetClearProgram(); + static LPDIRECT3DPIXELSHADER9 GetFSAAProgram(); + static LPDIRECT3DPIXELSHADER9 GetFSAAColorMatrixProgram(); #if defined(_DEBUG) || defined(DEBUGFAST) static std::string GetCurrentShaderCode(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 0188a26fee..46e5450141 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -77,8 +77,6 @@ char st[32768]; static bool s_bScreenshot = false; static Common::CriticalSection s_criticalScreenshot; static char s_sScreenshotName[1024]; -static LPDIRECT3DTEXTURE9 ScreenShootTexture = NULL; -static LPDIRECT3DSURFACE9 ScreenShootSurface = NULL; static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL; @@ -243,12 +241,6 @@ void TeardownDeviceObjects() if(ScreenShootMEMSurface) ScreenShootMEMSurface->Release(); ScreenShootMEMSurface = NULL; - if(ScreenShootSurface) - ScreenShootSurface->Release(); - ScreenShootSurface = NULL; - if(ScreenShootTexture) - ScreenShootTexture->Release(); - ScreenShootTexture = NULL; D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); FBManager::Destroy(); @@ -332,14 +324,7 @@ bool Renderer::Init() D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0, 1.0f, 0); D3D::BeginFrame(); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); - D3D::dev->CreateTexture(s_backbuffer_width, s_backbuffer_height, 1, D3DUSAGE_RENDERTARGET, FBManager::GetEFBColorRTSurfaceFormat(), - D3DPOOL_DEFAULT, &ScreenShootTexture, NULL); - if(ScreenShootTexture) - { - ScreenShootTexture->GetSurfaceLevel(0,&ScreenShootSurface); - } - D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, FBManager::GetEFBColorRTSurfaceFormat(), D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - + D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, FBManager::GetEFBColorRTSurfaceFormat(), D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); return true; } @@ -580,8 +565,18 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc) D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),&destinationrect,PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader()); + if(g_ActiveConfig.iMultisampleMode != 0 ) + { + D3D::ChangeSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT); + D3D::ChangeSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + D3D::drawFSAATexQuad(read_texture,FBManager::GetEFBDepthTexture(efbRect),&sourcerect,Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),PixelShaderCache::GetFSAAProgram(),VertexShaderCache::GetFSAAVertexShader(),g_ActiveConfig.iMultisampleMode,xfregs.rawViewport[2]); + D3D::RefreshSamplerState(1, D3DSAMP_MINFILTER); + D3D::RefreshSamplerState(1, D3DSAMP_MAGFILTER); + } + else + { + D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader()); + } D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); @@ -592,59 +587,56 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc) vp.MinZ = 0.0f; vp.MaxZ = 1.0f; D3D::dev->SetViewport(&vp); - if(s_bScreenshot || g_ActiveConfig.bDumpFrames) - { - HRESULT hr = D3D::dev->StretchRect(FBManager::GetEFBColorRTSurface(),&sourcerect,ScreenShootSurface,&destinationrect,D3DTEXF_LINEAR); - hr = D3D::dev->GetRenderTargetData(ScreenShootSurface,ScreenShootMEMSurface); - if(s_bScreenshot) - { - s_criticalScreenshot.Enter(); - hr = D3DXSaveSurfaceToFileA(s_sScreenshotName, D3DXIFF_JPG, ScreenShootMEMSurface, NULL, &destinationrect); - s_bScreenshot = false; - s_criticalScreenshot.Leave(); - } - if (g_ActiveConfig.bDumpFrames) - { - if (!s_LastFrameDumped) - { - s_recordWidth = destinationrect.right - destinationrect.left; - s_recordHeight = destinationrect.bottom - destinationrect.top; - s_AVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); - if (!s_AVIDumping) - { - PanicAlert("Error dumping frames to AVI."); - } - else - { - char msg [255]; - sprintf(msg, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", File::GetUserPath(D_DUMPFRAMES_IDX), s_recordWidth, s_recordHeight); - OSD::AddMessage(msg, 2000); - } - } - if (s_AVIDumping) - { - D3DLOCKED_RECT rect; - if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, &destinationrect, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) - { - char *data = (char *)malloc(3 * s_recordWidth * s_recordHeight); - formatBufferDump((const char *)rect.pBits, data, s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(data); - free(data); - ScreenShootMEMSurface->UnlockRect(); - } - } - s_LastFrameDumped = true; - } - else - { - if (s_LastFrameDumped && s_AVIDumping) - { - AVIDump::Stop(); - s_AVIDumping = false; - } - s_LastFrameDumped = false; - } + if(s_bScreenshot) + { + s_criticalScreenshot.Enter(); + D3DXSaveSurfaceToFileA(s_sScreenshotName, D3DXIFF_JPG, D3D::GetBackBufferSurface(), NULL, &destinationrect); + s_bScreenshot = false; + s_criticalScreenshot.Leave(); } + if (g_ActiveConfig.bDumpFrames) + { + D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if (!s_LastFrameDumped) + { + s_recordWidth = destinationrect.right - destinationrect.left; + s_recordHeight = destinationrect.bottom - destinationrect.top; + s_AVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); + if (!s_AVIDumping) + { + PanicAlert("Error dumping frames to AVI."); + } + else + { + char msg [255]; + sprintf(msg, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", File::GetUserPath(D_DUMPFRAMES_IDX), s_recordWidth, s_recordHeight); + OSD::AddMessage(msg, 2000); + } + } + if (s_AVIDumping) + { + D3DLOCKED_RECT rect; + if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, &destinationrect, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) + { + char *data = (char *)malloc(3 * s_recordWidth * s_recordHeight); + formatBufferDump((const char *)rect.pBits, data, s_recordWidth, s_recordHeight, rect.Pitch); + AVIDump::AddFrame(data); + free(data); + ScreenShootMEMSurface->UnlockRect(); + } + } + s_LastFrameDumped = true; + } + else + { + if (s_LastFrameDumped && s_AVIDumping) + { + AVIDump::Stop(); + s_AVIDumping = false; + } + s_LastFrameDumped = false; + } + // Finish up the current frame, print some stats if (g_ActiveConfig.bShowFPS) @@ -869,7 +861,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y) D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::drawShadedTexQuad(read_texture,&RectToLock, Renderer::GetFullTargetWidth() , Renderer::GetFullTargetHeight(),&PixelRect,(BufferFormat == FOURCC_RAWZ)?PixelShaderCache::GetColorMatrixProgram():PixelShaderCache::GetDepthMatrixProgram(),VertexShaderCache::GetSimpleVertexShader()); + D3D::drawShadedTexQuad(read_texture,&RectToLock, Renderer::GetFullTargetWidth() , Renderer::GetFullTargetHeight(),(BufferFormat == FOURCC_RAWZ)?PixelShaderCache::GetColorMatrixProgram():PixelShaderCache::GetDepthMatrixProgram(),VertexShaderCache::GetSimpleVertexShader()); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); @@ -1065,7 +1057,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE D3D::dev->SetScissorRect(&sirc); if (zEnable) D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - D3D::drawClearQuad(&sirc,color ,(z & 0xFFFFFF) / float(0xFFFFFF),PixelShaderCache::GetClearProgram(),VertexShaderCache::GetSimpleVertexShader()); + D3D::drawClearQuad(color ,(z & 0xFFFFFF) / float(0xFFFFFF),PixelShaderCache::GetClearProgram(),VertexShaderCache::GetSimpleVertexShader()); if (zEnable) D3D::RefreshRenderState(D3DRS_ZFUNC); //D3D::dev->Clear(0, NULL, (colorEnable ? D3DCLEAR_TARGET : 0)| ( zEnable ? D3DCLEAR_ZBUFFER : 0), color | ((alphaEnable)?0:0xFF000000),(z & 0xFFFFFF) / float(0xFFFFFF), 0); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index d6f9511b77..7ec72cc74b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -147,15 +147,16 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int expandedWidth = (width + bsw) & (~bsw); int expandedHeight = (height + bsh) & (~bsh); - u32 hash_value; + u64 hash_value; u32 texID = address; - u32 texHash; + u64 texHash; + u32 FullFormat = tex_format; + if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) + u32 FullFormat = (tex_format | (tlutfmt << 16)); if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) { texHash = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, expandedHeight, tex_format, 0); - if (g_ActiveConfig.bSafeTextureCache) - hash_value = texHash; if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) { // WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up) @@ -165,11 +166,13 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, // each other stored in a single texture, and uses the palette to make different characters // visible or invisible. Thus, unless we want to recreate the textures for every drawn character, // we must make sure that texture with different tluts get different IDs. - u32 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], (tex_format == GX_TF_C4) ? 32 : 128); + u64 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format)); texHash ^= tlutHash; if (g_ActiveConfig.bSafeTextureCache) texID ^= tlutHash; } + if (g_ActiveConfig.bSafeTextureCache) + hash_value = texHash; } bool skip_texture_create = false; @@ -182,7 +185,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, if (!g_ActiveConfig.bSafeTextureCache) hash_value = ((u32 *)ptr)[0]; - if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash))) + if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash) && FullFormat == entry.fmt)) { entry.frameCount = frameCount; D3D::SetTexture(stage, entry.texture); @@ -194,7 +197,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, // instead of destroying it and having to create a new one. // Might speed up movie playback very, very slightly. - if (width == entry.w && height==entry.h &&(tex_format | (tlutfmt << 16)) == entry.fmt) + if (width == entry.w && height==entry.h && FullFormat == entry.fmt) { skip_texture_create = true; } @@ -283,7 +286,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, entry.frameCount = frameCount; entry.w = width; entry.h = height; - entry.fmt = tex_format | (tlutfmt << 16); + entry.fmt = FullFormat; if (g_ActiveConfig.bDumpTextures) { @@ -522,10 +525,35 @@ have_texture: D3DFORMAT bformat = FBManager::GetEFBDepthRTSurfaceFormat(); - D3D::drawShadedTexQuad(read_texture,&sourcerect, Renderer::GetFullTargetWidth() , Renderer::GetFullTargetHeight(),&destrect,((bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8) && bFromZBuffer)? PixelShaderCache::GetDepthMatrixProgram(): PixelShaderCache::GetColorMatrixProgram(),VertexShaderCache::GetSimpleVertexShader()); + if(!bFromZBuffer && g_ActiveConfig.iMultisampleMode != 0) + { + D3D::ChangeSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT); + D3D::ChangeSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + D3D::drawFSAATexQuad( + read_texture, + FBManager::GetEFBDepthTexture(source_rect), + &sourcerect, + Renderer::GetFullTargetWidth() , + Renderer::GetFullTargetHeight(), + PixelShaderCache::GetFSAAColorMatrixProgram(), + VertexShaderCache::GetFSAAVertexShader(), + g_ActiveConfig.iMultisampleMode,1.0f); + D3D::RefreshSamplerState(1, D3DSAMP_MINFILTER); + D3D::RefreshSamplerState(1, D3DSAMP_MAGFILTER); + D3D::SetTexture(1,NULL); + } + else + { + D3D::drawShadedTexQuad(read_texture,&sourcerect, + Renderer::GetFullTargetWidth() , + Renderer::GetFullTargetHeight(), + ((bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8) && bFromZBuffer)? PixelShaderCache::GetDepthMatrixProgram(): PixelShaderCache::GetColorMatrixProgram(), + VertexShaderCache::GetSimpleVertexShader()); + } + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - + D3D::SetTexture(0,NULL); D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface()); Renderer::RestoreAPIState(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h index ca925e9143..806524d2bf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h @@ -34,7 +34,7 @@ public: u32 addr; u32 size_in_bytes; - u32 hash; + u64 hash; u32 paletteHash; u32 oldpixel; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index 2872044674..2bf0af72e8 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -34,7 +34,7 @@ #include "D3DShader.h" #include "TextureCache.h" #include "Math.h" -#include "FileUtil.h" +#include "FileUtil.h" namespace TextureConverter { @@ -125,7 +125,7 @@ LPDIRECT3DPIXELSHADER9 GetOrCreateEncodingShader(u32 format) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) { static int counter = 0; char szTemp[MAX_PATH]; - sprintf(szTemp, "%senc_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++); + sprintf(szTemp, "%senc_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++); SaveData(szTemp, shader); } @@ -269,7 +269,7 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr // Draw... - D3D::drawShadedTexQuad(srcTexture,&SrcRect,1,1,&DstRect,shader,VertexShaderCache::GetSimpleVertexShader()); + D3D::drawShadedTexQuad(srcTexture,&SrcRect,1,1,shader,VertexShaderCache::GetSimpleVertexShader()); hr = D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface()); hr = D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface()); Renderer::RestoreAPIState(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 7afb3af438..0de8e03ec2 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -41,6 +41,8 @@ const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; static float GC_ALIGNED16(lastVSconstants[C_FOGPARAMS + 8][4]); static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader; +static LPDIRECT3DVERTEXSHADER9 FSAAVertexShader; + LinearDiskCache g_vs_disk_cache; LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader() @@ -48,6 +50,11 @@ LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader() return SimpleVertexShader; } +LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetFSAAVertexShader() +{ + return FSAAVertexShader; +} + void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4) { if (lastVSconstants[const_number][0] != f1 || @@ -152,22 +159,51 @@ void VertexShaderCache::Init() sprintf(vSimpleProg,"struct VSOUTPUT\n" "{\n" "float4 vPosition : POSITION;\n" - "float4 Color : COLOR0;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float4 vTexCoord1 : TEXCOORD1;\n" + "float4 vColor0 : COLOR0;\n" + "float2 vTexCoord : TEXCOORD0;\n" "};\n" - "VSOUTPUT main( float4 inPosition : POSITION, float4 inUV : TEXCOORD0,float4 inColor : COLOR0)\n" + "void main(out VSOUTPUT OUT,in float4 inPosition : POSITION,in float2 inTEX0 : TEXCOORD0,in float4 inColor0: COLOR0)\n" "{\n" - "VSOUTPUT OUT = (VSOUTPUT)0;\n" - "OUT.vPosition = inPosition;\n" - "OUT.Color = inColor;\n" - "OUT.vTexCoord = inUV;\n" - "OUT.vTexCoord1 = inPosition.zzzz;\n" - "return OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vColor0 = inColor0;\n" + "OUT.vTexCoord = inTEX0;\n" "}\n"); SimpleVertexShader = D3D::CompileAndCreateVertexShader(vSimpleProg, (int)strlen(vSimpleProg)); + + char *vFSAAProg = new char[2048]; + sprintf(vFSAAProg, "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float4 vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "float4 vTexCoord4 : TEXCOORD4;\n" + "float2 vTexCoord5 : TEXCOORD5;\n" + "float2 vTexCoord6 : TEXCOORD6;\n" + "float2 vTexCoord7 : TEXCOORD7;\n" + "};\n" + + "void main( out VSOUTPUT OUT,in float4 inPosition : POSITION,in float2 inTEX0 : TEXCOORD0,in float2 inTEX1 : TEXCOORD1,in float2 inTEX2 : TEXCOORD2)\n" + "{\n" + "OUT.vPosition = inPosition;\n" + "OUT.vColor0 = float4(inTEX2.x / inTEX2.y,0.0f,0.0f,0.0f);\n" + "OUT.vTexCoord = inTEX0.xyyx + (float4(-1.0f,-1.0f,-0.45f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord1 = inTEX0.xyyx + (float4( 0.0f,-1.0f,-0.45f, 0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4( 1.0f,-1.0f, 0.45f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4(-1.0f, 1.0f, 0.45f, 0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord4 = inTEX0.xyyx + (float4( 0.0f, 1.0f, 0.0f, 0.0f) * inTEX1.xyyx);\n" + "OUT.vTexCoord5 = inTEX0 + (float2( 1.0f, 1.0f) * inTEX1);\n" + "OUT.vTexCoord6 = inTEX0 + (float2( 1.0f, 0.0f) * inTEX1);\n" + "OUT.vTexCoord7 = inTEX0 + (float2(-1.0f, 0.0f) * inTEX1);\n" + "}\n"); + FSAAVertexShader = D3D::CompileAndCreateVertexShader(vFSAAProg, (int)strlen(vFSAAProg)); + + Clear(); + delete [] vFSAAProg; delete [] vSimpleProg; if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) @@ -195,6 +231,10 @@ void VertexShaderCache::Shutdown() { if (SimpleVertexShader) SimpleVertexShader->Release(); + SimpleVertexShader = NULL; + if (FSAAVertexShader) + FSAAVertexShader->Release(); + FSAAVertexShader = NULL; Clear(); g_vs_disk_cache.Sync(); g_vs_disk_cache.Close(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h index d7487a091f..088a2066ae 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h @@ -56,6 +56,7 @@ public: static void Shutdown(); static bool SetShader(u32 components); static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(); + static LPDIRECT3DVERTEXSHADER9 GetFSAAVertexShader(); static bool InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); #if defined(_DEBUG) || defined(DEBUGFAST) static std::string GetCurrentShaderCode(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index b3be1faa2a..75a4526877 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -257,15 +257,15 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width int expandedWidth = (width + bsw) & (~bsw); int expandedHeight = (height + bsh) & (~bsh); - u32 hash_value; + u64 hash_value; u32 texID = address; - u32 texHash; - + u64 texHash; + u32 FullFormat = tex_format; + if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) + u32 FullFormat = (tex_format | (tlutfmt << 16)); if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) { texHash = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, expandedHeight, tex_format, 0); // remove last arg - if (g_ActiveConfig.bSafeTextureCache) - hash_value = texHash; if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) { // WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up) @@ -275,12 +275,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width // each other stored in a single texture, and uses the palette to make different characters // visible or invisible. Thus, unless we want to recreate the textures for every drawn character, // we must make sure that texture with different tluts get different IDs. - u32 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], (tex_format == GX_TF_C4) ? 32 : 128); + u64 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format)); texHash ^= tlutHash; if (g_ActiveConfig.bSafeTextureCache) texID ^= tlutHash; //DebugLog("addr: %08x | texID: %08x | texHash: %08x", address, texID, hash_value); } + if (g_ActiveConfig.bSafeTextureCache) + hash_value = texHash; } bool skip_texture_create = false; @@ -293,7 +295,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width if (!g_ActiveConfig.bSafeTextureCache) hash_value = ((u32 *)ptr)[0]; - if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash))) + if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash) && FullFormat == entry.fmt)) { entry.frameCount = frameCount; glEnable(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D); @@ -310,7 +312,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width // Let's reload the new texture data into the same texture, // instead of destroying it and having to create a new one. // Might speed up movie playback very, very slightly. - if (width == entry.w && height == entry.h && (tex_format | (tlutfmt << 16)) == entry.fmt) + if (width == entry.w && height == entry.h && FullFormat == entry.fmt) { glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture); if (entry.mode.hex != tm0.hex) @@ -450,20 +452,20 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width { if(skip_texture_create) { - glCompressedTexSubImage2D(target, 0,0,0,expandedWidth, expandedHeight, + glCompressedTexSubImage2D(target, 0,0,0,width, height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,expandedWidth*expandedHeight/2, temp); } else { glCompressedTexImage2D(target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - expandedWidth, expandedHeight, 0, expandedWidth*expandedHeight/2, temp); + width, height, 0, expandedWidth*expandedHeight/2, temp); } } entry.frameCount = frameCount; entry.w = width; entry.h = height; - entry.fmt = (tex_format | (tlutfmt << 16)); + entry.fmt = FullFormat; entry.SetTextureParameters(tm0); if (g_ActiveConfig.bDumpTextures) // dump texture to file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h index 7779f97383..d10f384b71 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h @@ -34,7 +34,7 @@ public: GLuint texture; u32 addr; u32 size_in_bytes; - u32 hash; + u64 hash; u32 paletteHash; u32 oldpixel; // used for simple cleanup TexMode0 mode; // current filter and clamp modes that texture is set to