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
enum
{
COPY_TYPE_DIRECT,
COPY_TYPE_MATRIXCOLOR,
NUM_COPY_TYPES
COPY_TYPE_DIRECT,
COPY_TYPE_MATRIXCOLOR,
NUM_COPY_TYPES
};
enum
{
DEPTH_CONVERSION_TYPE_NONE,
DEPTH_CONVERSION_TYPE_ON,
NUM_DEPTH_CONVERSION_TYPES
DEPTH_CONVERSION_TYPE_NONE,
DEPTH_CONVERSION_TYPE_ON,
NUM_DEPTH_CONVERSION_TYPES
};
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>
{
public:
void Read(const PixelShaderUid &key, const u8 *value, u32 value_size)
{
PixelShaderCache::InsertByteCode(key, value, value_size, false);
}
void Read(const PixelShaderUid &key, const u8 *value, u32 value_size)
{
PixelShaderCache::InsertByteCode(key, value, value_size, false);
}
};
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)
{
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)
{
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()
{
return s_ClearProgram;
return s_ClearProgram;
}
static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL;
@ -90,360 +90,360 @@ static LPDIRECT3DPIXELSHADER9 s_rgba6 = NULL;
LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8()
{
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
" out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\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.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.a = 255.f;\n"
" ocol0 /= 255.f;\n"
"}\n"
};
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
" out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\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.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.a = 255.f;\n"
" ocol0 /= 255.f;\n"
"}\n"
};
if (!s_rgba6_to_rgb8)
s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
if (!s_rgba6_to_rgb8)
s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
return s_rgba6_to_rgb8;
return s_rgba6_to_rgb8;
}
LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6()
{
/* old code here for reference
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
" out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\n"
" float4 src8 = round(ocol0*255.f);\n"
" 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.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 /= 63.f;\n"
"}\n"
};
*/
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\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 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n"
"float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n"
"ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n"
"}\n"
};
if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
return s_rgb8_to_rgba6;
/* old code here for reference
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
" out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0){\n"
" ocol0 = tex2D(samp0,uv0);\n"
" float4 src8 = round(ocol0*255.f);\n"
" 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.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 /= 63.f;\n"
"}\n"
};
*/
const char code[] =
{
"uniform sampler samp0 : register(s0);\n"
"void main(\n"
"out float4 ocol0 : COLOR0,\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 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n"
"float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n"
"ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n"
"}\n"
};
if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code));
return s_rgb8_to_rgba6;
}
#define WRITE p+=sprintf
static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode)
{
//Used for Copy/resolve the color buffer
//Color conversion 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
char text[3072];
//Used for Copy/resolve the color buffer
//Color conversion 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
char text[3072];
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
text[sizeof(text) - 1] = 0x7C; // canary
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
text[sizeof(text) - 1] = 0x7C; // canary
char* p = text;
WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode);
char* p = text;
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");
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX);
WRITE(p, "void main(\n"
"out float4 ocol0 : COLOR0,\n");
WRITE(p, "uniform sampler samp0 : register(s0);\n");
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX);
WRITE(p, "void main(\n"
"out float4 ocol0 : COLOR0,\n");
switch(SSAAMode % MAX_SSAA_SHADERS)
{
case 0: // 1 Sample
WRITE(p, "in float2 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n");
break;
case 1: // 4 Samples in 4x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\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");
break;
case 2: // 4 Samples in 9x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\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");
break;
}
switch(SSAAMode % MAX_SSAA_SHADERS)
{
case 0: // 1 Sample
WRITE(p, "in float2 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n");
break;
case 1: // 4 Samples in 4x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\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");
break;
case 2: // 4 Samples in 9x SSAA buffer
WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\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");
break;
}
if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE)
{
// 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.
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");
}
else
{
//Apply Gamma Correction
WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n");
}
if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE)
{
// 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.
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");
}
else
{
//Apply Gamma Correction
WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n");
}
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
{
if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE)
WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n");
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
{
if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE)
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");
}
else
WRITE(p, "ocol0 = texcol;\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
WRITE(p, "ocol0 = texcol;\n");
WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!");
WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!");
uselocale(old_locale); // restore locale
freelocale(locale);
return D3D::CompileAndCreatePixelShader(text, (int)strlen(text));
uselocale(old_locale); // restore locale
freelocale(locale);
return D3D::CompileAndCreatePixelShader(text, (int)strlen(text));
}
void PixelShaderCache::Init()
{
last_entry = NULL;
last_entry = NULL;
//program used for clear screen
{
char pprog[3072];
sprintf(pprog, "void main(\n"
"out float4 ocol0 : COLOR0,\n"
" in float4 incol0 : COLOR0){\n"
"ocol0 = incol0;\n"
"}\n");
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
}
//program used for clear screen
{
char pprog[3072];
sprintf(pprog, "void main(\n"
"out float4 ocol0 : COLOR0,\n"
" in float4 incol0 : COLOR0){\n"
"ocol0 = incol0;\n"
"}\n");
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
}
int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF);
int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF);
int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
// other screen copy/convert programs
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
{
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
{
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
{
if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1]
|| depthType && !s_CopyProgram[copyMatrixType][depthType-1][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,
// so skip this attempt to avoid duplicate error messages.
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
}
else
{
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode);
}
}
}
}
// other screen copy/convert programs
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
{
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
{
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
{
if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1]
|| depthType && !s_CopyProgram[copyMatrixType][depthType-1][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,
// so skip this attempt to avoid duplicate error messages.
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
}
else
{
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode);
}
}
}
}
Clear();
Clear();
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
SETSTAT(stats.numPixelShadersCreated, 0);
SETSTAT(stats.numPixelShadersAlive, 0);
SETSTAT(stats.numPixelShadersCreated, 0);
SETSTAT(stats.numPixelShadersAlive, 0);
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
if (g_Config.bEnableShaderDebugging)
Clear();
if (g_Config.bEnableShaderDebugging)
Clear();
}
// ONLY to be used during shutdown.
void PixelShaderCache::Clear()
{
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
iter->second.Destroy();
PixelShaders.clear();
pixel_uid_checker.Invalidate();
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
iter->second.Destroy();
PixelShaders.clear();
pixel_uid_checker.Invalidate();
last_entry = NULL;
last_entry = NULL;
}
void PixelShaderCache::Shutdown()
{
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
if(s_CopyProgram[copyMatrixType][depthType][ssaaMode]
&& (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]))
s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release();
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
if(s_CopyProgram[copyMatrixType][depthType][ssaaMode]
&& (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]))
s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release();
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
if (s_ClearProgram) s_ClearProgram->Release();
s_ClearProgram = NULL;
if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release();
s_rgb8_to_rgba6 = NULL;
if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release();
s_rgba6_to_rgb8 = NULL;
if (s_ClearProgram) s_ClearProgram->Release();
s_ClearProgram = NULL;
if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release();
s_rgb8_to_rgba6 = NULL;
if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release();
s_rgba6_to_rgb8 = NULL;
Clear();
g_ps_disk_cache.Sync();
g_ps_disk_cache.Close();
Clear();
g_ps_disk_cache.Sync();
g_ps_disk_cache.Close();
unique_shaders.clear();
unique_shaders.clear();
}
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
PixelShaderUid uid;
GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components);
if (g_ActiveConfig.bEnableShaderDebugging)
{
PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components);
pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p");
}
const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
PixelShaderUid uid;
GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components);
if (g_ActiveConfig.bEnableShaderDebugging)
{
PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components);
pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p");
}
// Check if the shader is already set
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return last_entry->shader != NULL;
}
}
// Check if the shader is already set
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return last_entry->shader != NULL;
}
}
last_uid = uid;
last_uid = uid;
// Check if the shader is already in the cache
PSCache::iterator iter;
iter = PixelShaders.find(uid);
if (iter != PixelShaders.end())
{
const PSCacheEntry &entry = iter->second;
last_entry = &entry;
// Check if the shader is already in the cache
PSCache::iterator iter;
iter = PixelShaders.find(uid);
if (iter != PixelShaders.end())
{
const PSCacheEntry &entry = iter->second;
last_entry = &entry;
if (entry.shader) D3D::SetPixelShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return (entry.shader != NULL);
}
if (entry.shader) D3D::SetPixelShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return (entry.shader != NULL);
}
// Need to compile a new shader
PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, api, components);
// Need to compile a new shader
PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, api, components);
if (g_ActiveConfig.bEnableShaderDebugging)
{
u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer()));
unique_shaders.insert(code_hash);
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
}
if (g_ActiveConfig.bEnableShaderDebugging)
{
u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer()));
unique_shaders.insert(code_hash);
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
}
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS) {
static int counter = 0;
char szTemp[MAX_PATH];
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
if (g_ActiveConfig.iLog & CONF_SAVESHADERS) {
static int counter = 0;
char szTemp[MAX_PATH];
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
SaveData(szTemp, code.GetBuffer());
}
SaveData(szTemp, code.GetBuffer());
}
#endif
u8 *bytecode = 0;
int bytecodelen = 0;
if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
u8 *bytecode = 0;
int bytecodelen = 0;
if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
// Insert the bytecode into the caches
g_ps_disk_cache.Append(uid, bytecode, bytecodelen);
// Insert the bytecode into the caches
g_ps_disk_cache.Append(uid, bytecode, bytecodelen);
// And insert it into the shader cache.
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
delete [] bytecode;
// And insert it into the shader cache.
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
delete [] bytecode;
if (g_ActiveConfig.bEnableShaderDebugging && success)
{
PixelShaders[uid].code = code.GetBuffer();
}
if (g_ActiveConfig.bEnableShaderDebugging && success)
{
PixelShaders[uid].code = code.GetBuffer();
}
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return success;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return success;
}
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
PSCacheEntry newentry;
newentry.shader = shader;
PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid];
// Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid];
if (!shader) {
// INCSTAT(stats.numPixelShadersFailed);
return false;
}
if (!shader) {
// INCSTAT(stats.numPixelShadersFailed);
return false;
}
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
if (activate)
{
D3D::SetPixelShader(shader);
}
return true;
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
if (activate)
{
D3D::SetPixelShader(shader);
}
return true;
}
void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{
float f[4] = { f1, f2, f3, f4 };
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
float f[4] = { f1, f2, f3, f4 };
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
}
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)
{
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count);
DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count);
}
} // 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()
{
#if defined(_DEBUG) || defined(DEBUGFAST)
// TODO: Reimplement!
/* std::string error_shaders;
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
char filename[512] = "bad_shader_combo_0.txt";
int which = 0;
while (File::Exists(filename))
{
which++;
sprintf(filename, "bad_shader_combo_%i.txt", which);
}
File::WriteStringToFile(true, error_shaders, filename);
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/
// TODO: Reimplement!
/* std::string error_shaders;
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
char filename[512] = "bad_shader_combo_0.txt";
int which = 0;
while (File::Exists(filename))
{
which++;
sprintf(filename, "bad_shader_combo_%i.txt", which);
}
File::WriteStringToFile(true, error_shaders, filename);
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/
#endif
}
void VertexManager::CreateDeviceObjects()
{
m_buffers_count = 0;
m_vertex_buffers = NULL;
m_index_buffers = NULL;
D3DCAPS9 DeviceCaps = D3D::GetCaps();
u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride;
//Calculate Device Dependant size
m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_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 (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return;
m_buffers_count = 0;
m_vertex_buffers = NULL;
m_index_buffers = NULL;
D3DCAPS9 DeviceCaps = D3D::GetCaps();
u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride;
//Calculate Device Dependant size
m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_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 (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return;
m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT];
m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT];
m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT];
m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT];
bool Fail = false;
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_index_buffers[m_current_vertex_buffer] = NULL;
}
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 ) ) )
{
Fail = true;
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 ) ) )
{
Fail = true;
return;
}
}
m_buffers_count = m_current_vertex_buffer;
m_current_vertex_buffer = 0;
m_current_index_buffer = 0;
m_index_buffer_cursor = m_index_buffer_size;
m_vertex_buffer_cursor = m_vertex_buffer_size;
m_current_stride = 0;
if (Fail)
{
m_buffers_count--;
if (m_buffers_count < 2)
{
//Error creating Vertex buffers. clean and fall to Vertex arrays
m_buffers_count = MAX_VBUFFER_COUNT;
DestroyDeviceObjects();
}
}
bool Fail = false;
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_index_buffers[m_current_vertex_buffer] = NULL;
}
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 ) ) )
{
Fail = true;
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 ) ) )
{
Fail = true;
return;
}
}
m_buffers_count = m_current_vertex_buffer;
m_current_vertex_buffer = 0;
m_current_index_buffer = 0;
m_index_buffer_cursor = m_index_buffer_size;
m_vertex_buffer_cursor = m_vertex_buffer_size;
m_current_stride = 0;
if (Fail)
{
m_buffers_count--;
if (m_buffers_count < 2)
{
//Error creating Vertex buffers. clean and fall to Vertex arrays
m_buffers_count = MAX_VBUFFER_COUNT;
DestroyDeviceObjects();
}
}
}
void VertexManager::DestroyDeviceObjects()
{
D3D::SetStreamSource( 0, NULL, 0, 0);
D3D::SetIndices(NULL);
for (int i = 0; i < MAX_VBUFFER_COUNT; i++)
{
if(m_vertex_buffers)
{
if (m_vertex_buffers[i])
{
m_vertex_buffers[i]->Release();
m_vertex_buffers[i] = NULL;
}
}
D3D::SetStreamSource( 0, NULL, 0, 0);
D3D::SetIndices(NULL);
for (int i = 0; i < MAX_VBUFFER_COUNT; i++)
{
if(m_vertex_buffers)
{
if (m_vertex_buffers[i])
{
m_vertex_buffers[i]->Release();
m_vertex_buffers[i] = NULL;
}
}
if (m_index_buffers[i])
{
m_index_buffers[i]->Release();
m_index_buffers[i] = NULL;
}
}
if(m_vertex_buffers)
delete [] m_vertex_buffers;
if(m_index_buffers)
delete [] m_index_buffers;
m_vertex_buffers = NULL;
m_index_buffers = NULL;
if (m_index_buffers[i])
{
m_index_buffers[i]->Release();
m_index_buffers[i] = NULL;
}
}
if(m_vertex_buffers)
delete [] m_vertex_buffers;
if(m_index_buffers)
delete [] m_index_buffers;
m_vertex_buffers = NULL;
m_index_buffers = NULL;
}
void VertexManager::PrepareDrawBuffers(u32 stride)
{
if (!m_buffers_count)
{
return;
}
u8* pVertices;
u16* pIndices;
int datasize = IndexGenerator::GetNumVerts() * stride;
int TdataSize = IndexGenerator::GetTriangleindexLen();
int LDataSize = IndexGenerator::GetLineindexLen();
int IndexDataSize = TdataSize + LDataSize;
if(IndexDataSize)
{
DWORD LockMode = D3DLOCK_NOOVERWRITE;
m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize)
{
LockMode = D3DLOCK_DISCARD;
m_vertex_buffer_cursor = 0;
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)))
{
DestroyDeviceObjects();
return;
}
memcpy(pVertices, s_pBaseBufferPointer, datasize);
m_vertex_buffers[m_current_vertex_buffer]->Unlock();
if (!m_buffers_count)
{
return;
}
u8* pVertices;
u16* pIndices;
int datasize = IndexGenerator::GetNumVerts() * stride;
int TdataSize = IndexGenerator::GetTriangleindexLen();
int LDataSize = IndexGenerator::GetLineindexLen();
int IndexDataSize = TdataSize + LDataSize;
if(IndexDataSize)
{
DWORD LockMode = D3DLOCK_NOOVERWRITE;
m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize)
{
LockMode = D3DLOCK_DISCARD;
m_vertex_buffer_cursor = 0;
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)))
{
DestroyDeviceObjects();
return;
}
memcpy(pVertices, s_pBaseBufferPointer, datasize);
m_vertex_buffers[m_current_vertex_buffer]->Unlock();
LockMode = D3DLOCK_NOOVERWRITE;
if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize)
{
LockMode = D3DLOCK_DISCARD;
m_index_buffer_cursor = 0;
m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count;
}
LockMode = D3DLOCK_NOOVERWRITE;
if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize)
{
LockMode = D3DLOCK_DISCARD;
m_index_buffer_cursor = 0;
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 )))
{
DestroyDeviceObjects();
return;
}
if(TdataSize)
{
memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16));
pIndices += TdataSize;
}
if(LDataSize)
{
memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16));
pIndices += LDataSize;
}
m_index_buffers[m_current_index_buffer]->Unlock();
}
if(m_current_stride != stride || m_vertex_buffer_cursor == 0)
{
m_current_stride = stride;
D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride);
}
if (m_index_buffer_cursor == 0)
{
D3D::SetIndices(m_index_buffers[m_current_index_buffer]);
}
if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode )))
{
DestroyDeviceObjects();
return;
}
if(TdataSize)
{
memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16));
pIndices += TdataSize;
}
if(LDataSize)
{
memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16));
pIndices += LDataSize;
}
m_index_buffers[m_current_index_buffer]->Unlock();
}
if(m_current_stride != stride || m_vertex_buffer_cursor == 0)
{
m_current_stride = stride;
D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride);
}
if (m_index_buffer_cursor == 0)
{
D3D::SetIndices(m_index_buffers[m_current_index_buffer]);
}
ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize);
ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize);
ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize);
ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize);
}
void VertexManager::DrawVertexBuffer(int stride)
{
int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
int StartIndex = m_index_buffer_cursor;
int basevertex = m_vertex_buffer_cursor / stride;
if (triangles > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
basevertex,
0,
numverts,
StartIndex,
triangles)))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetTriangleindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (lines > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
basevertex,
0,
numverts,
StartIndex,
IndexGenerator::GetNumLines())))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetLineindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (points > 0)
{
//DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive
u16* PointIndexBuffer = GetPointIndexBuffer();
int i = 0;
do
{
int count = i + 1;
while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count])
{
count++;
}
if (FAILED(D3D::dev->DrawPrimitive(
D3DPT_POINTLIST,
basevertex + PointIndexBuffer[i],
count - i)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numDrawCalls);
i = count;
} while (i < points);
}
int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
int StartIndex = m_index_buffer_cursor;
int basevertex = m_vertex_buffer_cursor / stride;
if (triangles > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
basevertex,
0,
numverts,
StartIndex,
triangles)))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetTriangleindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (lines > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
basevertex,
0,
numverts,
StartIndex,
IndexGenerator::GetNumLines())))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetLineindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (points > 0)
{
//DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive
u16* PointIndexBuffer = GetPointIndexBuffer();
int i = 0;
do
{
int count = i + 1;
while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count])
{
count++;
}
if (FAILED(D3D::dev->DrawPrimitive(
D3DPT_POINTLIST,
basevertex + PointIndexBuffer[i],
count - i)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numDrawCalls);
i = count;
} while (i < points);
}
}
void VertexManager::DrawVertexArray(int stride)
{
int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
if (triangles > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST,
0, numverts, triangles,
GetTriangleIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (lines > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST,
0, numverts, lines,
GetLineIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (points > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST,
0, numverts, points,
GetPointIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
if (triangles > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST,
0, numverts, triangles,
GetTriangleIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (lines > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST,
0, numverts, lines,
GetLineIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (points > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST,
0, numverts, points,
GetPointIndexBuffer(),
D3DFMT_INDEX16,
s_pBaseBufferPointer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
}
void VertexManager::vFlush()
{
u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i / 2].getEnable(i & 1))
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i / 2].getEnable(i & 1))
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
if (bpmem.genMode.numindstages > 0)
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
if (bpmem.genMode.numindstages > 0)
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
for (unsigned int i = 0; i < 8; i++)
{
if (usedtextures & (1 << i))
{
g_renderer->SetSamplerState(i & 3, i >> 2);
FourTexUnits &tex = bpmem.tex[i >> 2];
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
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.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3),
(tex.texMode1[i&3].max_lod + 0xf) / 0x10,
tex.texImage1[i&3].image_type);
for (unsigned int i = 0; i < 8; i++)
{
if (usedtextures & (1 << i))
{
g_renderer->SetSamplerState(i & 3, i >> 2);
FourTexUnits &tex = bpmem.tex[i >> 2];
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
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.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3),
(tex.texMode1[i&3].max_lod + 0xf) / 0x10,
tex.texImage1[i&3].image_type);
if (tentry)
{
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
}
else
ERROR_LOG(VIDEO, "Error loading texture");
}
}
if (tentry)
{
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0);
}
else
ERROR_LOG(VIDEO, "Error loading texture");
}
}
// set global constants
VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components);
u32 stride = g_nativeVertexFmt->GetVertexStride();
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE;
// set global constants
VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components);
u32 stride = g_nativeVertexFmt->GetVertexStride();
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE;
if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components))
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail;
}
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");});
goto shader_fail;
if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components))
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail;
}
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");});
goto shader_fail;
}
PrepareDrawBuffers(stride);
g_nativeVertexFmt->SetupVertexPointers();
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if (useDstAlpha && !useDualSource)
{
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");});
goto shader_fail;
}
// update alpha only
g_renderer->ApplyState(true);
if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
g_renderer->RestoreState();
}
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
}
PrepareDrawBuffers(stride);
g_nativeVertexFmt->SetupVertexPointers();
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
if (useDstAlpha && !useDualSource)
{
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");});
goto shader_fail;
}
// update alpha only
g_renderer->ApplyState(true);
if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
g_renderer->RestoreState();
}
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
shader_fail:
if(m_buffers_count)
{
m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride;
}
if(m_buffers_count)
{
m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
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)
{
return SimpleVertexShader[level % MAX_SSAA_SHADERS];
return SimpleVertexShader[level % MAX_SSAA_SHADERS];
}
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
{
return ClearVertexShader;
return ClearVertexShader;
}
// this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader<VertexShaderUid, u8>
{
public:
void Read(const VertexShaderUid &key, const u8 *value, u32 value_size)
{
VertexShaderCache::InsertByteCode(key, value, value_size, false);
}
void Read(const VertexShaderUid &key, const u8 *value, u32 value_size)
{
VertexShaderCache::InsertByteCode(key, value, value_size, false);
}
};
void VertexShaderCache::Init()
{
char* vProg = new char[2048];
sprintf(vProg,"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float2 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0;\n"
"OUT.vTexCoord1 = inTEX2;\n"
"return OUT;\n"
"}\n");
char* vProg = new char[2048];
sprintf(vProg,"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float2 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0;\n"
"OUT.vTexCoord1 = inTEX2;\n"
"return OUT;\n"
"}\n");
SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg,"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
"{\n"
"VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n"
"OUT.vColor0 = inColor0;\n"
"return OUT;\n"
"}\n");
sprintf(vProg,"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
"{\n"
"VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n"
"OUT.vColor0 = inColor0;\n"
"return OUT;\n"
"}\n");
ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\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"
"return OUT;\n"
"}\n");
SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\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"
"return OUT;\n"
"}\n");
SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\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"
"return OUT;\n"
"}\n");
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
sprintf(vProg, "struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n"
"};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n"
"VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX2.x;\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"
"return OUT;\n"
"}\n");
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
Clear();
delete [] vProg;
Clear();
delete [] vProg;
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());
SETSTAT(stats.numVertexShadersCreated, 0);
SETSTAT(stats.numVertexShadersAlive, 0);
SETSTAT(stats.numVertexShadersCreated, 0);
SETSTAT(stats.numVertexShadersAlive, 0);
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
if (g_Config.bEnableShaderDebugging)
Clear();
if (g_Config.bEnableShaderDebugging)
Clear();
last_entry = NULL;
last_entry = NULL;
}
void VertexShaderCache::Clear()
{
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
iter->second.Destroy();
vshaders.clear();
vertex_uid_checker.Invalidate();
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
iter->second.Destroy();
vshaders.clear();
vertex_uid_checker.Invalidate();
last_entry = NULL;
last_entry = NULL;
}
void VertexShaderCache::Shutdown()
{
for (int i = 0; i < MAX_SSAA_SHADERS; i++)
{
if (SimpleVertexShader[i])
SimpleVertexShader[i]->Release();
SimpleVertexShader[i] = NULL;
}
for (int i = 0; i < MAX_SSAA_SHADERS; i++)
{
if (SimpleVertexShader[i])
SimpleVertexShader[i]->Release();
SimpleVertexShader[i] = NULL;
}
if (ClearVertexShader)
ClearVertexShader->Release();
ClearVertexShader = NULL;
if (ClearVertexShader)
ClearVertexShader->Release();
ClearVertexShader = NULL;
Clear();
g_vs_disk_cache.Sync();
g_vs_disk_cache.Close();
Clear();
g_vs_disk_cache.Sync();
g_vs_disk_cache.Close();
}
bool VertexShaderCache::SetShader(u32 components)
{
VertexShaderUid uid;
GetVertexShaderUid(uid, components, API_D3D9);
if (g_ActiveConfig.bEnableShaderDebugging)
{
VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9);
vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v");
}
VertexShaderUid uid;
GetVertexShaderUid(uid, components, API_D3D9);
if (g_ActiveConfig.bEnableShaderDebugging)
{
VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9);
vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v");
}
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (last_entry->shader != NULL);
}
}
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (last_entry->shader != NULL);
}
}
last_uid = uid;
last_uid = uid;
VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
{
const VSCacheEntry &entry = iter->second;
last_entry = &entry;
VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
{
const VSCacheEntry &entry = iter->second;
last_entry = &entry;
if (entry.shader) D3D::SetVertexShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (entry.shader != NULL);
}
if (entry.shader) D3D::SetVertexShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (entry.shader != NULL);
}
VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9);
VertexShaderCode code;
GenerateVertexShaderCode(code, components, API_D3D9);
u8 *bytecode;
int bytecodelen;
if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen))
{
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
g_vs_disk_cache.Append(uid, bytecode, bytecodelen);
u8 *bytecode;
int bytecodelen;
if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen))
{
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
g_vs_disk_cache.Append(uid, bytecode, bytecodelen);
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
if (g_ActiveConfig.bEnableShaderDebugging && success)
{
vshaders[uid].code = code.GetBuffer();
}
delete [] bytecode;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return success;
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
if (g_ActiveConfig.bEnableShaderDebugging && success)
{
vshaders[uid].code = code.GetBuffer();
}
delete [] bytecode;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return success;
}
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
VSCacheEntry entry;
entry.shader = shader;
// Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
vshaders[uid] = entry;
last_entry = &vshaders[uid];
if (!shader)
return false;
vshaders[uid] = entry;
last_entry = &vshaders[uid];
if (!shader)
return false;
INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
if (activate)
{
D3D::SetVertexShader(shader);
return true;
}
return false;
INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
if (activate)
{
D3D::SetVertexShader(shader);
return true;
}
return false;
}
float VSConstantbuffer[4*C_VENVCONST_END];
void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{
float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
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);
float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
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)
{
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)
{
float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
for (unsigned int i = 0; i < count; i++)
{
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = 0.f;
}
DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count);
float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number];
for (unsigned int i = 0; i < count; i++)
{
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = *f++;
*VSConstantbuffer_pointer++ = 0.f;
}
DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count);
}
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

View File

@ -50,192 +50,192 @@
namespace DX9
{
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;
}
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);
}
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::GetName()
{
return "DX9";
}
std::string VideoBackend::GetDisplayName()
{
return "Direct3D9 (deprecated)";
}
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
// we cannot test for device caps because most drivers just declare the minimun caps
// 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));
}
else
{
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;
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
// we cannot test for device caps because most drivers just declare the minimun caps
// 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));
}
else
{
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);
// 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);
// 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);
}
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();
// Clear ppshaders string vector
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
InitBackendInfo();
VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9");
diag.ShowModal();
InitBackendInfo();
VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9");
diag.ShowModal();
#endif
}
}
bool VideoBackend::Initialize(void *&window_handle)
{
InitializeShared();
InitBackendInfo();
bool VideoBackend::Initialize(void *&window_handle)
{
InitializeShared();
InitBackendInfo();
frameCount = 0;
frameCount = 0;
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.UpdateProjectionHack();
g_Config.VerifyValidity();
// as only some driver/hardware configurations support dual source blending only enable it if is
// configured by user
g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend;
UpdateActiveConfig();
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.UpdateProjectionHack();
g_Config.VerifyValidity();
// as only some driver/hardware configurations support dual source blending only enable it if is
// configured by user
g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend;
UpdateActiveConfig();
window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait."));
if (window_handle == NULL)
{
ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
return false;
}
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);
return false;
}
window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait."));
if (window_handle == NULL)
{
ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
return false;
}
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);
return false;
}
s_BackendInitialized = true;
s_BackendInitialized = true;
return true;
}
return true;
}
void VideoBackend::Video_Prepare()
{
// Better be safe...
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
void VideoBackend::Video_Prepare()
{
// Better be safe...
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
// internal interfaces
g_vertex_manager = new VertexManager;
g_perf_query = new PerfQuery;
g_renderer = new Renderer;
g_texture_cache = new TextureCache;
// VideoCommon
BPInit();
Fifo_Init();
IndexGenerator::Init();
VertexLoaderManager::Init();
OpcodeDecoder_Init();
VertexShaderManager::Init();
PixelShaderManager::Init();
CommandProcessor::Init();
PixelEngine::Init();
DLCache::Init();
// Notify the core that the video backend is ready
Host_Message(WM_USER_CREATE);
}
// internal interfaces
g_vertex_manager = new VertexManager;
g_perf_query = new PerfQuery;
g_renderer = new Renderer;
g_texture_cache = new TextureCache;
// VideoCommon
BPInit();
Fifo_Init();
IndexGenerator::Init();
VertexLoaderManager::Init();
OpcodeDecoder_Init();
VertexShaderManager::Init();
PixelShaderManager::Init();
CommandProcessor::Init();
PixelEngine::Init();
DLCache::Init();
// Notify the core that the video backend is ready
Host_Message(WM_USER_CREATE);
}
void VideoBackend::Shutdown()
{
s_BackendInitialized = false;
void VideoBackend::Shutdown()
{
s_BackendInitialized = false;
// TODO: should be in Video_Cleanup
if (g_renderer)
{
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
// TODO: should be in Video_Cleanup
if (g_renderer)
{
s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
// VideoCommon
DLCache::Shutdown();
Fifo_Shutdown();
CommandProcessor::Shutdown();
PixelShaderManager::Shutdown();
VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown();
VertexLoaderManager::Shutdown();
// VideoCommon
DLCache::Shutdown();
Fifo_Shutdown();
CommandProcessor::Shutdown();
PixelShaderManager::Shutdown();
VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown();
VertexLoaderManager::Shutdown();
// internal interfaces
PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown();
delete g_texture_cache;
delete g_renderer;
delete g_perf_query;
delete g_vertex_manager;
g_renderer = NULL;
g_texture_cache = NULL;
}
D3D::Shutdown();
}
// internal interfaces
PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown();
delete g_texture_cache;
delete g_renderer;
delete g_perf_query;
delete g_vertex_manager;
g_renderer = NULL;
g_texture_cache = NULL;
}
D3D::Shutdown();
}
void VideoBackend::Video_Cleanup() {
}
void VideoBackend::Video_Cleanup() {
}
}