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
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-07-12 19:30:25 +00:00
parent dcc51e0ef8
commit 9cb41e7c70
11 changed files with 445 additions and 287 deletions

View File

@ -19,7 +19,6 @@
#include <stdio.h>
#include <math.h>
#include <locale.h>
#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);

View File

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

View File

@ -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.");

View File

@ -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;
}

View File

@ -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) {

View File

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

View File

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

View File

@ -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();
}

View File

@ -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_

View File

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

View File

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