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
|
||||
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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue