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:
parent
08a6b8920b
commit
1de39a4a6e
|
@ -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
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue