diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 22e31ad192..527fe5d177 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -40,15 +40,15 @@ static std::set 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 { 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!"); - - uselocale(old_locale); // restore locale - freelocale(locale); - return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); + 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)); } 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 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 93cd7a67df..2300291e7d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -37,251 +37,257 @@ LinearDiskCache 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 { 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)); - - Clear(); - delete [] 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)); - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); + Clear(); + delete [] vProg; - SETSTAT(stats.numVertexShadersCreated, 0); - SETSTAT(stats.numVertexShadersAlive, 0); + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - 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); + SETSTAT(stats.numVertexShadersCreated, 0); + SETSTAT(stats.numVertexShadersAlive, 0); - if (g_Config.bEnableShaderDebugging) - Clear(); + 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); - last_entry = NULL; + if (g_Config.bEnableShaderDebugging) + Clear(); + + 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; - - Clear(); - g_vs_disk_cache.Sync(); - g_vs_disk_cache.Close(); + if (ClearVertexShader) + ClearVertexShader->Release(); + ClearVertexShader = NULL; + + 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) { - const float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 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 buf[4*C_VENVCONST_END]; - for (unsigned int i = 0; i < count; i++) - { - buf[4*i ] = *f++; - buf[4*i+1] = *f++; - buf[4*i+2] = *f++; - buf[4*i+3] = 0.f; - } - DX9::D3D::dev->SetVertexShaderConstantF(const_number, buf, 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 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index ab5e85d64d..3c4c66d35f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -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; -} - -void VideoBackend::UpdateFPSDisplay(const char *text) -{ - TCHAR temp[512]; - swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); - EmuWindow::SetWindowText(temp); -} - -std::string VideoBackend::GetName() -{ - return "DX9"; -} - -std::string VideoBackend::GetDisplayName() -{ - return "Direct3D9 (deprecated)"; -} - -void InitBackendInfo() -{ - DX9::D3D::Init(); - D3DCAPS9 device_caps = DX9::D3D::GetCaps(); - const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); - const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - g_Config.backend_info.bUseRGBATextures = false; - g_Config.backend_info.bUseMinimalMipCount = true; - g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsPrimitiveRestart = false; // TODO: figure out if it does - g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; - // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupports3DVision = true; - OSVERSIONINFO info; - ZeroMemory(&info, sizeof(OSVERSIONINFO)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&info)) + unsigned int VideoBackend::PeekMessages() { + MSG msg; + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + return FALSE; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return TRUE; + } + + void VideoBackend::UpdateFPSDisplay(const char *text) + { + TCHAR temp[512]; + swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); + EmuWindow::SetWindowText(temp); + } + + std::string VideoBackend::GetName() + { + return "DX9"; + } + + std::string VideoBackend::GetDisplayName() + { + return "Direct3D9 (deprecated)"; + } + + void InitBackendInfo() + { + DX9::D3D::Init(); + D3DCAPS9 device_caps = DX9::D3D::GetCaps(); + const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); + const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); + g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; + g_Config.backend_info.bUseRGBATextures = false; + g_Config.backend_info.bUseMinimalMipCount = true; + g_Config.backend_info.bSupports3DVision = true; + g_Config.backend_info.bSupportsPrimitiveRestart = false; // 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 - { + } + 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); + + // aamodes + g_Config.backend_info.AAModes.clear(); + if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) + { + const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); + + for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) + g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); + } + + // Clear ppshaders string vector + g_Config.backend_info.PPShaders.clear(); + + DX9::D3D::Shutdown(); } - g_Config.backend_info.bSupportsFormatReinterpretation = true; - g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; - g_Config.backend_info.bSupportsEarlyZ = false; - // adapters - g_Config.backend_info.Adapters.clear(); - for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) - g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); - - // aamodes - g_Config.backend_info.AAModes.clear(); - if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) - { - const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); - - for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) - g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); - } - - // Clear ppshaders string vector - g_Config.backend_info.PPShaders.clear(); - - DX9::D3D::Shutdown(); -} - -void VideoBackend::ShowConfig(void* parent) -{ + 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() { + } }