Revert wrong indentation of some files. sorry for that one i was really convinced that i read that spaces must be used instead of tabs :)

This commit is contained in:
Rodolfo Bogado 2013-08-15 15:40:57 -03:00
parent 08a6b8920b
commit 1de39a4a6e
5 changed files with 2008 additions and 2008 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

File diff suppressed because it is too large Load Diff

View File

@ -36,383 +36,383 @@ const u32 MAX_VBUFFER_COUNT = 2;
inline void DumpBadShaders() inline void DumpBadShaders()
{ {
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
// TODO: Reimplement! // TODO: Reimplement!
/* std::string error_shaders; /* std::string error_shaders;
error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
char filename[512] = "bad_shader_combo_0.txt"; char filename[512] = "bad_shader_combo_0.txt";
int which = 0; int which = 0;
while (File::Exists(filename)) while (File::Exists(filename))
{ {
which++; which++;
sprintf(filename, "bad_shader_combo_%i.txt", which); sprintf(filename, "bad_shader_combo_%i.txt", which);
} }
File::WriteStringToFile(true, error_shaders, filename); File::WriteStringToFile(true, error_shaders, filename);
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/
#endif #endif
} }
void VertexManager::CreateDeviceObjects() void VertexManager::CreateDeviceObjects()
{ {
m_buffers_count = 0; m_buffers_count = 0;
m_vertex_buffers = NULL; m_vertex_buffers = NULL;
m_index_buffers = NULL; m_index_buffers = NULL;
D3DCAPS9 DeviceCaps = D3D::GetCaps(); D3DCAPS9 DeviceCaps = D3D::GetCaps();
u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride;
//Calculate Device Dependant size //Calculate Device Dependant size
m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE;
m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE;
//if device caps are not enough for Vbuffer fall back to vertex arrays //if device caps are not enough for Vbuffer fall back to vertex arrays
if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return;
m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT];
m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT];
bool Fail = false; bool Fail = false;
for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
m_vertex_buffers[m_current_vertex_buffer] = NULL; m_vertex_buffers[m_current_vertex_buffer] = NULL;
m_index_buffers[m_current_vertex_buffer] = NULL; m_index_buffers[m_current_vertex_buffer] = NULL;
} }
for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) )
{ {
Fail = true; Fail = true;
break; break;
} }
if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) )
{ {
Fail = true; Fail = true;
return; return;
} }
} }
m_buffers_count = m_current_vertex_buffer; m_buffers_count = m_current_vertex_buffer;
m_current_vertex_buffer = 0; m_current_vertex_buffer = 0;
m_current_index_buffer = 0; m_current_index_buffer = 0;
m_index_buffer_cursor = m_index_buffer_size; m_index_buffer_cursor = m_index_buffer_size;
m_vertex_buffer_cursor = m_vertex_buffer_size; m_vertex_buffer_cursor = m_vertex_buffer_size;
m_current_stride = 0; m_current_stride = 0;
if (Fail) if (Fail)
{ {
m_buffers_count--; m_buffers_count--;
if (m_buffers_count < 2) if (m_buffers_count < 2)
{ {
//Error creating Vertex buffers. clean and fall to Vertex arrays //Error creating Vertex buffers. clean and fall to Vertex arrays
m_buffers_count = MAX_VBUFFER_COUNT; m_buffers_count = MAX_VBUFFER_COUNT;
DestroyDeviceObjects(); DestroyDeviceObjects();
} }
} }
} }
void VertexManager::DestroyDeviceObjects() void VertexManager::DestroyDeviceObjects()
{ {
D3D::SetStreamSource( 0, NULL, 0, 0); D3D::SetStreamSource( 0, NULL, 0, 0);
D3D::SetIndices(NULL); D3D::SetIndices(NULL);
for (int i = 0; i < MAX_VBUFFER_COUNT; i++) for (int i = 0; i < MAX_VBUFFER_COUNT; i++)
{ {
if(m_vertex_buffers) if(m_vertex_buffers)
{ {
if (m_vertex_buffers[i]) if (m_vertex_buffers[i])
{ {
m_vertex_buffers[i]->Release(); m_vertex_buffers[i]->Release();
m_vertex_buffers[i] = NULL; m_vertex_buffers[i] = NULL;
} }
} }
if (m_index_buffers[i]) if (m_index_buffers[i])
{ {
m_index_buffers[i]->Release(); m_index_buffers[i]->Release();
m_index_buffers[i] = NULL; m_index_buffers[i] = NULL;
} }
} }
if(m_vertex_buffers) if(m_vertex_buffers)
delete [] m_vertex_buffers; delete [] m_vertex_buffers;
if(m_index_buffers) if(m_index_buffers)
delete [] m_index_buffers; delete [] m_index_buffers;
m_vertex_buffers = NULL; m_vertex_buffers = NULL;
m_index_buffers = NULL; m_index_buffers = NULL;
} }
void VertexManager::PrepareDrawBuffers(u32 stride) void VertexManager::PrepareDrawBuffers(u32 stride)
{ {
if (!m_buffers_count) if (!m_buffers_count)
{ {
return; return;
} }
u8* pVertices; u8* pVertices;
u16* pIndices; u16* pIndices;
int datasize = IndexGenerator::GetNumVerts() * stride; int datasize = IndexGenerator::GetNumVerts() * stride;
int TdataSize = IndexGenerator::GetTriangleindexLen(); int TdataSize = IndexGenerator::GetTriangleindexLen();
int LDataSize = IndexGenerator::GetLineindexLen(); int LDataSize = IndexGenerator::GetLineindexLen();
int IndexDataSize = TdataSize + LDataSize; int IndexDataSize = TdataSize + LDataSize;
if(IndexDataSize) if(IndexDataSize)
{ {
DWORD LockMode = D3DLOCK_NOOVERWRITE; DWORD LockMode = D3DLOCK_NOOVERWRITE;
m_vertex_buffer_cursor--; m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize)
{ {
LockMode = D3DLOCK_DISCARD; LockMode = D3DLOCK_DISCARD;
m_vertex_buffer_cursor = 0; m_vertex_buffer_cursor = 0;
m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count;
} }
if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode)))
{ {
DestroyDeviceObjects(); DestroyDeviceObjects();
return; return;
} }
memcpy(pVertices, s_pBaseBufferPointer, datasize); memcpy(pVertices, s_pBaseBufferPointer, datasize);
m_vertex_buffers[m_current_vertex_buffer]->Unlock(); m_vertex_buffers[m_current_vertex_buffer]->Unlock();
LockMode = D3DLOCK_NOOVERWRITE; LockMode = D3DLOCK_NOOVERWRITE;
if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize)
{ {
LockMode = D3DLOCK_DISCARD; LockMode = D3DLOCK_DISCARD;
m_index_buffer_cursor = 0; m_index_buffer_cursor = 0;
m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count;
} }
if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode )))
{ {
DestroyDeviceObjects(); DestroyDeviceObjects();
return; return;
} }
if(TdataSize) if(TdataSize)
{ {
memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16));
pIndices += TdataSize; pIndices += TdataSize;
} }
if(LDataSize) if(LDataSize)
{ {
memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16));
pIndices += LDataSize; pIndices += LDataSize;
} }
m_index_buffers[m_current_index_buffer]->Unlock(); m_index_buffers[m_current_index_buffer]->Unlock();
} }
if(m_current_stride != stride || m_vertex_buffer_cursor == 0) if(m_current_stride != stride || m_vertex_buffer_cursor == 0)
{ {
m_current_stride = stride; m_current_stride = stride;
D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride);
} }
if (m_index_buffer_cursor == 0) if (m_index_buffer_cursor == 0)
{ {
D3D::SetIndices(m_index_buffers[m_current_index_buffer]); D3D::SetIndices(m_index_buffers[m_current_index_buffer]);
} }
ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize);
ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize);
} }
void VertexManager::DrawVertexBuffer(int stride) void VertexManager::DrawVertexBuffer(int stride)
{ {
int triangles = IndexGenerator::GetNumTriangles(); int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines(); int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints(); int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts(); int numverts = IndexGenerator::GetNumVerts();
int StartIndex = m_index_buffer_cursor; int StartIndex = m_index_buffer_cursor;
int basevertex = m_vertex_buffer_cursor / stride; int basevertex = m_vertex_buffer_cursor / stride;
if (triangles > 0) if (triangles > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitive( if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
basevertex, basevertex,
0, 0,
numverts, numverts,
StartIndex, StartIndex,
triangles))) triangles)))
{ {
DumpBadShaders(); DumpBadShaders();
} }
StartIndex += IndexGenerator::GetTriangleindexLen(); StartIndex += IndexGenerator::GetTriangleindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (lines > 0) if (lines > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitive( if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST, D3DPT_LINELIST,
basevertex, basevertex,
0, 0,
numverts, numverts,
StartIndex, StartIndex,
IndexGenerator::GetNumLines()))) IndexGenerator::GetNumLines())))
{ {
DumpBadShaders(); DumpBadShaders();
} }
StartIndex += IndexGenerator::GetLineindexLen(); StartIndex += IndexGenerator::GetLineindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (points > 0) if (points > 0)
{ {
//DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive
u16* PointIndexBuffer = GetPointIndexBuffer(); u16* PointIndexBuffer = GetPointIndexBuffer();
int i = 0; int i = 0;
do do
{ {
int count = i + 1; int count = i + 1;
while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count])
{ {
count++; count++;
} }
if (FAILED(D3D::dev->DrawPrimitive( if (FAILED(D3D::dev->DrawPrimitive(
D3DPT_POINTLIST, D3DPT_POINTLIST,
basevertex + PointIndexBuffer[i], basevertex + PointIndexBuffer[i],
count - i))) count - i)))
{ {
DumpBadShaders(); DumpBadShaders();
} }
INCSTAT(stats.thisFrame.numDrawCalls); INCSTAT(stats.thisFrame.numDrawCalls);
i = count; i = count;
} while (i < points); } while (i < points);
} }
} }
void VertexManager::DrawVertexArray(int stride) void VertexManager::DrawVertexArray(int stride)
{ {
int triangles = IndexGenerator::GetNumTriangles(); int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines(); int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints(); int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts(); int numverts = IndexGenerator::GetNumVerts();
if (triangles > 0) if (triangles > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
0, numverts, triangles, 0, numverts, triangles,
GetTriangleIndexBuffer(), GetTriangleIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))
{ {
DumpBadShaders(); DumpBadShaders();
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (lines > 0) if (lines > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST, D3DPT_LINELIST,
0, numverts, lines, 0, numverts, lines,
GetLineIndexBuffer(), GetLineIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))
{ {
DumpBadShaders(); DumpBadShaders();
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (points > 0) if (points > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST, D3DPT_POINTLIST,
0, numverts, points, 0, numverts, points,
GetPointIndexBuffer(), GetPointIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))
{ {
DumpBadShaders(); DumpBadShaders();
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
} }
void VertexManager::vFlush() void VertexManager::vFlush()
{ {
u32 usedtextures = 0; u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i / 2].getEnable(i & 1)) if (bpmem.tevorders[i / 2].getEnable(i & 1))
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
if (bpmem.genMode.numindstages > 0) if (bpmem.genMode.numindstages > 0)
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
for (unsigned int i = 0; i < 8; i++) for (unsigned int i = 0; i < 8; i++)
{ {
if (usedtextures & (1 << i)) if (usedtextures & (1 << i))
{ {
g_renderer->SetSamplerState(i & 3, i >> 2); g_renderer->SetSamplerState(i & 3, i >> 2);
FourTexUnits &tex = bpmem.tex[i >> 2]; FourTexUnits &tex = bpmem.tex[i >> 2];
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format, tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3), (tex.texMode0[i&3].min_filter & 3),
(tex.texMode1[i&3].max_lod + 0xf) / 0x10, (tex.texMode1[i&3].max_lod + 0xf) / 0x10,
tex.texImage1[i&3].image_type); tex.texImage1[i&3].image_type);
if (tentry) if (tentry)
{ {
// 0s are probably for no manual wrapping needed. // 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
} }
else else
ERROR_LOG(VIDEO, "Error loading texture"); ERROR_LOG(VIDEO, "Error loading texture");
} }
} }
// set global constants // set global constants
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components);
u32 stride = g_nativeVertexFmt->GetVertexStride(); u32 stride = g_nativeVertexFmt->GetVertexStride();
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE;
if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components))
{ {
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail; goto shader_fail;
} }
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
{ {
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");});
goto shader_fail; goto shader_fail;
} }
PrepareDrawBuffers(stride); PrepareDrawBuffers(stride);
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if(m_buffers_count) if(m_buffers_count)
{ {
DrawVertexBuffer(stride); DrawVertexBuffer(stride);
} }
else else
{ {
DrawVertexArray(stride); DrawVertexArray(stride);
} }
g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if (useDstAlpha && !useDualSource) if (useDstAlpha && !useDualSource)
{ {
if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components))
{ {
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail; goto shader_fail;
} }
// update alpha only // update alpha only
g_renderer->ApplyState(true); g_renderer->ApplyState(true);
if(m_buffers_count) if(m_buffers_count)
{ {
DrawVertexBuffer(stride); DrawVertexBuffer(stride);
} }
else else
{ {
DrawVertexArray(stride); DrawVertexArray(stride);
} }
g_renderer->RestoreState(); g_renderer->RestoreState();
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
shader_fail: shader_fail:
if(m_buffers_count) if(m_buffers_count)
{ {
m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride;
} }
} }
} }

View File

@ -37,257 +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]; 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)
{ {
float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
VSConstantbuffer_pointer[0] = f1; VSConstantbuffer_pointer[0] = f1;
VSConstantbuffer_pointer[1] = f2; VSConstantbuffer_pointer[1] = f2;
VSConstantbuffer_pointer[2] = f3; VSConstantbuffer_pointer[2] = f3;
VSConstantbuffer_pointer[3] = f4; VSConstantbuffer_pointer[3] = f4;
DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); 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* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
*VSConstantbuffer_pointer++ = *f++; *VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++; *VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++; *VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = 0.f; *VSConstantbuffer_pointer++ = 0.f;
} }
DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], 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; MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{ {
if (msg.message == WM_QUIT) if (msg.message == WM_QUIT)
return FALSE; return FALSE;
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
return TRUE; return TRUE;
} }
void VideoBackend::UpdateFPSDisplay(const char *text) void VideoBackend::UpdateFPSDisplay(const char *text)
{ {
TCHAR temp[512]; TCHAR temp[512];
swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text);
EmuWindow::SetWindowText(temp); EmuWindow::SetWindowText(temp);
} }
std::string VideoBackend::GetName() std::string VideoBackend::GetName()
{ {
return "DX9"; return "DX9";
} }
std::string VideoBackend::GetDisplayName() std::string VideoBackend::GetDisplayName()
{ {
return "Direct3D9 (deprecated)"; return "Direct3D9 (deprecated)";
} }
void InitBackendInfo() void InitBackendInfo()
{ {
DX9::D3D::Init(); DX9::D3D::Init();
D3DCAPS9 device_caps = DX9::D3D::GetCaps(); D3DCAPS9 device_caps = DX9::D3D::GetCaps();
const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF);
const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); 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.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
g_Config.backend_info.bUseRGBATextures = false; g_Config.backend_info.bUseRGBATextures = false;
g_Config.backend_info.bUseMinimalMipCount = true; g_Config.backend_info.bUseMinimalMipCount = true;
g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupports3DVision = true;
g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart
g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; 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 // Dual source blend disabled by default until a proper method to test for support is found
g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupports3DVision = true;
OSVERSIONINFO info; OSVERSIONINFO info;
ZeroMemory(&info, sizeof(OSVERSIONINFO)); ZeroMemory(&info, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&info)) 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.bSupportsFormatReinterpretation = true;
g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants;
g_Config.backend_info.bSupportsEarlyZ = false; g_Config.backend_info.bSupportsEarlyZ = false;
// adapters // adapters
g_Config.backend_info.Adapters.clear(); g_Config.backend_info.Adapters.clear();
for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i)
g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description);
// aamodes // aamodes
g_Config.backend_info.AAModes.clear(); g_Config.backend_info.AAModes.clear();
if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) if (g_Config.iAdapter < DX9::D3D::GetNumAdapters())
{ {
const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter);
for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) for (int i = 0; i < (int)adapter.aa_levels.size(); ++i)
g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name);
} }
// Clear ppshaders string vector // Clear ppshaders string vector
g_Config.backend_info.PPShaders.clear(); g_Config.backend_info.PPShaders.clear();
DX9::D3D::Shutdown(); DX9::D3D::Shutdown();
} }
void VideoBackend::ShowConfig(void* parent) 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() {
} }
} }