From 9cb41e7c70af37af9f4ea7a097f73b5f240c6203 Mon Sep 17 00:00:00 2001 From: Rodolfo Osvaldo Bogado Date: Mon, 12 Jul 2010 19:30:25 +0000 Subject: [PATCH] hopefully fixed zww issue with new efb to ram. implemented new efb to ram in opengl modified TextureConversionShader preparing the implementation of new efb to ram in dx11 please test for regressions git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5874 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Src/TextureConversionShader.cpp | 385 ++++++++++-------- .../VideoCommon/Src/TextureConversionShader.h | 3 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2 +- .../Plugin_VideoDX9/Src/TextureCache.cpp | 35 +- .../Plugin_VideoDX9/Src/TextureConverter.cpp | 2 +- .../Plugin_VideoOGL/Src/BPFunctions.cpp | 5 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 8 +- .../Plugin_VideoOGL/Src/TextureConverter.cpp | 94 ++++- .../Plugin_VideoOGL/Src/TextureConverter.h | 2 + .../Plugin_VideoOGL/Src/TextureMngr.cpp | 189 ++++++--- .../Plugins/Plugin_VideoOGL/Src/TextureMngr.h | 7 +- 11 files changed, 445 insertions(+), 287 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp index eecc620fec..09c3059d17 100644 --- a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp +++ b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp @@ -19,7 +19,6 @@ #include #include #include -#include "Common.h" #include "TextureConversionShader.h" #include "TextureDecoder.h" @@ -67,7 +66,7 @@ u16 GetEncodedSampleCount(u32 format) // block dimensions : widthStride, heightStride // texture dims : width, height, x offset, y offset -void WriteSwizzler(char*& p, u32 format,bool HLSL) +void WriteSwizzler(char*& p, u32 format, API_TYPE ApiType) { WRITE(p, "uniform float4 blkDims : register(c%d);\n", C_COLORMATRIX); WRITE(p, "uniform float4 textureDims : register(c%d);\n", C_COLORMATRIX + 1); @@ -75,14 +74,32 @@ void WriteSwizzler(char*& p, u32 format,bool HLSL) float blkW = (float)TexDecoder_GetBlockWidthInTexels(format); float blkH = (float)TexDecoder_GetBlockHeightInTexels(format); float samples = (float)GetEncodedSampleCount(format); - if(HLSL) - WRITE(p,"uniform sampler samp0 : register(s0);\n"); - else + if(ApiType == API_OPENGL) + { WRITE(p,"uniform samplerRECT samp0 : register(s0);\n"); - WRITE(p, - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0)\n" + } + else if (ApiType == API_D3D9) + { + WRITE(p,"uniform sampler samp0 : register(s0);\n"); + } + else + { + WRITE(p,"sampler samp0 : register(s0);\n"); + WRITE(p, "Texture2D Tex0 : register(t0);\n"); + } + + + WRITE(p,"void main(\n"); + if(ApiType != API_D3D11) + { + WRITE(p," out float4 ocol0 : COLOR0,\n"); + } + else + { + WRITE(p," out float4 ocol0 : SV_Target,\n"); + } + + WRITE(p," in float2 uv0 : TEXCOORD0)\n" "{\n" " float2 sampleUv;\n" " float2 uv1 = floor(uv0);\n"); @@ -104,12 +121,12 @@ void WriteSwizzler(char*& p, u32 format,bool HLSL) WRITE(p, " sampleUv = sampleUv * blkDims.xy;\n"); - if(!HLSL) + if(ApiType == API_OPENGL) WRITE(p," sampleUv.y = textureDims.y - sampleUv.y;\n"); WRITE(p, " sampleUv = sampleUv + textureDims.zw;\n"); - if(HLSL) + if(ApiType != API_OPENGL) { WRITE(p, " sampleUv = sampleUv + float2(0.0f,1.0f);\n");// still to determine the reason for this WRITE(p, " sampleUv = sampleUv / blkDims.zw;\n"); @@ -118,7 +135,7 @@ void WriteSwizzler(char*& p, u32 format,bool HLSL) // block dimensions : widthStride, heightStride // texture dims : width, height, x offset, y offset -void Write32BitSwizzler(char*& p, u32 format, bool HLSL) +void Write32BitSwizzler(char*& p, u32 format, API_TYPE ApiType) { WRITE(p, "uniform float4 blkDims : register(c%d);\n", C_COLORMATRIX); WRITE(p, "uniform float4 textureDims : register(c%d);\n", C_COLORMATRIX + 1); @@ -127,15 +144,33 @@ void Write32BitSwizzler(char*& p, u32 format, bool HLSL) float blkH = (float)TexDecoder_GetBlockHeightInTexels(format); // 32 bit textures (RGBA8 and Z24) are store in 2 cache line increments - if(HLSL) - WRITE(p,"uniform sampler samp0 : register(s0);\n"); - else + if(ApiType == API_OPENGL) + { WRITE(p,"uniform samplerRECT samp0 : register(s0);\n"); - WRITE(p, - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0)\n" - "{\n" + } + else if (ApiType == API_D3D9) + { + WRITE(p,"uniform sampler samp0 : register(s0);\n"); + } + else + { + WRITE(p,"sampler samp0 : register(s0);\n"); + WRITE(p, "Texture2D Tex0 : register(t0);\n"); + } + + + WRITE(p,"void main(\n"); + if(ApiType != API_D3D11) + { + WRITE(p," out float4 ocol0 : COLOR0,\n"); + } + else + { + WRITE(p," out float4 ocol0 : SV_Target,\n"); + } + + WRITE(p," in float2 uv0 : TEXCOORD0)\n" + "{\n" " float2 sampleUv;\n" " float2 uv1 = floor(uv0);\n"); @@ -157,22 +192,24 @@ void Write32BitSwizzler(char*& p, u32 format, bool HLSL) WRITE(p, " sampleUv.y = yb + xoff;\n"); WRITE(p, " sampleUv = sampleUv * blkDims.xy;\n"); - if(!HLSL) + if(ApiType == API_OPENGL) WRITE(p," sampleUv.y = textureDims.y - sampleUv.y;\n"); WRITE(p, " sampleUv = sampleUv + textureDims.zw;\n"); - if(HLSL) + if(ApiType != API_OPENGL) { WRITE(p, " sampleUv = sampleUv + float2(0.0f,1.0f);\n");// still to determine the reason for this WRITE(p, " sampleUv = sampleUv / blkDims.zw;\n"); } } -void WriteSampleColor(char*& p, const char* colorComp, const char* dest,bool HLSL) +void WriteSampleColor(char*& p, const char* colorComp, const char* dest,API_TYPE ApiType) { - if(HLSL) + if (ApiType == API_D3D9) WRITE(p, " %s = tex2D(samp0, sampleUv).%s;\n", dest, colorComp); + else if (ApiType == API_D3D11) + WRITE(p, " %s = tex0.Sample(samp0, sampleUv).%s;\n", dest, colorComp); else WRITE(p, " %s = texRECT(samp0, sampleUv).%s;\n", dest, colorComp); } @@ -187,9 +224,9 @@ void WriteColorToIntensity(char*& p, const char* src, const char* dest) WRITE(p, " %s = dot(IntensityConst.rgb, %s.rgb) + IntensityConst.a;\n", dest, src); } -void WriteIncrementSampleX(char*& p,bool HLSL) +void WriteIncrementSampleX(char*& p,API_TYPE ApiType) { - if(HLSL) + if(ApiType != API_OPENGL) WRITE(p, " sampleUv.x = sampleUv.x + blkDims.x / blkDims.z;\n"); else WRITE(p, " sampleUv.x = sampleUv.x + blkDims.x;\n"); @@ -207,65 +244,65 @@ void WriteEncoderEnd(char* p) IntensityConstantAdded = false; } -void WriteI8Encoder(char* p, bool HLSL) +void WriteI8Encoder(char* p, API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_I8,HLSL); + WriteSwizzler(p, GX_TF_I8,ApiType); WRITE(p, " float3 texSample;\n"); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "ocol0.b"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "ocol0.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "ocol0.r"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "ocol0.a"); WriteEncoderEnd(p); } -void WriteI4Encoder(char* p, bool HLSL) +void WriteI4Encoder(char* p, API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_I4,HLSL); + WriteSwizzler(p, GX_TF_I4,ApiType); WRITE(p, " float3 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color0.b"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color1.b"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color0.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color1.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color0.r"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color1.r"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color0.a"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteColorToIntensity(p, "texSample", "color1.a"); WriteToBitDepth(p, 4, "color0", "color0"); @@ -275,46 +312,46 @@ void WriteI4Encoder(char* p, bool HLSL) WriteEncoderEnd(p); } -void WriteIA8Encoder(char* p,bool HLSL) +void WriteIA8Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_IA8,HLSL); + WriteSwizzler(p, GX_TF_IA8,ApiType); WRITE(p, " float4 texSample;\n"); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " ocol0.b = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "ocol0.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " ocol0.r = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "ocol0.a"); WriteEncoderEnd(p); } -void WriteIA4Encoder(char* p,bool HLSL) +void WriteIA4Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_IA4,HLSL); + WriteSwizzler(p, GX_TF_IA4,ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.b = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.b"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.g = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.r = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.r"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.a = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.a"); @@ -325,16 +362,16 @@ void WriteIA4Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteRGB565Encoder(char* p,bool HLSL) +void WriteRGB565Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_RGB565,HLSL); + WriteSwizzler(p, GX_TF_RGB565,ApiType); WRITE(p, " float3 texSample;\n"); WRITE(p, " float gInt;\n"); WRITE(p, " float gUpper;\n"); WRITE(p, " float gLower;\n"); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteToBitDepth(p, 6, "texSample.g", "gInt"); WRITE(p, " gUpper = floor(gInt / 8.0f);\n"); WRITE(p, " gLower = gInt - gUpper * 8.0f;\n"); @@ -344,9 +381,9 @@ void WriteRGB565Encoder(char* p,bool HLSL) WriteToBitDepth(p, 5, "texSample.b", "ocol0.g"); WRITE(p, " ocol0.g = ocol0.g + gLower * 32.0f;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgb", "texSample",HLSL); + WriteSampleColor(p, "rgb", "texSample",ApiType); WriteToBitDepth(p, 6, "texSample.g", "gInt"); WRITE(p, " gUpper = floor(gInt / 8.0f);\n"); WRITE(p, " gLower = gInt - gUpper * 8.0f;\n"); @@ -360,16 +397,16 @@ void WriteRGB565Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteRGB5A3Encoder(char* p,bool HLSL) +void WriteRGB5A3Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_RGB5A3,HLSL); + WriteSwizzler(p, GX_TF_RGB5A3,ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float color0;\n"); WRITE(p, " float gUpper;\n"); WRITE(p, " float gLower;\n"); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); // 0.8784 = 224 / 255 which is the maximum alpha value that can be represented in 3 bits WRITE(p, "if(texSample.a > 0.878f) {\n"); @@ -396,9 +433,9 @@ void WriteRGB5A3Encoder(char* p,bool HLSL) WRITE(p, "}\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, "if(texSample.a > 0.878f) {\n"); @@ -427,23 +464,23 @@ void WriteRGB5A3Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteRGBA4443Encoder(char* p,bool HLSL) +void WriteRGBA4443Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_RGB5A3,HLSL); + WriteSwizzler(p, GX_TF_RGB5A3,ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WriteToBitDepth(p, 3, "texSample.a", "color0.b"); WriteToBitDepth(p, 4, "texSample.r", "color1.b"); WriteToBitDepth(p, 4, "texSample.g", "color0.g"); WriteToBitDepth(p, 4, "texSample.b", "color1.g"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WriteToBitDepth(p, 3, "texSample.a", "color0.r"); WriteToBitDepth(p, 4, "texSample.r", "color1.r"); WriteToBitDepth(p, 4, "texSample.g", "color0.a"); @@ -453,9 +490,9 @@ void WriteRGBA4443Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteRGBA8Encoder(char* p,bool HLSL) +void WriteRGBA8Encoder(char* p,API_TYPE ApiType) { - Write32BitSwizzler(p, GX_TF_RGBA8,HLSL); + Write32BitSwizzler(p, GX_TF_RGBA8,ApiType); WRITE(p, " float cl1 = xb - (halfxb * 2);\n"); WRITE(p, " float cl0 = 1.0f - cl1;\n"); @@ -464,15 +501,15 @@ void WriteRGBA8Encoder(char* p,bool HLSL) WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.b = texSample.a;\n"); WRITE(p, " color0.g = texSample.r;\n"); WRITE(p, " color1.b = texSample.g;\n"); WRITE(p, " color1.g = texSample.b;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "rgba", "texSample",HLSL); + WriteSampleColor(p, "rgba", "texSample",ApiType); WRITE(p, " color0.r = texSample.a;\n"); WRITE(p, " color0.a = texSample.r;\n"); WRITE(p, " color1.r = texSample.g;\n"); @@ -483,34 +520,34 @@ void WriteRGBA8Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteC4Encoder(char* p, const char* comp,bool HLSL) +void WriteC4Encoder(char* p, const char* comp,API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_R4,HLSL); + WriteSwizzler(p, GX_CTF_R4,ApiType); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, comp, "color0.b",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color0.b",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color1.b",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color1.b",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color0.g",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color0.g",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color1.g",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color1.g",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color0.r",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color0.r",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color1.r",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color1.r",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color0.a",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "color0.a",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "color1.a",HLSL); + WriteSampleColor(p, comp, "color1.a",ApiType); WriteToBitDepth(p, 4, "color0", "color0"); WriteToBitDepth(p, 4, "color1", "color1"); @@ -519,47 +556,47 @@ void WriteC4Encoder(char* p, const char* comp,bool HLSL) WriteEncoderEnd(p); } -void WriteC8Encoder(char* p, const char* comp,bool HLSL) +void WriteC8Encoder(char* p, const char* comp,API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_R8,HLSL); + WriteSwizzler(p, GX_CTF_R8,ApiType); - WriteSampleColor(p, comp, "ocol0.b",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "ocol0.b",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "ocol0.g",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "ocol0.g",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "ocol0.r",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "ocol0.r",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "ocol0.a",HLSL); + WriteSampleColor(p, comp, "ocol0.a",ApiType); WriteEncoderEnd(p); } -void WriteCC4Encoder(char* p, const char* comp,bool HLSL) +void WriteCC4Encoder(char* p, const char* comp,API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_RA4,HLSL); + WriteSwizzler(p, GX_CTF_RA4,ApiType); WRITE(p, " float2 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, comp, "texSample",HLSL); + WriteSampleColor(p, comp, "texSample",ApiType); WRITE(p, " color0.b = texSample.x;\n"); WRITE(p, " color1.b = texSample.y;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "texSample",HLSL); + WriteSampleColor(p, comp, "texSample",ApiType); WRITE(p, " color0.g = texSample.x;\n"); WRITE(p, " color1.g = texSample.y;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "texSample",HLSL); + WriteSampleColor(p, comp, "texSample",ApiType); WRITE(p, " color0.r = texSample.x;\n"); WRITE(p, " color1.r = texSample.y;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "texSample",HLSL); + WriteSampleColor(p, comp, "texSample",ApiType); WRITE(p, " color0.a = texSample.x;\n"); WRITE(p, " color1.a = texSample.y;\n"); @@ -570,52 +607,52 @@ void WriteCC4Encoder(char* p, const char* comp,bool HLSL) WriteEncoderEnd(p); } -void WriteCC8Encoder(char* p, const char* comp, bool HLSL) +void WriteCC8Encoder(char* p, const char* comp, API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_RA8,HLSL); + WriteSwizzler(p, GX_CTF_RA8,ApiType); - WriteSampleColor(p, comp, "ocol0.bg",HLSL); - WriteIncrementSampleX(p,HLSL); + WriteSampleColor(p, comp, "ocol0.bg",ApiType); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, comp, "ocol0.ra",HLSL); + WriteSampleColor(p, comp, "ocol0.ra",ApiType); WriteEncoderEnd(p); } -void WriteZ8Encoder(char* p, const char* multiplier,bool HLSL) +void WriteZ8Encoder(char* p, const char* multiplier,API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_Z8M,HLSL); + WriteSwizzler(p, GX_CTF_Z8M,ApiType); WRITE(p, " float depth;\n"); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, "ocol0.b = frac(depth * %s);\n", multiplier); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, "ocol0.g = frac(depth * %s);\n", multiplier); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, "ocol0.r = frac(depth * %s);\n", multiplier); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, "ocol0.a = frac(depth * %s);\n", multiplier); WriteEncoderEnd(p); } -void WriteZ16Encoder(char* p,bool HLSL) +void WriteZ16Encoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_TF_Z16,HLSL); + WriteSwizzler(p, GX_TF_Z16,ApiType); WRITE(p, " float depth;\n"); WRITE(p, " float3 expanded;\n"); // byte order is reversed - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, " depth *= 16777215.0f;\n"); WRITE(p, " expanded.r = floor(depth / (256 * 256));\n"); @@ -625,9 +662,9 @@ void WriteZ16Encoder(char* p,bool HLSL) WRITE(p, " ocol0.b = expanded.g / 255;\n"); WRITE(p, " ocol0.g = expanded.r / 255;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, " depth *= 16777215.0f;\n"); WRITE(p, " expanded.r = floor(depth / (256 * 256));\n"); @@ -640,16 +677,16 @@ void WriteZ16Encoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteZ16LEncoder(char* p,bool HLSL) +void WriteZ16LEncoder(char* p,API_TYPE ApiType) { - WriteSwizzler(p, GX_CTF_Z16L,HLSL); + WriteSwizzler(p, GX_CTF_Z16L,ApiType); WRITE(p, " float depth;\n"); WRITE(p, " float3 expanded;\n"); // byte order is reversed - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, " depth *= 16777215.0f;\n"); WRITE(p, " expanded.r = floor(depth / (256 * 256));\n"); @@ -661,9 +698,9 @@ void WriteZ16LEncoder(char* p,bool HLSL) WRITE(p, " ocol0.b = expanded.b / 255;\n"); WRITE(p, " ocol0.g = expanded.g / 255;\n"); - WriteIncrementSampleX(p,HLSL); + WriteIncrementSampleX(p,ApiType); - WriteSampleColor(p, "b", "depth",HLSL); + WriteSampleColor(p, "b", "depth",ApiType); WRITE(p, " depth *= 16777215.0f;\n"); WRITE(p, " expanded.r = floor(depth / (256 * 256));\n"); @@ -678,9 +715,9 @@ void WriteZ16LEncoder(char* p,bool HLSL) WriteEncoderEnd(p); } -void WriteZ24Encoder(char* p, bool HLSL) +void WriteZ24Encoder(char* p, API_TYPE ApiType) { - Write32BitSwizzler(p, GX_TF_Z24X8,HLSL); + Write32BitSwizzler(p, GX_TF_Z24X8,ApiType); WRITE(p, " float cl = xb - (halfxb * 2);\n"); @@ -689,9 +726,9 @@ void WriteZ24Encoder(char* p, bool HLSL) WRITE(p, " float3 expanded0;\n"); WRITE(p, " float3 expanded1;\n"); - WriteSampleColor(p, "b", "depth0",HLSL); - WriteIncrementSampleX(p,HLSL); - WriteSampleColor(p, "b", "depth1",HLSL); + WriteSampleColor(p, "b", "depth0",ApiType); + WriteIncrementSampleX(p,ApiType); + WriteSampleColor(p, "b", "depth1",ApiType); for (int i = 0; i < 2; i++) { @@ -721,7 +758,7 @@ void WriteZ24Encoder(char* p, bool HLSL) WriteEncoderEnd(p); } -const char *GenerateEncodingShader(u32 format,bool HLSL) +const char *GenerateEncodingShader(u32 format,API_TYPE ApiType) { setlocale(LC_NUMERIC, "C"); // Reset locale for compilation text[sizeof(text) - 1] = 0x7C; // canary @@ -731,73 +768,73 @@ const char *GenerateEncodingShader(u32 format,bool HLSL) switch(format) { case GX_TF_I4: - WriteI4Encoder(p,HLSL); + WriteI4Encoder(p,ApiType); break; case GX_TF_I8: - WriteI8Encoder(p,HLSL); + WriteI8Encoder(p,ApiType); break; case GX_TF_IA4: - WriteIA4Encoder(p,HLSL); + WriteIA4Encoder(p,ApiType); break; case GX_TF_IA8: - WriteIA8Encoder(p,HLSL); + WriteIA8Encoder(p,ApiType); break; case GX_TF_RGB565: - WriteRGB565Encoder(p,HLSL); + WriteRGB565Encoder(p,ApiType); break; case GX_TF_RGB5A3: - WriteRGB5A3Encoder(p,HLSL); + WriteRGB5A3Encoder(p,ApiType); break; case GX_TF_RGBA8: - WriteRGBA8Encoder(p,HLSL); + WriteRGBA8Encoder(p,ApiType); break; case GX_CTF_R4: - WriteC4Encoder(p, "r",HLSL); + WriteC4Encoder(p, "r",ApiType); break; case GX_CTF_RA4: - WriteCC4Encoder(p, "ar",HLSL); + WriteCC4Encoder(p, "ar",ApiType); break; case GX_CTF_RA8: - WriteCC8Encoder(p, "ar",HLSL); + WriteCC8Encoder(p, "ar",ApiType); break; case GX_CTF_A8: - WriteC8Encoder(p, "a",HLSL); + WriteC8Encoder(p, "a",ApiType); break; case GX_CTF_R8: - WriteC8Encoder(p, "r",HLSL); + WriteC8Encoder(p, "r",ApiType); break; case GX_CTF_G8: - WriteC8Encoder(p, "g",HLSL); + WriteC8Encoder(p, "g",ApiType); break; case GX_CTF_B8: - WriteC8Encoder(p, "b",HLSL); + WriteC8Encoder(p, "b",ApiType); break; case GX_CTF_RG8: - WriteCC8Encoder(p, "rg",HLSL); + WriteCC8Encoder(p, "rg",ApiType); break; case GX_CTF_GB8: - WriteCC8Encoder(p, "gb",HLSL); + WriteCC8Encoder(p, "gb",ApiType); break; case GX_TF_Z8: - WriteC8Encoder(p, "b",HLSL); + WriteC8Encoder(p, "b",ApiType); break; case GX_TF_Z16: - WriteZ16Encoder(p,HLSL); + WriteZ16Encoder(p,ApiType); break; case GX_TF_Z24X8: - WriteZ24Encoder(p,HLSL); + WriteZ24Encoder(p,ApiType); break; case GX_CTF_Z4: - WriteC4Encoder(p, "b",HLSL); + WriteC4Encoder(p, "b",ApiType); break; case GX_CTF_Z8M: - WriteZ8Encoder(p, "256.0f",HLSL); + WriteZ8Encoder(p, "256.0f",ApiType); break; case GX_CTF_Z8L: - WriteZ8Encoder(p, "65536.0f" ,HLSL); + WriteZ8Encoder(p, "65536.0f" ,ApiType); break; case GX_CTF_Z16L: - WriteZ16LEncoder(p,HLSL); + WriteZ16LEncoder(p,ApiType); break; default: PanicAlert("Unknown texture copy format: 0x%x\n", format); diff --git a/Source/Core/VideoCommon/Src/TextureConversionShader.h b/Source/Core/VideoCommon/Src/TextureConversionShader.h index e49f2a24ef..10d80376ad 100644 --- a/Source/Core/VideoCommon/Src/TextureConversionShader.h +++ b/Source/Core/VideoCommon/Src/TextureConversionShader.h @@ -20,12 +20,13 @@ #include "Common.h" #include "TextureDecoder.h" +#include "VideoCommon.h" namespace TextureConversionShader { u16 GetEncodedSampleCount(u32 format); -const char *GenerateEncodingShader(u32 format, bool HLSL = false); +const char *GenerateEncodingShader(u32 format, API_TYPE ApiType = API_OPENGL); void SetShaderParameters(float width, float height, float offsetX, float offsetY, float widthStride, float heightStride,float buffW = 0.0f,float buffH = 0.0f); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 8854692e55..0639557338 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1107,7 +1107,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if(s_bScreenshot) { s_criticalScreenshot.Enter(); - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);//, NULL, dst_rect.AsRECT(), D3D::GetBackBufferSurface(), NULL, dst_rect.AsRECT(), D3DX_FILTER_NONE, 0); + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); if(FAILED(hr)) { PanicAlert("Error dumping surface data."); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index aafcd34864..113ab8e64c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -90,15 +90,9 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size) iter->second.Destroy(false); textures.erase(iter++); } - else { - if(rangePosition<0) - { - ++iter; - } - else - { - break; - } + else + { + ++iter; } } } @@ -113,11 +107,6 @@ void TextureCache::MakeRangeDynamic(u32 start_address, u32 size) { iter->second.hash = 0; } - else - { - if(rangePosition > 0) - break; - } ++iter; } } @@ -145,17 +134,8 @@ void TextureCache::Cleanup() { if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount) { - if (!iter->second.isRenderTarget) - { - iter->second.Destroy(false); - iter = textures.erase(iter); - } - else - { - // Used to be just iter++ - iter->second.Destroy(false); - iter = textures.erase(iter); - } + iter->second.Destroy(false); + iter = textures.erase(iter); } else { @@ -247,11 +227,10 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, } } if (((entry.isRenderTarget || entry.isDinamic) && hash_value == entry.hash && address == entry.addr) - || ((address == entry.addr) - && (hash_value == entry.hash) - && FullFormat == entry.fmt/* && entry.MipLevels == maxlevel*/)) + || ((address == entry.addr) && (hash_value == entry.hash) && FullFormat == entry.fmt/* && entry.MipLevels == maxlevel*/)) { entry.frameCount = frameCount; + entry.isDinamic = false; D3D::SetTexture(stage, entry.texture); return &entry; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index b4b32ecf05..6100888618 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -121,7 +121,7 @@ LPDIRECT3DPIXELSHADER9 GetOrCreateEncodingShader(u32 format) if (!s_encodingPrograms[format]) { - const char* shader = TextureConversionShader::GenerateEncodingShader(format,true); + const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_D3D9); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp index 9d7a46ff38..74fb8d33e1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp @@ -81,10 +81,7 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) if (!g_ActiveConfig.bEFBCopyDisable) { - if (g_ActiveConfig.bCopyEFBToTexture) // To OGL Texture - TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); - else // To RAM - TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); + TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 4d7ae6f412..eb62b81a94 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -886,9 +886,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Copy the framebuffer to screen. - // Render to the real buffer now. - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer - + // Texture map s_xfbTexture onto the main buffer glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_RECTANGLE_ARB); @@ -905,6 +903,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if(g_ActiveConfig.bUseXFB) { // draw each xfb source + // Render to the real buffer now. + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer + for (u32 i = 0; i < xfbCount; ++i) { xfbSource = xfbSourceList[i]; @@ -992,6 +993,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { TargetRectangle targetRc = Renderer::ConvertEFBRectangle(Rc); GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(Rc); + // Render to the real buffer now. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); if (applyShader) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 80943e5d46..0cb1d74c42 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -112,7 +112,7 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format) if (s_encodingPrograms[format].glprogid == 0) { - const char* shader = TextureConversionShader::GenerateEncodingShader(format); + const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_OPENGL); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) { @@ -170,7 +170,7 @@ void Shutdown() void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter) { - Renderer::ResetAPIState(); + // switch to texture converter frame buffer // attach render buffer as color destination @@ -240,13 +240,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr); GL_REPORT_ERRORD(); - - g_framebufferManager.SetFramebuffer(0); - VertexShaderManager::SetViewportChanged(); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); - TextureMngr::DisableStage(0); - Renderer::RestoreAPIState(); - GL_REPORT_ERRORD(); + } void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) @@ -312,6 +306,74 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf scaledSource.right = expandedWidth / samples; + int cacheBytes = 32; + if ((format & 0x0f) == 6) + cacheBytes = 64; + + int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); + Renderer::ResetAPIState(); + EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); + g_framebufferManager.SetFramebuffer(0); + VertexShaderManager::SetViewportChanged(); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); + TextureMngr::DisableStage(0); + Renderer::RestoreAPIState(); + GL_REPORT_ERRORD(); +} + + +u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) +{ + u32 format = copyfmt; + + if (bFromZBuffer) + { + format |= _GX_TF_ZTF; + if (copyfmt == 11) + format = GX_TF_Z16; + else if (format < GX_TF_Z8 || format > GX_TF_Z24X8) + format |= _GX_TF_CTF; + } + else + if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt)) + format |= _GX_TF_CTF; + + FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format); + if (texconv_shader.glprogid == 0) + return 0; + + u8 *dest_ptr = Memory_GetPtr(address); + + int width = (source.right - source.left) >> bScaleByHalf; + int height = (source.bottom - source.top) >> bScaleByHalf; + + int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format); + + u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; + u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; + u16 samples = TextureConversionShader::GetEncodedSampleCount(format); + + // only copy on cache line boundaries + // extra pixels are copied but not displayed in the resulting texture + s32 expandedWidth = (width + blkW) & (~blkW); + s32 expandedHeight = (height + blkH) & (~blkH); + + float sampleStride = bScaleByHalf?2.0f:1.0f; + float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ; + TextureConversionShader::SetShaderParameters((float)expandedWidth, + expandedHeight * MValueY, + source.left * MValueX, + top, + sampleStride * MValueX, + sampleStride * MValueY); + + TargetRectangle scaledSource; + scaledSource.top = 0; + scaledSource.bottom = expandedHeight; + scaledSource.left = 0; + scaledSource.right = expandedWidth / samples; + + int cacheBytes = 32; if ((format & 0x0f) == 6) cacheBytes = 64; @@ -319,12 +381,26 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); + TextureMngr::MakeRangeDynamic(address,size_in_bytes); + u64 Hashvalue = 0; + if(g_ActiveConfig.bVerifyTextureModificationsByCPU) + { + Hashvalue = TexDecoder_GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); + } + return Hashvalue; } void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) { + Renderer::ResetAPIState(); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); + g_framebufferManager.SetFramebuffer(0); + VertexShaderManager::SetViewportChanged(); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); + TextureMngr::DisableStage(0); + Renderer::RestoreAPIState(); + GL_REPORT_ERRORD(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h index 70bf1083fa..5b7db575ec 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h @@ -37,6 +37,8 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture); +u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source); + } #endif // _TEXTURECONVERTER_H_ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index e9d033da1b..dbad2fbc3a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -52,6 +52,7 @@ #include "FramebufferManager.h" #include "FileUtil.h" #include "HiresTextures.h" +#include "TextureConverter.h" u8 *TextureMngr::temp = NULL; TextureMngr::TexCache TextureMngr::textures; @@ -95,13 +96,13 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he return SaveTGA(filename, width, height, &data[0]); } -bool TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size) +int TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size) { if (addr + size_in_bytes < range_address) - return false; + return -1; if (addr >= range_address + range_size) - return false; - return true; + return 1; + return 0; } void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1) @@ -197,14 +198,8 @@ void TextureMngr::ProgressiveCleanup() { if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount) { - if (!iter->second.isRenderTarget) { - iter->second.Destroy(false); - textures.erase(iter++); - } - else { - iter->second.Destroy(false); - textures.erase(iter++); - } + iter->second.Destroy(false); + iter = textures.erase(iter); } else ++iter; @@ -216,17 +211,34 @@ void TextureMngr::InvalidateRange(u32 start_address, u32 size) TexCache::iterator iter = textures.begin(); while (iter != textures.end()) { - if (iter->second.IntersectsMemoryRange(start_address, size)) + int rangePosition = iter->second.IntersectsMemoryRange(start_address, size); + if (rangePosition == 0) { iter->second.Destroy(false); textures.erase(iter++); } - else { - ++iter; + else + { + ++iter; } } } +void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size) +{ + TexCache::iterator iter = textures.begin(); + while (iter != textures.end()) + { + int rangePosition = iter->second.IntersectsMemoryRange(start_address, size); + if ( rangePosition == 0) + { + iter->second.hash = 0; + } + ++iter; + } +} + + TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt) { // notes (about "UNsafe texture cache"): @@ -273,6 +285,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width u32 texID = address; u64 texHash = 0; u32 FullFormat = tex_format; + bool TextureIsDinamic = false; if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) FullFormat = (tex_format | (tlutfmt << 16)); if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) @@ -306,19 +319,47 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width TCacheEntry &entry = iter->second; if (!g_ActiveConfig.bSafeTextureCache) - hash_value = ((u32 *)ptr)[0]; + { + if(entry.isRenderTarget || entry.isDinamic) + { + if(!g_ActiveConfig.bCopyEFBToTexture && g_ActiveConfig.bVerifyTextureModificationsByCPU) + { + hash_value = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples); + if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) + { + hash_value ^= TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples); + } + } + else + { + hash_value = 0; + } + } + else + { + hash_value = ((u32 *)ptr)[0]; + } + } + else + { + if(entry.isRenderTarget || entry.isDinamic) + { + if(g_ActiveConfig.bCopyEFBToTexture || !g_ActiveConfig.bVerifyTextureModificationsByCPU) + { + hash_value = 0; + } + } + } - if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt && entry.MipLevels >= maxlevel))) + if (((entry.isRenderTarget || entry.isDinamic) && hash_value == entry.hash && address == entry.addr) + || ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel)) { entry.frameCount = frameCount; glEnable(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D); -// entry.isRectangle ? TextureMngr::EnableTex2D(texstage) : TextureMngr::EnableTexRECT(texstage); - glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture); + glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture); GL_REPORT_ERRORD(); - //if (entry.mode.hex != tm0.hex || entry.mode1.hex != tm1.hex)//gl needs this refreshed for every texture to work right - entry.SetTextureParameters(tm0,tm1); - //DebugLog("%cC addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_ActiveConfig.bSafeTextureCache ? 'S' : 'U' - // , address, tex_format, entry.hash, width, height); + entry.SetTextureParameters(tm0,tm1); + entry.isDinamic = false; return &entry; } else @@ -326,12 +367,14 @@ 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 && (int) FullFormat == entry.fmt) - { + TextureIsDinamic = (entry.isRenderTarget || entry.isDinamic) && !g_ActiveConfig.bCopyEFBToTexture; + if (!entry.isRenderTarget && + ((!entry.isDinamic && width == entry.w && height==entry.h && FullFormat == entry.fmt) + || (entry.isDinamic && entry.w == width && entry.h == height))) + { glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture); GL_REPORT_ERRORD(); - //if (entry.mode.hex != tm0.hex || entry.mode1.hex != tm1.hex) //gl needs this refreshed for every texture to work right - entry.SetTextureParameters(tm0,tm1); + entry.SetTextureParameters(tm0,tm1); skip_texture_create = true; } else @@ -344,6 +387,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width //Make an entry in the table TCacheEntry& entry = textures[texID]; + entry.isDinamic = TextureIsDinamic; PC_TexFormat dfmt = PC_TEX_FMT_NONE; if (g_ActiveConfig.bHiresTextures) @@ -370,12 +414,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width entry.oldpixel = ((u32 *)ptr)[0]; - if (g_ActiveConfig.bSafeTextureCache) + if (g_ActiveConfig.bSafeTextureCache || entry.isDinamic) entry.hash = hash_value; - else + else { entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF); - ((u32 *)ptr)[0] = entry.hash; + ((u32 *)ptr)[0] = entry.hash; } entry.addr = address; @@ -575,9 +619,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool // IA4,RA4 - IA4 // Z8M,G8,I8,A8,Z8,R8,B8,Z8L - I8 // Z16,GB8,RG8,Z16L,IA8,RA8 - IA8 - GLenum gl_format = GL_RGBA; - GLenum gl_iformat = 4; - GLenum gl_type = GL_UNSIGNED_BYTE; float colmat[16]; float fConstAdd[4] = {0}; memset(colmat, 0, sizeof(colmat)); @@ -688,6 +729,9 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool int w = (abs(source_rect.GetWidth()) >> bScaleByHalf); int h = (abs(source_rect.GetHeight()) >> bScaleByHalf); + GLenum gl_format = GL_RGBA; + GLenum gl_iformat = 4; + GLenum gl_type = GL_UNSIGNED_BYTE; GL_REPORT_ERRORD(); @@ -699,12 +743,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool GL_REPORT_ERRORD(); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_iformat, w, h, 0, gl_format, gl_type, NULL); GL_REPORT_ERRORD(); + entry.isRenderTarget = true; + entry.isDinamic = false; } else { _assert_(entry.texture); GL_REPORT_ERRORD(); - if (entry.w == w && entry.h == h && entry.isRectangle && entry.fmt == (int) copyfmt) + if (entry.w == w && entry.h == h && entry.isRectangle) { glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture); // for some reason mario sunshine errors here... @@ -717,6 +763,8 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_iformat, w, h, 0, gl_format, gl_type, NULL); GL_REPORT_ERRORD(); + entry.isRenderTarget = true; + entry.isDinamic = false; } } @@ -737,7 +785,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool entry.w = w; entry.h = h; entry.isRectangle = true; - entry.isRenderTarget = true; entry.fmt = copyfmt; // Make sure to resolve anything we need to read from. @@ -747,41 +794,57 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool // We have to run a pixel shader, for color conversion. Renderer::ResetAPIState(); // reset any game specific settings + if(!entry.isDinamic || g_ActiveConfig.bCopyEFBToTexture) + { + if (s_TempFramebuffer == 0) + glGenFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer); - if (s_TempFramebuffer == 0) - glGenFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer); + g_framebufferManager.SetFramebuffer(s_TempFramebuffer); + // Bind texture to temporary framebuffer + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, entry.texture, 0); + GL_REPORT_FBO_ERROR(); + GL_REPORT_ERRORD(); + + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); + + glViewport(0, 0, w, h); - g_framebufferManager.SetFramebuffer(s_TempFramebuffer); - // Bind texture to temporary framebuffer - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, entry.texture, 0); - GL_REPORT_FBO_ERROR(); - GL_REPORT_ERRORD(); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_RECTANGLE_ARB); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); - - glViewport(0, 0, w, h); + PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram()); + PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation + GL_REPORT_ERRORD(); - PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram()); - PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation - GL_REPORT_ERRORD(); + TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect); - TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect); + glBegin(GL_QUADS); + glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1); + glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1); + glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1); + glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1); + glEnd(); - glBegin(GL_QUADS); - glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1); - glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1); - glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1); - glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1); - glEnd(); + GL_REPORT_ERRORD(); - GL_REPORT_ERRORD(); - - // Unbind texture from temporary framebuffer - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); + // Unbind texture from temporary framebuffer + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); + } + if(!g_ActiveConfig.bCopyEFBToTexture) + { + textures[address].hash = TextureConverter::EncodeToRamFromTexture( + address, + read_texture, + Renderer::GetTargetScaleX(), + Renderer::GetTargetScaleY(), + bFromZBuffer, + bIsIntensityFmt, + copyfmt, + bScaleByHalf, + source_rect); + + } // Return to the EFB. g_framebufferManager.SetFramebuffer(0); Renderer::RestoreAPIState(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h index 66f06197bc..5dd50c5fa6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h @@ -29,7 +29,7 @@ class TextureMngr public: struct TCacheEntry { - TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0),MipLevels(0), scaleX(1.0f), scaleY(1.0f), isRenderTarget(false), isRectangle(true), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; } + TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0),MipLevels(0), scaleX(1.0f), scaleY(1.0f),isDinamic(false), isRenderTarget(false), isRectangle(true), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; } GLuint texture; u32 addr; @@ -47,13 +47,14 @@ public: bool isRenderTarget; // if render texture, then rendertex is filled with the direct copy of the render target // later conversions would have to convert properly from rendertexfmt to texfmt + bool isDinamic;// mofified from cpu bool isRectangle; // if nonpow2, use GL_TEXTURE_2D, else GL_TEXTURE_RECTANGLE_NV bool bHaveMipMaps; void SetTextureParameters(TexMode0& newmode,TexMode1 &newmode1); void Destroy(bool shutdown); void ConvertFromRenderTarget(u32 taddr, int twidth, int theight, int tformat, int tlutaddr, int tlutfmt); - bool IntersectsMemoryRange(u32 range_address, u32 range_size); + int IntersectsMemoryRange(u32 range_address, u32 range_size); }; private: @@ -68,7 +69,7 @@ public: static void Shutdown(); static void Invalidate(bool shutdown); static void InvalidateRange(u32 start_address, u32 size); - + static void MakeRangeDynamic(u32 start_address, u32 size); static TCacheEntry* Load(int texstage, u32 address, int width, int height, u32 format, int tlutaddr, int tlutfmt); static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source);