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);