re indentation to follow emulators code rules in some files I'm modifying

This commit is contained in:
Rodolfo Bogado 2013-08-15 15:16:32 -03:00
parent 8e9bbdeb2f
commit 08a6b8920b
3 changed files with 631 additions and 625 deletions

View File

@ -40,15 +40,15 @@ static std::set<u32> unique_shaders;
#define MAX_SSAA_SHADERS 3 #define MAX_SSAA_SHADERS 3
enum enum
{ {
COPY_TYPE_DIRECT, COPY_TYPE_DIRECT,
COPY_TYPE_MATRIXCOLOR, COPY_TYPE_MATRIXCOLOR,
NUM_COPY_TYPES NUM_COPY_TYPES
}; };
enum enum
{ {
DEPTH_CONVERSION_TYPE_NONE, DEPTH_CONVERSION_TYPE_NONE,
DEPTH_CONVERSION_TYPE_ON, DEPTH_CONVERSION_TYPE_ON,
NUM_DEPTH_CONVERSION_TYPES NUM_DEPTH_CONVERSION_TYPES
}; };
static LPDIRECT3DPIXELSHADER9 s_CopyProgram[NUM_COPY_TYPES][NUM_DEPTH_CONVERSION_TYPES][MAX_SSAA_SHADERS]; static LPDIRECT3DPIXELSHADER9 s_CopyProgram[NUM_COPY_TYPES][NUM_DEPTH_CONVERSION_TYPES][MAX_SSAA_SHADERS];
@ -59,30 +59,30 @@ static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL;
class PixelShaderCacheInserter : public LinearDiskCacheReader<PixelShaderUid, u8> class PixelShaderCacheInserter : public LinearDiskCacheReader<PixelShaderUid, u8>
{ {
public: public:
void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) void Read(const PixelShaderUid &key, const u8 *value, u32 value_size)
{ {
PixelShaderCache::InsertByteCode(key, value, value_size, false); PixelShaderCache::InsertByteCode(key, value, value_size, false);
} }
}; };
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode) LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode)
{ {
return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS];
} }
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode, bool depthConversion) LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode, bool depthConversion)
{ {
return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS];
} }
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode) LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode)
{ {
return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS];
} }
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram() LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram()
{ {
return s_ClearProgram; return s_ClearProgram;
} }
static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL; static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL;
@ -90,360 +90,360 @@ static LPDIRECT3DPIXELSHADER9 s_rgba6 = NULL;
LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8() LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8()
{ {
const char code[] = const char code[] =
{ {
"uniform sampler samp0 : register(s0);\n" "uniform sampler samp0 : register(s0);\n"
"void main(\n" "void main(\n"
" out float4 ocol0 : COLOR0,\n" " out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n" " in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\n" " ocol0 = tex2D(samp0,uv0);\n"
" float4 src6 = round(ocol0 * 63.f);\n" " float4 src6 = round(ocol0 * 63.f);\n"
" ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4);
" ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2);
" ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a;
" ocol0.a = 255.f;\n" " ocol0.a = 255.f;\n"
" ocol0 /= 255.f;\n" " ocol0 /= 255.f;\n"
"}\n" "}\n"
}; };
if (!s_rgba6_to_rgb8) if (!s_rgba6_to_rgb8)
s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
return s_rgba6_to_rgb8; return s_rgba6_to_rgb8;
} }
LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6() LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6()
{ {
/* old code here for reference /* old code here for reference
const char code[] = const char code[] =
{ {
"uniform sampler samp0 : register(s0);\n" "uniform sampler samp0 : register(s0);\n"
"void main(\n" "void main(\n"
" out float4 ocol0 : COLOR0,\n" " out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n" " in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\n" " ocol0 = tex2D(samp0,uv0);\n"
" float4 src8 = round(ocol0*255.f);\n" " float4 src8 = round(ocol0*255.f);\n"
" ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2;
" ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4);
" ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6);
" ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F;
" ocol0 /= 63.f;\n" " ocol0 /= 63.f;\n"
"}\n" "}\n"
}; };
*/ */
const char code[] = const char code[] =
{ {
"uniform sampler samp0 : register(s0);\n" "uniform sampler samp0 : register(s0);\n"
"void main(\n" "void main(\n"
"out float4 ocol0 : COLOR0,\n" "out float4 ocol0 : COLOR0,\n"
"in float2 uv0 : TEXCOORD0){\n" "in float2 uv0 : TEXCOORD0){\n"
"float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n"
"float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n"
"float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n"
"ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n"
"}\n" "}\n"
}; };
if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
return s_rgb8_to_rgba6; return s_rgb8_to_rgba6;
} }
#define WRITE p+=sprintf #define WRITE p+=sprintf
static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode) static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode)
{ {
//Used for Copy/resolve the color buffer //Used for Copy/resolve the color buffer
//Color conversion Programs //Color conversion Programs
//Depth copy programs //Depth copy programs
// this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination
char text[3072]; char text[3072];
locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
locale_t old_locale = uselocale(locale); // Apply the locale for this thread locale_t old_locale = uselocale(locale); // Apply the locale for this thread
text[sizeof(text) - 1] = 0x7C; // canary text[sizeof(text) - 1] = 0x7C; // canary
char* p = text; char* p = text;
WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode);
WRITE(p, "uniform sampler samp0 : register(s0);\n"); WRITE(p, "uniform sampler samp0 : register(s0);\n");
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX);
WRITE(p, "void main(\n" WRITE(p, "void main(\n"
"out float4 ocol0 : COLOR0,\n"); "out float4 ocol0 : COLOR0,\n");
switch(SSAAMode % MAX_SSAA_SHADERS) switch(SSAAMode % MAX_SSAA_SHADERS)
{ {
case 0: // 1 Sample case 0: // 1 Sample
WRITE(p, "in float2 uv0 : TEXCOORD0,\n" WRITE(p, "in float2 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1){\n" "in float uv1 : TEXCOORD1){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n"); "float4 texcol = tex2D(samp0,uv0.xy);\n");
break; break;
case 1: // 4 Samples in 4x SSAA buffer case 1: // 4 Samples in 4x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n" WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n" "in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\n" "in float4 uv2 : TEXCOORD2,\n"
"in float4 uv3 : TEXCOORD3){\n" "in float4 uv3 : TEXCOORD3){\n"
"float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n");
break; break;
case 2: // 4 Samples in 9x SSAA buffer case 2: // 4 Samples in 9x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n" WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n" "in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\n" "in float4 uv2 : TEXCOORD2,\n"
"in float4 uv3 : TEXCOORD3){\n" "in float4 uv3 : TEXCOORD3){\n"
"float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n");
break; break;
} }
if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE)
{ {
// Watch out for the fire fumes effect in Metroid it's really sensitive to this, // Watch out for the fire fumes effect in Metroid it's really sensitive to this,
// the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off.
WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n"
"texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n");
} }
else else
{ {
//Apply Gamma Correction //Apply Gamma Correction
WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n");
} }
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
{ {
if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE)
WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n");
WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n");
} }
else else
WRITE(p, "ocol0 = texcol;\n"); WRITE(p, "ocol0 = texcol;\n");
WRITE(p, "}\n"); WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C) if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!");
uselocale(old_locale); // restore locale uselocale(old_locale); // restore locale
freelocale(locale); freelocale(locale);
return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); return D3D::CompileAndCreatePixelShader(text, (int)strlen(text));
} }
void PixelShaderCache::Init() void PixelShaderCache::Init()
{ {
last_entry = NULL; last_entry = NULL;
//program used for clear screen //program used for clear screen
{ {
char pprog[3072]; char pprog[3072];
sprintf(pprog, "void main(\n" sprintf(pprog, "void main(\n"
"out float4 ocol0 : COLOR0,\n" "out float4 ocol0 : COLOR0,\n"
" in float4 incol0 : COLOR0){\n" " in float4 incol0 : COLOR0){\n"
"ocol0 = incol0;\n" "ocol0 = incol0;\n"
"}\n"); "}\n");
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
} }
int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF);
int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
// other screen copy/convert programs // other screen copy/convert programs
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
{ {
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
{ {
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
{ {
if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1]
|| depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode]
|| copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])
{ {
// if it failed at a lower setting, it's going to fail here for the same reason it did there, // if it failed at a lower setting, it's going to fail here for the same reason it did there,
// so skip this attempt to avoid duplicate error messages. // so skip this attempt to avoid duplicate error messages.
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
} }
else else
{ {
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode);
} }
} }
} }
} }
Clear(); Clear();
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
SETSTAT(stats.numPixelShadersCreated, 0); SETSTAT(stats.numPixelShadersCreated, 0);
SETSTAT(stats.numPixelShadersAlive, 0); SETSTAT(stats.numPixelShadersAlive, 0);
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter; PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter); g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
if (g_Config.bEnableShaderDebugging) if (g_Config.bEnableShaderDebugging)
Clear(); Clear();
} }
// ONLY to be used during shutdown. // ONLY to be used during shutdown.
void PixelShaderCache::Clear() void PixelShaderCache::Clear()
{ {
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
PixelShaders.clear(); PixelShaders.clear();
pixel_uid_checker.Invalidate(); pixel_uid_checker.Invalidate();
last_entry = NULL; last_entry = NULL;
} }
void PixelShaderCache::Shutdown() void PixelShaderCache::Shutdown()
{ {
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] if(s_CopyProgram[copyMatrixType][depthType][ssaaMode]
&& (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]))
s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release();
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
if (s_ClearProgram) s_ClearProgram->Release(); if (s_ClearProgram) s_ClearProgram->Release();
s_ClearProgram = NULL; s_ClearProgram = NULL;
if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release();
s_rgb8_to_rgba6 = NULL; s_rgb8_to_rgba6 = NULL;
if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release();
s_rgba6_to_rgb8 = NULL; s_rgba6_to_rgb8 = NULL;
Clear(); Clear();
g_ps_disk_cache.Sync(); g_ps_disk_cache.Sync();
g_ps_disk_cache.Close(); g_ps_disk_cache.Close();
unique_shaders.clear(); unique_shaders.clear();
} }
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{ {
const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
PixelShaderUid uid; PixelShaderUid uid;
GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components);
if (g_ActiveConfig.bEnableShaderDebugging) if (g_ActiveConfig.bEnableShaderDebugging)
{ {
PixelShaderCode code; PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components);
pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p");
} }
// Check if the shader is already set // Check if the shader is already set
if (last_entry) if (last_entry)
{ {
if (uid == last_uid) if (uid == last_uid)
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return last_entry->shader != NULL; return last_entry->shader != NULL;
} }
} }
last_uid = uid; last_uid = uid;
// Check if the shader is already in the cache // Check if the shader is already in the cache
PSCache::iterator iter; PSCache::iterator iter;
iter = PixelShaders.find(uid); iter = PixelShaders.find(uid);
if (iter != PixelShaders.end()) if (iter != PixelShaders.end())
{ {
const PSCacheEntry &entry = iter->second; const PSCacheEntry &entry = iter->second;
last_entry = &entry; last_entry = &entry;
if (entry.shader) D3D::SetPixelShader(entry.shader); if (entry.shader) D3D::SetPixelShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
// Need to compile a new shader // Need to compile a new shader
PixelShaderCode code; PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, api, components); GeneratePixelShaderCode(code, dstAlphaMode, api, components);
if (g_ActiveConfig.bEnableShaderDebugging) if (g_ActiveConfig.bEnableShaderDebugging)
{ {
u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer()));
unique_shaders.insert(code_hash); unique_shaders.insert(code_hash);
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
} }
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { if (g_ActiveConfig.iLog & CONF_SAVESHADERS) {
static int counter = 0; static int counter = 0;
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
SaveData(szTemp, code.GetBuffer()); SaveData(szTemp, code.GetBuffer());
} }
#endif #endif
u8 *bytecode = 0; u8 *bytecode = 0;
int bytecodelen = 0; int bytecodelen = 0;
if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false; return false;
} }
// Insert the bytecode into the caches // Insert the bytecode into the caches
g_ps_disk_cache.Append(uid, bytecode, bytecodelen); g_ps_disk_cache.Append(uid, bytecode, bytecodelen);
// And insert it into the shader cache. // And insert it into the shader cache.
bool success = InsertByteCode(uid, bytecode, bytecodelen, true); bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
delete [] bytecode; delete [] bytecode;
if (g_ActiveConfig.bEnableShaderDebugging && success) if (g_ActiveConfig.bEnableShaderDebugging && success)
{ {
PixelShaders[uid].code = code.GetBuffer(); PixelShaders[uid].code = code.GetBuffer();
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return success; return success;
} }
bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate)
{ {
LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
// Make an entry in the table // Make an entry in the table
PSCacheEntry newentry; PSCacheEntry newentry;
newentry.shader = shader; newentry.shader = shader;
PixelShaders[uid] = newentry; PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid]; last_entry = &PixelShaders[uid];
if (!shader) { if (!shader) {
// INCSTAT(stats.numPixelShadersFailed); // INCSTAT(stats.numPixelShadersFailed);
return false; return false;
} }
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
if (activate) if (activate)
{ {
D3D::SetPixelShader(shader); D3D::SetPixelShader(shader);
} }
return true; return true;
} }
void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{ {
float f[4] = { f1, f2, f3, f4 }; float f[4] = { f1, f2, f3, f4 };
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
} }
void Renderer::SetPSConstant4fv(unsigned int const_number, const float *f) void Renderer::SetPSConstant4fv(unsigned int const_number, const float *f)
{ {
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
} }
void Renderer::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) void Renderer::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
{ {
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count);
} }
} // namespace DX9 } // namespace DX9

View File

@ -37,251 +37,257 @@ LinearDiskCache<VertexShaderUid, u8> g_vs_disk_cache;
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level) LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level)
{ {
return SimpleVertexShader[level % MAX_SSAA_SHADERS]; return SimpleVertexShader[level % MAX_SSAA_SHADERS];
} }
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
{ {
return ClearVertexShader; return ClearVertexShader;
} }
// this class will load the precompiled shaders into our cache // this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader<VertexShaderUid, u8> class VertexShaderCacheInserter : public LinearDiskCacheReader<VertexShaderUid, u8>
{ {
public: public:
void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) void Read(const VertexShaderUid &key, const u8 *value, u32 value_size)
{ {
VertexShaderCache::InsertByteCode(key, value, value_size, false); VertexShaderCache::InsertByteCode(key, value, value_size, false);
} }
}; };
void VertexShaderCache::Init() void VertexShaderCache::Init()
{ {
char* vProg = new char[2048]; char* vProg = new char[2048];
sprintf(vProg,"struct VSOUTPUT\n" sprintf(vProg,"struct VSOUTPUT\n"
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float2 vTexCoord : TEXCOORD0;\n" "float2 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n" "float vTexCoord1 : TEXCOORD1;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;\n" "VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0;\n" "OUT.vTexCoord = inTEX0;\n"
"OUT.vTexCoord1 = inTEX2;\n" "OUT.vTexCoord1 = inTEX2;\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg,"struct VSOUTPUT\n" sprintf(vProg,"struct VSOUTPUT\n"
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n" "float4 vColor0 : COLOR0;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
"{\n" "{\n"
"VSOUTPUT OUT;\n" "VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vColor0 = inColor0;\n" "OUT.vColor0 = inColor0;\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n" sprintf(vProg, "struct VSOUTPUT\n"
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n" "float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n" "float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n" "float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n" "float4 vTexCoord3 : TEXCOORD3;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;" "VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n" "OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\n" "OUT.vTexCoord1 = inTEX2.x;\n"
"OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n"
"OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n" sprintf(vProg, "struct VSOUTPUT\n"
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n" "float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n" "float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n" "float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n" "float4 vTexCoord3 : TEXCOORD3;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;" "VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n" "OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\n" "OUT.vTexCoord1 = inTEX2.x;\n"
"OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n"
"OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
Clear(); Clear();
delete [] vProg; delete [] vProg;
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
SETSTAT(stats.numVertexShadersCreated, 0); SETSTAT(stats.numVertexShadersCreated, 0);
SETSTAT(stats.numVertexShadersAlive, 0); SETSTAT(stats.numVertexShadersAlive, 0);
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter; VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter); g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
if (g_Config.bEnableShaderDebugging) if (g_Config.bEnableShaderDebugging)
Clear(); Clear();
last_entry = NULL; last_entry = NULL;
} }
void VertexShaderCache::Clear() void VertexShaderCache::Clear()
{ {
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
iter->second.Destroy(); iter->second.Destroy();
vshaders.clear(); vshaders.clear();
vertex_uid_checker.Invalidate(); vertex_uid_checker.Invalidate();
last_entry = NULL; last_entry = NULL;
} }
void VertexShaderCache::Shutdown() void VertexShaderCache::Shutdown()
{ {
for (int i = 0; i < MAX_SSAA_SHADERS; i++) for (int i = 0; i < MAX_SSAA_SHADERS; i++)
{ {
if (SimpleVertexShader[i]) if (SimpleVertexShader[i])
SimpleVertexShader[i]->Release(); SimpleVertexShader[i]->Release();
SimpleVertexShader[i] = NULL; SimpleVertexShader[i] = NULL;
} }
if (ClearVertexShader) if (ClearVertexShader)
ClearVertexShader->Release(); ClearVertexShader->Release();
ClearVertexShader = NULL; ClearVertexShader = NULL;
Clear(); Clear();
g_vs_disk_cache.Sync(); g_vs_disk_cache.Sync();
g_vs_disk_cache.Close(); g_vs_disk_cache.Close();
} }
bool VertexShaderCache::SetShader(u32 components) bool VertexShaderCache::SetShader(u32 components)
{ {
VertexShaderUid uid; VertexShaderUid uid;
GetVertexShaderUid(uid, components, API_D3D9); GetVertexShaderUid(uid, components, API_D3D9);
if (g_ActiveConfig.bEnableShaderDebugging) if (g_ActiveConfig.bEnableShaderDebugging)
{ {
VertexShaderCode code; VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9); GenerateVertexShaderCode(code, components, API_D3D9);
vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v");
} }
if (last_entry) if (last_entry)
{ {
if (uid == last_uid) if (uid == last_uid)
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (last_entry->shader != NULL); return (last_entry->shader != NULL);
} }
} }
last_uid = uid; last_uid = uid;
VSCache::iterator iter = vshaders.find(uid); VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end()) if (iter != vshaders.end())
{ {
const VSCacheEntry &entry = iter->second; const VSCacheEntry &entry = iter->second;
last_entry = &entry; last_entry = &entry;
if (entry.shader) D3D::SetVertexShader(entry.shader); if (entry.shader) D3D::SetVertexShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
VertexShaderCode code; VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9); GenerateVertexShaderCode(code, components, API_D3D9);
u8 *bytecode; u8 *bytecode;
int bytecodelen; int bytecodelen;
if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen))
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false; return false;
} }
g_vs_disk_cache.Append(uid, bytecode, bytecodelen); g_vs_disk_cache.Append(uid, bytecode, bytecodelen);
bool success = InsertByteCode(uid, bytecode, bytecodelen, true); bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
if (g_ActiveConfig.bEnableShaderDebugging && success) if (g_ActiveConfig.bEnableShaderDebugging && success)
{ {
vshaders[uid].code = code.GetBuffer(); vshaders[uid].code = code.GetBuffer();
} }
delete [] bytecode; delete [] bytecode;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return success; return success;
} }
bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) {
LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen);
// Make an entry in the table // Make an entry in the table
VSCacheEntry entry; VSCacheEntry entry;
entry.shader = shader; entry.shader = shader;
vshaders[uid] = entry; vshaders[uid] = entry;
last_entry = &vshaders[uid]; last_entry = &vshaders[uid];
if (!shader) if (!shader)
return false; return false;
INCSTAT(stats.numVertexShadersCreated); INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
if (activate) if (activate)
{ {
D3D::SetVertexShader(shader); D3D::SetVertexShader(shader);
return true; return true;
} }
return false; return false;
} }
float VSConstantbuffer[4*C_VENVCONST_END];
void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{ {
const float f[4] = { f1, f2, f3, f4 }; float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); VSConstantbuffer_pointer[0] = f1;
VSConstantbuffer_pointer[1] = f2;
VSConstantbuffer_pointer[2] = f3;
VSConstantbuffer_pointer[3] = f4;
DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1);
} }
void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f)
{ {
DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
} }
void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f)
{ {
float buf[4*C_VENVCONST_END]; float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
buf[4*i ] = *f++; *VSConstantbuffer_pointer++ = *f++;
buf[4*i+1] = *f++; *VSConstantbuffer_pointer++ = *f++;
buf[4*i+2] = *f++; *VSConstantbuffer_pointer++ = *f++;
buf[4*i+3] = 0.f; *VSConstantbuffer_pointer++ = 0.f;
} }
DX9::D3D::dev->SetVertexShaderConstantF(const_number, buf, count); DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count);
} }
void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
{ {
DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count);
} }
} // namespace DX9 } // namespace DX9

View File

@ -50,192 +50,192 @@
namespace DX9 namespace DX9
{ {
unsigned int VideoBackend::PeekMessages() unsigned int VideoBackend::PeekMessages()
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
void VideoBackend::UpdateFPSDisplay(const char *text)
{
TCHAR temp[512];
swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text);
EmuWindow::SetWindowText(temp);
}
std::string VideoBackend::GetName()
{
return "DX9";
}
std::string VideoBackend::GetDisplayName()
{
return "Direct3D9 (deprecated)";
}
void InitBackendInfo()
{
DX9::D3D::Init();
D3DCAPS9 device_caps = DX9::D3D::GetCaps();
const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF);
const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
g_Config.backend_info.bUseRGBATextures = false;
g_Config.backend_info.bUseMinimalMipCount = true;
g_Config.backend_info.bSupports3DVision = true;
g_Config.backend_info.bSupportsPrimitiveRestart = false; // TODO: figure out if it does
g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND;
// Dual source blend disabled by default until a proper method to test for support is found
g_Config.backend_info.bSupports3DVision = true;
OSVERSIONINFO info;
ZeroMemory(&info, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&info))
{ {
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
void VideoBackend::UpdateFPSDisplay(const char *text)
{
TCHAR temp[512];
swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text);
EmuWindow::SetWindowText(temp);
}
std::string VideoBackend::GetName()
{
return "DX9";
}
std::string VideoBackend::GetDisplayName()
{
return "Direct3D9 (deprecated)";
}
void InitBackendInfo()
{
DX9::D3D::Init();
D3DCAPS9 device_caps = DX9::D3D::GetCaps();
const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF);
const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
g_Config.backend_info.bUseRGBATextures = false;
g_Config.backend_info.bUseMinimalMipCount = true;
g_Config.backend_info.bSupports3DVision = true;
g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart
g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND;
// Dual source blend disabled by default until a proper method to test for support is found
g_Config.backend_info.bSupports3DVision = true;
OSVERSIONINFO info;
ZeroMemory(&info, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&info))
{
// dual source blending is only supported in windows 7 o newer. sorry xp users // dual source blending is only supported in windows 7 o newer. sorry xp users
// we cannot test for device caps because most drivers just declare the minimun caps // we cannot test for device caps because most drivers just declare the minimun caps
// and don't expose their support for some functionalities // and don't expose their support for some functionalities
g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1));
} }
else else
{ {
g_Config.backend_info.bSupportsDualSourceBlend = false; g_Config.backend_info.bSupportsDualSourceBlend = false;
}
g_Config.backend_info.bSupportsFormatReinterpretation = true;
g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants;
g_Config.backend_info.bSupportsEarlyZ = false;
// adapters
g_Config.backend_info.Adapters.clear();
for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i)
g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description);
// aamodes
g_Config.backend_info.AAModes.clear();
if (g_Config.iAdapter < DX9::D3D::GetNumAdapters())
{
const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter);
for (int i = 0; i < (int)adapter.aa_levels.size(); ++i)
g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name);
}
// Clear ppshaders string vector
g_Config.backend_info.PPShaders.clear();
DX9::D3D::Shutdown();
} }
g_Config.backend_info.bSupportsFormatReinterpretation = true;
g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants;
g_Config.backend_info.bSupportsEarlyZ = false;
// adapters void VideoBackend::ShowConfig(void* parent)
g_Config.backend_info.Adapters.clear(); {
for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i)
g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description);
// aamodes
g_Config.backend_info.AAModes.clear();
if (g_Config.iAdapter < DX9::D3D::GetNumAdapters())
{
const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter);
for (int i = 0; i < (int)adapter.aa_levels.size(); ++i)
g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name);
}
// Clear ppshaders string vector
g_Config.backend_info.PPShaders.clear();
DX9::D3D::Shutdown();
}
void VideoBackend::ShowConfig(void* parent)
{
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
InitBackendInfo(); InitBackendInfo();
VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9");
diag.ShowModal(); diag.ShowModal();
#endif #endif
} }
bool VideoBackend::Initialize(void *&window_handle) bool VideoBackend::Initialize(void *&window_handle)
{ {
InitializeShared(); InitializeShared();
InitBackendInfo(); InitBackendInfo();
frameCount = 0; frameCount = 0;
g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str());
g_Config.UpdateProjectionHack(); g_Config.UpdateProjectionHack();
g_Config.VerifyValidity(); g_Config.VerifyValidity();
// as only some driver/hardware configurations support dual source blending only enable it if is // as only some driver/hardware configurations support dual source blending only enable it if is
// configured by user // configured by user
g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend;
UpdateActiveConfig(); UpdateActiveConfig();
window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait."));
if (window_handle == NULL) if (window_handle == NULL)
{ {
ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
return false; return false;
} }
else if (FAILED(DX9::D3D::Init())) else if (FAILED(DX9::D3D::Init()))
{ {
MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK);
return false; return false;
} }
s_BackendInitialized = true; s_BackendInitialized = true;
return true; return true;
} }
void VideoBackend::Video_Prepare() void VideoBackend::Video_Prepare()
{ {
// Better be safe... // Better be safe...
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
// internal interfaces // internal interfaces
g_vertex_manager = new VertexManager; g_vertex_manager = new VertexManager;
g_perf_query = new PerfQuery; g_perf_query = new PerfQuery;
g_renderer = new Renderer; g_renderer = new Renderer;
g_texture_cache = new TextureCache; g_texture_cache = new TextureCache;
// VideoCommon // VideoCommon
BPInit(); BPInit();
Fifo_Init(); Fifo_Init();
IndexGenerator::Init(); IndexGenerator::Init();
VertexLoaderManager::Init(); VertexLoaderManager::Init();
OpcodeDecoder_Init(); OpcodeDecoder_Init();
VertexShaderManager::Init(); VertexShaderManager::Init();
PixelShaderManager::Init(); PixelShaderManager::Init();
CommandProcessor::Init(); CommandProcessor::Init();
PixelEngine::Init(); PixelEngine::Init();
DLCache::Init(); DLCache::Init();
// Notify the core that the video backend is ready // Notify the core that the video backend is ready
Host_Message(WM_USER_CREATE); Host_Message(WM_USER_CREATE);
} }
void VideoBackend::Shutdown() void VideoBackend::Shutdown()
{ {
s_BackendInitialized = false; s_BackendInitialized = false;
// TODO: should be in Video_Cleanup // TODO: should be in Video_Cleanup
if (g_renderer) if (g_renderer)
{ {
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
// VideoCommon // VideoCommon
DLCache::Shutdown(); DLCache::Shutdown();
Fifo_Shutdown(); Fifo_Shutdown();
CommandProcessor::Shutdown(); CommandProcessor::Shutdown();
PixelShaderManager::Shutdown(); PixelShaderManager::Shutdown();
VertexShaderManager::Shutdown(); VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
VertexLoaderManager::Shutdown(); VertexLoaderManager::Shutdown();
// internal interfaces // internal interfaces
PixelShaderCache::Shutdown(); PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown(); VertexShaderCache::Shutdown();
delete g_texture_cache; delete g_texture_cache;
delete g_renderer; delete g_renderer;
delete g_perf_query; delete g_perf_query;
delete g_vertex_manager; delete g_vertex_manager;
g_renderer = NULL; g_renderer = NULL;
g_texture_cache = NULL; g_texture_cache = NULL;
} }
D3D::Shutdown(); D3D::Shutdown();
} }
void VideoBackend::Video_Cleanup() { void VideoBackend::Video_Cleanup() {
} }
} }