From ca0e292dd4553d078393d626444c2b88922f5b62 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 6 Aug 2012 22:41:30 +0200 Subject: [PATCH 001/352] Replace the shader uid system with a new one which quasi-automatically generates uids for shaders. Currently used in the vertex shader only (had to fork lighting shaders for now). --- Source/Core/VideoCommon/Src/Debugger.cpp | 2 +- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 609 +++++++++++------- Source/Core/VideoCommon/Src/VertexShaderGen.h | 124 ++-- .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 17 +- .../Plugin_VideoOGL/Src/VertexShaderCache.h | 6 +- 5 files changed, 464 insertions(+), 294 deletions(-) diff --git a/Source/Core/VideoCommon/Src/Debugger.cpp b/Source/Core/VideoCommon/Src/Debugger.cpp index 4aa25b72be..005f81c8e6 100644 --- a/Source/Core/VideoCommon/Src/Debugger.cpp +++ b/Source/Core/VideoCommon/Src/Debugger.cpp @@ -131,7 +131,7 @@ void GFXDebuggerBase::DumpVertexShader(const char* path) sprintf(filename, "%sdump_vs.txt", path); File::CreateEmptyFile(filename); - File::WriteStringToFile(true, GenerateVertexShaderCode(g_nativeVertexFmt->m_components, g_ActiveConfig.backend_info.APIType), filename); +/// File::WriteStringToFile(true, GenerateVertexShaderCode(g_nativeVertexFmt->m_components, g_ActiveConfig.backend_info.APIType), filename); } void GFXDebuggerBase::DumpPixelShaderConstants(const char* path) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index cad117c2c8..d7134b6dcb 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -26,149 +26,260 @@ #include "VertexShaderGen.h" #include "VideoConfig.h" -// Mash together all the inputs that contribute to the code of a generated vertex shader into -// a unique identifier, basically containing all the bits. Yup, it's a lot .... -void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components) +static char text[16768]; + +enum GenOutput { - memset(uid->values, 0, sizeof(uid->values)); - uid->values[0] = components | - (xfregs.numTexGen.numTexGens << 23) | - (xfregs.numChan.numColorChans << 27) | - (xfregs.dualTexTrans.enabled << 29); - - // TODO: If pixel lighting is enabled, do we even have to bother about storing lighting related registers here? - GetLightingShaderId(&uid->values[1]); - - uid->values[2] |= (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) << 31; - u32 *pcurvalue = &uid->values[3]; - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) { - TexMtxInfo tinfo = xfregs.texMtxInfo[i]; - if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP) - tinfo.hex &= 0x7ff; - if (tinfo.texgentype != XF_TEXGEN_REGULAR) - tinfo.projection = 0; - - u32 val = ((tinfo.hex >> 1) & 0x1ffff); - if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR) { - // rewrite normalization and post index - val |= ((u32)xfregs.postMtxInfo[i].index << 17) | ((u32)xfregs.postMtxInfo[i].normalize << 23); - } - - switch (i & 3) { - case 0: pcurvalue[0] |= val; break; - case 1: pcurvalue[0] |= val << 24; pcurvalue[1] = val >> 8; ++pcurvalue; break; - case 2: pcurvalue[0] |= val << 16; pcurvalue[1] = val >> 16; ++pcurvalue; break; - case 3: pcurvalue[0] |= val << 8; ++pcurvalue; break; - } - } -} - -void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components) + GO_ShaderCode, + GO_ShaderUid, +}; +// TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? +template +void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) { - // Just store all used registers here without caring whether we need all bits or less. - memset(uid->values, 0, sizeof(uid->values)); - u32* ptr = uid->values; - *ptr++ = components; - *ptr++ = xfregs.numTexGen.hex; - *ptr++ = xfregs.numChan.hex; - *ptr++ = xfregs.dualTexTrans.hex; + object.Write("struct VS_OUTPUT {\n"); + object.Write(" float4 pos : POSITION;\n"); + object.Write(" float4 colors_0 : COLOR0;\n"); + object.Write(" float4 colors_1 : COLOR1;\n"); - for (int i = 0; i < 2; ++i) { - *ptr++ = xfregs.color[i].hex; - *ptr++ = xfregs.alpha[i].hex; - } - *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; - for (unsigned int i = 0; i < 8; ++i) { - *ptr++ = xfregs.texMtxInfo[i].hex; - *ptr++ = xfregs.postMtxInfo[i].hex; - } - _assert_((ptr - uid->values) == uid->GetNumValues()); -} - - -void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std::string& old_code, u32 components) -{ - if (!g_ActiveConfig.bEnableShaderDebugging) - return; - - VERTEXSHADERUIDSAFE new_id; - GetSafeVertexShaderId(&new_id, components); - - if (!(old_id == new_id)) + if (xfregs.numTexGen.numTexGens < 7) { - std::string new_code(GenerateVertexShaderCode(components, api)); - if (old_code != new_code) + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + object.Write(" float3 tex%d : TEXCOORD%d;\n", i, i); + + object.Write(" float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens); +/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) +/// object.Write(" float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1); + } + else + { + // clip position is in w of first 4 texcoords +/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) +/// { +/// for (int i = 0; i < 8; ++i) +/// object.Write(" float4 tex%d : TEXCOORD%d;\n", i, i); +/// } +/// else { - _assert_(old_id.GetNumValues() == new_id.GetNumValues()); - - char msg[8192]; - char* ptr = msg; - ptr += sprintf(ptr, "Vertex shader IDs matched but unique IDs did not!\nUnique IDs (old <-> new):\n"); - const int N = new_id.GetNumValues(); - for (int i = 0; i < N/2; ++i) - ptr += sprintf(ptr, "%02d, %08X %08X | %08X %08X\n", 2*i, old_id.values[2*i], old_id.values[2*i+1], - new_id.values[2*i], new_id.values[2*i+1]); - if (N % 2) - ptr += sprintf(ptr, "%02d, %08X | %08X\n", N-1, old_id.values[N-1], new_id.values[N-1]); - - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%svsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); - file << msg; - file << "\n\nOld shader code:\n" << old_code; - file << "\n\nNew shader code:\n" << new_code; - file.close(); - - PanicAlert("Unique pixel shader ID mismatch!\n\nReport this to the devs, along with the contents of %s.", szTemp); + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + object.Write(" float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i); } } + object.Write("};\n"); } - -static char text[16384]; - -#define WRITE p+=sprintf - -char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type) +template +void _GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) { - WRITE(p, "struct VS_OUTPUT {\n"); - WRITE(p, " float4 pos : POSITION;\n"); - WRITE(p, " float4 colors_0 : COLOR0;\n"); - WRITE(p, " float4 colors_1 : COLOR1;\n"); +#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; + const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; + const char* swizzle = "xyzw"; + if (coloralpha == 1 ) swizzle = "xyz"; + else if (coloralpha == 2 ) swizzle = "w"; - if (xfregs.numTexGen.numTexGens < 7) { - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, " float3 tex%d : TEXCOORD%d;\n", i, i); - WRITE(p, " float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens); - if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - WRITE(p, " float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1); - } else { - // clip position is in w of first 4 texcoords - if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); + SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); + if (!(chan.attnfunc & 1)) { + // atten disabled + switch (chan.diffusefunc) { + case LIGHTDIF_NONE: + object.Write("lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); + object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); + break; + default: _assert_(0); + } + } + else { // spec and spot + + if (chan.attnfunc == 3) + { // spot + object.Write("ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); + object.Write("dist2 = dot(ldir, ldir);\n" + "dist = sqrt(dist2);\n" + "ldir = ldir / dist;\n" + "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); + } + else if (chan.attnfunc == 1) + { // specular + object.Write("ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); + object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); + } + + switch (chan.diffusefunc) { - for (int i = 0; i < 8; ++i) - WRITE(p, " float4 tex%d : TEXCOORD%d;\n", i, i); + case LIGHTDIF_NONE: + object.Write("lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, + chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", + lightsName, + index, + swizzle); + break; + default: _assert_(0); + } + } + object.Write("\n"); +} + +// vertex shader +// lights/colors +// materials name is I_MATERIALS in vs and I_PMATERIALS in ps +// inColorName is color in vs and colors_ in ps +// dest is o.colors_ in vs and colors_ in ps +template +void _GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +{ + for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) + { + const LitChannel& color = xfregs.color[j]; + const LitChannel& alpha = xfregs.alpha[j]; + + object.Write("{\n"); + + SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); + if (color.matsource) {// from vertex + if (components & (VB_HAS_COL0 << j)) + object.Write("mat = %s%d;\n", inColorName, j); + else if (components & VB_HAS_COL0) + object.Write("mat = %s0;\n", inColorName); + else + object.Write("mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + } + else // from color + object.Write("mat = %s.C%d;\n", materialsName, j+2); + + SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); + if (color.enablelighting) { + SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); + if (color.ambsource) { // from vertex + if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); + } + } + } + } + + // no shared lights + for (int i = 0; i < 8; ++i) + { + if (!(mask&(1<(object, i, j, lightsName, 1); + if (!(mask&(1<(object, i, j+2, lightsName, 2); + } + } + else if (color.enablelighting || alpha.enablelighting) + { + // lights are disabled on one channel so process only the active ones + const LitChannel& workingchannel = color.enablelighting ? color : alpha; + const int lit_index = color.enablelighting ? j : (j+2); + int coloralpha = color.enablelighting ? 1 : 2; + + SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); + for (int i = 0; i < 8; ++i) + { + if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); + } + } + object.Write("%s%d = mat * saturate(lacc);\n", dest, j); + object.Write("}\n"); + } } -const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) +// TODO: Problem: this one uses copy constructors or sth for uids when returning... +template +void GenerateShader(T& out, u32 components, API_TYPE api_type) { - setlocale(LC_NUMERIC, "C"); // Reset locale for compilation - text[sizeof(text) - 1] = 0x7C; // canary +#undef SetUidField +#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; + + if (type == GO_ShaderCode) + { + out.SetBuffer(text); + setlocale(LC_NUMERIC, "C"); // Reset locale for compilation + } + + /// text[sizeof(text) - 1] = 0x7C; // canary - _assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens); - _assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans); - bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); u32 lightMask = 0; if (xfregs.numChan.numColorChans > 0) @@ -176,141 +287,146 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) if (xfregs.numChan.numColorChans > 1) lightMask |= xfregs.color[1].GetFullLightMask() | xfregs.alpha[1].GetFullLightMask(); - char *p = text; - WRITE(p, "//Vertex Shader: comp:%x, \n", components); - WRITE(p, "typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_" I_POSNORMALMATRIX";\n" - "typedef struct { float4 t; } FLT4;\n" - "typedef struct { FLT4 T[24]; } s_" I_TEXMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_TRANSFORMMATRICES";\n" - "typedef struct { FLT4 T[32]; } s_" I_NORMALMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_POSTTRANSFORMMATRICES";\n" - "typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n" - "typedef struct { Light lights[8]; } s_" I_LIGHTS";\n" - "typedef struct { float4 C0, C1, C2, C3; } s_" I_MATERIALS";\n" - "typedef struct { float4 T0, T1, T2, T3; } s_" I_PROJECTION";\n" - ); + out.Write("//Vertex Shader: comp:%x, \n", components); + out.Write("typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_" I_POSNORMALMATRIX";\n" + "typedef struct { float4 t; } FLT4;\n" + "typedef struct { FLT4 T[24]; } s_" I_TEXMATRICES";\n" + "typedef struct { FLT4 T[64]; } s_" I_TRANSFORMMATRICES";\n" + "typedef struct { FLT4 T[32]; } s_" I_NORMALMATRICES";\n" + "typedef struct { FLT4 T[64]; } s_" I_POSTTRANSFORMMATRICES";\n" + "typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n" + "typedef struct { Light lights[8]; } s_" I_LIGHTS";\n" + "typedef struct { float4 C0, C1, C2, C3; } s_" I_MATERIALS";\n" + "typedef struct { float4 T0, T1, T2, T3; } s_" I_PROJECTION";\n" + ); - p = GenerateVSOutputStruct(p, components, api_type); +/// p = GenerateVSOutputStruct(p, components, api_type); + GenerateVSOutputStruct(out, components, api_type); // uniforms - WRITE(p, "uniform s_" I_TRANSFORMMATRICES" " I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES); - WRITE(p, "uniform s_" I_TEXMATRICES" " I_TEXMATRICES" : register(c%d);\n", C_TEXMATRICES); // also using tex matrices - WRITE(p, "uniform s_" I_NORMALMATRICES" " I_NORMALMATRICES" : register(c%d);\n", C_NORMALMATRICES); - WRITE(p, "uniform s_" I_POSNORMALMATRIX" " I_POSNORMALMATRIX" : register(c%d);\n", C_POSNORMALMATRIX); - WRITE(p, "uniform s_" I_POSTTRANSFORMMATRICES" " I_POSTTRANSFORMMATRICES" : register(c%d);\n", C_POSTTRANSFORMMATRICES); - WRITE(p, "uniform s_" I_LIGHTS" " I_LIGHTS" : register(c%d);\n", C_LIGHTS); - WRITE(p, "uniform s_" I_MATERIALS" " I_MATERIALS" : register(c%d);\n", C_MATERIALS); - WRITE(p, "uniform s_" I_PROJECTION" " I_PROJECTION" : register(c%d);\n", C_PROJECTION); - WRITE(p, "uniform float4 " I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); + out.Write("uniform s_" I_TRANSFORMMATRICES" " I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES); + out.Write("uniform s_" I_TEXMATRICES" " I_TEXMATRICES" : register(c%d);\n", C_TEXMATRICES); + out.Write("uniform s_" I_NORMALMATRICES" " I_NORMALMATRICES" : register(c%d);\n", C_NORMALMATRICES); + out.Write("uniform s_" I_POSNORMALMATRIX" " I_POSNORMALMATRIX" : register(c%d);\n", C_POSNORMALMATRIX); + out.Write("uniform s_" I_POSTTRANSFORMMATRICES" " I_POSTTRANSFORMMATRICES" : register(c%d);\n", C_POSTTRANSFORMMATRICES); + out.Write("uniform s_" I_LIGHTS" " I_LIGHTS" : register(c%d);\n", C_LIGHTS); + out.Write("uniform s_" I_MATERIALS" " I_MATERIALS" : register(c%d);\n", C_MATERIALS); + out.Write("uniform s_" I_PROJECTION" " I_PROJECTION" : register(c%d);\n", C_PROJECTION); + out.Write("uniform float4 " I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); - WRITE(p, "VS_OUTPUT main(\n"); - + out.Write("VS_OUTPUT main(\n"); + + SetUidField(numTexGens, xfregs.numTexGen.numTexGens); + SetUidField(components, components); // inputs if (components & VB_HAS_NRM0) - WRITE(p, " float3 rawnorm0 : NORMAL0,\n"); - if (components & VB_HAS_NRM1) { + out.Write(" float3 rawnorm0 : NORMAL0,\n"); + if (components & VB_HAS_NRM1) + { if (is_d3d) - WRITE(p, " float3 rawnorm1 : NORMAL1,\n"); + out.Write(" float3 rawnorm1 : NORMAL1,\n"); else - WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); + out.Write(" float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); } - if (components & VB_HAS_NRM2) { + if (components & VB_HAS_NRM2) + { if (is_d3d) - WRITE(p, " float3 rawnorm2 : NORMAL2,\n"); + out.Write(" float3 rawnorm2 : NORMAL2,\n"); else - WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); + out.Write(" float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); } if (components & VB_HAS_COL0) - WRITE(p, " float4 color0 : COLOR0,\n"); + out.Write(" float4 color0 : COLOR0,\n"); if (components & VB_HAS_COL1) - WRITE(p, " float4 color1 : COLOR1,\n"); + out.Write(" float4 color1 : COLOR1,\n"); for (int i = 0; i < 8; ++i) { u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<= 32 ? (posmtx-32) : posmtx;\n"); - WRITE(p, "float3 N0 = " I_NORMALMATRICES".T[normidx].t.xyz, N1 = " I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = " I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); + out.Write("int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n"); + out.Write("float3 N0 = " I_NORMALMATRICES".T[normidx].t.xyz, N1 = " I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = " I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); } if (components & VB_HAS_NRM0) - WRITE(p, "float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n"); + out.Write("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n"); if (components & VB_HAS_NRM1) - WRITE(p, "float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); + out.Write("float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); if (components & VB_HAS_NRM2) - WRITE(p, "float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); + out.Write("float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); } else { - WRITE(p, "float4 pos = float4(dot(" I_POSNORMALMATRIX".T0, rawpos), dot(" I_POSNORMALMATRIX".T1, rawpos), dot(" I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n"); + out.Write("float4 pos = float4(dot(" I_POSNORMALMATRIX".T0, rawpos), dot(" I_POSNORMALMATRIX".T1, rawpos), dot(" I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n"); if (components & VB_HAS_NRM0) - WRITE(p, "float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm0)));\n"); + out.Write("float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm0)));\n"); if (components & VB_HAS_NRM1) - WRITE(p, "float3 _norm1 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); + out.Write("float3 _norm1 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); if (components & VB_HAS_NRM2) - WRITE(p, "float3 _norm2 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); + out.Write("float3 _norm2 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); } if (!(components & VB_HAS_NRM0)) - WRITE(p, "float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); + out.Write("float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); - - WRITE(p, "o.pos = float4(dot(" I_PROJECTION".T0, pos), dot(" I_PROJECTION".T1, pos), dot(" I_PROJECTION".T2, pos), dot(" I_PROJECTION".T3, pos));\n"); - WRITE(p, "float4 mat, lacc;\n" - "float3 ldir, h;\n" - "float dist, dist2, attn;\n"); + out.Write("o.pos = float4(dot(" I_PROJECTION".T0, pos), dot(" I_PROJECTION".T1, pos), dot(" I_PROJECTION".T2, pos), dot(" I_PROJECTION".T3, pos));\n"); + out.Write("float4 mat, lacc;\n" + "float3 ldir, h;\n" + "float dist, dist2, attn;\n"); + + SetUidField(numColorChans, xfregs.numChan.numColorChans); if(xfregs.numChan.numColorChans == 0) { if (components & VB_HAS_COL0) - WRITE(p, "o.colors_0 = color0;\n"); + out.Write("o.colors_0 = color0;\n"); else - WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + out.Write("o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); } // TODO: This probably isn't necessary if pixel lighting is enabled. - p = GenerateLightingShader(p, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + _GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); if(xfregs.numChan.numColorChans < 2) { if (components & VB_HAS_COL1) - WRITE(p, "o.colors_1 = color1;\n"); + out.Write("o.colors_1 = color1;\n"); else - WRITE(p, "o.colors_1 = o.colors_0;\n"); + out.Write("o.colors_1 = o.colors_0;\n"); } // special case if only pos and tex coord 0 and tex coord input is AB11 // donko - this has caused problems in some games. removed for now. @@ -322,21 +438,22 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) */ // transform texcoords - WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); + out.Write("float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) { TexMtxInfo& texinfo = xfregs.texMtxInfo[i]; - WRITE(p, "{\n"); - WRITE(p, "coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); + out.Write("{\n"); + out.Write("coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); + SetUidField(texMtxInfo[i].sourcerow, xfregs.texMtxInfo[i].sourcerow); switch (texinfo.sourcerow) { case XF_SRCGEOM_INROW: _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - WRITE(p, "coord = rawpos;\n"); // pos.w is 1 + out.Write("coord = rawpos;\n"); // pos.w is 1 break; case XF_SRCNORMAL_INROW: if (components & VB_HAS_NRM0) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - WRITE(p, "coord = float4(rawnorm0.xyz, 1.0f);\n"); + out.Write("coord = float4(rawnorm0.xyz, 1.0f);\n"); } break; case XF_SRCCOLORS_INROW: @@ -345,72 +462,79 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) case XF_SRCBINORMAL_T_INROW: if (components & VB_HAS_NRM1) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - WRITE(p, "coord = float4(rawnorm1.xyz, 1.0f);\n"); + out.Write("coord = float4(rawnorm1.xyz, 1.0f);\n"); } break; case XF_SRCBINORMAL_B_INROW: if (components & VB_HAS_NRM2) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - WRITE(p, "coord = float4(rawnorm2.xyz, 1.0f);\n"); + out.Write("coord = float4(rawnorm2.xyz, 1.0f);\n"); } break; default: _assert_(texinfo.sourcerow <= XF_SRCTEX7_INROW); if (components & (VB_HAS_UV0<<(texinfo.sourcerow - XF_SRCTEX0_INROW)) ) - WRITE(p, "coord = float4(tex%d.x, tex%d.y, 1.0f, 1.0f);\n", texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW); + out.Write("coord = float4(tex%d.x, tex%d.y, 1.0f, 1.0f);\n", texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW); break; } // first transformation + SetUidField(texMtxInfo[i].texgentype, xfregs.texMtxInfo[i].texgentype); switch (texinfo.texgentype) { case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { // transform the light dir into tangent space - WRITE(p, "ldir = normalize(" I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); - WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); + SetUidField(texMtxInfo[i].embosslightshift, xfregs.texMtxInfo[i].embosslightshift); + SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + out.Write("ldir = normalize(" I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); + out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); } else { _assert_(0); // should have normals - WRITE(p, "o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); + SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); } break; case XF_TEXGEN_COLOR_STRGBC0: _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); - WRITE(p, "o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i); + out.Write("o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i); break; case XF_TEXGEN_COLOR_STRGBC1: _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); - WRITE(p, "o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i); + out.Write("o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i); break; case XF_TEXGEN_REGULAR: default: + SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); if (components & (VB_HAS_TEXMTXIDX0<(object, components, api_type); +} + +void GenerateShaderCode(ShaderCode& object, u32 components, API_TYPE api_type) +{ + return GenerateShader(object, components, api_type); } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index cb253a9b6c..11bb5c29f6 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -18,6 +18,7 @@ #ifndef GCOGL_VERTEXSHADER_H #define GCOGL_VERTEXSHADER_H +#include #include "XFMemory.h" #include "VideoCommon.h" @@ -48,71 +49,106 @@ #define C_DEPTHPARAMS (C_POSTTRANSFORMMATRICES + 64) #define C_VENVCONST_END (C_DEPTHPARAMS + 4) -template -class _VERTEXSHADERUID +// TODO: Need packing? +struct uid_data +{ + u32 components; + u32 numColorChans : 2; + u32 numTexGens : 4; + + struct { + u32 projection : 1; // XF_TEXPROJ_X + u32 inputform : 2; // XF_TEXINPUT_X + u32 texgentype : 3; // XF_TEXGEN_X + u32 sourcerow : 5; // XF_SRCGEOM_X + u32 embosssourceshift : 3; // what generated texcoord to use + u32 embosslightshift : 3; // light index that is used + } texMtxInfo[8]; + struct { + u32 index : 6; // base row of dual transform matrix + u32 normalize : 1; // normalize before send operation + } postMtxInfo[8]; + struct { + u32 enabled : 1; + } dualTexTrans; + struct { + u32 matsource : 1; + u32 enablelighting : 1; + u32 ambsource : 1; + u32 diffusefunc : 2; + u32 attnfunc : 2; + u32 light_mask : 8; + } lit_chans[4]; +}; + + +class ShaderUid { -#define NUM_VSUID_VALUES_SAFE 25 public: - u32 values[safe ? NUM_VSUID_VALUES_SAFE : 9]; - - _VERTEXSHADERUID() + ShaderUid() { + memset(values, 0, sizeof(values)); } - _VERTEXSHADERUID(const _VERTEXSHADERUID& r) + void Write(const char* fmt, ...) {} + const char* GetBuffer() { return NULL; } + void SetBuffer(char* buffer) { } + + bool operator == (const ShaderUid& obj) const { - for (size_t i = 0; i < sizeof(values) / sizeof(u32); ++i) - values[i] = r.values[i]; + return memcmp(this->values, obj.values, sizeof(values)) == 0; } - int GetNumValues() const + // TODO: Store last frame used and order by that? makes much more sense anyway... + bool operator < (const ShaderUid& obj) const { - if (safe) return NUM_VSUID_VALUES_SAFE; - else return (((values[0] >> 23) & 0xf) * 3 + 3) / 4 + 3; // numTexGens*3/4+1 - } - - bool operator <(const _VERTEXSHADERUID& _Right) const - { - if (values[0] < _Right.values[0]) - return true; - else if (values[0] > _Right.values[0]) - return false; - int N = GetNumValues(); - for (int i = 1; i < N; ++i) + for (int i = 0; i < 24; ++i) { - if (values[i] < _Right.values[i]) + if (this->values[i] < obj.values[i]) return true; - else if (values[i] > _Right.values[i]) + else if (this->values[i] > obj.values[i]) return false; } return false; } - bool operator ==(const _VERTEXSHADERUID& _Right) const + uid_data& GetUidData() { return data; } + +private: + union { - if (values[0] != _Right.values[0]) - return false; - int N = GetNumValues(); - for (int i = 1; i < N; ++i) - { - if (values[i] != _Right.values[i]) - return false; - } - return true; - } + uid_data data; + u32 values[24]; // TODO: Length? + }; }; -typedef _VERTEXSHADERUID VERTEXSHADERUID; -typedef _VERTEXSHADERUID VERTEXSHADERUIDSAFE; +class ShaderCode +{ +public: + ShaderCode() : buf(NULL), write_ptr(NULL) + { -// components is included in the uid. -char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type); -const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type); + } -void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components); -void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components); + void Write(const char* fmt, ...) + { + va_list arglist; + va_start(arglist, fmt); + write_ptr += vsprintf(write_ptr, fmt, arglist); + va_end(arglist); + } + + const char* GetBuffer() { return buf; } + void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; } + uid_data& GetUidData() { return *(uid_data*)NULL; } + +private: + const char* buf; + char* write_ptr; +}; + +void GenerateShaderUid(ShaderUid& object, u32 components, API_TYPE api_type); +void GenerateShaderCode(ShaderCode& object, u32 components, API_TYPE api_type); -// Used to make sure that our optimized vertex shader IDs don't lose any possible shader code changes -void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std::string& old_code, u32 components); #endif // GCOGL_VERTEXSHADER_H diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index dbbb7ee29b..7eaf1546da 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -42,7 +42,7 @@ GLuint VertexShaderCache::CurrentShader; bool VertexShaderCache::ShaderEnabled; VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry = NULL; -VERTEXSHADERUID VertexShaderCache::last_uid; +ShaderUid VertexShaderCache::last_uid; static int s_nMaxVertexInstructions; @@ -74,14 +74,14 @@ void VertexShaderCache::Shutdown() VERTEXSHADER* VertexShaderCache::SetShader(u32 components) { - VERTEXSHADERUID uid; - GetVertexShaderId(&uid, components); + // Possible optimization: Don't always generate the shader uid, but keep track of changes in BPStructs instead + ShaderUid uid; + GenerateShaderUid(uid, components, API_OPENGL); if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_OPENGL, vshaders[uid].safe_uid, vshaders[uid].shader.strprog, components); return &last_entry->shader; } } @@ -95,15 +95,14 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components) last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, components); return &last_entry->shader; } // Make an entry in the table VSCacheEntry& entry = vshaders[uid]; last_entry = &entry; - const char *code = GenerateVertexShaderCode(components, API_OPENGL); - GetSafeVertexShaderId(&entry.safe_uid, components); + ShaderCode code; + GenerateShaderCode(code, components, API_OPENGL); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { @@ -111,11 +110,11 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components) char szTemp[MAX_PATH]; sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - SaveData(szTemp, code); + SaveData(szTemp, code.GetBuffer()); } #endif - if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) { + if (!code.GetBuffer() || !VertexShaderCache::CompileVertexShader(entry.shader, code.GetBuffer())) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return NULL; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h index 6f4cbe25c2..f3831b3f7b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h @@ -40,7 +40,7 @@ class VertexShaderCache struct VSCacheEntry { VERTEXSHADER shader; - VERTEXSHADERUIDSAFE safe_uid; + ShaderUid safe_uid; VSCacheEntry() {} void Destroy() { // printf("Destroying vs %i\n", shader.glprogid); @@ -49,12 +49,12 @@ class VertexShaderCache } }; - typedef std::map VSCache; + typedef std::map VSCache; static VSCache vshaders; static VSCacheEntry* last_entry; - static VERTEXSHADERUID last_uid; + static ShaderUid last_uid; // TODO: Use reference instead.. static GLuint CurrentShader; static bool ShaderEnabled; From 3c8df842bba1067ce8f7f41dd1c13cb4f047fc90 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 6 Aug 2012 23:09:43 +0200 Subject: [PATCH 002/352] Moved some of the new shader uid stuff to a common header file. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 94 +++ .../Core/VideoCommon/Src/VertexShaderGen.cpp | 10 +- .../Core/VideoCommon/Src/VertexShaderGen.cpp~ | 645 ++++++++++++++++++ Source/Core/VideoCommon/Src/VertexShaderGen.h | 72 +- .../Core/VideoCommon/Src/VertexShaderGen.h~ | 92 +++ .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 10 +- .../Src/VertexShaderCache.cpp~ | 271 ++++++++ .../Plugin_VideoOGL/Src/VertexShaderCache.h | 6 +- .../Plugin_VideoOGL/Src/VertexShaderCache.h~ | 76 +++ 9 files changed, 1196 insertions(+), 80 deletions(-) create mode 100644 Source/Core/VideoCommon/Src/ShaderGenCommon.h create mode 100644 Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ create mode 100644 Source/Core/VideoCommon/Src/VertexShaderGen.h~ create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp~ create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h~ diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h new file mode 100644 index 0000000000..28fb8e8956 --- /dev/null +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -0,0 +1,94 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _SHADERGENCOMMON_H +#define _SHADERGENCOMMON_H + +#include +#include +#include +#include "CommonTypes.h" + +template +class ShaderUid +{ +public: + ShaderUid() + { + memset(values, 0, sizeof(values)); + } + + void Write(const char* fmt, ...) {} + const char* GetBuffer() { return NULL; } + void SetBuffer(char* buffer) { } + + bool operator == (const ShaderUid& obj) const + { + return memcmp(this->values, obj.values, sizeof(values)) == 0; + } + + // TODO: Store last frame used and order by that? makes much more sense anyway... + bool operator < (const ShaderUid& obj) const + { + for (int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i) + { + if (this->values[i] < obj.values[i]) + return true; + else if (this->values[i] > obj.values[i]) + return false; + } + return false; + } + + uid_data& GetUidData() { return data; } + +private: + union + { + uid_data data; + u32 values[sizeof(uid_data) / sizeof(u32)]; + }; +}; + +// Needs to be a template for hacks... +template +class ShaderCode +{ +public: + ShaderCode() : buf(NULL), write_ptr(NULL) + { + + } + + void Write(const char* fmt, ...) + { + va_list arglist; + va_start(arglist, fmt); + write_ptr += vsprintf(write_ptr, fmt, arglist); + va_end(arglist); + } + + const char* GetBuffer() { return buf; } + void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; } + uid_data& GetUidData() { return *(uid_data*)NULL; } + +private: + const char* buf; + char* write_ptr; +}; + +#endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index d7134b6dcb..acc89c6a54 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -267,7 +267,7 @@ void _GenerateLightingShader(T& object, int components, const char* materialsNam // TODO: Problem: this one uses copy constructors or sth for uids when returning... template -void GenerateShader(T& out, u32 components, API_TYPE api_type) +void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { #undef SetUidField #define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; @@ -635,12 +635,12 @@ void GenerateShader(T& out, u32 components, API_TYPE api_type) setlocale(LC_NUMERIC, ""); // restore locale } -void GenerateShaderUid(ShaderUid& object, u32 components, API_TYPE api_type) +void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) { - return GenerateShader(object, components, api_type); + GenerateVertexShader(object, components, api_type); } -void GenerateShaderCode(ShaderCode& object, u32 components, API_TYPE api_type) +void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) { - return GenerateShader(object, components, api_type); + GenerateVertexShader(object, components, api_type); } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ new file mode 100644 index 0000000000..be57103918 --- /dev/null +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ @@ -0,0 +1,645 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "NativeVertexFormat.h" + +#include "BPMemory.h" +#include "CPMemory.h" +#include "LightingShaderGen.h" +#include "VertexShaderGen.h" +#include "VideoConfig.h" + +static char text[16768]; + +enum GenOutput +{ + GO_ShaderCode, + GO_ShaderUid, +}; +// TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? +template +void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) +{ + object.Write("struct VS_OUTPUT {\n"); + object.Write(" float4 pos : POSITION;\n"); + object.Write(" float4 colors_0 : COLOR0;\n"); + object.Write(" float4 colors_1 : COLOR1;\n"); + + if (xfregs.numTexGen.numTexGens < 7) + { + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + object.Write(" float3 tex%d : TEXCOORD%d;\n", i, i); + + object.Write(" float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens); +/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) +/// object.Write(" float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1); + } + else + { + // clip position is in w of first 4 texcoords +/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) +/// { +/// for (int i = 0; i < 8; ++i) +/// object.Write(" float4 tex%d : TEXCOORD%d;\n", i, i); +/// } +/// else + { + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + object.Write(" float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i); + } + } + object.Write("};\n"); +} + +template +void _GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) +{ +#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; + const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; + const char* swizzle = "xyzw"; + if (coloralpha == 1 ) swizzle = "xyz"; + else if (coloralpha == 2 ) swizzle = "w"; + + SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); + SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); + if (!(chan.attnfunc & 1)) { + // atten disabled + switch (chan.diffusefunc) { + case LIGHTDIF_NONE: + object.Write("lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); + object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); + break; + default: _assert_(0); + } + } + else { // spec and spot + + if (chan.attnfunc == 3) + { // spot + object.Write("ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); + object.Write("dist2 = dot(ldir, ldir);\n" + "dist = sqrt(dist2);\n" + "ldir = ldir / dist;\n" + "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); + } + else if (chan.attnfunc == 1) + { // specular + object.Write("ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); + object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); + } + + switch (chan.diffusefunc) + { + case LIGHTDIF_NONE: + object.Write("lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, + chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", + lightsName, + index, + swizzle); + break; + default: _assert_(0); + } + } + object.Write("\n"); +} + +// vertex shader +// lights/colors +// materials name is I_MATERIALS in vs and I_PMATERIALS in ps +// inColorName is color in vs and colors_ in ps +// dest is o.colors_ in vs and colors_ in ps +template +void _GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +{ + for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) + { + const LitChannel& color = xfregs.color[j]; + const LitChannel& alpha = xfregs.alpha[j]; + + object.Write("{\n"); + + SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); + if (color.matsource) {// from vertex + if (components & (VB_HAS_COL0 << j)) + object.Write("mat = %s%d;\n", inColorName, j); + else if (components & VB_HAS_COL0) + object.Write("mat = %s0;\n", inColorName); + else + object.Write("mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + } + else // from color + object.Write("mat = %s.C%d;\n", materialsName, j+2); + + SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); + if (color.enablelighting) { + SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); + if (color.ambsource) { // from vertex + if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); + } + } + } + } + + // no shared lights + for (int i = 0; i < 8; ++i) + { + if (!(mask&(1<(object, i, j, lightsName, 1); + if (!(mask&(1<(object, i, j+2, lightsName, 2); + } + } + else if (color.enablelighting || alpha.enablelighting) + { + // lights are disabled on one channel so process only the active ones + const LitChannel& workingchannel = color.enablelighting ? color : alpha; + const int lit_index = color.enablelighting ? j : (j+2); + int coloralpha = color.enablelighting ? 1 : 2; + + SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); + for (int i = 0; i < 8; ++i) + { + if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); + } + } + object.Write("%s%d = mat * saturate(lacc);\n", dest, j); + object.Write("}\n"); + } +} + +// TODO: Problem: this one uses copy constructors or sth for uids when returning... +template +void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) +{ +#undef SetUidField +#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; + + if (type == GO_ShaderCode) + { + out.SetBuffer(text); + setlocale(LC_NUMERIC, "C"); // Reset locale for compilation + } + + /// text[sizeof(text) - 1] = 0x7C; // canary + + bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); + u32 lightMask = 0; + if (xfregs.numChan.numColorChans > 0) + lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask(); + if (xfregs.numChan.numColorChans > 1) + lightMask |= xfregs.color[1].GetFullLightMask() | xfregs.alpha[1].GetFullLightMask(); + + out.Write("//Vertex Shader: comp:%x, \n", components); + out.Write("typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_" I_POSNORMALMATRIX";\n" + "typedef struct { float4 t; } FLT4;\n" + "typedef struct { FLT4 T[24]; } s_" I_TEXMATRICES";\n" + "typedef struct { FLT4 T[64]; } s_" I_TRANSFORMMATRICES";\n" + "typedef struct { FLT4 T[32]; } s_" I_NORMALMATRICES";\n" + "typedef struct { FLT4 T[64]; } s_" I_POSTTRANSFORMMATRICES";\n" + "typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n" + "typedef struct { Light lights[8]; } s_" I_LIGHTS";\n" + "typedef struct { float4 C0, C1, C2, C3; } s_" I_MATERIALS";\n" + "typedef struct { float4 T0, T1, T2, T3; } s_" I_PROJECTION";\n" + ); + +/// p = GenerateVSOutputStruct(p, components, api_type); + GenerateVSOutputStruct(out, components, api_type); + + // uniforms + + out.Write("uniform s_" I_TRANSFORMMATRICES" " I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES); + out.Write("uniform s_" I_TEXMATRICES" " I_TEXMATRICES" : register(c%d);\n", C_TEXMATRICES); + out.Write("uniform s_" I_NORMALMATRICES" " I_NORMALMATRICES" : register(c%d);\n", C_NORMALMATRICES); + out.Write("uniform s_" I_POSNORMALMATRIX" " I_POSNORMALMATRIX" : register(c%d);\n", C_POSNORMALMATRIX); + out.Write("uniform s_" I_POSTTRANSFORMMATRICES" " I_POSTTRANSFORMMATRICES" : register(c%d);\n", C_POSTTRANSFORMMATRICES); + out.Write("uniform s_" I_LIGHTS" " I_LIGHTS" : register(c%d);\n", C_LIGHTS); + out.Write("uniform s_" I_MATERIALS" " I_MATERIALS" : register(c%d);\n", C_MATERIALS); + out.Write("uniform s_" I_PROJECTION" " I_PROJECTION" : register(c%d);\n", C_PROJECTION); + out.Write("uniform float4 " I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); + + out.Write("VS_OUTPUT main(\n"); + + SetUidField(numTexGens, xfregs.numTexGen.numTexGens); + SetUidField(components, components); + // inputs + if (components & VB_HAS_NRM0) + out.Write(" float3 rawnorm0 : NORMAL0,\n"); + if (components & VB_HAS_NRM1) + { + if (is_d3d) + out.Write(" float3 rawnorm1 : NORMAL1,\n"); + else + out.Write(" float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); + } + if (components & VB_HAS_NRM2) + { + if (is_d3d) + out.Write(" float3 rawnorm2 : NORMAL2,\n"); + else + out.Write(" float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); + } + if (components & VB_HAS_COL0) + out.Write(" float4 color0 : COLOR0,\n"); + if (components & VB_HAS_COL1) + out.Write(" float4 color1 : COLOR1,\n"); + for (int i = 0; i < 8; ++i) { + u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<= 32 ? (posmtx-32) : posmtx;\n"); + out.Write("float3 N0 = " I_NORMALMATRICES".T[normidx].t.xyz, N1 = " I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = " I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); + } + + if (components & VB_HAS_NRM0) + out.Write("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n"); + if (components & VB_HAS_NRM1) + out.Write("float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); + if (components & VB_HAS_NRM2) + out.Write("float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); + } + else + { + out.Write("float4 pos = float4(dot(" I_POSNORMALMATRIX".T0, rawpos), dot(" I_POSNORMALMATRIX".T1, rawpos), dot(" I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n"); + if (components & VB_HAS_NRM0) + out.Write("float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm0)));\n"); + if (components & VB_HAS_NRM1) + out.Write("float3 _norm1 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); + if (components & VB_HAS_NRM2) + out.Write("float3 _norm2 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); + } + + if (!(components & VB_HAS_NRM0)) + out.Write("float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); + + + + out.Write("o.pos = float4(dot(" I_PROJECTION".T0, pos), dot(" I_PROJECTION".T1, pos), dot(" I_PROJECTION".T2, pos), dot(" I_PROJECTION".T3, pos));\n"); + + out.Write("float4 mat, lacc;\n" + "float3 ldir, h;\n" + "float dist, dist2, attn;\n"); + + SetUidField(numColorChans, xfregs.numChan.numColorChans); + if(xfregs.numChan.numColorChans == 0) + { + if (components & VB_HAS_COL0) + out.Write("o.colors_0 = color0;\n"); + else + out.Write("o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + } + + // TODO: This probably isn't necessary if pixel lighting is enabled. + _GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + + if(xfregs.numChan.numColorChans < 2) + { + if (components & VB_HAS_COL1) + out.Write("o.colors_1 = color1;\n"); + else + out.Write("o.colors_1 = o.colors_0;\n"); + } + // special case if only pos and tex coord 0 and tex coord input is AB11 + // donko - this has caused problems in some games. removed for now. + bool texGenSpecialCase = false; + /*bool texGenSpecialCase = + ((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0 + (g_VtxDesc.Tex0Coord != NOT_PRESENT) && + (xfregs.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11); + */ + + // transform texcoords + out.Write("float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) { + TexMtxInfo& texinfo = xfregs.texMtxInfo[i]; + + out.Write("{\n"); + out.Write("coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); + SetUidField(texMtxInfo[i].sourcerow, xfregs.texMtxInfo[i].sourcerow); + switch (texinfo.sourcerow) { + case XF_SRCGEOM_INROW: + _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); + out.Write("coord = rawpos;\n"); // pos.w is 1 + break; + case XF_SRCNORMAL_INROW: + if (components & VB_HAS_NRM0) { + _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); + out.Write("coord = float4(rawnorm0.xyz, 1.0f);\n"); + } + break; + case XF_SRCCOLORS_INROW: + _assert_( texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 || texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1 ); + break; + case XF_SRCBINORMAL_T_INROW: + if (components & VB_HAS_NRM1) { + _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); + out.Write("coord = float4(rawnorm1.xyz, 1.0f);\n"); + } + break; + case XF_SRCBINORMAL_B_INROW: + if (components & VB_HAS_NRM2) { + _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); + out.Write("coord = float4(rawnorm2.xyz, 1.0f);\n"); + } + break; + default: + _assert_(texinfo.sourcerow <= XF_SRCTEX7_INROW); + if (components & (VB_HAS_UV0<<(texinfo.sourcerow - XF_SRCTEX0_INROW)) ) + out.Write("coord = float4(tex%d.x, tex%d.y, 1.0f, 1.0f);\n", texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW); + break; + } + + // first transformation + SetUidField(texMtxInfo[i].texgentype, xfregs.texMtxInfo[i].texgentype); + switch (texinfo.texgentype) { + case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map + + if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { + // transform the light dir into tangent space + SetUidField(texMtxInfo[i].embosslightshift, xfregs.texMtxInfo[i].embosslightshift); + SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + out.Write("ldir = normalize(" I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); + out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); + } + else + { + _assert_(0); // should have normals + SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); + } + + break; + case XF_TEXGEN_COLOR_STRGBC0: + _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); + out.Write("o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i); + break; + case XF_TEXGEN_COLOR_STRGBC1: + _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); + out.Write("o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i); + break; + case XF_TEXGEN_REGULAR: + default: + SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); + if (components & (VB_HAS_TEXMTXIDX0<(object, components, api_type); +} + +void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) +{ + GenerateVertexShader(object, components, api_type); +} diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index 11bb5c29f6..32d3eff91b 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -21,6 +21,7 @@ #include #include "XFMemory.h" #include "VideoCommon.h" +#include "ShaderGenCommon.h" #define SHADER_POSMTX_ATTRIB 1 #define SHADER_NORM1_ATTRIB 6 @@ -81,74 +82,11 @@ struct uid_data } lit_chans[4]; }; +typedef ShaderUid VertexShaderUid; +typedef ShaderCode VertexShaderCode; -class ShaderUid -{ -public: - ShaderUid() - { - memset(values, 0, sizeof(values)); - } - - void Write(const char* fmt, ...) {} - const char* GetBuffer() { return NULL; } - void SetBuffer(char* buffer) { } - - bool operator == (const ShaderUid& obj) const - { - return memcmp(this->values, obj.values, sizeof(values)) == 0; - } - - // TODO: Store last frame used and order by that? makes much more sense anyway... - bool operator < (const ShaderUid& obj) const - { - for (int i = 0; i < 24; ++i) - { - if (this->values[i] < obj.values[i]) - return true; - else if (this->values[i] > obj.values[i]) - return false; - } - return false; - } - - uid_data& GetUidData() { return data; } - -private: - union - { - uid_data data; - u32 values[24]; // TODO: Length? - }; -}; - -class ShaderCode -{ -public: - ShaderCode() : buf(NULL), write_ptr(NULL) - { - - } - - void Write(const char* fmt, ...) - { - va_list arglist; - va_start(arglist, fmt); - write_ptr += vsprintf(write_ptr, fmt, arglist); - va_end(arglist); - } - - const char* GetBuffer() { return buf; } - void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; } - uid_data& GetUidData() { return *(uid_data*)NULL; } - -private: - const char* buf; - char* write_ptr; -}; - -void GenerateShaderUid(ShaderUid& object, u32 components, API_TYPE api_type); -void GenerateShaderCode(ShaderCode& object, u32 components, API_TYPE api_type); +void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); +void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type); #endif // GCOGL_VERTEXSHADER_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h~ b/Source/Core/VideoCommon/Src/VertexShaderGen.h~ new file mode 100644 index 0000000000..050ed76649 --- /dev/null +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h~ @@ -0,0 +1,92 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef GCOGL_VERTEXSHADER_H +#define GCOGL_VERTEXSHADER_H + +#include +#include "XFMemory.h" +#include "VideoCommon.h" +#include "ShaderGenCommon.h" + +#define SHADER_POSMTX_ATTRIB 1 +#define SHADER_NORM1_ATTRIB 6 +#define SHADER_NORM2_ATTRIB 7 + + +// shader variables +#define I_POSNORMALMATRIX "cpnmtx" +#define I_PROJECTION "cproj" +#define I_MATERIALS "cmtrl" +#define I_LIGHTS "clights" +#define I_TEXMATRICES "ctexmtx" +#define I_TRANSFORMMATRICES "ctrmtx" +#define I_NORMALMATRICES "cnmtx" +#define I_POSTTRANSFORMMATRICES "cpostmtx" +#define I_DEPTHPARAMS "cDepth" // farZ, zRange, scaled viewport width, scaled viewport height + +#define C_POSNORMALMATRIX 0 +#define C_PROJECTION (C_POSNORMALMATRIX + 6) +#define C_MATERIALS (C_PROJECTION + 4) +#define C_LIGHTS (C_MATERIALS + 4) +#define C_TEXMATRICES (C_LIGHTS + 40) +#define C_TRANSFORMMATRICES (C_TEXMATRICES + 24) +#define C_NORMALMATRICES (C_TRANSFORMMATRICES + 64) +#define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES + 32) +#define C_DEPTHPARAMS (C_POSTTRANSFORMMATRICES + 64) +#define C_VENVCONST_END (C_DEPTHPARAMS + 4) + +// TODO: Need packing? +struct uid_data +{ + u32 components; + u32 numColorChans : 2; + u32 numTexGens : 4; + + struct { + u32 projection : 1; // XF_TEXPROJ_X + u32 inputform : 2; // XF_TEXINPUT_X + u32 texgentype : 3; // XF_TEXGEN_X + u32 sourcerow : 5; // XF_SRCGEOM_X + u32 embosssourceshift : 3; // what generated texcoord to use + u32 embosslightshift : 3; // light index that is used + } texMtxInfo[8]; + struct { + u32 index : 6; // base row of dual transform matrix + u32 normalize : 1; // normalize before send operation + } postMtxInfo[8]; + struct { + u32 enabled : 1; + } dualTexTrans; + struct { + u32 matsource : 1; + u32 enablelighting : 1; + u32 ambsource : 1; + u32 diffusefunc : 2; + u32 attnfunc : 2; + u32 light_mask : 8; + } lit_chans[4]; +}; + +typedef ShaderUid VertexShaderUid; +typedef ShaderCode VertexShaderCode; + +void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); +void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type); + + +#endif // GCOGL_VERTEXSHADER_H diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index 7eaf1546da..29dd76fe6d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -42,7 +42,7 @@ GLuint VertexShaderCache::CurrentShader; bool VertexShaderCache::ShaderEnabled; VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry = NULL; -ShaderUid VertexShaderCache::last_uid; +VertexShaderUid VertexShaderCache::last_uid; static int s_nMaxVertexInstructions; @@ -75,8 +75,8 @@ void VertexShaderCache::Shutdown() VERTEXSHADER* VertexShaderCache::SetShader(u32 components) { // Possible optimization: Don't always generate the shader uid, but keep track of changes in BPStructs instead - ShaderUid uid; - GenerateShaderUid(uid, components, API_OPENGL); + VertexShaderUid uid; + GetVertexShaderUid(uid, components, API_OPENGL); if (last_entry) { if (uid == last_uid) @@ -101,8 +101,8 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components) // Make an entry in the table VSCacheEntry& entry = vshaders[uid]; last_entry = &entry; - ShaderCode code; - GenerateShaderCode(code, components, API_OPENGL); + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_OPENGL); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp~ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp~ new file mode 100644 index 0000000000..f42cf09581 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp~ @@ -0,0 +1,271 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#include "Globals.h" +#include "VideoConfig.h" +#include "Statistics.h" + +#include "GLUtil.h" + +#include "Render.h" +#include "VertexShaderGen.h" +#include "VertexShaderManager.h" +#include "VertexShaderCache.h" +#include "VertexManager.h" +#include "VertexLoader.h" +#include "XFMemory.h" +#include "ImageWrite.h" +#include "FileUtil.h" +#include "Debugger.h" + +namespace OGL +{ + +VertexShaderCache::VSCache VertexShaderCache::vshaders; +GLuint VertexShaderCache::CurrentShader; +bool VertexShaderCache::ShaderEnabled; + +VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry = NULL; +VertexShaderUid VertexShaderCache::last_uid; + +static int s_nMaxVertexInstructions; + + +void VertexShaderCache::Init() +{ + glEnable(GL_VERTEX_PROGRAM_ARB); + ShaderEnabled = true; + CurrentShader = 0; + last_entry = NULL; + + glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); + if (strstr((const char*)glGetString(GL_VENDOR), "Humper") != NULL) s_nMaxVertexInstructions = 4096; +#if CG_VERSION_NUM == 2100 + if (strstr((const char*)glGetString(GL_VENDOR), "ATI") != NULL) + { + s_nMaxVertexInstructions = 4096; + } +#endif +} + +void VertexShaderCache::Shutdown() +{ + for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) + iter->second.Destroy(); + vshaders.clear(); +} + + +VERTEXSHADER* VertexShaderCache::SetShader(u32 components) +{ + // Possible optimization: Don't always generate the shader uid, but keep track of changes in BPStructs instead + VertexShaderUid uid; + GetVertexShaderUid(uid, components, API_OPENGL); + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return &last_entry->shader; + } + } + + last_uid = uid; + + VSCache::iterator iter = vshaders.find(uid); + if (iter != vshaders.end()) + { + VSCacheEntry &entry = iter->second; + last_entry = &entry; + + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return &last_entry->shader; + } + + // Make an entry in the table + VSCacheEntry& entry = vshaders[uid]; + last_entry = &entry; + ShaderCode code; + GenerateShaderCode(code, components, API_OPENGL); + +#if defined(_DEBUG) || defined(DEBUGFAST) + if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { + static int counter = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); + + SaveData(szTemp, code.GetBuffer()); + } +#endif + + if (!code.GetBuffer() || !VertexShaderCache::CompileVertexShader(entry.shader, code.GetBuffer())) { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + return NULL; + } + + INCSTAT(stats.numVertexShadersCreated); + SETSTAT(stats.numVertexShadersAlive, vshaders.size()); + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return &last_entry->shader; +} + +bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) +{ + // Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these. + GLenum err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) + { + ERROR_LOG(VIDEO, "glError %08x before VS!", err); + } + +#if defined HAVE_CG && HAVE_CG + char stropt[64]; + sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); + const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); + if (!cgIsProgram(tempprog)) { + static int num_failures = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "%sbad_vs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); + std::ofstream file(szTemp); + file << pstrprogram; + file.close(); + + PanicAlert("Failed to compile vertex shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s", + szTemp, + g_cgfProf, + cgGetLastListing(g_cgcontext)); + + cgDestroyProgram(tempprog); + ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); + ERROR_LOG(VIDEO, "%s", pstrprogram); + return false; + } + + if (cgGetError() != CG_NO_ERROR) + { + WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); + WARN_LOG(VIDEO, "%s", pstrprogram); + } + + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char *plocal = strstr(pcompiledprog, "program.local"); + while (plocal != NULL) { + const char* penv = " program.env"; + memcpy(plocal, penv, 13); + plocal = strstr(plocal + 13, "program.local"); + } + glGenProgramsARB(1, &vs.glprogid); + SetCurrentShader(vs.glprogid); + + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) { + ERROR_LOG(VIDEO, "%s", pstrprogram); + ERROR_LOG(VIDEO, "%s", pcompiledprog); + } + + cgDestroyProgram(tempprog); +#endif + + if (g_ActiveConfig.bEnableShaderDebugging) + vs.strprog = pstrprogram; + + return true; +} + +void VertexShaderCache::DisableShader() +{ + if (ShaderEnabled) + { + glDisable(GL_VERTEX_PROGRAM_ARB); + ShaderEnabled = false; + } +} + + +void VertexShaderCache::SetCurrentShader(GLuint Shader) +{ + if (!ShaderEnabled) + { + glEnable(GL_VERTEX_PROGRAM_ARB); + ShaderEnabled= true; + } + if (CurrentShader != Shader) + { + if(Shader != 0) + CurrentShader = Shader; + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, CurrentShader); + } +} + +void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) +{ + glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4); +} + +void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) +{ + glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f); +} + +void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) +{ + if(GLEW_EXT_gpu_program_parameters) + { + glProgramEnvParameters4fvEXT(GL_VERTEX_PROGRAM_ARB, const_number, count, f); + } + else + { + for (unsigned int i = 0; i < count; i++,f+=4) + glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, f); + } +} + +void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) +{ + if(GLEW_EXT_gpu_program_parameters) + { + 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; + } + glProgramEnvParameters4fvEXT(GL_VERTEX_PROGRAM_ARB, const_number, count, buf); + } + else + { + for (unsigned int i = 0; i < count; i++) + { + float buf[4]; + buf[0] = *f++; + buf[1] = *f++; + buf[2] = *f++; + buf[3] = 0.f; + glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, buf); + } + } +} + +} // namespace OGL diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h index f3831b3f7b..019abf6b6f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h @@ -40,7 +40,7 @@ class VertexShaderCache struct VSCacheEntry { VERTEXSHADER shader; - ShaderUid safe_uid; + VertexShaderUid safe_uid; VSCacheEntry() {} void Destroy() { // printf("Destroying vs %i\n", shader.glprogid); @@ -49,12 +49,12 @@ class VertexShaderCache } }; - typedef std::map VSCache; + typedef std::map VSCache; static VSCache vshaders; static VSCacheEntry* last_entry; - static ShaderUid last_uid; // TODO: Use reference instead.. + static VertexShaderUid last_uid; // TODO: Use reference instead.. static GLuint CurrentShader; static bool ShaderEnabled; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h~ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h~ new file mode 100644 index 0000000000..859645c59a --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h~ @@ -0,0 +1,76 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _VERTEXSHADERCACHE_H_ +#define _VERTEXSHADERCACHE_H_ + +#include +#include + +#include "BPMemory.h" +#include "VertexShaderGen.h" + +namespace OGL +{ + +struct VERTEXSHADER +{ + VERTEXSHADER() : glprogid(0) {} + GLuint glprogid; // opengl program id + + std::string strprog; +}; + +class VertexShaderCache +{ + struct VSCacheEntry + { + VERTEXSHADER shader; + VertexShaderUid safe_uid; + VSCacheEntry() {} + void Destroy() { + // printf("Destroying vs %i\n", shader.glprogid); + glDeleteProgramsARB(1, &shader.glprogid); + shader.glprogid = 0; + } + }; + + typedef std::map VSCache; + + static VSCache vshaders; + + static VSCacheEntry* last_entry; + static ShaderUid last_uid; // TODO: Use reference instead.. + + static GLuint CurrentShader; + static bool ShaderEnabled; + +public: + static void Init(); + static void Shutdown(); + + static VERTEXSHADER* SetShader(u32 components); + static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram); + + static void SetCurrentShader(GLuint Shader); + static void DisableShader(); + +}; + +} // namespace OGL + +#endif // _VERTEXSHADERCACHE_H_ From dc0f470215b4b8268c3d60cfdfc1aa07cec99277 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 7 Aug 2012 01:02:04 +0200 Subject: [PATCH 003/352] Added new shader cache uids for pixel shader gen. --- Source/Core/VideoCommon/Src/Debugger.cpp | 8 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 670 +++++++----------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 112 ++- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 8 +- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 5 - .../Core/VideoCommon/Src/VertexShaderGen.cpp~ | 645 ----------------- Source/Core/VideoCommon/Src/VertexShaderGen.h | 6 +- .../Core/VideoCommon/Src/VertexShaderGen.h~ | 2 +- Source/Core/VideoCommon/Src/VideoConfig.h | 2 +- .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 24 +- .../Plugin_VideoOGL/Src/PixelShaderCache.h | 7 +- 11 files changed, 318 insertions(+), 1171 deletions(-) delete mode 100644 Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ diff --git a/Source/Core/VideoCommon/Src/Debugger.cpp b/Source/Core/VideoCommon/Src/Debugger.cpp index 005f81c8e6..e0024db655 100644 --- a/Source/Core/VideoCommon/Src/Debugger.cpp +++ b/Source/Core/VideoCommon/Src/Debugger.cpp @@ -103,21 +103,21 @@ void GFXDebuggerBase::DumpPixelShader(const char* path) if (!useDstAlpha) { output = "Destination alpha disabled:\n"; - output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); +/// output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); } else { if(g_ActiveConfig.backend_info.bSupportsDualSourceBlend) { output = "Using dual source blending for destination alpha:\n"; - output += GeneratePixelShaderCode(DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); +/// output += GeneratePixelShaderCode(DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); } else { output = "Using two passes for emulating destination alpha:\n"; - output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); +/// output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); output += "\n\nDestination alpha pass shader:\n"; - output += GeneratePixelShaderCode(DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); +/// output += GeneratePixelShaderCode(DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); } } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 448501aad0..5ee95848b5 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -28,241 +28,6 @@ #include "NativeVertexFormat.h" -static void StageHash(u32 stage, u32* out) -{ - out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24 - u32 alphaC = bpmem.combiners[stage].alphaC.hex & 0xFFFFF0; // 24, strip out tswap and rswap for now - out[0] |= (alphaC&0xF0) << 24; // 8 - out[1] |= alphaC >> 8; // 16 - - // reserve 3 bits for bpmem.tevorders[stage/2].getTexMap - out[1] |= bpmem.tevorders[stage/2].getTexCoord(stage&1) << 19; // 3 - out[1] |= bpmem.tevorders[stage/2].getEnable(stage&1) << 22; // 1 - // reserve 3 bits for bpmem.tevorders[stage/2].getColorChan - - bool bHasIndStage = bpmem.tevind[stage].IsActive() && bpmem.tevind[stage].bt < bpmem.genMode.numindstages; - out[2] |= bHasIndStage << 2; // 1 - - bool needstexcoord = false; - - if (bHasIndStage) - { - out[2] |= (bpmem.tevind[stage].hex & 0x17FFFF) << 3; // 21, TODO: needs an explanation - needstexcoord = true; - } - - - TevStageCombiner::ColorCombiner& cc = bpmem.combiners[stage].colorC; - TevStageCombiner::AlphaCombiner& ac = bpmem.combiners[stage].alphaC; - - if(cc.a == TEVCOLORARG_RASA || cc.a == TEVCOLORARG_RASC - || cc.b == TEVCOLORARG_RASA || cc.b == TEVCOLORARG_RASC - || cc.c == TEVCOLORARG_RASA || cc.c == TEVCOLORARG_RASC - || cc.d == TEVCOLORARG_RASA || cc.d == TEVCOLORARG_RASC - || ac.a == TEVALPHAARG_RASA || ac.b == TEVALPHAARG_RASA - || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA) - { - out[0] |= bpmem.combiners[stage].alphaC.rswap; - out[2] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.rswap*2].swap1 << 24; // 2 - out[2] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.rswap*2].swap2 << 26; // 2 - out[2] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.rswap*2+1].swap1 << 28; // 2 - out[2] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.rswap*2+1].swap2 << 30; // 2 - out[1] |= (bpmem.tevorders[stage/2].getColorChan(stage&1)&1) << 23; - out[2] |= (bpmem.tevorders[stage/2].getColorChan(stage&1)&0x6) >> 1; - } - - out[3] |= bpmem.tevorders[stage/2].getEnable(stage&1); - if (bpmem.tevorders[stage/2].getEnable(stage&1)) - { - if (bHasIndStage) needstexcoord = true; - - out[0] |= bpmem.combiners[stage].alphaC.tswap; - out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2].swap1 << 1; // 2 - out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2].swap2 << 3; // 2 - out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2+1].swap1 << 5; // 2 - out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2+1].swap2 << 7; // 2 - out[1] |= bpmem.tevorders[stage/2].getTexMap(stage&1) << 16; - } - - if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST || cc.d == TEVCOLORARG_KONST - || ac.a == TEVALPHAARG_KONST || ac.b == TEVALPHAARG_KONST || ac.c == TEVALPHAARG_KONST || ac.d == TEVALPHAARG_KONST) - { - out[3] |= bpmem.tevksel[stage/2].getKC(stage&1) << 9; // 5 - out[3] |= bpmem.tevksel[stage/2].getKA(stage&1) << 14; // 5 - } - - if (needstexcoord) - { - out[1] |= bpmem.tevorders[stage/2].getTexCoord(stage&1) << 16; - } -} - -// Mash together all the inputs that contribute to the code of a generated pixel shader into -// a unique identifier, basically containing all the bits. Yup, it's a lot .... -// It would likely be a lot more efficient to build this incrementally as the attributes -// are set... -void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components) -{ - memset(uid->values, 0, sizeof(uid->values)); - uid->values[0] |= bpmem.genMode.numtevstages; // 4 - uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4 - uid->values[0] |= dstAlphaMode << 8; // 2 - - bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; - uid->values[0] |= enablePL << 10; // 1 - - if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4 - - AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult(); - uid->values[0] |= alphaPreTest << 15; // 2 - - // numtexgens should be <= 8 - for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) - uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1 - - uid->values[1] = bpmem.genMode.numindstages; // 3 - u32 indirectStagesUsed = 0; - for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i) - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - indirectStagesUsed |= (1 << bpmem.tevind[i].bt); - - assert(indirectStagesUsed == (indirectStagesUsed & 0xF)); - - uid->values[1] |= indirectStagesUsed << 3; // 4; - - for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i) - { - if (indirectStagesUsed & (1 << i)) - { - uid->values[1] |= (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens) << (7 + 3*i); // 1 - if (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens) - uid->values[1] |= bpmem.tevindref.getTexCoord(i) << (8 + 3*i); // 2 - } - } - - u32* ptr = &uid->values[2]; - for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1u; ++i) - { - StageHash(i, ptr); - ptr += 4; // max: ptr = &uid->values[66] - } - - ptr[0] |= bpmem.alpha_test.comp0; // 3 - ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3 - ptr[0] |= bpmem.alpha_test.logic << 6; // 2 - - ptr[0] |= bpmem.ztex2.op << 8; // 2 - ptr[0] |= bpmem.zcontrol.early_ztest << 10; // 1 - ptr[0] |= bpmem.zmode.testenable << 11; // 1 - ptr[0] |= bpmem.zmode.updateenable << 12; // 1 - - if (dstAlphaMode != DSTALPHA_ALPHA_PASS) - { - ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 13; // 3 - if (bpmem.fog.c_proj_fsel.fsel != 0) - { - ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1 - ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1 - } - } - - ++ptr; - if (enablePL) - { - ptr += GetLightingShaderId(ptr); - *ptr++ = components; - } - - uid->num_values = ptr - uid->values; -} - -void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components) -{ - memset(uid->values, 0, sizeof(uid->values)); - u32* ptr = uid->values; - *ptr++ = dstAlphaMode; // 0 - *ptr++ = bpmem.genMode.hex; // 1 - *ptr++ = bpmem.ztex2.hex; // 2 - *ptr++ = bpmem.zcontrol.hex; // 3 - *ptr++ = bpmem.zmode.hex; // 4 - *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 5 - *ptr++ = xfregs.numTexGen.hex; // 6 - - if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - { - *ptr++ = xfregs.color[0].hex; - *ptr++ = xfregs.alpha[0].hex; - *ptr++ = xfregs.color[1].hex; - *ptr++ = xfregs.alpha[1].hex; - *ptr++ = components; - } - - for (unsigned int i = 0; i < 8; ++i) - *ptr++ = xfregs.texMtxInfo[i].hex; // 7-14 - - for (unsigned int i = 0; i < 16; ++i) - *ptr++ = bpmem.tevind[i].hex; // 15-30 - - *ptr++ = bpmem.tevindref.hex; // 31 - - for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1u; ++i) // up to 16 times - { - *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i - *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i - *ptr++ = bpmem.tevind[i].hex; // 34+5*i - *ptr++ = bpmem.tevksel[i/2].hex; // 35+5*i - *ptr++ = bpmem.tevorders[i/2].hex; // 36+5*i - } - - ptr = &uid->values[112]; - - *ptr++ = bpmem.alpha_test.hex; // 112 - - *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113 - *ptr++ = bpmem.fogRange.Base.hex; // 114 - - _assert_((ptr - uid->values) == uid->GetNumValues()); -} - -void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, DSTALPHA_MODE dstAlphaMode, u32 components) -{ - if (!g_ActiveConfig.bEnableShaderDebugging) - return; - - PIXELSHADERUIDSAFE new_id; - GetSafePixelShaderId(&new_id, dstAlphaMode, components); - - if (!(old_id == new_id)) - { - std::string new_code(GeneratePixelShaderCode(dstAlphaMode, api, components)); - if (old_code != new_code) - { - _assert_(old_id.GetNumValues() == new_id.GetNumValues()); - - char msg[8192]; - char* ptr = msg; - ptr += sprintf(ptr, "Pixel shader IDs matched but unique IDs did not!\nUnique IDs (old <-> new):\n"); - const int N = new_id.GetNumValues(); - for (int i = 0; i < N/2; ++i) - ptr += sprintf(ptr, "%02d, %08X %08X | %08X %08X\n", 2*i, old_id.values[2*i], old_id.values[2*i+1], - new_id.values[2*i], new_id.values[2*i+1]); - if (N % 2) - ptr += sprintf(ptr, "%02d, %08X | %08X\n", N-1, old_id.values[N-1], new_id.values[N-1]); - - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%spsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); - file << msg; - file << "\n\nOld shader code:\n" << old_code; - file << "\n\nNew shader code:\n" << new_code; - file.close(); - - PanicAlert("Unique pixel shader ID mismatch!\n\nReport this to the devs, along with the contents of %s.", szTemp); - } - } -} - // old tev->pixelshader notes // // color for this stage (alpha, color) is given by bpmem.tevorders[0].colorchan0 @@ -272,11 +37,11 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std:: // output is given by .outreg // tevtemp is set according to swapmodetables and -static void WriteStage(char *&p, int n, API_TYPE ApiType); -static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); +template static void WriteStage(char *&p, int n, API_TYPE ApiType); +template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); // static void WriteAlphaCompare(char *&p, int num, int comp); -static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); -static void WriteFog(char *&p); +template static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); +template static void WriteFog(char *&p); static const char *tevKSelTableC[] = // KCSEL { @@ -456,8 +221,6 @@ static const char *tevIndBiasAdd[] = {"-128.0f", "1.0f", "1.0f", "1.0f" }; // static const char *tevIndWrapStart[] = {"0.0f", "256.0f", "128.0f", "64.0f", "32.0f", "16.0f", "0.001f" }; static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "7.0f" }; -#define WRITE p+=sprintf - static char swapModeTable[4][5]; static char text[16384]; @@ -484,105 +247,109 @@ static void BuildSwapModeTable() } } -const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +template +void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - setlocale(LC_NUMERIC, "C"); // Reset locale for compilation - text[sizeof(text) - 1] = 0x7C; // canary +#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; + if (type == GO_ShaderCode) + { + setlocale(LC_NUMERIC, "C"); // Reset locale for compilation + out.SetBuffer(text); + } +/// text[sizeof(text) - 1] = 0x7C; // canary + /// TODO: Uids! BuildSwapModeTable(); // Needed for WriteStage - int numStages = bpmem.genMode.numtevstages + 1; - int numTexgen = bpmem.genMode.numtexgens; + unsigned int numStages = bpmem.genMode.numtevstages + 1; + unsigned int numTexgen = bpmem.genMode.numtexgens; char *p = text; - WRITE(p, "//Pixel Shader for TEV stages\n"); - WRITE(p, "//%i TEV stages, %i texgens, XXX IND stages\n", + out.Write("//Pixel Shader for TEV stages\n"); + out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", numStages, numTexgen/*, bpmem.genMode.numindstages*/); - int nIndirectStagesUsed = 0; - if (bpmem.genMode.numindstages > 0) - { - for (int i = 0; i < numStages; ++i) - { - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; - } - } - // Declare samplers + SetUidField(components, components); + SetUidField(dstAlphaMode, dstAlphaMode); + SetUidField(genMode.numindstages, bpmem.genMode.numindstages); + SetUidField(genMode.numtevstages, bpmem.genMode.numtevstages); + SetUidField(genMode.numtexgens, bpmem.genMode.numtexgens); + + // Declare samplers if(ApiType != API_D3D11) { - WRITE(p, "uniform sampler2D "); + out.Write("uniform sampler2D "); } else { - WRITE(p, "sampler "); + out.Write("sampler "); } bool bfirst = true; for (int i = 0; i < 8; ++i) { - WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i); + out.Write("%s samp%d : register(s%d)", bfirst?"":",", i, i); bfirst = false; } - WRITE(p, ";\n"); + out.Write(";\n"); if(ApiType == API_D3D11) { - WRITE(p, "Texture2D "); + out.Write("Texture2D "); bfirst = true; for (int i = 0; i < 8; ++i) { - WRITE(p, "%s Tex%d : register(t%d)", bfirst?"":",", i, i); + out.Write("%s Tex%d : register(t%d)", bfirst?"":",", i, i); bfirst = false; } - WRITE(p, ";\n"); + out.Write(";\n"); } - WRITE(p, "\n"); + out.Write("\n"); - WRITE(p, "uniform float4 " I_COLORS"[4] : register(c%d);\n", C_COLORS); - WRITE(p, "uniform float4 " I_KCOLORS"[4] : register(c%d);\n", C_KCOLORS); - WRITE(p, "uniform float4 " I_ALPHA"[1] : register(c%d);\n", C_ALPHA); - WRITE(p, "uniform float4 " I_TEXDIMS"[8] : register(c%d);\n", C_TEXDIMS); - WRITE(p, "uniform float4 " I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS); - WRITE(p, "uniform float4 " I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE); - WRITE(p, "uniform float4 " I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX); - WRITE(p, "uniform float4 " I_FOG"[3] : register(c%d);\n", C_FOG); + out.Write("uniform float4 " I_COLORS"[4] : register(c%d);\n", C_COLORS); + out.Write("uniform float4 " I_KCOLORS"[4] : register(c%d);\n", C_KCOLORS); + out.Write("uniform float4 " I_ALPHA"[1] : register(c%d);\n", C_ALPHA); + out.Write("uniform float4 " I_TEXDIMS"[8] : register(c%d);\n", C_TEXDIMS); + out.Write("uniform float4 " I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS); + out.Write("uniform float4 " I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE); + out.Write("uniform float4 " I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX); + out.Write("uniform float4 " I_FOG"[3] : register(c%d);\n", C_FOG); if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { - WRITE(p,"typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n"); - WRITE(p,"typedef struct { Light lights[8]; } s_" I_PLIGHTS";\n"); - WRITE(p, "uniform s_" I_PLIGHTS" " I_PLIGHTS" : register(c%d);\n", C_PLIGHTS); - WRITE(p, "typedef struct { float4 C0, C1, C2, C3; } s_" I_PMATERIALS";\n"); - WRITE(p, "uniform s_" I_PMATERIALS" " I_PMATERIALS" : register(c%d);\n", C_PMATERIALS); + out.Write("typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n"); + out.Write("typedef struct { Light lights[8]; } s_" I_PLIGHTS";\n"); + out.Write("uniform s_" I_PLIGHTS" " I_PLIGHTS" : register(c%d);\n", C_PLIGHTS); + out.Write("typedef struct { float4 C0, C1, C2, C3; } s_" I_PMATERIALS";\n"); + out.Write("uniform s_" I_PMATERIALS" " I_PMATERIALS" : register(c%d);\n", C_PMATERIALS); } - WRITE(p, "void main(\n"); + out.Write("void main(\n"); if(ApiType != API_D3D11) { - WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", + out.Write(" out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", "\n out float depth : DEPTH,", ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS"); } else { - WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", + out.Write(" out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", "\n out float depth : SV_Depth,"); } - WRITE(p, " in float4 colors_0 : COLOR0,\n"); - WRITE(p, " in float4 colors_1 : COLOR1"); + out.Write(" in float4 colors_0 : COLOR0,\n"); + out.Write(" in float4 colors_1 : COLOR1"); // compute window position if needed because binding semantic WPOS is not widely supported if (numTexgen < 7) { - for (int i = 0; i < numTexgen; ++i) - WRITE(p, ",\n in float3 uv%d : TEXCOORD%d", i, i); - WRITE(p, ",\n in float4 clipPos : TEXCOORD%d", numTexgen); + for (unsigned int i = 0; i < numTexgen; ++i) + out.Write(",\n in float3 uv%d : TEXCOORD%d", i, i); + out.Write(",\n in float4 clipPos : TEXCOORD%d", numTexgen); if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1); + out.Write(",\n in float4 Normal : TEXCOORD%d", numTexgen + 1); } else { @@ -590,17 +357,18 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { for (int i = 0; i < 8; ++i) - WRITE(p, ",\n in float4 uv%d : TEXCOORD%d", i, i); + out.Write(",\n in float4 uv%d : TEXCOORD%d", i, i); } else { + /// TODO: Set numTexGen used for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, ",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i); + out.Write(",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i); } } - WRITE(p, " ) {\n"); + out.Write(" ) {\n"); - WRITE(p, " float4 c0 = " I_COLORS"[1], c1 = " I_COLORS"[2], c2 = " I_COLORS"[3], prev = float4(0.0f, 0.0f, 0.0f, 0.0f), textemp = float4(0.0f, 0.0f, 0.0f, 0.0f), rastemp = float4(0.0f, 0.0f, 0.0f, 0.0f), konsttemp = float4(0.0f, 0.0f, 0.0f, 0.0f);\n" + out.Write(" float4 c0 = " I_COLORS"[1], c1 = " I_COLORS"[2], c2 = " I_COLORS"[3], prev = float4(0.0f, 0.0f, 0.0f, 0.0f), textemp = float4(0.0f, 0.0f, 0.0f, 0.0f), rastemp = float4(0.0f, 0.0f, 0.0f, 0.0f), konsttemp = float4(0.0f, 0.0f, 0.0f, 0.0f);\n" " float3 comp16 = float3(1.0f, 255.0f, 0.0f), comp24 = float3(1.0f, 255.0f, 255.0f*255.0f);\n" " float4 alphabump=float4(0.0f,0.0f,0.0f,0.0f);\n" " float3 tevcoord=float3(0.0f, 0.0f, 0.0f);\n" @@ -613,63 +381,96 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType { if (xfregs.numTexGen.numTexGens < 7) { - WRITE(p,"float3 _norm0 = normalize(Normal.xyz);\n\n"); - WRITE(p,"float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n"); + out.Write("float3 _norm0 = normalize(Normal.xyz);\n\n"); + out.Write("float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n"); } else { - WRITE(p," float3 _norm0 = normalize(float3(uv4.w,uv5.w,uv6.w));\n\n"); - WRITE(p,"float3 pos = float3(uv0.w,uv1.w,uv7.w);\n"); + out.Write(" float3 _norm0 = normalize(float3(uv4.w,uv5.w,uv6.w));\n\n"); + out.Write("float3 pos = float3(uv0.w,uv1.w,uv7.w);\n"); } - WRITE(p, "float4 mat, lacc;\n" + out.Write("float4 mat, lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); - p = GenerateLightingShader(p, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); +/// p = GenerateLightingShader(p, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } if (numTexgen < 7) - WRITE(p, "clipPos = float4(rawpos.x, rawpos.y, clipPos.z, clipPos.w);\n"); + out.Write("clipPos = float4(rawpos.x, rawpos.y, clipPos.z, clipPos.w);\n"); else - WRITE(p, "float4 clipPos = float4(rawpos.x, rawpos.y, uv2.w, uv3.w);\n"); + out.Write("float4 clipPos = float4(rawpos.x, rawpos.y, uv2.w, uv3.w);\n"); // HACK to handle cases where the tex gen is not enabled if (numTexgen == 0) { - WRITE(p, "float3 uv0 = float3(0.0f, 0.0f, 0.0f);\n"); + out.Write("float3 uv0 = float3(0.0f, 0.0f, 0.0f);\n"); } else { - for (int i = 0; i < numTexgen; ++i) + for (unsigned int i = 0; i < numTexgen; ++i) { // optional perspective divides + SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); if (xfregs.texMtxInfo[i].projection == XF_TEXPROJ_STQ) { - WRITE(p, "if (uv%d.z)", i); - WRITE(p, " uv%d.xy = uv%d.xy / uv%d.z;\n", i, i, i); + out.Write("if (uv%d.z)", i); + out.Write(" uv%d.xy = uv%d.xy / uv%d.z;\n", i, i, i); } - WRITE(p, "uv%d.xy = uv%d.xy * " I_TEXDIMS"[%d].zw;\n", i, i, i); + out.Write("uv%d.xy = uv%d.xy * " I_TEXDIMS"[%d].zw;\n", i, i, i); } } // indirect texture map lookup + int nIndirectStagesUsed = 0; + if (bpmem.genMode.numindstages > 0) + { + for (unsigned int i = 0; i < numStages; ++i) + { + /// Ignoring this for now, handled in WriteStage. + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) + nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; + } + } + SetUidField(nIndirectStagesUsed, nIndirectStagesUsed); for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { if (nIndirectStagesUsed & (1<(out, buffer, "tempcoord", "abg", texmap, ApiType); } } @@ -683,8 +484,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType RegisterStates[i].AuxStored = false; } - for (int i = 0; i < numStages; i++) - WriteStage(p, i, ApiType); //build the equation for this stage + for (unsigned int i = 0; i < numStages; i++) + WriteStage(out, i, ApiType); //build the equation for this stage if(numStages) { @@ -692,48 +493,49 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType // regardless of the used destination register if(bpmem.combiners[numStages - 1].colorC.dest != 0) { +/// SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].AuxStored; - WRITE(p, "prev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]); + out.Write("prev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]); RegisterStates[0].ColorNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl; } if(bpmem.combiners[numStages - 1].alphaC.dest != 0) { bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AuxStored; - WRITE(p, "prev.a = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevAOutputTable[bpmem.combiners[numStages - 1].alphaC.dest]); + out.Write("prev.a = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevAOutputTable[bpmem.combiners[numStages - 1].alphaC.dest]); RegisterStates[0].AlphaNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl; } } // emulation of unsigned 8 overflow when casting if needed if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) - WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); if (Pretest == AlphaTest::UNDETERMINED) - WriteAlphaTest(p, ApiType, dstAlphaMode); + WriteAlphaTest(out, ApiType, dstAlphaMode); // the screen space depth value = far z + (clip z / clip w) * z range - WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); + out.Write("float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); // Note: depth textures are disabled if early depth test is enabled if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... - WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", + out.Write("zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : ""); // scale to make result from frac correct - WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); - WRITE(p, "zCoord = frac(zCoord);\n"); - WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); + out.Write("zCoord = zCoord * (16777215.0f/16777216.0f);\n"); + out.Write("zCoord = frac(zCoord);\n"); + out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n"); } - WRITE(p, "depth = zCoord;\n"); + out.Write("depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) - WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); + out.Write(" ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); else { - WriteFog(p); - WRITE(p, " ocol0 = prev;\n"); + WriteFog(out); + out.Write(" ocol0 = prev;\n"); } // On D3D11, use dual-source color blending to perform dst alpha in a @@ -741,17 +543,16 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { // Colors will be blended against the alpha from ocol1... - WRITE(p, " ocol1 = ocol0;\n"); + out.Write(" ocol1 = ocol0;\n"); // ...and the alpha from ocol0 will be written to the framebuffer. - WRITE(p, " ocol0.a = " I_ALPHA"[0].a;\n"); + out.Write(" ocol0.a = " I_ALPHA"[0].a;\n"); } - WRITE(p, "}\n"); - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); + out.Write("}\n"); +/// if (text[sizeof(text) - 1] != 0x7C) +/// PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); setlocale(LC_NUMERIC, ""); // restore locale - return text; } @@ -800,7 +601,8 @@ static const char *TEVCMPAlphaOPTable[16] = }; -static void WriteStage(char *&p, int n, API_TYPE ApiType) +template +static void WriteStage(T& out, int n, API_TYPE ApiType) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens; @@ -810,25 +612,25 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) if (!bHasTexCoord) texcoord = 0; - WRITE(p, "// TEV stage %d\n", n); + out.Write("// TEV stage %d\n", n); if (bHasIndStage) { - WRITE(p, "// indirect op\n"); + out.Write("// indirect op\n"); // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords if (bpmem.tevind[n].bs != ITBA_OFF) { - WRITE(p, "alphabump = indtex%d.%s %s;\n", + out.Write("alphabump = indtex%d.%s %s;\n", bpmem.tevind[n].bt, tevIndAlphaSel[bpmem.tevind[n].bs], tevIndAlphaScale[bpmem.tevind[n].fmt]); } // format - WRITE(p, "float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]); + out.Write("float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]); // bias if (bpmem.tevind[n].bias != ITB_NONE ) - WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); + out.Write("indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); // multiply by offset matrix and scale if (bpmem.tevind[n].mid != 0) @@ -836,26 +638,26 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) if (bpmem.tevind[n].mid <= 3) { int mtxidx = 2*(bpmem.tevind[n].mid-1); - WRITE(p, "float2 indtevtrans%d = float2(dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", + out.Write("float2 indtevtrans%d = float2(dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", n, mtxidx, n, mtxidx+1, n); } else if (bpmem.tevind[n].mid <= 7 && bHasTexCoord) { // s matrix _assert_(bpmem.tevind[n].mid >= 5); int mtxidx = 2*(bpmem.tevind[n].mid-5); - WRITE(p, "float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n); + out.Write("float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n); } else if (bpmem.tevind[n].mid <= 11 && bHasTexCoord) { // t matrix _assert_(bpmem.tevind[n].mid >= 9); int mtxidx = 2*(bpmem.tevind[n].mid-9); - WRITE(p, "float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n); + out.Write("float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n); } else - WRITE(p, "float2 indtevtrans%d = 0;\n", n); + out.Write("float2 indtevtrans%d = 0;\n", n); } else - WRITE(p, "float2 indtevtrans%d = 0;\n", n); + out.Write("float2 indtevtrans%d = 0;\n", n); // --------- // Wrapping @@ -863,24 +665,24 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) // wrap S if (bpmem.tevind[n].sw == ITW_OFF) - WRITE(p, "wrappedcoord.x = uv%d.x;\n", texcoord); + out.Write("wrappedcoord.x = uv%d.x;\n", texcoord); else if (bpmem.tevind[n].sw == ITW_0) - WRITE(p, "wrappedcoord.x = 0.0f;\n"); + out.Write("wrappedcoord.x = 0.0f;\n"); else - WRITE(p, "wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]); + out.Write("wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]); // wrap T if (bpmem.tevind[n].tw == ITW_OFF) - WRITE(p, "wrappedcoord.y = uv%d.y;\n", texcoord); + out.Write("wrappedcoord.y = uv%d.y;\n", texcoord); else if (bpmem.tevind[n].tw == ITW_0) - WRITE(p, "wrappedcoord.y = 0.0f;\n"); + out.Write("wrappedcoord.y = 0.0f;\n"); else - WRITE(p, "wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]); + out.Write("wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]); if (bpmem.tevind[n].fb_addprev) // add previous tevcoord - WRITE(p, "tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n); + out.Write("tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n); else - WRITE(p, "tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n); + out.Write("tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n); } TevStageCombiner::ColorCombiner &cc = bpmem.combiners[n].colorC; @@ -894,8 +696,8 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA) { char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; - WRITE(p, "rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); - WRITE(p, "crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); + out.Write("crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); } @@ -905,17 +707,17 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { // calc tevcord if(bHasTexCoord) - WRITE(p, "tevcoord.xy = uv%d.xy;\n", texcoord); + out.Write("tevcoord.xy = uv%d.xy;\n", texcoord); else - WRITE(p, "tevcoord.xy = float2(0.0f, 0.0f);\n"); + out.Write("tevcoord.xy = float2(0.0f, 0.0f);\n"); } char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); - SampleTexture(p, "textemp", "tevcoord", texswap, texmap, ApiType); + SampleTexture(out, "textemp", "tevcoord", texswap, texmap, ApiType); } else - WRITE(p, "textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + out.Write("textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST || cc.d == TEVCOLORARG_KONST @@ -923,14 +725,14 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { int kc = bpmem.tevksel[n / 2].getKC(n & 1); int ka = bpmem.tevksel[n / 2].getKA(n & 1); - WRITE(p, "konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]); + out.Write("konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]); if(kc > 7 || ka > 7) { - WRITE(p, "ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); } else { - WRITE(p, "ckonsttemp = konsttemp;\n"); + out.Write("ckonsttemp = konsttemp;\n"); } } @@ -941,13 +743,13 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) { - WRITE(p, "cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); RegisterStates[0].AlphaNeedOverflowControl = false; RegisterStates[0].ColorNeedOverflowControl = false; } else { - WRITE(p, "cprev = prev;\n"); + out.Write("cprev = prev;\n"); } RegisterStates[0].AuxStored = true; } @@ -959,13 +761,13 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl) { - WRITE(p, "cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); RegisterStates[1].AlphaNeedOverflowControl = false; RegisterStates[1].ColorNeedOverflowControl = false; } else { - WRITE(p, "cc0 = c0;\n"); + out.Write("cc0 = c0;\n"); } RegisterStates[1].AuxStored = true; } @@ -977,13 +779,13 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl) { - WRITE(p, "cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); RegisterStates[2].AlphaNeedOverflowControl = false; RegisterStates[2].ColorNeedOverflowControl = false; } else { - WRITE(p, "cc1 = c1;\n"); + out.Write("cc1 = c1;\n"); } RegisterStates[2].AuxStored = true; } @@ -995,13 +797,13 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl) { - WRITE(p, "cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + out.Write("cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); RegisterStates[3].AlphaNeedOverflowControl = false; RegisterStates[3].ColorNeedOverflowControl = false; } else { - WRITE(p, "cc2 = c2;\n"); + out.Write("cc2 = c2;\n"); } RegisterStates[3].AuxStored = true; } @@ -1009,117 +811,116 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) RegisterStates[cc.dest].ColorNeedOverflowControl = (cc.clamp == 0); RegisterStates[cc.dest].AuxStored = false; - // combine the color channel - WRITE(p, "// color combine\n"); + out.Write("// color combine\n"); if (cc.clamp) - WRITE(p, "%s = saturate(", tevCOutputTable[cc.dest]); + out.Write("%s = saturate(", tevCOutputTable[cc.dest]); else - WRITE(p, "%s = ", tevCOutputTable[cc.dest]); + out.Write("%s = ", tevCOutputTable[cc.dest]); // combine the color channel if (cc.bias != TevBias_COMPARE) // if not compare { //normal color combiner goes here if (cc.shift > TEVSCALE_1) - WRITE(p, "%s*(", tevScaleTable[cc.shift]); + out.Write("%s*(", tevScaleTable[cc.shift]); if(!(cc.d == TEVCOLORARG_ZERO && cc.op == TEVOP_ADD)) - WRITE(p, "%s%s", tevCInputTable[cc.d], tevOpTable[cc.op]); + out.Write("%s%s", tevCInputTable[cc.d], tevOpTable[cc.op]); if (cc.a == cc.b) - WRITE(p, "%s", tevCInputTable[cc.a + 16]); + out.Write("%s", tevCInputTable[cc.a + 16]); else if (cc.c == TEVCOLORARG_ZERO) - WRITE(p, "%s", tevCInputTable[cc.a + 16]); + out.Write("%s", tevCInputTable[cc.a + 16]); else if (cc.c == TEVCOLORARG_ONE) - WRITE(p, "%s", tevCInputTable[cc.b + 16]); + out.Write("%s", tevCInputTable[cc.b + 16]); else if (cc.a == TEVCOLORARG_ZERO) - WRITE(p, "%s*%s", tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); + out.Write("%s*%s", tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); else if (cc.b == TEVCOLORARG_ZERO) - WRITE(p, "%s*(float3(1.0f, 1.0f, 1.0f)-%s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.c + 16]); + out.Write("%s*(float3(1.0f, 1.0f, 1.0f)-%s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.c + 16]); else - WRITE(p, "lerp(%s, %s, %s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); + out.Write("lerp(%s, %s, %s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); - WRITE(p, "%s", tevBiasTable[cc.bias]); + out.Write("%s", tevBiasTable[cc.bias]); if (cc.shift > TEVSCALE_1) - WRITE(p, ")"); + out.Write(")"); } else { int cmp = (cc.shift<<1)|cc.op|8; // comparemode stored here - WRITE(p, TEVCMPColorOPTable[cmp],//lookup the function from the op table + out.Write(TEVCMPColorOPTable[cmp],//lookup the function from the op table tevCInputTable[cc.d], tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); } if (cc.clamp) - WRITE(p, ")"); - WRITE(p,";\n"); + out.Write(")"); + out.Write(";\n"); RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0); RegisterStates[ac.dest].AuxStored = false; - // combine the alpha channel - WRITE(p, "// alpha combine\n"); + out.Write("// alpha combine\n"); if (ac.clamp) - WRITE(p, "%s = saturate(", tevAOutputTable[ac.dest]); + out.Write("%s = saturate(", tevAOutputTable[ac.dest]); else - WRITE(p, "%s = ", tevAOutputTable[ac.dest]); + out.Write("%s = ", tevAOutputTable[ac.dest]); if (ac.bias != TevBias_COMPARE) // if not compare { //normal alpha combiner goes here if (ac.shift > TEVSCALE_1) - WRITE(p, "%s*(", tevScaleTable[ac.shift]); + out.Write("%s*(", tevScaleTable[ac.shift]); if(!(ac.d == TEVALPHAARG_ZERO && ac.op == TEVOP_ADD)) - WRITE(p, "%s.a%s", tevAInputTable[ac.d], tevOpTable[ac.op]); + out.Write("%s.a%s", tevAInputTable[ac.d], tevOpTable[ac.op]); if (ac.a == ac.b) - WRITE(p, "%s.a", tevAInputTable[ac.a + 8]); + out.Write("%s.a", tevAInputTable[ac.a + 8]); else if (ac.c == TEVALPHAARG_ZERO) - WRITE(p, "%s.a", tevAInputTable[ac.a + 8]); + out.Write("%s.a", tevAInputTable[ac.a + 8]); else if (ac.a == TEVALPHAARG_ZERO) - WRITE(p, "%s.a*%s.a", tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); + out.Write("%s.a*%s.a", tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); else if (ac.b == TEVALPHAARG_ZERO) - WRITE(p, "%s.a*(1.0f-%s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.c + 8]); + out.Write("%s.a*(1.0f-%s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.c + 8]); else - WRITE(p, "lerp(%s.a, %s.a, %s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); + out.Write("lerp(%s.a, %s.a, %s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); - WRITE(p, "%s",tevBiasTable[ac.bias]); + out.Write("%s",tevBiasTable[ac.bias]); if (ac.shift>0) - WRITE(p, ")"); + out.Write(")"); } else { //compare alpha combiner goes here int cmp = (ac.shift<<1)|ac.op|8; // comparemode stored here - WRITE(p, TEVCMPAlphaOPTable[cmp], + out.Write(TEVCMPAlphaOPTable[cmp], tevAInputTable[ac.d], tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); } if (ac.clamp) - WRITE(p, ")"); - WRITE(p, ";\n\n"); - WRITE(p, "// TEV done\n"); + out.Write(")"); + out.Write(";\n\n"); + out.Write("// TEV done\n"); } -void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType) +template +void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType) { if (ApiType == API_D3D11) - WRITE(p, "%s=Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", destination, texmap,texmap, texcoords, texmap, texswap); + out.Write("%s=Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", destination, texmap,texmap, texcoords, texmap, texswap); else - WRITE(p, "%s=tex2D(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap); + out.Write("%s=tex2D(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap); } static const char *tevAlphaFuncsTable[] = { - "(false)", //ALPHACMP_NEVER 0 + "(false)", //ALPHACMP_NEVER 0, TODO: Not safe? "(prev.a <= %s - (0.25f/255.0f))", //ALPHACMP_LESS 1 "(abs( prev.a - %s ) < (0.5f/255.0f))", //ALPHACMP_EQUAL 2 "(prev.a < %s + (0.25f/255.0f))", //ALPHACMP_LEQUAL 3 @@ -1137,7 +938,8 @@ static const char *tevAlphaFunclogicTable[] = " == " // xnor }; -static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) +template +static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode) { static const char *alphaRef[2] = { @@ -1146,21 +948,21 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode }; // using discard then return works the same in cg and dx9 but not in dx11 - WRITE(p, "if(!( "); + out.Write("if(!( "); int compindex = bpmem.alpha_test.comp0; - WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table + out.Write(tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table - WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op + out.Write("%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op compindex = bpmem.alpha_test.comp1; - WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table - WRITE(p, ")) {\n"); + out.Write(tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table + out.Write(")) {\n"); - WRITE(p, "ocol0 = 0;\n"); + out.Write("ocol0 = 0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) - WRITE(p, "ocol1 = 0;\n"); - WRITE(p, "depth = 1.f;\n"); + out.Write("ocol1 = 0;\n"); + out.Write("depth = 1.f;\n"); // HAXX: zcomploc (aka early_ztest) is a way to control whether depth test is done before // or after texturing and alpha test. PC GPUs have no way to support this @@ -1174,12 +976,12 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode // we don't have a choice. if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { - WRITE(p, "discard;\n"); + out.Write("discard;\n"); if (ApiType != API_D3D11) - WRITE(p, "return;\n"); + out.Write("return;\n"); } - WRITE(p, "}\n"); + out.Write("}\n"); } static const char *tevFogFuncsTable[] = @@ -1194,38 +996,40 @@ static const char *tevFogFuncsTable[] = " fog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" //backward exp2 }; -static void WriteFog(char *&p) +template +static void WriteFog(T& out) { - if(bpmem.fog.c_proj_fsel.fsel == 0)return;//no Fog + if(bpmem.fog.c_proj_fsel.fsel == 0) + return; //no Fog if (bpmem.fog.c_proj_fsel.proj == 0) { // perspective // ze = A/(B - (Zs >> B_SHF) - WRITE (p, " float ze = " I_FOG"[1].x / (" I_FOG"[1].y - (zCoord / " I_FOG"[1].w));\n"); + out.Write(" float ze = " I_FOG"[1].x / (" I_FOG"[1].y - (zCoord / " I_FOG"[1].w));\n"); } else { // orthographic // ze = a*Zs (here, no B_SHF) - WRITE (p, " float ze = " I_FOG"[1].x * zCoord;\n"); + out.Write(" float ze = " I_FOG"[1].x * zCoord;\n"); } // x_adjust = sqrt((x-center)^2 + k^2)/k // ze *= x_adjust - //this is complitly teorical as the real hard seems to use a table intead of calculate the values. + // this is completely theoretical as the real hardware seems to use a table intead of calculating the values. if(bpmem.fogRange.Base.Enabled) { - WRITE (p, " float x_adjust = (2.0f * (clipPos.x / " I_FOG"[2].y)) - 1.0f - " I_FOG"[2].x;\n"); - WRITE (p, " x_adjust = sqrt(x_adjust * x_adjust + " I_FOG"[2].z * " I_FOG"[2].z) / " I_FOG"[2].z;\n"); - WRITE (p, " ze *= x_adjust;\n"); + out.Write(" float x_adjust = (2.0f * (clipPos.x / " I_FOG"[2].y)) - 1.0f - " I_FOG"[2].x;\n"); + out.Write(" x_adjust = sqrt(x_adjust * x_adjust + " I_FOG"[2].z * " I_FOG"[2].z) / " I_FOG"[2].z;\n"); + out.Write(" ze *= x_adjust;\n"); } - WRITE (p, " float fog = saturate(ze - " I_FOG"[1].z);\n"); + out.Write("float fog = saturate(ze - " I_FOG"[1].z);\n"); if(bpmem.fog.c_proj_fsel.fsel > 3) { - WRITE(p, "%s", tevFogFuncsTable[bpmem.fog.c_proj_fsel.fsel]); + out.Write("%s", tevFogFuncsTable[bpmem.fog.c_proj_fsel.fsel]); } else { @@ -1233,7 +1037,15 @@ static void WriteFog(char *&p) WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel); } - WRITE(p, " prev.rgb = lerp(prev.rgb," I_FOG"[0].rgb,fog);\n"); - - + out.Write(" prev.rgb = lerp(prev.rgb," I_FOG"[0].rgb,fog);\n"); +} + +void GetPixelShaderId(PixelShaderUid& object, DSTALPHA_MODE dst_alpha_mode, API_TYPE ApiType, u32 components) +{ + GeneratePixelShader(object, dst_alpha_mode, ApiType, components); +} + +void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dst_alpha_mode, API_TYPE ApiType, u32 components) +{ + GeneratePixelShader(object, dst_alpha_mode, ApiType, components); } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 9c8bfce256..61be98aa6e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -19,6 +19,7 @@ #define GCOGL_PIXELSHADER_H #include "VideoCommon.h" +#include "ShaderGenCommon.h" #define I_COLORS "color" #define I_KCOLORS "k" @@ -44,66 +45,6 @@ #define C_PLIGHTS (C_FOG + 3) #define C_PMATERIALS (C_PLIGHTS + 40) #define C_PENVCONST_END (C_PMATERIALS + 4) -#define PIXELSHADERUID_MAX_VALUES 70 -#define PIXELSHADERUID_MAX_VALUES_SAFE 115 - -// DO NOT make anything in this class virtual. -template -class _PIXELSHADERUID -{ -public: - u32 values[safe ? PIXELSHADERUID_MAX_VALUES_SAFE : PIXELSHADERUID_MAX_VALUES]; - int num_values; - - _PIXELSHADERUID() - { - } - - _PIXELSHADERUID(const _PIXELSHADERUID& r) - { - num_values = r.num_values; - if (safe) memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE); - else memcpy(values, r.values, r.GetNumValues() * sizeof(values[0])); - } - - int GetNumValues() const - { - if (safe) return (sizeof(values) / sizeof(u32)); - else return num_values; - } - - bool operator <(const _PIXELSHADERUID& _Right) const - { - int N = GetNumValues(); - if (N < _Right.GetNumValues()) - return true; - else if (N > _Right.GetNumValues()) - return false; - for (int i = 0; i < N; ++i) - { - if (values[i] < _Right.values[i]) - return true; - else if (values[i] > _Right.values[i]) - return false; - } - return false; - } - - bool operator ==(const _PIXELSHADERUID& _Right) const - { - int N = GetNumValues(); - if (N != _Right.GetNumValues()) - return false; - for (int i = 0; i < N; ++i) - { - if (values[i] != _Right.values[i]) - return false; - } - return true; - } -}; -typedef _PIXELSHADERUID PIXELSHADERUID; -typedef _PIXELSHADERUID PIXELSHADERUIDSAFE; // Different ways to achieve rendering with destination alpha enum DSTALPHA_MODE @@ -113,12 +54,53 @@ enum DSTALPHA_MODE DSTALPHA_DUAL_SOURCE_BLEND // Use dual-source blending }; -const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +enum ALPHA_PRETEST_RESULT +{ + ALPHAPT_UNDEFINED, // AlphaTest Result is not defined + ALPHAPT_ALWAYSFAIL, // Alpha test alway Fail + ALPHAPT_ALWAYSPASS // Alpha test alway Pass +}; -void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components); -void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components); +struct pixel_shader_uid_data +{ + u32 components; + DSTALPHA_MODE dstAlphaMode; // TODO: as u32 :2 + ALPHA_PRETEST_RESULT Pretest; // TODO: As :2 + u32 nIndirectStagesUsed : 8; + struct { + u32 numtexgens : 4; + u32 numtevstages : 4; + u32 numindstages : 3; + } genMode; + u32 fogc_proj_fselfsel : 3; + struct + { + u32 unknown : 1; + u32 projection : 1; // XF_TEXPROJ_X + u32 inputform : 2; // XF_TEXINPUT_X + u32 texgentype : 3; // XF_TEXGEN_X + u32 sourcerow : 5; // XF_SRCGEOM_X + u32 embosssourceshift : 3; // what generated texcoord to use + u32 embosslightshift : 3; // light index that is used + } texMtxInfo[8]; + struct + { + u32 bi0 : 3; // indirect tex stage 0 ntexmap + u32 bc0 : 3; // indirect tex stage 0 ntexcoord + u32 bi1 : 3; + u32 bc1 : 3; + u32 bi2 : 3; + u32 bc3 : 3; + u32 bi4 : 3; + u32 bc4 : 3; + } tevindref; +}; -// Used to make sure that our optimized pixel shader IDs don't lose any possible shader code changes -void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, DSTALPHA_MODE dstAlphaMode, u32 components); +typedef ShaderUid PixelShaderUid; +typedef ShaderCode PixelShaderCode; + + +void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +void GetPixelShaderId(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); #endif // GCOGL_PIXELSHADER_H diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 28fb8e8956..090fb24b57 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -44,7 +44,7 @@ public: // TODO: Store last frame used and order by that? makes much more sense anyway... bool operator < (const ShaderUid& obj) const { - for (int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i) + for (unsigned int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i) { if (this->values[i] < obj.values[i]) return true; @@ -91,4 +91,10 @@ private: char* write_ptr; }; +enum GenOutput +{ + GO_ShaderCode, + GO_ShaderUid, +}; + #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index acc89c6a54..db4946a49f 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -28,11 +28,6 @@ static char text[16768]; -enum GenOutput -{ - GO_ShaderCode, - GO_ShaderUid, -}; // TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? template void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ deleted file mode 100644 index be57103918..0000000000 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp~ +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include -#include - -#include "NativeVertexFormat.h" - -#include "BPMemory.h" -#include "CPMemory.h" -#include "LightingShaderGen.h" -#include "VertexShaderGen.h" -#include "VideoConfig.h" - -static char text[16768]; - -enum GenOutput -{ - GO_ShaderCode, - GO_ShaderUid, -}; -// TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? -template -void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) -{ - object.Write("struct VS_OUTPUT {\n"); - object.Write(" float4 pos : POSITION;\n"); - object.Write(" float4 colors_0 : COLOR0;\n"); - object.Write(" float4 colors_1 : COLOR1;\n"); - - if (xfregs.numTexGen.numTexGens < 7) - { - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - object.Write(" float3 tex%d : TEXCOORD%d;\n", i, i); - - object.Write(" float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens); -/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) -/// object.Write(" float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1); - } - else - { - // clip position is in w of first 4 texcoords -/// if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) -/// { -/// for (int i = 0; i < 8; ++i) -/// object.Write(" float4 tex%d : TEXCOORD%d;\n", i, i); -/// } -/// else - { - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - object.Write(" float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i); - } - } - object.Write("};\n"); -} - -template -void _GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) -{ -#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; - const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; - const char* swizzle = "xyzw"; - if (coloralpha == 1 ) swizzle = "xyz"; - else if (coloralpha == 2 ) swizzle = "w"; - - SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); - SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); - if (!(chan.attnfunc & 1)) { - // atten disabled - switch (chan.diffusefunc) { - case LIGHTDIF_NONE: - object.Write("lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - object.Write("ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); - object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); - break; - default: _assert_(0); - } - } - else { // spec and spot - - if (chan.attnfunc == 3) - { // spot - object.Write("ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); - object.Write("dist2 = dot(ldir, ldir);\n" - "dist = sqrt(dist2);\n" - "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); - } - else if (chan.attnfunc == 1) - { // specular - object.Write("ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); - object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); - } - - switch (chan.diffusefunc) - { - case LIGHTDIF_NONE: - object.Write("lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, - chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", - lightsName, - index, - swizzle); - break; - default: _assert_(0); - } - } - object.Write("\n"); -} - -// vertex shader -// lights/colors -// materials name is I_MATERIALS in vs and I_PMATERIALS in ps -// inColorName is color in vs and colors_ in ps -// dest is o.colors_ in vs and colors_ in ps -template -void _GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) -{ - for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) - { - const LitChannel& color = xfregs.color[j]; - const LitChannel& alpha = xfregs.alpha[j]; - - object.Write("{\n"); - - SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); - if (color.matsource) {// from vertex - if (components & (VB_HAS_COL0 << j)) - object.Write("mat = %s%d;\n", inColorName, j); - else if (components & VB_HAS_COL0) - object.Write("mat = %s0;\n", inColorName); - else - object.Write("mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); - } - else // from color - object.Write("mat = %s.C%d;\n", materialsName, j+2); - - SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); - if (color.enablelighting) { - SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); - if (color.ambsource) { // from vertex - if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); - } - } - } - } - - // no shared lights - for (int i = 0; i < 8; ++i) - { - if (!(mask&(1<(object, i, j, lightsName, 1); - if (!(mask&(1<(object, i, j+2, lightsName, 2); - } - } - else if (color.enablelighting || alpha.enablelighting) - { - // lights are disabled on one channel so process only the active ones - const LitChannel& workingchannel = color.enablelighting ? color : alpha; - const int lit_index = color.enablelighting ? j : (j+2); - int coloralpha = color.enablelighting ? 1 : 2; - - SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); - for (int i = 0; i < 8; ++i) - { - if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); - } - } - object.Write("%s%d = mat * saturate(lacc);\n", dest, j); - object.Write("}\n"); - } -} - -// TODO: Problem: this one uses copy constructors or sth for uids when returning... -template -void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) -{ -#undef SetUidField -#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; - - if (type == GO_ShaderCode) - { - out.SetBuffer(text); - setlocale(LC_NUMERIC, "C"); // Reset locale for compilation - } - - /// text[sizeof(text) - 1] = 0x7C; // canary - - bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); - u32 lightMask = 0; - if (xfregs.numChan.numColorChans > 0) - lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask(); - if (xfregs.numChan.numColorChans > 1) - lightMask |= xfregs.color[1].GetFullLightMask() | xfregs.alpha[1].GetFullLightMask(); - - out.Write("//Vertex Shader: comp:%x, \n", components); - out.Write("typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_" I_POSNORMALMATRIX";\n" - "typedef struct { float4 t; } FLT4;\n" - "typedef struct { FLT4 T[24]; } s_" I_TEXMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_TRANSFORMMATRICES";\n" - "typedef struct { FLT4 T[32]; } s_" I_NORMALMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_POSTTRANSFORMMATRICES";\n" - "typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n" - "typedef struct { Light lights[8]; } s_" I_LIGHTS";\n" - "typedef struct { float4 C0, C1, C2, C3; } s_" I_MATERIALS";\n" - "typedef struct { float4 T0, T1, T2, T3; } s_" I_PROJECTION";\n" - ); - -/// p = GenerateVSOutputStruct(p, components, api_type); - GenerateVSOutputStruct(out, components, api_type); - - // uniforms - - out.Write("uniform s_" I_TRANSFORMMATRICES" " I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES); - out.Write("uniform s_" I_TEXMATRICES" " I_TEXMATRICES" : register(c%d);\n", C_TEXMATRICES); - out.Write("uniform s_" I_NORMALMATRICES" " I_NORMALMATRICES" : register(c%d);\n", C_NORMALMATRICES); - out.Write("uniform s_" I_POSNORMALMATRIX" " I_POSNORMALMATRIX" : register(c%d);\n", C_POSNORMALMATRIX); - out.Write("uniform s_" I_POSTTRANSFORMMATRICES" " I_POSTTRANSFORMMATRICES" : register(c%d);\n", C_POSTTRANSFORMMATRICES); - out.Write("uniform s_" I_LIGHTS" " I_LIGHTS" : register(c%d);\n", C_LIGHTS); - out.Write("uniform s_" I_MATERIALS" " I_MATERIALS" : register(c%d);\n", C_MATERIALS); - out.Write("uniform s_" I_PROJECTION" " I_PROJECTION" : register(c%d);\n", C_PROJECTION); - out.Write("uniform float4 " I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); - - out.Write("VS_OUTPUT main(\n"); - - SetUidField(numTexGens, xfregs.numTexGen.numTexGens); - SetUidField(components, components); - // inputs - if (components & VB_HAS_NRM0) - out.Write(" float3 rawnorm0 : NORMAL0,\n"); - if (components & VB_HAS_NRM1) - { - if (is_d3d) - out.Write(" float3 rawnorm1 : NORMAL1,\n"); - else - out.Write(" float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); - } - if (components & VB_HAS_NRM2) - { - if (is_d3d) - out.Write(" float3 rawnorm2 : NORMAL2,\n"); - else - out.Write(" float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); - } - if (components & VB_HAS_COL0) - out.Write(" float4 color0 : COLOR0,\n"); - if (components & VB_HAS_COL1) - out.Write(" float4 color1 : COLOR1,\n"); - for (int i = 0; i < 8; ++i) { - u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<= 32 ? (posmtx-32) : posmtx;\n"); - out.Write("float3 N0 = " I_NORMALMATRICES".T[normidx].t.xyz, N1 = " I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = " I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); - } - - if (components & VB_HAS_NRM0) - out.Write("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n"); - if (components & VB_HAS_NRM1) - out.Write("float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); - if (components & VB_HAS_NRM2) - out.Write("float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); - } - else - { - out.Write("float4 pos = float4(dot(" I_POSNORMALMATRIX".T0, rawpos), dot(" I_POSNORMALMATRIX".T1, rawpos), dot(" I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n"); - if (components & VB_HAS_NRM0) - out.Write("float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm0)));\n"); - if (components & VB_HAS_NRM1) - out.Write("float3 _norm1 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); - if (components & VB_HAS_NRM2) - out.Write("float3 _norm2 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); - } - - if (!(components & VB_HAS_NRM0)) - out.Write("float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); - - - - out.Write("o.pos = float4(dot(" I_PROJECTION".T0, pos), dot(" I_PROJECTION".T1, pos), dot(" I_PROJECTION".T2, pos), dot(" I_PROJECTION".T3, pos));\n"); - - out.Write("float4 mat, lacc;\n" - "float3 ldir, h;\n" - "float dist, dist2, attn;\n"); - - SetUidField(numColorChans, xfregs.numChan.numColorChans); - if(xfregs.numChan.numColorChans == 0) - { - if (components & VB_HAS_COL0) - out.Write("o.colors_0 = color0;\n"); - else - out.Write("o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); - } - - // TODO: This probably isn't necessary if pixel lighting is enabled. - _GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); - - if(xfregs.numChan.numColorChans < 2) - { - if (components & VB_HAS_COL1) - out.Write("o.colors_1 = color1;\n"); - else - out.Write("o.colors_1 = o.colors_0;\n"); - } - // special case if only pos and tex coord 0 and tex coord input is AB11 - // donko - this has caused problems in some games. removed for now. - bool texGenSpecialCase = false; - /*bool texGenSpecialCase = - ((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0 - (g_VtxDesc.Tex0Coord != NOT_PRESENT) && - (xfregs.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11); - */ - - // transform texcoords - out.Write("float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) { - TexMtxInfo& texinfo = xfregs.texMtxInfo[i]; - - out.Write("{\n"); - out.Write("coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); - SetUidField(texMtxInfo[i].sourcerow, xfregs.texMtxInfo[i].sourcerow); - switch (texinfo.sourcerow) { - case XF_SRCGEOM_INROW: - _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - out.Write("coord = rawpos;\n"); // pos.w is 1 - break; - case XF_SRCNORMAL_INROW: - if (components & VB_HAS_NRM0) { - _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - out.Write("coord = float4(rawnorm0.xyz, 1.0f);\n"); - } - break; - case XF_SRCCOLORS_INROW: - _assert_( texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 || texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1 ); - break; - case XF_SRCBINORMAL_T_INROW: - if (components & VB_HAS_NRM1) { - _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - out.Write("coord = float4(rawnorm1.xyz, 1.0f);\n"); - } - break; - case XF_SRCBINORMAL_B_INROW: - if (components & VB_HAS_NRM2) { - _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); - out.Write("coord = float4(rawnorm2.xyz, 1.0f);\n"); - } - break; - default: - _assert_(texinfo.sourcerow <= XF_SRCTEX7_INROW); - if (components & (VB_HAS_UV0<<(texinfo.sourcerow - XF_SRCTEX0_INROW)) ) - out.Write("coord = float4(tex%d.x, tex%d.y, 1.0f, 1.0f);\n", texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW); - break; - } - - // first transformation - SetUidField(texMtxInfo[i].texgentype, xfregs.texMtxInfo[i].texgentype); - switch (texinfo.texgentype) { - case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map - - if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { - // transform the light dir into tangent space - SetUidField(texMtxInfo[i].embosslightshift, xfregs.texMtxInfo[i].embosslightshift); - SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); - out.Write("ldir = normalize(" I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); - out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); - } - else - { - _assert_(0); // should have normals - SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); - out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); - } - - break; - case XF_TEXGEN_COLOR_STRGBC0: - _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); - out.Write("o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i); - break; - case XF_TEXGEN_COLOR_STRGBC1: - _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); - out.Write("o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i); - break; - case XF_TEXGEN_REGULAR: - default: - SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); - if (components & (VB_HAS_TEXMTXIDX0<(object, components, api_type); -} - -void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) -{ - GenerateVertexShader(object, components, api_type); -} diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index 32d3eff91b..e2c96b972a 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -51,7 +51,7 @@ #define C_VENVCONST_END (C_DEPTHPARAMS + 4) // TODO: Need packing? -struct uid_data +struct vertex_shader_uid_data { u32 components; u32 numColorChans : 2; @@ -82,8 +82,8 @@ struct uid_data } lit_chans[4]; }; -typedef ShaderUid VertexShaderUid; -typedef ShaderCode VertexShaderCode; +typedef ShaderUid VertexShaderUid; +typedef ShaderCode VertexShaderCode; void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type); diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h~ b/Source/Core/VideoCommon/Src/VertexShaderGen.h~ index 050ed76649..32d3eff91b 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h~ +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h~ @@ -82,7 +82,7 @@ struct uid_data } lit_chans[4]; }; -typedef ShaderUid VertexShaderUid; +typedef ShaderUid VertexShaderUid; typedef ShaderCode VertexShaderCode; void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 4364bea6ea..7fef0cac3c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -144,7 +144,7 @@ struct VideoConfig int iAdapter; // Debugging - bool bEnableShaderDebugging; + bool bEnableShaderDebugging; // TODO: Obsolete? // Static config per API // TODO: Move this out of VideoConfig diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 61e41008b3..cdd5d6e044 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -39,13 +39,13 @@ static int s_nMaxPixelInstructions; static GLuint s_ColorMatrixProgram = 0; static GLuint s_DepthMatrixProgram = 0; PixelShaderCache::PSCache PixelShaderCache::PixelShaders; -PIXELSHADERUID PixelShaderCache::s_curuid; +PixelShaderUid PixelShaderCache::s_curuid; bool PixelShaderCache::s_displayCompileAlert; GLuint PixelShaderCache::CurrentShader; bool PixelShaderCache::ShaderEnabled; PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry = NULL; -PIXELSHADERUID PixelShaderCache::last_uid; +PixelShaderUid PixelShaderCache::last_uid; GLuint PixelShaderCache::GetDepthMatrixProgram() { @@ -183,16 +183,15 @@ void PixelShaderCache::Shutdown() FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { - PIXELSHADERUID uid; - GetPixelShaderId(&uid, dstAlphaMode, components); - + PixelShaderUid uid; + GetPixelShaderId(uid, dstAlphaMode, API_OPENGL, components); + // Check if the shader is already set if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, dstAlphaMode, components); return &last_entry->shader; } } @@ -206,19 +205,18 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, dstAlphaMode, components); return &last_entry->shader; } // Make an entry in the table PSCacheEntry& newentry = PixelShaders[uid]; last_entry = &newentry; - const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components); + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_OPENGL, components); - if (g_ActiveConfig.bEnableShaderDebugging && code) + if (g_ActiveConfig.bEnableShaderDebugging) { - GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components); - newentry.shader.strprog = code; + newentry.shader.strprog = code.GetBuffer(); } #if defined(_DEBUG) || defined(DEBUGFAST) @@ -227,11 +225,11 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp char szTemp[MAX_PATH]; sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - SaveData(szTemp, code); + SaveData(szTemp, code.GetBuffer()); /// XXX } #endif - if (!code || !CompilePixelShader(newentry.shader, code)) { + if (!code.GetBuffer() || !CompilePixelShader(newentry.shader, code.GetBuffer())) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return NULL; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h index f528eeb35b..aff1b49fcb 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -53,20 +53,19 @@ class PixelShaderCache { shader.Destroy(); } - PIXELSHADERUIDSAFE safe_uid; }; - typedef std::map PSCache; + typedef std::map PSCache; static PSCache PixelShaders; - static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written) + static PixelShaderUid s_curuid; // the current pixel shader uid (progressively changed as memory is written) static bool s_displayCompileAlert; static GLuint CurrentShader; static PSCacheEntry* last_entry; - static PIXELSHADERUID last_uid; + static PixelShaderUid last_uid; static bool ShaderEnabled; From b519d371286e8c5fa614167cc0652e16789a699c Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 7 Aug 2012 01:16:02 +0200 Subject: [PATCH 004/352] Move new lighting shader uids to LightingShaderGen.h --- .../VideoCommon/Src/LightingShaderGen.cpp | 195 ----------------- .../Core/VideoCommon/Src/LightingShaderGen.h | 204 +++++++++++++++++- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 4 +- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 199 +---------------- 4 files changed, 204 insertions(+), 398 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index f32e5dfeee..963b2c529a 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -18,198 +18,3 @@ #include "LightingShaderGen.h" #include "NativeVertexFormat.h" #include "XFMemory.h" - -#define WRITE p+=sprintf - -int GetLightingShaderId(u32* out) -{ - for (u32 i = 0; i < xfregs.numChan.numColorChans; ++i) - { - out[i] = xfregs.color[i].enablelighting ? - (u32)xfregs.color[i].hex : - (u32)xfregs.color[i].matsource; - out[i] |= (xfregs.alpha[i].enablelighting ? - (u32)xfregs.alpha[i].hex : - (u32)xfregs.alpha[i].matsource) << 15; - } - _assert_(xfregs.numChan.numColorChans <= 2); - return xfregs.numChan.numColorChans; -} - -// coloralpha - 1 if color, 2 if alpha -char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char* lightsName, int coloralpha) -{ - const char* swizzle = "xyzw"; - if (coloralpha == 1 ) swizzle = "xyz"; - else if (coloralpha == 2 ) swizzle = "w"; - - if (!(chan.attnfunc & 1)) { - // atten disabled - switch (chan.diffusefunc) { - case LIGHTDIF_NONE: - WRITE(p, "lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - WRITE(p, "ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); - WRITE(p, "lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); - break; - default: _assert_(0); - } - } - else { // spec and spot - - if (chan.attnfunc == 3) - { // spot - WRITE(p, "ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); - WRITE(p, "dist2 = dot(ldir, ldir);\n" - "dist = sqrt(dist2);\n" - "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); - WRITE(p, "attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); - } - else if (chan.attnfunc == 1) - { // specular - WRITE(p, "ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); - WRITE(p, "attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); - WRITE(p, "attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); - } - - switch (chan.diffusefunc) - { - case LIGHTDIF_NONE: - WRITE(p, "lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - WRITE(p, "lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, - chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", - lightsName, - index, - swizzle); - break; - default: _assert_(0); - } - } - WRITE(p, "\n"); - return p; -} - -// vertex shader -// lights/colors -// materials name is I_MATERIALS in vs and I_PMATERIALS in ps -// inColorName is color in vs and colors_ in ps -// dest is o.colors_ in vs and colors_ in ps -char *GenerateLightingShader(char *p, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) -{ - for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) - { - const LitChannel& color = xfregs.color[j]; - const LitChannel& alpha = xfregs.alpha[j]; - - WRITE(p, "{\n"); - - if (color.matsource) {// from vertex - if (components & (VB_HAS_COL0 << j)) - WRITE(p, "mat = %s%d;\n", inColorName, j); - else if (components & VB_HAS_COL0) - WRITE(p, "mat = %s0;\n", inColorName); - else - WRITE(p, "mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); - } - else // from color - WRITE(p, "mat = %s.C%d;\n", materialsName, j+2); - - if (color.enablelighting) { - if (color.ambsource) { // from vertex - if (components & (VB_HAS_COL0< +void GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) +{ +#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; + const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; + const char* swizzle = "xyzw"; + if (coloralpha == 1 ) swizzle = "xyz"; + else if (coloralpha == 2 ) swizzle = "w"; + + SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); + SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); + if (!(chan.attnfunc & 1)) { + // atten disabled + switch (chan.diffusefunc) { + case LIGHTDIF_NONE: + object.Write("lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); + object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); + break; + default: _assert_(0); + } + } + else { // spec and spot + + if (chan.attnfunc == 3) + { // spot + object.Write("ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); + object.Write("dist2 = dot(ldir, ldir);\n" + "dist = sqrt(dist2);\n" + "ldir = ldir / dist;\n" + "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); + } + else if (chan.attnfunc == 1) + { // specular + object.Write("ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); + object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); + object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); + } + + switch (chan.diffusefunc) + { + case LIGHTDIF_NONE: + object.Write("lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", + swizzle, + chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", + lightsName, + index, + swizzle); + break; + default: _assert_(0); + } + } + object.Write("\n"); +} + +// vertex shader +// lights/colors +// materials name is I_MATERIALS in vs and I_PMATERIALS in ps +// inColorName is color in vs and colors_ in ps +// dest is o.colors_ in vs and colors_ in ps +template +void GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +{ + for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) + { + const LitChannel& color = xfregs.color[j]; + const LitChannel& alpha = xfregs.alpha[j]; + + object.Write("{\n"); + + SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); + if (color.matsource) {// from vertex + if (components & (VB_HAS_COL0 << j)) + object.Write("mat = %s%d;\n", inColorName, j); + else if (components & VB_HAS_COL0) + object.Write("mat = %s0;\n", inColorName); + else + object.Write("mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + } + else // from color + object.Write("mat = %s.C%d;\n", materialsName, j+2); + + SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); + if (color.enablelighting) { + SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); + if (color.ambsource) { // from vertex + if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); + } + } + } + } + + // no shared lights + for (int i = 0; i < 8; ++i) + { + if (!(mask&(1<(object, i, j, lightsName, 1); + if (!(mask&(1<(object, i, j+2, lightsName, 2); + } + } + else if (color.enablelighting || alpha.enablelighting) + { + // lights are disabled on one channel so process only the active ones + const LitChannel& workingchannel = color.enablelighting ? color : alpha; + const int lit_index = color.enablelighting ? j : (j+2); + int coloralpha = color.enablelighting ? 1 : 2; + + SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); + for (int i = 0; i < 8; ++i) + { + if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); + } + } + object.Write("%s%d = mat * saturate(lacc);\n", dest, j); + object.Write("}\n"); + } +} +#undef SetUidField #endif // _LIGHTINGSHADERGEN_H_ diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 5ee95848b5..d52ed1ac0a 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -440,8 +440,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u { if (nIndirectStagesUsed & (1< -void _GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) -{ -#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; - const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; - const char* swizzle = "xyzw"; - if (coloralpha == 1 ) swizzle = "xyz"; - else if (coloralpha == 2 ) swizzle = "w"; - SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); - SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); - if (!(chan.attnfunc & 1)) { - // atten disabled - switch (chan.diffusefunc) { - case LIGHTDIF_NONE: - object.Write("lacc.%s += %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - object.Write("ldir = normalize(%s.lights[%d].pos.xyz - pos.xyz);\n", lightsName, index); - object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); - break; - default: _assert_(0); - } - } - else { // spec and spot - - if (chan.attnfunc == 3) - { // spot - object.Write("ldir = %s.lights[%d].pos.xyz - pos.xyz;\n", lightsName, index); - object.Write("dist2 = dot(ldir, ldir);\n" - "dist = sqrt(dist2);\n" - "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s.lights[%d].dir.xyz));\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); - } - else if (chan.attnfunc == 1) - { // specular - object.Write("ldir = normalize(%s.lights[%d].pos.xyz);\n", lightsName, index); - object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.lights[%d].dir.xyz)) : 0.0f;\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s.lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s.lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); - } - - switch (chan.diffusefunc) - { - case LIGHTDIF_NONE: - object.Write("lacc.%s += attn * %s.lights[%d].col.%s;\n", swizzle, lightsName, index, swizzle); - break; - case LIGHTDIF_SIGN: - case LIGHTDIF_CLAMP: - object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s.lights[%d].col.%s;\n", - swizzle, - chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", - lightsName, - index, - swizzle); - break; - default: _assert_(0); - } - } - object.Write("\n"); -} - -// vertex shader -// lights/colors -// materials name is I_MATERIALS in vs and I_PMATERIALS in ps -// inColorName is color in vs and colors_ in ps -// dest is o.colors_ in vs and colors_ in ps -template -void _GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) -{ - for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) - { - const LitChannel& color = xfregs.color[j]; - const LitChannel& alpha = xfregs.alpha[j]; - - object.Write("{\n"); - - SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); - if (color.matsource) {// from vertex - if (components & (VB_HAS_COL0 << j)) - object.Write("mat = %s%d;\n", inColorName, j); - else if (components & VB_HAS_COL0) - object.Write("mat = %s0;\n", inColorName); - else - object.Write("mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); - } - else // from color - object.Write("mat = %s.C%d;\n", materialsName, j+2); - - SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); - if (color.enablelighting) { - SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); - if (color.ambsource) { // from vertex - if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); - } - } - } - } - - // no shared lights - for (int i = 0; i < 8; ++i) - { - if (!(mask&(1<(object, i, j, lightsName, 1); - if (!(mask&(1<(object, i, j+2, lightsName, 2); - } - } - else if (color.enablelighting || alpha.enablelighting) - { - // lights are disabled on one channel so process only the active ones - const LitChannel& workingchannel = color.enablelighting ? color : alpha; - const int lit_index = color.enablelighting ? j : (j+2); - int coloralpha = color.enablelighting ? 1 : 2; - - SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); - for (int i = 0; i < 8; ++i) - { - if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); - } - } - object.Write("%s%d = mat * saturate(lacc);\n", dest, j); - object.Write("}\n"); - } -} - -// TODO: Problem: this one uses copy constructors or sth for uids when returning... template void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { @@ -414,7 +217,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) } // TODO: This probably isn't necessary if pixel lighting is enabled. - _GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); if(xfregs.numChan.numColorChans < 2) { From 8902c6e38b68ab3327fd25183425c37c3445e9d1 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 7 Aug 2012 14:36:56 +0200 Subject: [PATCH 005/352] Some cleanups, add more fields to pixel shader uid. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 73 ++++++++++++------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 59 +++++++++++++++ Source/Core/VideoCommon/Src/ShaderGenCommon.h | 1 + 3 files changed, 107 insertions(+), 26 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index d52ed1ac0a..9aad5556aa 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -243,7 +243,7 @@ static void BuildSwapModeTable() swapModeTable[i][1] = swapColors[bpmem.tevksel[i*2].swap2]; swapModeTable[i][2] = swapColors[bpmem.tevksel[i*2+1].swap1]; swapModeTable[i][3] = swapColors[bpmem.tevksel[i*2+1].swap2]; - swapModeTable[i][4] = 0; + swapModeTable[i][4] = '\0'; } } @@ -251,6 +251,7 @@ template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { #define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; +#define OR_UidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name |= value; }; if (type == GO_ShaderCode) { setlocale(LC_NUMERIC, "C"); // Reset locale for compilation @@ -258,12 +259,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } /// text[sizeof(text) - 1] = 0x7C; // canary - /// TODO: Uids! - BuildSwapModeTable(); // Needed for WriteStage unsigned int numStages = bpmem.genMode.numtevstages + 1; unsigned int numTexgen = bpmem.genMode.numtexgens; - char *p = text; out.Write("//Pixel Shader for TEV stages\n"); out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", numStages, numTexgen/*, bpmem.genMode.numindstages*/); @@ -276,31 +274,17 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u SetUidField(genMode.numtexgens, bpmem.genMode.numtexgens); // Declare samplers - if(ApiType != API_D3D11) - { - out.Write("uniform sampler2D "); - } - else - { - out.Write("sampler "); - } - - bool bfirst = true; + out.Write((ApiType != API_D3D11) ? "uniform sampler2D " : "sampler "); for (int i = 0; i < 8; ++i) - { - out.Write("%s samp%d : register(s%d)", bfirst?"":",", i, i); - bfirst = false; - } + out.Write("%s samp%d : register(s%d)", (i==0)?"":",", i, i); + out.Write(";\n"); if(ApiType == API_D3D11) { out.Write("Texture2D "); - bfirst = true; for (int i = 0; i < 8; ++i) - { - out.Write("%s Tex%d : register(t%d)", bfirst?"":",", i, i); - bfirst = false; - } + out.Write("%s Tex%d : register(t%d)", (i==0)?"":",", i, i); + out.Write(";\n"); } @@ -484,6 +468,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u RegisterStates[i].AuxStored = false; } + BuildSwapModeTable(); // Uids set in WriteStage for (unsigned int i = 0; i < numStages; i++) WriteStage(out, i, ApiType); //build the equation for this stage @@ -491,6 +476,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u { // The results of the last texenv stage are put onto the screen, // regardless of the used destination register + SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); + SetUidField(combiners[numStages-1].alphaC.dest, bpmem.combiners[numStages-1].alphaC.dest); if(bpmem.combiners[numStages - 1].colorC.dest != 0) { /// SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); @@ -614,8 +601,15 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("// TEV stage %d\n", n); + OR_UidField(bHasIndStage, bHasIndStage << n); + if (n < 8) { OR_UidField(tevorders_n_texcoord1, texcoord << (3 * n)); } + else OR_UidField(tevorders_n_texcoord2, texcoord << (3 * n - 24)); if (bHasIndStage) { + OR_UidField(tevind_n_bs, bpmem.tevind[n].bs << (2*n)); + OR_UidField(tevind_n_bt, bpmem.tevind[n].bt << (2*n)); + OR_UidField(tevind_n_fmt, bpmem.tevind[n].fmt << (2*n)); + out.Write("// indirect op\n"); // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords if (bpmem.tevind[n].bs != ITBA_OFF) @@ -629,17 +623,21 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]); // bias + if (n < 8) { OR_UidField(tevind_n_bias1, bpmem.tevind[n].bias << (3*n)); } /// XXX: brackets? + else OR_UidField(tevind_n_bias2, bpmem.tevind[n].bias << (3*n - 24)); if (bpmem.tevind[n].bias != ITB_NONE ) out.Write("indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); // multiply by offset matrix and scale + if (n < 8) { OR_UidField(tevind_n_mid1, bpmem.tevind[n].mid << (4*n)); } /// XXX: brackets? + else OR_UidField(tevind_n_mid2, bpmem.tevind[n].mid << (4*n - 32)); if (bpmem.tevind[n].mid != 0) { if (bpmem.tevind[n].mid <= 3) { int mtxidx = 2*(bpmem.tevind[n].mid-1); out.Write("float2 indtevtrans%d = float2(dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", - n, mtxidx, n, mtxidx+1, n); + n, mtxidx, n, mtxidx+1, n); } else if (bpmem.tevind[n].mid <= 7 && bHasTexCoord) { // s matrix @@ -663,6 +661,11 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) // Wrapping // --------- + if (n < 8) { OR_UidField(tevorders_n_sw1, bpmem.tevind[n].sw << (3 * n)); } + else OR_UidField(tevorders_n_sw2, bpmem.tevind[n].sw << (3 * n - 24)); + if (n < 8) { OR_UidField(tevorders_n_tw1, bpmem.tevind[n].tw << (3 * n)); } + else OR_UidField(tevorders_n_tw2, bpmem.tevind[n].tw << (3 * n - 24)); + // wrap S if (bpmem.tevind[n].sw == ITW_OFF) out.Write("wrappedcoord.x = uv%d.x;\n", texcoord); @@ -695,6 +698,12 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || ac.a == TEVALPHAARG_RASA || ac.b == TEVALPHAARG_RASA || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA) { + const int i = bpmem.combiners[n].alphaC.rswap; + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap1 << (i*2)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap1 << (i*2 + 1)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap2 << (i*2 + 16)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap2 << (i*2 + 17)); + char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; out.Write("rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); out.Write("crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); @@ -712,6 +721,12 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("tevcoord.xy = float2(0.0f, 0.0f);\n"); } + const int i = bpmem.combiners[n].alphaC.tswap; + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap1 << (i*2)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap1 << (i*2 + 1)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap2 << (i*2 + 16)); + OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap2 << (i*2 + 17)); + char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); SampleTexture(out, "textemp", "tevcoord", texswap, texmap, ApiType); @@ -950,13 +965,19 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode) // using discard then return works the same in cg and dx9 but not in dx11 out.Write("if(!( "); + SetUidField(alpha_test.comp0, bpmem.alpha_test.comp0); + SetUidField(alpha_test.logic, bpmem.alpha_test.comp1); + SetUidField(alpha_test.logic, bpmem.alpha_test.logic); + + // Lookup the first component from the alpha function table int compindex = bpmem.alpha_test.comp0; - out.Write(tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table + out.Write(tevAlphaFuncsTable[compindex], alphaRef[0]); out.Write("%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op + // Lookup the second component from the alpha function table compindex = bpmem.alpha_test.comp1; - out.Write(tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table + out.Write(tevAlphaFuncsTable[compindex], alphaRef[1]); out.Write(")) {\n"); out.Write("ocol0 = 0;\n"); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 61be98aa6e..994f70c9ea 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -94,6 +94,65 @@ struct pixel_shader_uid_data u32 bi4 : 3; u32 bc4 : 3; } tevindref; + + u32 tevorders_n_texcoord1 : 24; // 8 x 3 bit + u32 tevorders_n_texcoord2 : 24; // 8 x 3 bit + u32 tevorders_n_sw1 : 24; // 8 x 3 bit + u32 tevorders_n_sw2 : 24; // 8 x 3 bit + u32 tevorders_n_tw1 : 24; // 8 x 3 bit + u32 tevorders_n_tw2 : 24; // 8 x 3 bit + + u32 tevind_n_bs : 32; // 16 x 2 bit + u32 tevind_n_fmt : 32; // 16 x 2 bit + u32 tevind_n_bt : 32; // 16 x 2 bit + u32 tevind_n_bias1 : 24; // 8 x 3 bit + u32 tevind_n_bias2 : 24; // 8 x 3 bit + u32 tevind_n_mid1 : 32; // 8 x 4 bit + u32 tevind_n_mid2 : 32; // 8 x 4 bit + + u32 tevksel_n_swap : 32; // 8 x 2 bit (swap1) + 8 x 2 bit (swap2) + struct + { + struct //abc=8bit,d=10bit + { + u32 d : 4; // TEVSELCC_X + u32 c : 4; // TEVSELCC_X + u32 b : 4; // TEVSELCC_X + u32 a : 4; // TEVSELCC_X + + u32 bias : 2; + u32 op : 1; + u32 clamp : 1; + + u32 shift : 2; + u32 dest : 2; //1,2,3 + } colorC; + struct + { + u32 rswap : 2; + u32 tswap : 2; + u32 d : 3; // TEVSELCA_ + u32 c : 3; // TEVSELCA_ + u32 b : 3; // TEVSELCA_ + u32 a : 3; // TEVSELCA_ + + u32 bias : 2; //GXTevBias + u32 op : 1; + u32 clamp : 1; + + u32 shift : 2; + u32 dest : 2; //1,2,3 + } alphaC; + } combiners[16]; + struct + { + u32 comp0 : 3; + u32 comp1 : 3; + u32 logic : 2; + // TODO: ref??? + } alpha_test; + + u32 bHasIndStage : 16; }; typedef ShaderUid PixelShaderUid; diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 090fb24b57..39fcf13d95 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -29,6 +29,7 @@ class ShaderUid public: ShaderUid() { + // TODO: Move to Shadergen => can be optimized out memset(values, 0, sizeof(values)); } From 67be1e939a15fd881565e38c63a590dc94473bc7 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 2 Sep 2012 14:31:37 +0200 Subject: [PATCH 006/352] PixelShaderGen: Some more work... --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 47 ++++++++++--------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 4 +- .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 2 +- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 9aad5556aa..8bfc3abd8a 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -40,8 +40,8 @@ template static void WriteStage(char *&p, int n, API_TYPE ApiType); template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); // static void WriteAlphaCompare(char *&p, int num, int comp); -template static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); -template static void WriteFog(char *&p); +template static void WriteAlphaTest(T& out, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); +template static void WriteFog(T& out); static const char *tevKSelTableC[] = // KCSEL { @@ -273,6 +273,16 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u SetUidField(genMode.numtevstages, bpmem.genMode.numtevstages); SetUidField(genMode.numtexgens, bpmem.genMode.numtexgens); + int nIndirectStagesUsed = 0; + if (bpmem.genMode.numindstages > 0) + { + for (unsigned int i = 0; i < numStages; ++i) + { + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) + nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; + } + } + // Declare samplers out.Write((ApiType != API_D3D11) ? "uniform sampler2D " : "sampler "); for (int i = 0; i < 8; ++i) @@ -287,7 +297,6 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write(";\n"); } - out.Write("\n"); out.Write("uniform float4 " I_COLORS"[4] : register(c%d);\n", C_COLORS); @@ -326,6 +335,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write(" in float4 colors_0 : COLOR0,\n"); out.Write(" in float4 colors_1 : COLOR1"); + // TODO: ... this looks like an incredibly ugly hack - is it still needed? // compute window position if needed because binding semantic WPOS is not widely supported if (numTexgen < 7) { @@ -345,7 +355,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } else { - /// TODO: Set numTexGen used + SetUidField(xfregs_numTexGen_numTexGens, xfregs.numTexGen.numTexGens); for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) out.Write(",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i); } @@ -363,6 +373,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { + SetUidField(xfregs_numTexGen_numTexGens, xfregs.numTexGen.numTexGens); if (xfregs.numTexGen.numTexGens < 7) { out.Write("float3 _norm0 = normalize(Normal.xyz);\n\n"); @@ -378,7 +389,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("float4 mat, lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); - +/// TODO /// p = GenerateLightingShader(p, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } @@ -409,16 +420,6 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } // indirect texture map lookup - int nIndirectStagesUsed = 0; - if (bpmem.genMode.numindstages > 0) - { - for (unsigned int i = 0; i < numStages; ++i) - { - /// Ignoring this for now, handled in WriteStage. - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; - } - } SetUidField(nIndirectStagesUsed, nIndirectStagesUsed); for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { @@ -427,6 +428,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u unsigned int texcoord = bpmem.tevindref.getTexCoord(i); unsigned int texmap = bpmem.tevindref.getTexMap(i); + /// TODO: Cleanup... if (i == 0) { SetUidField(tevindref.bc0, texcoord); @@ -468,15 +470,16 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u RegisterStates[i].AuxStored = false; } - BuildSwapModeTable(); // Uids set in WriteStage + // Uid fields for BuildSwapModeTable are set in WriteStage + BuildSwapModeTable(); for (unsigned int i = 0; i < numStages; i++) - WriteStage(out, i, ApiType); //build the equation for this stage + WriteStage(out, i, ApiType); // build the equation for this stage if(numStages) { // The results of the last texenv stage are put onto the screen, // regardless of the used destination register - SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); + SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); // TODO: These probably don't need to be set anymore here... SetUidField(combiners[numStages-1].alphaC.dest, bpmem.combiners[numStages-1].alphaC.dest); if(bpmem.combiners[numStages - 1].colorC.dest != 0) { @@ -1061,12 +1064,12 @@ static void WriteFog(T& out) out.Write(" prev.rgb = lerp(prev.rgb," I_FOG"[0].rgb,fog);\n"); } -void GetPixelShaderId(PixelShaderUid& object, DSTALPHA_MODE dst_alpha_mode, API_TYPE ApiType, u32 components) +void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - GeneratePixelShader(object, dst_alpha_mode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType, components); } -void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dst_alpha_mode, API_TYPE ApiType, u32 components) +void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - GeneratePixelShader(object, dst_alpha_mode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType, components); } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 994f70c9ea..86fdd5dd82 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -153,6 +153,8 @@ struct pixel_shader_uid_data } alpha_test; u32 bHasIndStage : 16; + + u32 xfregs_numTexGen_numTexGens : 4; }; typedef ShaderUid PixelShaderUid; @@ -160,6 +162,6 @@ typedef ShaderCode PixelShaderCode; void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); -void GetPixelShaderId(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); #endif // GCOGL_PIXELSHADER_H diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index cdd5d6e044..81e1547c71 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -184,7 +184,7 @@ void PixelShaderCache::Shutdown() FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PixelShaderUid uid; - GetPixelShaderId(uid, dstAlphaMode, API_OPENGL, components); + GetPixelShaderUid(uid, dstAlphaMode, API_OPENGL, components); // Check if the shader is already set if (last_entry) From 700cce9588fcd53b016161690f0d4c1fa5ccf3f3 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 2 Sep 2012 18:30:21 +0200 Subject: [PATCH 007/352] More work on making new pixel shader uids work --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 19 +++-- Source/Core/VideoCommon/Src/PixelShaderGen.h | 76 ++++++++++++------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 8bfc3abd8a..01f7768fb1 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -39,7 +39,6 @@ template static void WriteStage(char *&p, int n, API_TYPE ApiType); template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); -// static void WriteAlphaCompare(char *&p, int num, int comp); template static void WriteAlphaTest(T& out, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); template static void WriteFog(T& out); @@ -250,6 +249,7 @@ static void BuildSwapModeTable() template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { + // TODO: Can be optimized if using alpha pass #define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; #define OR_UidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name |= value; }; if (type == GO_ShaderCode) @@ -664,10 +664,12 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) // Wrapping // --------- - if (n < 8) { OR_UidField(tevorders_n_sw1, bpmem.tevind[n].sw << (3 * n)); } - else OR_UidField(tevorders_n_sw2, bpmem.tevind[n].sw << (3 * n - 24)); - if (n < 8) { OR_UidField(tevorders_n_tw1, bpmem.tevind[n].tw << (3 * n)); } - else OR_UidField(tevorders_n_tw2, bpmem.tevind[n].tw << (3 * n - 24)); + if (n < 8) { OR_UidField(tevind_n_sw1, bpmem.tevind[n].sw << (3 * n)); } + else OR_UidField(tevind_n_sw2, bpmem.tevind[n].sw << (3 * n - 24)); + if (n < 8) { OR_UidField(tevind_n_tw1, bpmem.tevind[n].tw << (3 * n)); } + else OR_UidField(tevind_n_tw2, bpmem.tevind[n].tw << (3 * n - 24)); + + OR_UidField(tevind_n_fb_addprev, bpmem.tevind[n].fb_addprev << n); // wrap S if (bpmem.tevind[n].sw == ITW_OFF) @@ -694,6 +696,9 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) TevStageCombiner::ColorCombiner &cc = bpmem.combiners[n].colorC; TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[n].alphaC; + SetUidField(combiners[n].colorC.hex, cc.hex&0xFFFFFF); + SetUidField(combiners[n].alphaC.hex, ac.hex&0xFFFFFF); + if(cc.a == TEVCOLORARG_RASA || cc.a == TEVCOLORARG_RASC || cc.b == TEVCOLORARG_RASA || cc.b == TEVCOLORARG_RASC || cc.c == TEVCOLORARG_RASA || cc.c == TEVCOLORARG_RASC @@ -1023,9 +1028,12 @@ static const char *tevFogFuncsTable[] = template static void WriteFog(T& out) { + SetUidField(fog.fsel, bpmem.fog.c_proj_fsel.fsel); if(bpmem.fog.c_proj_fsel.fsel == 0) return; //no Fog + SetUidField(fog.proj, bpmem.fog.c_proj_fsel.proj); + if (bpmem.fog.c_proj_fsel.proj == 0) { // perspective @@ -1042,6 +1050,7 @@ static void WriteFog(T& out) // x_adjust = sqrt((x-center)^2 + k^2)/k // ze *= x_adjust // this is completely theoretical as the real hardware seems to use a table intead of calculating the values. + SetUidField(fog.RangeBaseEnabled, bpmem.fogRange.Base.Enabled); if(bpmem.fogRange.Base.Enabled) { out.Write(" float x_adjust = (2.0f * (clipPos.x / " I_FOG"[2].y)) - 1.0f - " I_FOG"[2].x;\n"); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 86fdd5dd82..1476cb634d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -97,10 +97,11 @@ struct pixel_shader_uid_data u32 tevorders_n_texcoord1 : 24; // 8 x 3 bit u32 tevorders_n_texcoord2 : 24; // 8 x 3 bit - u32 tevorders_n_sw1 : 24; // 8 x 3 bit - u32 tevorders_n_sw2 : 24; // 8 x 3 bit - u32 tevorders_n_tw1 : 24; // 8 x 3 bit - u32 tevorders_n_tw2 : 24; // 8 x 3 bit + u32 tevind_n_sw1 : 24; // 8 x 3 bit + u32 tevind_n_sw2 : 24; // 8 x 3 bit + u32 tevind_n_tw1 : 24; // 8 x 3 bit + u32 tevind_n_tw2 : 24; // 8 x 3 bit + u32 tevind_n_fb_addprev : 16; // 16 x 1 bit u32 tevind_n_bs : 32; // 16 x 2 bit u32 tevind_n_fmt : 32; // 16 x 2 bit @@ -113,35 +114,41 @@ struct pixel_shader_uid_data u32 tevksel_n_swap : 32; // 8 x 2 bit (swap1) + 8 x 2 bit (swap2) struct { - struct //abc=8bit,d=10bit - { - u32 d : 4; // TEVSELCC_X - u32 c : 4; // TEVSELCC_X - u32 b : 4; // TEVSELCC_X - u32 a : 4; // TEVSELCC_X + union { + struct //abc=8bit,d=10bit + { + u32 d : 4; // TEVSELCC_X + u32 c : 4; // TEVSELCC_X + u32 b : 4; // TEVSELCC_X + u32 a : 4; // TEVSELCC_X - u32 bias : 2; - u32 op : 1; - u32 clamp : 1; + u32 bias : 2; + u32 op : 1; + u32 clamp : 1; - u32 shift : 2; - u32 dest : 2; //1,2,3 + u32 shift : 2; + u32 dest : 2; //1,2,3 + }; + u32 hex : 24; } colorC; - struct - { - u32 rswap : 2; - u32 tswap : 2; - u32 d : 3; // TEVSELCA_ - u32 c : 3; // TEVSELCA_ - u32 b : 3; // TEVSELCA_ - u32 a : 3; // TEVSELCA_ + union { + struct + { + u32 rswap : 2; + u32 tswap : 2; + u32 d : 3; // TEVSELCA_ + u32 c : 3; // TEVSELCA_ + u32 b : 3; // TEVSELCA_ + u32 a : 3; // TEVSELCA_ - u32 bias : 2; //GXTevBias - u32 op : 1; - u32 clamp : 1; + u32 bias : 2; //GXTevBias + u32 op : 1; + u32 clamp : 1; - u32 shift : 2; - u32 dest : 2; //1,2,3 + u32 shift : 2; + u32 dest : 2; //1,2,3 + }; + u32 hex : 24; } alphaC; } combiners[16]; struct @@ -152,6 +159,17 @@ struct pixel_shader_uid_data // TODO: ref??? } alpha_test; + union { + struct + { + u32 proj : 1; // 0 - perspective, 1 - orthographic + u32 fsel : 3; // 0 - off, 2 - linear, 4 - exp, 5 - exp2, 6 - backward exp, 7 - backward exp2 + u32 RangeBaseEnabled : 1; + }; + u32 hex : 4; + } fog; + + u32 bHasIndStage : 16; u32 xfregs_numTexGen_numTexGens : 4; @@ -159,9 +177,11 @@ struct pixel_shader_uid_data typedef ShaderUid PixelShaderUid; typedef ShaderCode PixelShaderCode; +//typedef ShaderConstantProfile PixelShaderConstantProfile; void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +//void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); #endif // GCOGL_PIXELSHADER_H From 0fdeb81038d9ef599d4741035245972c3d374be7 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 2 Sep 2012 20:00:15 +0200 Subject: [PATCH 008/352] Add some code for generating a shader constant usage profile. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 62 +++++++++++- Source/Core/VideoCommon/Src/PixelShaderGen.h | 5 +- .../VideoCommon/Src/PixelShaderManager.cpp | 99 ++++++++++++------- .../Core/VideoCommon/Src/PixelShaderManager.h | 2 +- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 35 ++++++- .../Plugin_VideoOGL/Src/VertexManager.cpp | 2 +- 6 files changed, 163 insertions(+), 42 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 01f7768fb1..a19eb1a27e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -299,9 +299,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } out.Write("\n"); - out.Write("uniform float4 " I_COLORS"[4] : register(c%d);\n", C_COLORS); + out.Write("uniform float4 " I_COLORS"[4] : register(c%d);\n", C_COLORS); // TODO: first element not used?? out.Write("uniform float4 " I_KCOLORS"[4] : register(c%d);\n", C_KCOLORS); - out.Write("uniform float4 " I_ALPHA"[1] : register(c%d);\n", C_ALPHA); + out.Write("uniform float4 " I_ALPHA"[1] : register(c%d);\n", C_ALPHA); // TODO: Why is this an array...-.- out.Write("uniform float4 " I_TEXDIMS"[8] : register(c%d);\n", C_TEXDIMS); out.Write("uniform float4 " I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS); out.Write("uniform float4 " I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE); @@ -390,6 +390,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u "float3 ldir, h;\n" "float dist, dist2, attn;\n"); /// TODO + out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+39); // TODO: Can be optimized further + out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); /// p = GenerateLightingShader(p, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } @@ -405,6 +407,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } else { + out.SetConstantsUsed(C_TEXDIMS, C_TEXDIMS+numTexgen-1); for (unsigned int i = 0; i < numTexgen; ++i) { // optional perspective divides @@ -450,7 +453,10 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u SetUidField(tevindref.bi4, texmap); } if (texcoord < numTexgen) + { + out.SetConstantsUsed(C_INDTEXSCALE+i/2,C_INDTEXSCALE+i/2); out.Write("tempcoord = uv%d.xy * " I_INDTEXSCALE"[%d].%s;\n", texcoord, i/2, (i&1)?"zw":"xy"); + } else out.Write("tempcoord = float2(0.0f, 0.0f);\n"); @@ -504,12 +510,14 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u WriteAlphaTest(out, ApiType, dstAlphaMode); // the screen space depth value = far z + (clip z / clip w) * z range + out.SetConstantsUsed(C_ZBIAS+1, C_ZBIAS+1); out.Write("float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); // Note: depth textures are disabled if early depth test is enabled if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... + out.SetConstantsUsed(C_ZBIAS, C_ZBIAS+1); out.Write("zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : ""); @@ -521,7 +529,10 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) + { + out.SetConstantsUsed(C_ALPHA, C_ALPHA); out.Write(" ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); + } else { WriteFog(out); @@ -532,6 +543,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // single pass if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { + out.SetConstantsUsed(C_ALPHA, C_ALPHA); // Colors will be blended against the alpha from ocol1... out.Write(" ocol1 = ocol0;\n"); // ...and the alpha from ocol0 will be written to the framebuffer. @@ -639,6 +651,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) if (bpmem.tevind[n].mid <= 3) { int mtxidx = 2*(bpmem.tevind[n].mid-1); + out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx); out.Write("float2 indtevtrans%d = float2(dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot(" I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", n, mtxidx, n, mtxidx+1, n); } @@ -646,12 +659,14 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) { // s matrix _assert_(bpmem.tevind[n].mid >= 5); int mtxidx = 2*(bpmem.tevind[n].mid-5); + out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx); out.Write("float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n); } else if (bpmem.tevind[n].mid <= 11 && bHasTexCoord) { // t matrix _assert_(bpmem.tevind[n].mid >= 9); int mtxidx = 2*(bpmem.tevind[n].mid-9); + out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx); out.Write("float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n); } else @@ -757,6 +772,10 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) { out.Write("ckonsttemp = konsttemp;\n"); } + if (kc > 7) + out.SetConstantsUsed(C_KCOLORS+((kc-0xc)%4),C_KCOLORS+((kc-0xc)%4)); + if (ka > 7) + out.SetConstantsUsed(C_KCOLORS+((ka-0xc)%4),C_KCOLORS+((ka-0xc)%4)); } if(cc.a == TEVCOLORARG_CPREV || cc.a == TEVCOLORARG_APREV @@ -782,6 +801,8 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || cc.c == TEVCOLORARG_C0 || cc.c == TEVCOLORARG_A0 || ac.a == TEVALPHAARG_A0 || ac.b == TEVALPHAARG_A0 || ac.c == TEVALPHAARG_A0) { + // TODO: WTF? + out.SetConstantsUsed(C_COLORS+1,C_COLORS+1); if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl) { out.Write("cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); @@ -800,6 +821,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || cc.c == TEVCOLORARG_C1 || cc.c == TEVCOLORARG_A1 || ac.a == TEVALPHAARG_A1 || ac.b == TEVALPHAARG_A1 || ac.c == TEVALPHAARG_A1) { + out.SetConstantsUsed(C_COLORS+2,C_COLORS+2); if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl) { out.Write("cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); @@ -818,6 +840,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || cc.c == TEVCOLORARG_C2 || cc.c == TEVCOLORARG_A2 || ac.a == TEVALPHAARG_A2 || ac.b == TEVALPHAARG_A2 || ac.c == TEVALPHAARG_A2) { + out.SetConstantsUsed(C_COLORS+3,C_COLORS+3); if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl) { out.Write("cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); @@ -834,6 +857,28 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) RegisterStates[cc.dest].ColorNeedOverflowControl = (cc.clamp == 0); RegisterStates[cc.dest].AuxStored = false; +/* if (cc.d == TEVCOLORARG_C0 || cc.d == TEVCOLORARG_A0 || ac.d == TEVALPHAARG_A0) + { + out.SetConstantsUsed(C_COLORS+1,C_COLORS+1); + // TODO: 11 bit signed overflow.. + } + if (cc.d == TEVCOLORARG_C1 || cc.d == TEVCOLORARG_A1 || ac.d == TEVALPHAARG_A1) + { + out.SetConstantsUsed(C_COLORS+2,C_COLORS+2); + // TODO: 11 bit signed overflow.. + } + if (cc.d == TEVCOLORARG_C2 || cc.d == TEVCOLORARG_A2 || ac.d == TEVALPHAARG_A2) + { + out.SetConstantsUsed(C_COLORS+3,C_COLORS+3); + // TODO: 11 bit signed overflow.. + }*/ + + // TODO: Are there enums for this? + if (cc.dest >= 1 && cc.dest <= 3) + out.SetConstantsUsed(C_COLORS+cc.dest, C_COLORS+cc.dest); + if (ac.dest >= 1 && ac.dest <= 3) + out.SetConstantsUsed(C_COLORS+ac.dest, C_COLORS+ac.dest); + out.Write("// color combine\n"); if (cc.clamp) out.Write("%s = saturate(", tevCOutputTable[cc.dest]); @@ -935,6 +980,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) template void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType) { + out.SetConstantsUsed(C_TEXDIMS+texmap,C_TEXDIMS+texmap); if (ApiType == API_D3D11) out.Write("%s=Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", destination, texmap,texmap, texcoords, texmap, texswap); else @@ -968,7 +1014,9 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode) { I_ALPHA"[0].r", I_ALPHA"[0].g" - }; + }; + + out.SetConstantsUsed(C_ALPHA, C_ALPHA); // using discard then return works the same in cg and dx9 but not in dx11 out.Write("if(!( "); @@ -1034,6 +1082,7 @@ static void WriteFog(T& out) SetUidField(fog.proj, bpmem.fog.c_proj_fsel.proj); + out.SetConstantsUsed(C_FOG, C_FOG+1); if (bpmem.fog.c_proj_fsel.proj == 0) { // perspective @@ -1053,6 +1102,7 @@ static void WriteFog(T& out) SetUidField(fog.RangeBaseEnabled, bpmem.fogRange.Base.Enabled); if(bpmem.fogRange.Base.Enabled) { + out.SetConstantsUsed(C_FOG+2, C_FOG+2); out.Write(" float x_adjust = (2.0f * (clipPos.x / " I_FOG"[2].y)) - 1.0f - " I_FOG"[2].x;\n"); out.Write(" x_adjust = sqrt(x_adjust * x_adjust + " I_FOG"[2].z * " I_FOG"[2].z) / " I_FOG"[2].z;\n"); out.Write(" ze *= x_adjust;\n"); @@ -1082,3 +1132,9 @@ void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode { GeneratePixelShader(object, dstAlphaMode, ApiType, components); } + +void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +{ + GeneratePixelShader(object, dstAlphaMode, ApiType, components); +} + diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 1476cb634d..221b04612e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -72,7 +72,6 @@ struct pixel_shader_uid_data u32 numtevstages : 4; u32 numindstages : 3; } genMode; - u32 fogc_proj_fselfsel : 3; struct { u32 unknown : 1; @@ -177,11 +176,11 @@ struct pixel_shader_uid_data typedef ShaderUid PixelShaderUid; typedef ShaderCode PixelShaderCode; -//typedef ShaderConstantProfile PixelShaderConstantProfile; +typedef ShaderConstantProfile PixelShaderConstantProfile; void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); -//void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); #endif // GCOGL_PIXELSHADER_H diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index eaaf99fbc8..ffec7d64cb 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -83,39 +83,58 @@ void PixelShaderManager::Shutdown() } -void PixelShaderManager::SetConstants() +void PixelShaderManager::SetConstants(u32 components) { - for (int i = 0; i < 2; ++i) + PixelShaderConstantProfile constant_profile(C_PENVCONST_END); + /// TODO: dst alpha/api/components type parameter... + GetPixelShaderConstantProfile(constant_profile, DSTALPHA_DUAL_SOURCE_BLEND, API_OPENGL, components); + + static int saved_updates = 0; + static int necessary_updates = 0; + + +#define IncStuff() { \ + saved_updates++; \ + printf("Saved a constant update at line %d! Saved %d against %d now!\n", __LINE__, saved_updates, necessary_updates); } + + for (int i = 0; i < 2; ++i) { - if (s_nColorsChanged[i]) + if (s_nColorsChanged[i]) { - int baseind = i ? C_KCOLORS : C_COLORS; - for (int j = 0; j < 4; ++j) + int baseind = i ? C_KCOLORS : C_COLORS; + for (int j = 0; j < 4; ++j) { - if (s_nColorsChanged[i] & (1 << j)) - SetPSConstant4fv(baseind+j, &lastRGBAfull[i][j][0]); - } - s_nColorsChanged[i] = 0; - } - } + if ((s_nColorsChanged[i] & (1 << j)) && constant_profile.ConstantIsUsed(baseind+j)) + { + SetPSConstant4fv(baseind+j, &lastRGBAfull[i][j][0]); + s_nColorsChanged[i] &= ~(1<>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f); s_bAlphaChanged = false; - } + } else if (s_bAlphaChanged) IncStuff(); - if (s_bZTextureTypeChanged) + if (s_bZTextureTypeChanged && constant_profile.ConstantIsUsed(C_ZBIAS)) { float ftemp[4]; switch (bpmem.ztex2.type) @@ -133,11 +152,12 @@ void PixelShaderManager::SetConstants() ftemp[0] = 16711680.0f/16777215.0f; ftemp[1] = 65280.0f/16777215.0f; ftemp[2] = 255.0f/16777215.0f; ftemp[3] = 0; break; } + ++necessary_updates; SetPSConstant4fv(C_ZBIAS, ftemp); s_bZTextureTypeChanged = false; - } + } else if (s_bZTextureTypeChanged) IncStuff(); - if (s_bZBiasChanged || s_bDepthRangeChanged) + if ((s_bZBiasChanged || s_bDepthRangeChanged) && constant_profile.ConstantIsUsed(C_ZBIAS+1)) { // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) // [0] = width/2 @@ -148,9 +168,10 @@ void PixelShaderManager::SetConstants() // [5] = 16777215 * farz //ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias); + ++necessary_updates; SetPSConstant4f(C_ZBIAS+1, xfregs.viewport.farZ / 16777216.0f, xfregs.viewport.zRange / 16777216.0f, 0, (float)(lastZBias)/16777215.0f); s_bZBiasChanged = s_bDepthRangeChanged = false; - } + }else if ((s_bZBiasChanged || s_bDepthRangeChanged)) IncStuff(); // indirect incoming texture scales if (s_nIndTexScaleChanged) @@ -158,7 +179,7 @@ void PixelShaderManager::SetConstants() // set as two sets of vec4s, each containing S and T of two ind stages. float f[8]; - if (s_nIndTexScaleChanged & 0x03) + if ((s_nIndTexScaleChanged & 0x03) && constant_profile.ConstantIsUsed(C_INDTEXSCALE)) { for (u32 i = 0; i < 2; ++i) { @@ -166,26 +187,30 @@ void PixelShaderManager::SetConstants() f[2 * i + 1] = bpmem.texscale[0].getScaleT(i & 1); PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]); } + ++necessary_updates; SetPSConstant4fv(C_INDTEXSCALE, f); + s_nIndTexScaleChanged &= ~0x03; } + else if ((s_nIndTexScaleChanged & 0x03)) IncStuff(); - if (s_nIndTexScaleChanged & 0x0c) { + if ((s_nIndTexScaleChanged & 0x0c) && constant_profile.ConstantIsUsed(C_INDTEXSCALE+1)) { for (u32 i = 2; i < 4; ++i) { f[2 * i] = bpmem.texscale[1].getScaleS(i & 1); f[2 * i + 1] = bpmem.texscale[1].getScaleT(i & 1); PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]); } + ++necessary_updates; SetPSConstant4fv(C_INDTEXSCALE+1, &f[4]); + s_nIndTexScaleChanged &= ~0x0c; } - - s_nIndTexScaleChanged = 0; + else if ((s_nIndTexScaleChanged & 0x0c)) IncStuff(); } if (s_nIndTexMtxChanged) { for (int i = 0; i < 3; ++i) { - if (s_nIndTexMtxChanged & (1 << i)) + if ((s_nIndTexMtxChanged & (1 << i)) && (constant_profile.ConstantIsUsed(C_INDTEXMTX+2*i) || constant_profile.ConstantIsUsed(C_INDTEXMTX+2*i+1))) { int scale = ((u32)bpmem.indmtx[i].col0.s0 << 0) | ((u32)bpmem.indmtx[i].col1.s1 << 2) | @@ -195,6 +220,8 @@ void PixelShaderManager::SetConstants() // xyz - static matrix // TODO w - dynamic matrix scale / 256...... somehow / 4 works better // rev 2972 - now using / 256.... verify that this works + ++necessary_updates; + ++necessary_updates; SetPSConstant4f(C_INDTEXMTX + 2 * i, bpmem.indmtx[i].col0.ma * fscale, bpmem.indmtx[i].col1.mc * fscale, @@ -210,19 +237,22 @@ void PixelShaderManager::SetConstants() i, 1024.0f*fscale, bpmem.indmtx[i].col0.ma * fscale, bpmem.indmtx[i].col1.mc * fscale, bpmem.indmtx[i].col2.me * fscale, bpmem.indmtx[i].col0.mb * fscale, bpmem.indmtx[i].col1.md * fscale, bpmem.indmtx[i].col2.mf * fscale); - } + + s_nIndTexMtxChanged &= ~(1 << i); + }else if ((s_nIndTexMtxChanged & (1 << i))) {IncStuff();IncStuff();} } - s_nIndTexMtxChanged = 0; } - if (s_bFogColorChanged) + if (s_bFogColorChanged && constant_profile.ConstantIsUsed(C_FOG)) { + ++necessary_updates; SetPSConstant4f(C_FOG, bpmem.fog.color.r / 255.0f, bpmem.fog.color.g / 255.0f, bpmem.fog.color.b / 255.0f, 0); s_bFogColorChanged = false; - } + }else if (s_bFogColorChanged) IncStuff(); - if (s_bFogParamChanged) + if (s_bFogParamChanged && constant_profile.ConstantIsUsed(C_FOG+1)) { + ++necessary_updates; if(!g_ActiveConfig.bDisableFog) { //downscale magnitude to 0.24 bits @@ -235,10 +265,11 @@ void PixelShaderManager::SetConstants() SetPSConstant4f(C_FOG + 1, 0.0, 1.0, 0.0, 1.0); s_bFogParamChanged = false; - } + }else if ( s_bFogParamChanged) IncStuff(); - if (s_bFogRangeAdjustChanged) + if (s_bFogRangeAdjustChanged && constant_profile.ConstantIsUsed(C_FOG+2)) { + ++necessary_updates; if(!g_ActiveConfig.bDisableFog && bpmem.fogRange.Base.Enabled == 1) { //bpmem.fogRange.Base.Center : center of the viewport in x axis. observation: bpmem.fogRange.Base.Center = realcenter + 342; @@ -257,8 +288,9 @@ void PixelShaderManager::SetConstants() SetPSConstant4f(C_FOG + 2, 0.0f, 1.0f, 1.0f, 0.0f); // Need to update these values for older hardware that fails to divide by zero in shaders. s_bFogRangeAdjustChanged = false; - } + }else if ( s_bFogRangeAdjustChanged) IncStuff(); + // TODO: use constant profile here! if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) // config check added because the code in here was crashing for me inside SetPSConstant4f { if (nLightsChanged[0] >= 0) @@ -353,7 +385,8 @@ void PixelShaderManager::SetPSTextureDims(int texid) SetPSConstant4fv(C_TEXDIMS + texid, fdims); } -// This one is high in profiles (0.5%). TODO: Move conversion out, only store the raw color value +// This one is high in profiles (0.5%). +// TODO: Move conversion out, only store the raw color value // and update it when the shader constant is set, only. void PixelShaderManager::SetColorChanged(int type, int num, bool high) { diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index 12d749c871..348940f495 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -34,7 +34,7 @@ public: static void Shutdown(); static void DoState(PointerWrap &p); - static void SetConstants(); // sets pixel shader constants + static void SetConstants(u32 components); // sets pixel shader constants // constant management, should be called after memory is committed static void SetColorChanged(int type, int index, bool high); diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 39fcf13d95..e052066628 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -23,6 +23,8 @@ #include #include "CommonTypes.h" +#include + template class ShaderUid { @@ -36,6 +38,7 @@ public: void Write(const char* fmt, ...) {} const char* GetBuffer() { return NULL; } void SetBuffer(char* buffer) { } + inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} bool operator == (const ShaderUid& obj) const { @@ -55,7 +58,7 @@ public: return false; } - uid_data& GetUidData() { return data; } + inline uid_data& GetUidData() { return data; } private: union @@ -86,16 +89,46 @@ public: const char* GetBuffer() { return buf; } void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; } uid_data& GetUidData() { return *(uid_data*)NULL; } + inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} private: const char* buf; char* write_ptr; }; +template +class ShaderConstantProfile +{ +public: + ShaderConstantProfile(int num_constants) { constant_usage.resize(num_constants); } + + void Write(const char* fmt, ...) {} + const char* GetBuffer() { return NULL; } + void SetBuffer(char* buffer) { } + uid_data& GetUidData() { return *(uid_data*)NULL; } + + // has room for optimization (if it matters at all...) + void NumConstants() { return constant_usage.size(); } + + inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) + { + for (unsigned int i = first_index; i < last_index+1; ++i) + constant_usage[i] = true; + } + + inline bool ConstantIsUsed(unsigned int index) + { + return constant_usage[index]; + } +private: + std::vector constant_usage; // TODO: Is vector appropriate here? +}; + enum GenOutput { GO_ShaderCode, GO_ShaderUid, + GO_ShaderConstantProfile, }; #endif // _SHADERGENCOMMON_H diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index ce33247d7c..d89f28ba5d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -180,7 +180,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(); + PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; From 9f1582843d03dbe9ee607ddcc8323699d408d693 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 2 Sep 2012 19:14:43 +0200 Subject: [PATCH 009/352] PixelShaderManager: Reduce number of redundant shader constant updates --- .../VideoCommon/Src/PixelShaderManager.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index ffec7d64cb..e458c5f1e1 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -42,19 +42,45 @@ static u32 lastTexDims[8]; // width | height << 16 | wrap_s << 28 | wrap_t << 30 static u32 lastZBias; static int nMaterialsChanged; +static float s_constant_cache[C_PENVCONST_END*4]; + inline void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { + if (s_constant_cache[const_number*4] == f1 && s_constant_cache[const_number*4+1] == f2 && + s_constant_cache[const_number*4+2] == f3 && s_constant_cache[const_number*4+3] == f4) + return; + g_renderer->SetPSConstant4f(const_number, f1, f2, f3, f4); + s_constant_cache[const_number*4] = f1; + s_constant_cache[const_number*4+1] = f2; + s_constant_cache[const_number*4+2] = f3; + s_constant_cache[const_number*4+3] = f4; } inline void SetPSConstant4fv(unsigned int const_number, const float *f) { + if (s_constant_cache[const_number*4] == f[0] && s_constant_cache[const_number*4+1] == f[1] && + s_constant_cache[const_number*4+2] == f[2] && s_constant_cache[const_number*4+3] == f[3]) + return; + g_renderer->SetPSConstant4fv(const_number, f); + s_constant_cache[const_number*4] = f[0]; + s_constant_cache[const_number*4+1] = f[1]; + s_constant_cache[const_number*4+2] = f[2]; + s_constant_cache[const_number*4+3] == f[3]; } inline void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { + for (unsigned int i = 0; i < 4*count; ++i) + if (s_constant_cache[const_number*4+i] != f[i]) + break; + else if (i == 4*count-1) + return; + g_renderer->SetMultiPSConstant4fv(const_number, count, f); + for (unsigned int i = 0; i < 4*count; ++i) + s_constant_cache[const_number*4+i] = f[i]; } void PixelShaderManager::Init() @@ -63,6 +89,7 @@ void PixelShaderManager::Init() memset(lastTexDims, 0, sizeof(lastTexDims)); lastZBias = 0; memset(lastRGBAfull, 0, sizeof(lastRGBAfull)); + memset(s_constant_cache, 0, sizeof(s_constant_cache)); // TODO: Should reflect that on the GPU side.... Dirty(); } @@ -95,7 +122,7 @@ void PixelShaderManager::SetConstants(u32 components) #define IncStuff() { \ saved_updates++; \ - printf("Saved a constant update at line %d! Saved %d against %d now!\n", __LINE__, saved_updates, necessary_updates); } + /*printf("Saved a constant update at line %d! Saved %d against %d now!\n", __LINE__, saved_updates, necessary_updates);*/ } for (int i = 0; i < 2; ++i) { From 76148a52b82cae8e6cf11b6eeeeff55345b0f12e Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 28 Jan 2013 22:51:15 +0100 Subject: [PATCH 010/352] Fix a few other things --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 30 ++++++++++++------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 19 +++++++----- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index a19eb1a27e..fa38075118 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -273,16 +273,6 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u SetUidField(genMode.numtevstages, bpmem.genMode.numtevstages); SetUidField(genMode.numtexgens, bpmem.genMode.numtexgens); - int nIndirectStagesUsed = 0; - if (bpmem.genMode.numindstages > 0) - { - for (unsigned int i = 0; i < numStages; ++i) - { - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; - } - } - // Declare samplers out.Write((ApiType != API_D3D11) ? "uniform sampler2D " : "sampler "); for (int i = 0; i < 8; ++i) @@ -317,6 +307,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("uniform s_" I_PMATERIALS" " I_PMATERIALS" : register(c%d);\n", C_PMATERIALS); } + // TODO: Somehow should put ApiType in the hash.. out.Write("void main(\n"); if(ApiType != API_D3D11) { @@ -355,6 +346,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } else { + // TODO: Not necessary... SetUidField(xfregs_numTexGen_numTexGens, xfregs.numTexGen.numTexGens); for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) out.Write(",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i); @@ -423,10 +415,20 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } // indirect texture map lookup + int nIndirectStagesUsed = 0; + if (bpmem.genMode.numindstages > 0) + { + for (unsigned int i = 0; i < numStages; ++i) + { + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) + nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; + } + } + SetUidField(nIndirectStagesUsed, nIndirectStagesUsed); for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { - if (nIndirectStagesUsed & (1<(out, ApiType, dstAlphaMode); @@ -514,8 +517,13 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); // Note: depth textures are disabled if early depth test is enabled + SetUidField(Pretest, Pretest); + SetUidField(ztex.op, bpmem.ztex2.op); + SetUidField(early_z, bpmem.zcontrol.early_ztest); + SetUidField(ztestenable, bpmem.zmode.testenable); if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { + // TODO: Implement type?? // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... out.SetConstantsUsed(C_ZBIAS, C_ZBIAS+1); out.Write("zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 221b04612e..c1c210dce6 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -20,6 +20,7 @@ #include "VideoCommon.h" #include "ShaderGenCommon.h" +#include "BPMemory.h" #define I_COLORS "color" #define I_KCOLORS "k" @@ -54,18 +55,11 @@ enum DSTALPHA_MODE DSTALPHA_DUAL_SOURCE_BLEND // Use dual-source blending }; -enum ALPHA_PRETEST_RESULT -{ - ALPHAPT_UNDEFINED, // AlphaTest Result is not defined - ALPHAPT_ALWAYSFAIL, // Alpha test alway Fail - ALPHAPT_ALWAYSPASS // Alpha test alway Pass -}; - struct pixel_shader_uid_data { u32 components; DSTALPHA_MODE dstAlphaMode; // TODO: as u32 :2 - ALPHA_PRETEST_RESULT Pretest; // TODO: As :2 + AlphaTest::TEST_RESULT Pretest; // TODO: As :2 u32 nIndirectStagesUsed : 8; struct { u32 numtexgens : 4; @@ -168,6 +162,15 @@ struct pixel_shader_uid_data u32 hex : 4; } fog; + union { + struct { + u32 op : 2; + }; + u32 hex : 2; + } ztex; + + u32 early_z : 1; + u32 ztestenable : 1; u32 bHasIndStage : 16; From 30f1a4b4fe154bb6e58dda9d3d1c8bfb4bd822d7 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 18:07:42 +0100 Subject: [PATCH 011/352] Partially revert "Now CG plays nice with this new stuff." This reverts commit 3943840d5c422af45941a96e6d4407d59380b39d. Suppport for old GLSL versions has been dropped, so to make things less ugly we can use a structure for lights again. --- .../VideoCommon/Src/LightingShaderGen.cpp | 26 +++++++++---------- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 3 ++- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 5 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index 2b717bdba6..2cb52004a9 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -47,13 +47,13 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char // atten disabled switch (chan.diffusefunc) { case LIGHTDIF_NONE: - WRITE(p, "lacc.%s += %s[%d].%s;\n", swizzle, lightsName, index * 5, swizzle); + WRITE(p, "lacc.%s += %s[%d].col.%s;\n", swizzle, lightsName, index, swizzle); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - WRITE(p, "ldir = normalize(%s[%d + 3].xyz - pos.xyz);\n", lightsName, index * 5); - WRITE(p, "lacc.%s += %sdot(ldir, _norm0)) * %s[%d].%s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index * 5, swizzle); + WRITE(p, "ldir = normalize(%s[%d].pos.xyz - pos.xyz);\n", lightsName, index); + WRITE(p, "lacc.%s += %sdot(ldir, _norm0)) * %s[%d].col.%s;\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); break; default: _assert_(0); } @@ -62,32 +62,32 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char if (chan.attnfunc == 3) { // spot - WRITE(p, "ldir = %s[%d + 3].xyz - pos.xyz;\n", lightsName, index * 5); + WRITE(p, "ldir = %s[%d].pos.xyz - pos.xyz;\n", lightsName, index); WRITE(p, "dist2 = dot(ldir, ldir);\n" "dist = sqrt(dist2);\n" "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s[%d + 4].xyz));\n", lightsName, index * 5); - WRITE(p, "attn = max(0.0f, dot(%s[%d + 1].xyz, float3(1.0f, attn, attn*attn))) / dot(%s[%d + 2].xyz, float3(1.0f,dist,dist2));\n", lightsName, index * 5, lightsName, index * 5); + "attn = max(0.0f, dot(ldir, %s[%d].dir.xyz));\n", lightsName, index); + WRITE(p, "attn = max(0.0f, dot(%s[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); } else if (chan.attnfunc == 1) { // specular - WRITE(p, "ldir = normalize(%s[%d + 3].xyz);\n", lightsName, index * 5); - WRITE(p, "attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s[%d + 4].xyz)) : 0.0f;\n", lightsName, index * 5); - WRITE(p, "attn = max(0.0f, dot(%s[%d + 1].xyz, float3(1,attn,attn*attn))) / dot(%s[%d + 2].xyz, float3(1,attn,attn*attn));\n", lightsName, index * 5, lightsName, index * 5); + WRITE(p, "ldir = normalize(%s[%d].pos.xyz);\n", lightsName, index); + WRITE(p, "attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s[%d].dir.xyz)) : 0.0f;\n", lightsName, index); + WRITE(p, "attn = max(0.0f, dot(%s[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); } switch (chan.diffusefunc) { case LIGHTDIF_NONE: - WRITE(p, "lacc.%s += attn * %s[%d].%s;\n", swizzle, lightsName, index * 5, swizzle); + WRITE(p, "lacc.%s += attn * %s[%d].col.%s;\n", swizzle, lightsName, index, swizzle); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - WRITE(p, "lacc.%s += attn * %sdot(ldir, _norm0)) * %s[%d].%s;\n", + WRITE(p, "lacc.%s += attn * %sdot(ldir, _norm0)) * %s[%d].col.%s;\n", swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, - index * 5, + index, swizzle); break; default: _assert_(0); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index d863a6e0a9..d7e74a049d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -590,7 +590,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "\t%sfloat4 " I_FOG"[3] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_FOG)); // For pixel lighting - WRITE(p, "\t%sfloat4 " I_PLIGHTS"[40] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); + WRITE(p, "struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); + WRITE(p, "\t%sLight " I_PLIGHTS"[8] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); WRITE(p, "\t%sfloat4 " I_PMATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PMATERIALS)); if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 2c0f5676ed..2410548397 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -192,7 +192,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType) WRITE(p, "%sfloat4 " I_POSNORMALMATRIX"[6] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_POSNORMALMATRIX)); WRITE(p, "%sfloat4 " I_PROJECTION"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PROJECTION)); WRITE(p, "%sfloat4 " I_MATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_MATERIALS)); - WRITE(p, "%sfloat4 " I_LIGHTS"[40] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_LIGHTS)); + WRITE(p, "struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); + WRITE(p, "%sLight " I_LIGHTS"[8] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_LIGHTS)); WRITE(p, "%sfloat4 " I_TEXMATRICES"[24] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_TEXMATRICES)); // also using tex matrices WRITE(p, "%sfloat4 " I_TRANSFORMMATRICES"[64] %s;\n", WriteLocation(ApiType),WriteRegister(ApiType, "c", C_TRANSFORMMATRICES)); WRITE(p, "%sfloat4 " I_NORMALMATRICES"[32] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_NORMALMATRICES)); @@ -413,7 +414,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType) if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { // transform the light dir into tangent space - WRITE(p, "ldir = normalize(" I_LIGHTS"[%d + 3].xyz - pos.xyz);\n", texinfo.embosslightshift); + WRITE(p, "ldir = normalize(" I_LIGHTS"[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); } else From b75a617d8a2e4307ed4af06669e92fc33f6af1df Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 19:35:00 +0100 Subject: [PATCH 012/352] VertexShaderGen: De-uglify VS output structure writing --- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 2410548397..f647bd0280 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -131,33 +131,49 @@ static char text[16384]; #define WRITE p+=sprintf +char* DefineVSOutputStructMember(char* p, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic, int semantic_index = -1) +{ + WRITE(p, " %s %s", type, name); + if (var_index != -1) + WRITE(p, "%d", var_index); + + if (api_type == API_OPENGL) + WRITE(p, ";\n"); + else + { + if (semantic_index != -1) + WRITE(p, " : %s%d;\n", semantic, semantic_index); + else + WRITE(p, " : %s;\n", semantic); + } + + return p; +} + char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE ApiType) { - // GLSL makes this ugly - // TODO: Make pretty WRITE(p, "struct VS_OUTPUT {\n"); - WRITE(p, " float4 pos %s POSITION;\n", ApiType == API_OPENGL ? ";//" : ":"); - WRITE(p, " float4 colors_0 %s COLOR0;\n", ApiType == API_OPENGL ? ";//" : ":"); - WRITE(p, " float4 colors_1 %s COLOR1;\n", ApiType == API_OPENGL ? ";//" : ":"); + p = DefineVSOutputStructMember(p, ApiType, "float4", "pos", -1, "POSITION"); + p = DefineVSOutputStructMember(p, ApiType, "float4", "colors_", 0, "COLOR", 0); + p = DefineVSOutputStructMember(p, ApiType, "float4", "colors_", 1, "COLOR", 1); - if (xfregs.numTexGen.numTexGens < 7) { + if (xfregs.numTexGen.numTexGens < 7) + { for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, " float3 tex%d %s TEXCOORD%d;\n", i, ApiType == API_OPENGL ? ";//" : ":", i); - WRITE(p, " float4 clipPos %s TEXCOORD%d;\n", ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens); + p = DefineVSOutputStructMember(p, ApiType, "float3", "tex", i, "TEXCOORD", i); + + p = DefineVSOutputStructMember(p, ApiType, "float4", "clipPos", -1, "TEXCOORD", xfregs.numTexGen.numTexGens); + if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - WRITE(p, " float4 Normal %s TEXCOORD%d;\n", ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens + 1); - } else { - // clip position is in w of first 4 texcoords - if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - { - for (int i = 0; i < 8; ++i) - WRITE(p, " float4 tex%d %s TEXCOORD%d;\n", i, ApiType == API_OPENGL? ";//" : ":", i); - } - else - { - for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, " float%d tex%d %s TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, ApiType == API_OPENGL ? ";//" : ":", i); - } + p = DefineVSOutputStructMember(p, ApiType, "float4", "Normal", -1, "TEXCOORD", xfregs.numTexGen.numTexGens + 1); + } + else + { + // Store clip position in the w component of first 4 texcoords + bool ppl = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; + int num_texcoords = ppl ? 8 : xfregs.numTexGen.numTexGens; + for (int i = 0; i < num_texcoords; ++i) + p = DefineVSOutputStructMember(p, ApiType, (ppl || i < 4) ? "float4" : "float3", "tex", i, "TEXCOORD", i); } WRITE(p, "};\n"); From 0e319432164ef0c906e947a2c54fa51739d00e7c Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 23:03:10 +0100 Subject: [PATCH 013/352] ShaderGenCommon: Introduce a common shader generator interface to make stuff less confusing. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index e052066628..d02462360d 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -26,7 +26,18 @@ #include template -class ShaderUid +class ShaderGeneratorInterface +{ +public: + void Write(const char* fmt, ...) {} + const char* GetBuffer() { return NULL; } + void SetBuffer(char* buffer) { } + inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} + uid_data& GetUidData() { return *(uid_data*)NULL; } +}; + +template +class ShaderUid : public ShaderGeneratorInterface { public: ShaderUid() @@ -35,11 +46,6 @@ public: memset(values, 0, sizeof(values)); } - void Write(const char* fmt, ...) {} - const char* GetBuffer() { return NULL; } - void SetBuffer(char* buffer) { } - inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} - bool operator == (const ShaderUid& obj) const { return memcmp(this->values, obj.values, sizeof(values)) == 0; @@ -70,7 +76,7 @@ private: // Needs to be a template for hacks... template -class ShaderCode +class ShaderCode : public ShaderGeneratorInterface { public: ShaderCode() : buf(NULL), write_ptr(NULL) @@ -88,8 +94,6 @@ public: const char* GetBuffer() { return buf; } void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; } - uid_data& GetUidData() { return *(uid_data*)NULL; } - inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} private: const char* buf; @@ -97,16 +101,11 @@ private: }; template -class ShaderConstantProfile +class ShaderConstantProfile : public ShaderGeneratorInterface { public: ShaderConstantProfile(int num_constants) { constant_usage.resize(num_constants); } - void Write(const char* fmt, ...) {} - const char* GetBuffer() { return NULL; } - void SetBuffer(char* buffer) { } - uid_data& GetUidData() { return *(uid_data*)NULL; } - // has room for optimization (if it matters at all...) void NumConstants() { return constant_usage.size(); } From 364a5093d9e36a43de44c0aec735d0ee11e7a3bb Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 23:21:08 +0100 Subject: [PATCH 014/352] ShaderGenCommon: Replace the GenOutput enum by using typeid instead. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 16 ++++---- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 41 ++++++++++--------- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 7 ---- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 15 +++---- 4 files changed, 38 insertions(+), 41 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index 09b0cdc28f..5945bc09ca 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -18,15 +18,17 @@ #ifndef _LIGHTINGSHADERGEN_H_ #define _LIGHTINGSHADERGEN_H_ +#include + #include "ShaderGenCommon.h" #include "NativeVertexFormat.h" #include "XFMemory.h" // T.uid_data needs to have a struct named lighting_uid -template +template void GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) { -#define SetUidField(name, value) if (type == GO_ShaderUid) { object.GetUidData().name = value; }; +#define SetUidField(name, value) if (typeid(T) == typeid(UidType)) { object.GetUidData().name = value; }; const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; if (coloralpha == 1 ) swizzle = "xyz"; @@ -92,7 +94,7 @@ void GenerateLightShader(T& object, int index, int litchan_index, const char* li // materials name is I_MATERIALS in vs and I_PMATERIALS in ps // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps -template +template void GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) @@ -186,7 +188,7 @@ void GenerateLightingShader(T& object, int components, const char* materialsName { if (mask & (1<(object, i, j, lightsName, 3); + GenerateLightShader(object, i, j, lightsName, 3); } } } @@ -196,9 +198,9 @@ void GenerateLightingShader(T& object, int components, const char* materialsName for (int i = 0; i < 8; ++i) { if (!(mask&(1<(object, i, j, lightsName, 1); + GenerateLightShader(object, i, j, lightsName, 1); if (!(mask&(1<(object, i, j+2, lightsName, 2); + GenerateLightShader(object, i, j+2, lightsName, 2); } } else if (color.enablelighting || alpha.enablelighting) @@ -212,7 +214,7 @@ void GenerateLightingShader(T& object, int components, const char* materialsName for (int i = 0; i < 8; ++i) { if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); + GenerateLightShader(object, i, lit_index, lightsName, coloralpha); } } object.Write("%s%d = mat * saturate(lacc);\n", dest, j); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 44023e2000..f22ef94c6d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "LightingShaderGen.h" #include "PixelShaderGen.h" @@ -37,10 +38,10 @@ // output is given by .outreg // tevtemp is set according to swapmodetables and -template static void WriteStage(char *&p, int n, API_TYPE ApiType); -template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); -template static void WriteAlphaTest(T& out, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); -template static void WriteFog(T& out); +template static void WriteStage(char *&p, int n, API_TYPE ApiType); +template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); +template static void WriteAlphaTest(T& out, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); +template static void WriteFog(T& out); static const char *tevKSelTableC[] = // KCSEL { @@ -266,13 +267,13 @@ const char *WriteLocation(API_TYPE ApiType) return result; } -template +template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { // TODO: Can be optimized if using alpha pass -#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; -#define OR_UidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name |= value; }; - if (type == GO_ShaderCode) +#define SetUidField(name, value) if (typeid(T) == typeid(PixelShaderUid)) {out.GetUidData().name = value; }; +#define OR_UidField(name, value) if (typeid(T) == typeid(PixelShaderUid)) {out.GetUidData().name |= value; }; + if (typeid(T) == typeid(PixelShaderCode)) { setlocale(LC_NUMERIC, "C"); // Reset locale for compilation out.SetBuffer(text); @@ -558,7 +559,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u char buffer[32]; sprintf(buffer, "float3 indtex%d", i); - SampleTexture(out, buffer, "tempcoord", "abg", texmap, ApiType); + SampleTexture(out, buffer, "tempcoord", "abg", texmap, ApiType); } } @@ -575,7 +576,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // Uid fields for BuildSwapModeTable are set in WriteStage BuildSwapModeTable(); for (unsigned int i = 0; i < numStages; i++) - WriteStage(out, i, ApiType); // build the equation for this stage + WriteStage(out, i, ApiType); // build the equation for this stage if (numStages) { @@ -604,7 +605,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); SetUidField(Pretest, Pretest); if (Pretest == AlphaTest::UNDETERMINED) - WriteAlphaTest(out, ApiType, dstAlphaMode, per_pixel_depth); + WriteAlphaTest(out, ApiType, dstAlphaMode, per_pixel_depth); // the screen space depth value = far z + (clip z / clip w) * z range @@ -648,7 +649,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } else { - WriteFog(out); + WriteFog(out); out.Write("\tocol0 = prev;\n"); } @@ -716,7 +717,7 @@ static const char *TEVCMPAlphaOPTable[16] = }; -template +template static void WriteStage(T& out, int n, API_TYPE ApiType) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); @@ -865,7 +866,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); - SampleTexture(out, "textemp", "tevcoord", texswap, texmap, ApiType); + SampleTexture(out, "textemp", "tevcoord", texswap, texmap, ApiType); } else out.Write("textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); @@ -1090,7 +1091,7 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("// TEV done\n"); } -template +template void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType) { out.SetConstantsUsed(C_TEXDIMS+texmap,C_TEXDIMS+texmap); @@ -1120,7 +1121,7 @@ static const char *tevAlphaFunclogicTable[] = " == " // xnor }; -template +template static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth) { static const char *alphaRef[2] = @@ -1188,7 +1189,7 @@ static const char *tevFogFuncsTable[] = "\tfog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" //backward exp2 }; -template +template static void WriteFog(T& out) { SetUidField(fog.fsel, bpmem.fog.c_proj_fsel.fsel); @@ -1240,16 +1241,16 @@ static void WriteFog(T& out) void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType, components); } void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType, components); } void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType, components); } diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index d02462360d..8606a4e5b9 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -123,11 +123,4 @@ private: std::vector constant_usage; // TODO: Is vector appropriate here? }; -enum GenOutput -{ - GO_ShaderCode, - GO_ShaderUid, - GO_ShaderConstantProfile, -}; - #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 2ea5ef5d7f..3e2daf55d3 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "NativeVertexFormat.h" @@ -80,13 +81,13 @@ void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) extern const char *WriteRegister(API_TYPE api_type, const char *prefix, const u32 num); extern const char *WriteLocation(API_TYPE api_type); -template +template void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { #undef SetUidField -#define SetUidField(name, value) if (type == GO_ShaderUid) {out.GetUidData().name = value; }; +#define SetUidField(name, value) if (typeid(T) == typeid(VertexShaderUid)) {out.GetUidData().name = value; }; - if (type == GO_ShaderCode) + if (typeid(T) == typeid(VertexShaderCode)) { out.SetBuffer(text); setlocale(LC_NUMERIC, "C"); // Reset locale for compilation @@ -275,7 +276,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) } // TODO: This probably isn't necessary if pixel lighting is enabled. - GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); if (xfregs.numChan.numColorChans < 2) { @@ -522,16 +523,16 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) /// if (text[sizeof(text) - 1] != 0x7C) /// PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); - if (type == GO_ShaderCode) + if (typeid(T) == typeid(VertexShaderCode)) setlocale(LC_NUMERIC, ""); // restore locale } void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) { - GenerateVertexShader(object, components, api_type); + GenerateVertexShader(object, components, api_type); } void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) { - GenerateVertexShader(object, components, api_type); + GenerateVertexShader(object, components, api_type); } From 24ab51f9f618cea9260f5b432317f5ac95a538d6 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 23:35:14 +0100 Subject: [PATCH 015/352] Fix Windows build, try 1. --- .../Plugin_VideoDX11/Src/PixelShaderCache.cpp | 23 +++++++------- .../Plugin_VideoDX11/Src/PixelShaderCache.h | 7 ++--- .../Src/VertexShaderCache.cpp | 24 +++++++-------- .../Plugin_VideoDX11/Src/VertexShaderCache.h | 7 ++--- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 30 +++++++++---------- .../Plugin_VideoDX9/Src/PixelShaderCache.h | 7 ++--- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 25 ++++++++-------- .../Plugin_VideoDX9/Src/VertexShaderCache.h | 7 ++--- 8 files changed, 60 insertions(+), 70 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 56f3719057..f818c5df87 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -41,9 +41,9 @@ namespace DX11 PixelShaderCache::PSCache PixelShaderCache::PixelShaders; const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry; -PIXELSHADERUID PixelShaderCache::last_uid; +PixelShaderUid PixelShaderCache::last_uid; -LinearDiskCache g_ps_disk_cache; +LinearDiskCache g_ps_disk_cache; ID3D11PixelShader* s_ColorMatrixProgram[2] = {NULL}; ID3D11PixelShader* s_ColorCopyProgram[2] = {NULL}; @@ -363,10 +363,10 @@ ID3D11Buffer* &PixelShaderCache::GetConstantBuffer() } // this class will load the precompiled shaders into our cache -class PixelShaderCacheInserter : public LinearDiskCacheReader +class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size) + void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) { PixelShaderCache::InsertByteCode(key, value, value_size); } @@ -461,8 +461,8 @@ void PixelShaderCache::Shutdown() bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { - PIXELSHADERUID uid; - GetPixelShaderId(&uid, dstAlphaMode, components); + PixelShaderUid uid; + GetPixelShaderUid(uid, dstAlphaMode, components); // Check if the shader is already set if (last_entry) @@ -470,7 +470,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); - ValidatePixelShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, dstAlphaMode, components); return (last_entry->shader != NULL); } } @@ -486,15 +485,15 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); - ValidatePixelShaderIDs(API_D3D11, entry.safe_uid, entry.code, dstAlphaMode, components); return (entry.shader != NULL); } // Need to compile a new shader - const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components); + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D11, components); D3DBlob* pbytecode; - if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode)) + if (!D3D::CompilePixelShader(code.GetBuffer(), (unsigned int)strlen(code.GetBuffer()), &pbytecode)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; @@ -508,7 +507,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (g_ActiveConfig.bEnableShaderDebugging && success) { - PixelShaders[uid].code = code; + PixelShaders[uid].code = code.GetBuffer(); GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components); } @@ -516,7 +515,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) return success; } -bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen) +bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const void* bytecode, unsigned int bytecodelen) { ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); if (shader == NULL) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h index 874a47e4c1..f08fa43142 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h @@ -35,7 +35,7 @@ public: static void Clear(); static void Shutdown(); static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader - static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen); + static bool InsertByteCode(const PixelShaderUid &uid, const void* bytecode, unsigned int bytecodelen); static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; } static ID3D11Buffer* &GetConstantBuffer(); @@ -54,18 +54,17 @@ private: { ID3D11PixelShader* shader; - PIXELSHADERUIDSAFE safe_uid; std::string code; PSCacheEntry() : shader(NULL) {} void Destroy() { SAFE_RELEASE(shader); } }; - typedef std::map PSCache; + typedef std::map PSCache; static PSCache PixelShaders; static const PSCacheEntry* last_entry; - static PIXELSHADERUID last_uid; + static PixelShaderUid last_uid; }; } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 6fdc815554..4ba720528e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -37,14 +37,14 @@ namespace DX11 { VertexShaderCache::VSCache VertexShaderCache::vshaders; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; -VERTEXSHADERUID VertexShaderCache::last_uid; +VertexShaderUid VertexShaderCache::last_uid; static ID3D11VertexShader* SimpleVertexShader = NULL; static ID3D11VertexShader* ClearVertexShader = NULL; static ID3D11InputLayout* SimpleLayout = NULL; static ID3D11InputLayout* ClearLayout = NULL; -LinearDiskCache g_vs_disk_cache; +LinearDiskCache g_vs_disk_cache; ID3D11VertexShader* VertexShaderCache::GetSimpleVertexShader() { return SimpleVertexShader; } ID3D11VertexShader* VertexShaderCache::GetClearVertexShader() { return ClearVertexShader; } @@ -68,10 +68,10 @@ ID3D11Buffer* &VertexShaderCache::GetConstantBuffer() } // this class will load the precompiled shaders into our cache -class VertexShaderCacheInserter : public LinearDiskCacheReader +class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size) + void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) { D3DBlob* blob = new D3DBlob(value_size, value); VertexShaderCache::InsertByteCode(key, blob); @@ -208,14 +208,13 @@ void VertexShaderCache::Shutdown() bool VertexShaderCache::SetShader(u32 components) { - VERTEXSHADERUID uid; - GetVertexShaderId(&uid, components); + VertexShaderUid uid; + GetVertexShaderUid(uid, components, API_D3D11); if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, components); return (last_entry->shader != NULL); } } @@ -229,14 +228,14 @@ bool VertexShaderCache::SetShader(u32 components) last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_D3D11, entry.safe_uid, entry.code, components); return (entry.shader != NULL); } - const char *code = GenerateVertexShaderCode(components, API_D3D11); + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D11); D3DBlob* pbytecode = NULL; - D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode); + D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &pbytecode); if (pbytecode == NULL) { @@ -250,15 +249,14 @@ bool VertexShaderCache::SetShader(u32 components) if (g_ActiveConfig.bEnableShaderDebugging && success) { - vshaders[uid].code = code; - GetSafeVertexShaderId(&vshaders[uid].safe_uid, components); + vshaders[uid].code = code.GetBuffer(); } GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return success; } -bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob) +bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, D3DBlob* bcodeblob) { ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob); if (shader == NULL) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h index 6d9537606a..0c1dba790f 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h @@ -44,7 +44,7 @@ public: static ID3D11InputLayout* GetSimpleInputLayout(); static ID3D11InputLayout* GetClearInputLayout(); - static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob); + static bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, D3DBlob* bcodeblob); private: struct VSCacheEntry @@ -52,7 +52,6 @@ private: ID3D11VertexShader* shader; D3DBlob* bytecode; // needed to initialize the input layout - VERTEXSHADERUIDSAFE safe_uid; std::string code; VSCacheEntry() : shader(NULL), bytecode(NULL) {} @@ -68,11 +67,11 @@ private: SAFE_RELEASE(bytecode); } }; - typedef std::map VSCache; + typedef std::map VSCache; static VSCache vshaders; static const VSCacheEntry* last_entry; - static VERTEXSHADERUID last_uid; + static VertexShaderUid last_uid; }; } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index f66d096ab6..76beaa2c9f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -43,9 +43,9 @@ namespace DX9 PixelShaderCache::PSCache PixelShaderCache::PixelShaders; const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry; -PIXELSHADERUID PixelShaderCache::last_uid; +PixelShaderUid PixelShaderCache::last_uid; -static LinearDiskCache g_ps_disk_cache; +static LinearDiskCache g_ps_disk_cache; static std::set unique_shaders; #define MAX_SSAA_SHADERS 3 @@ -67,10 +67,10 @@ static LPDIRECT3DPIXELSHADER9 s_ClearProgram = NULL; static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL; static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL; -class PixelShaderCacheInserter : public LinearDiskCacheReader +class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size) + void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) { PixelShaderCache::InsertByteCode(key, value, value_size, false); } @@ -333,8 +333,8 @@ void PixelShaderCache::Shutdown() 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; - GetPixelShaderId(&uid, dstAlphaMode, components); + PixelShaderUid uid; + GetPixelShaderUid(uid, dstAlphaMode, components); // Check if the shader is already set if (last_entry) @@ -342,7 +342,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - ValidatePixelShaderIDs(api, last_entry->safe_uid, last_entry->code, dstAlphaMode, components); return last_entry->shader != NULL; } } @@ -359,34 +358,34 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (entry.shader) D3D::SetPixelShader(entry.shader); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - ValidatePixelShaderIDs(api, entry.safe_uid, entry.code, dstAlphaMode, components); return (entry.shader != NULL); } // Need to compile a new shader - const char *code = GeneratePixelShaderCode(dstAlphaMode, api, components); + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, api, components); if (g_ActiveConfig.bEnableShaderDebugging) { - u32 code_hash = HashAdler32((const u8 *)code, strlen(code)); + 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 && code) { + 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); + SaveData(szTemp, code.GetBuffer()); } #endif u8 *bytecode = 0; int bytecodelen = 0; - if (!D3D::CompilePixelShader(code, (int)strlen(code), &bytecode, &bytecodelen)) { + if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; } @@ -400,15 +399,14 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (g_ActiveConfig.bEnableShaderDebugging && success) { - PixelShaders[uid].code = code; - GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components); + PixelShaders[uid].code = code.GetBuffer(); } GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); return success; } -bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) +bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index c771984d36..96d2c29cd9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -41,7 +41,6 @@ private: LPDIRECT3DPIXELSHADER9 shader; bool owns_shader; - PIXELSHADERUIDSAFE safe_uid; std::string code; PSCacheEntry() : shader(NULL), owns_shader(true) {} @@ -53,18 +52,18 @@ private: } }; - typedef std::map PSCache; + typedef std::map PSCache; static PSCache PixelShaders; static const PSCacheEntry *last_entry; - static PIXELSHADERUID last_uid; + static PixelShaderUid last_uid; static void Clear(); public: static void Init(); static void Shutdown(); static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 componets); - static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); + static bool InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate); static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(int SSAAMode, bool depthConversion); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index e392cf3de0..93685335ae 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -38,14 +38,14 @@ namespace DX9 VertexShaderCache::VSCache VertexShaderCache::vshaders; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; -VERTEXSHADERUID VertexShaderCache::last_uid; +VertexShaderUid VertexShaderCache::last_uid; #define MAX_SSAA_SHADERS 3 static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader[MAX_SSAA_SHADERS]; static LPDIRECT3DVERTEXSHADER9 ClearVertexShader; -LinearDiskCache g_vs_disk_cache; +LinearDiskCache g_vs_disk_cache; LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level) { @@ -58,10 +58,10 @@ LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() } // this class will load the precompiled shaders into our cache -class VertexShaderCacheInserter : public LinearDiskCacheReader +class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size) + void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) { VertexShaderCache::InsertByteCode(key, value, value_size, false); } @@ -188,14 +188,13 @@ void VertexShaderCache::Shutdown() bool VertexShaderCache::SetShader(u32 components) { - VERTEXSHADERUID uid; - GetVertexShaderId(&uid, components); + VertexShaderUid uid; + GetVertexShaderUid(uid, components); if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_D3D9, last_entry->safe_uid, last_entry->code, components); return (last_entry->shader != NULL); } } @@ -210,14 +209,15 @@ bool VertexShaderCache::SetShader(u32 components) if (entry.shader) D3D::SetVertexShader(entry.shader); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - ValidateVertexShaderIDs(API_D3D9, entry.safe_uid, entry.code, components); return (entry.shader != NULL); } - const char *code = GenerateVertexShaderCode(components, API_D3D9); + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D9); + u8 *bytecode; int bytecodelen; - if (!D3D::CompileVertexShader(code, (int)strlen(code), &bytecode, &bytecodelen)) + if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; @@ -227,15 +227,14 @@ bool VertexShaderCache::SetShader(u32 components) bool success = InsertByteCode(uid, bytecode, bytecodelen, true); if (g_ActiveConfig.bEnableShaderDebugging && success) { - vshaders[uid].code = code; - GetSafeVertexShaderId(&vshaders[uid].safe_uid, components); + 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) { +bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); // Make an entry in the table diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h index c9c447e35b..9b6ff0d863 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h @@ -36,7 +36,6 @@ private: LPDIRECT3DVERTEXSHADER9 shader; std::string code; - VERTEXSHADERUIDSAFE safe_uid; VSCacheEntry() : shader(NULL) {} void Destroy() @@ -47,11 +46,11 @@ private: } }; - typedef std::map VSCache; + typedef std::map VSCache; static VSCache vshaders; static const VSCacheEntry *last_entry; - static VERTEXSHADERUID last_uid; + static VertexShaderUid last_uid; static void Clear(); public: @@ -60,7 +59,7 @@ public: static bool SetShader(u32 components); static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(int level); static LPDIRECT3DVERTEXSHADER9 GetClearVertexShader(); - static bool InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); + static bool InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate); static std::string GetCurrentShaderCode(); }; From 98362e5934d7c3dadbc8a4f5adc6dd523e535447 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 26 Mar 2013 23:44:41 +0100 Subject: [PATCH 016/352] Fix Windows build, try 2. --- Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp | 3 +-- Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index f818c5df87..7237603eab 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -462,7 +462,7 @@ void PixelShaderCache::Shutdown() bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, components); + GetPixelShaderUid(uid, dstAlphaMode, API_D3D11, components); // Check if the shader is already set if (last_entry) @@ -508,7 +508,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) if (g_ActiveConfig.bEnableShaderDebugging && success) { PixelShaders[uid].code = code.GetBuffer(); - GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components); } GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index da8c98e19e..36e2ed2a68 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -248,7 +248,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(); + PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 76beaa2c9f..7061ea8657 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -334,7 +334,7 @@ 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, components); + GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); // Check if the shader is already set if (last_entry) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 543a1b9ddc..d2fcd6164a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -359,7 +359,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(); + PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); u32 stride = g_nativeVertexFmt->GetVertexStride(); if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components)) { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 93685335ae..05e034cedf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -189,7 +189,7 @@ void VertexShaderCache::Shutdown() bool VertexShaderCache::SetShader(u32 components) { VertexShaderUid uid; - GetVertexShaderUid(uid, components); + GetVertexShaderUid(uid, components, API_D3D9); if (last_entry) { if (uid == last_uid) From f8d2936840482b9132a751466c3c056c5988fa9a Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 27 Mar 2013 00:13:23 +0100 Subject: [PATCH 017/352] Fix Windows build, try 3. --- .../Plugin_VideoDX11/Src/LineGeometryShader.cpp | 13 +++++++------ .../Plugin_VideoDX11/Src/PointGeometryShader.cpp | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index 3afd38a2e1..74c58e8d17 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -182,11 +182,12 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, if (shaderIt == m_shaders.end()) { // Generate new shader. Warning: not thread-safe. - static char code[16384]; - char* p = code; - p = GenerateVSOutputStruct(p, components, API_D3D11); - p += sprintf(p, "\n%s", LINE_GS_COMMON); - + static char buffer[16384]; + ShaderCode code; + code.SetBuffer(buffer); + GenerateVSOutputStruct(code, components, API_D3D11); + code.Write("\n%s", LINE_GS_COMMON); + std::stringstream numTexCoordsStream; numTexCoordsStream << xfregs.numTexGen.numTexGens; @@ -198,7 +199,7 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, { "NUM_TEXCOORDS", numTexCoordsStr.c_str() }, { NULL, NULL } }; - ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); + ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), unsigned int(strlen(code.GetBuffer())), macros); if (!newShader) { WARN_LOG(VIDEO, "Line geometry shader for components 0x%.08X failed to compile", components); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index ad23786610..e6cea19ce9 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -176,10 +176,11 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, if (shaderIt == m_shaders.end()) { // Generate new shader. Warning: not thread-safe. - static char code[16384]; - char* p = code; - p = GenerateVSOutputStruct(p, components, API_D3D11); - p += sprintf(p, "\n%s", POINT_GS_COMMON); + static char buffer[16384]; + ShaderCode code; + code.SetBuffer(buffer); + GenerateVSOutputStruct(code, components, API_D3D11); + code.Write("\n%s", POINT_GS_COMMON); std::stringstream numTexCoordsStream; numTexCoordsStream << xfregs.numTexGen.numTexGens; @@ -192,7 +193,7 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, { "NUM_TEXCOORDS", numTexCoordsStr.c_str() }, { NULL, NULL } }; - ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); + ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), unsigned int(strlen(code.GetBuffer())), macros); if (!newShader) { WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components); From 11fae2e1cbce03333bdceb613eb81953adae930b Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 27 Mar 2013 00:17:46 +0100 Subject: [PATCH 018/352] Fix Windows build, try 4. --- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 5 +++++ Source/Core/VideoCommon/Src/VertexShaderGen.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 3e2daf55d3..88fe24f627 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -536,3 +536,8 @@ void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE { GenerateVertexShader(object, components, api_type); } + +void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type) +{ + GenerateVSOutputStruct >(object, components, api_type); +} diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index 3167229fe3..b6b176c806 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -114,6 +114,6 @@ typedef ShaderCode VertexShaderCode; void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type); - +void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type); #endif // GCOGL_VERTEXSHADER_H From 45c70be83f2263c22377ac414809d85bb21e25cd Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 27 Mar 2013 00:20:25 +0100 Subject: [PATCH 019/352] Fix Windows build, try 5. --- Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp | 2 +- Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index 74c58e8d17..f22ebef0df 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -185,7 +185,7 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); - GenerateVSOutputStruct(code, components, API_D3D11); + GenerateVSOutputStructForGS(code, components, API_D3D11); code.Write("\n%s", LINE_GS_COMMON); std::stringstream numTexCoordsStream; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index e6cea19ce9..5976c09ab9 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -179,7 +179,7 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); - GenerateVSOutputStruct(code, components, API_D3D11); + GenerateVSOutputStructForGS(code, components, API_D3D11); code.Write("\n%s", POINT_GS_COMMON); std::stringstream numTexCoordsStream; From a171525df6f0b0b43ebfc5330d9f21cfd6af298e Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 27 Mar 2013 01:33:27 +0100 Subject: [PATCH 020/352] Fix Windows crash. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index f22ef94c6d..d20e6ca755 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -314,7 +314,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u { // Declare samplers for (int i = 0; i < 8; ++i) - out.Write("%s samp%d %s;\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", (i==0)?"":",", i, WriteRegister(ApiType, "s", i)); + out.Write("%s samp%d %s;\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", i, WriteRegister(ApiType, "s", i)); if (ApiType == API_D3D11) { From f2a8fbb314aabb986e9f5711278272649a78b098 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 14:51:54 +0100 Subject: [PATCH 021/352] PixelShaderGen: Slightly reduce the number of redundant shader compilations. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 12 +++++++----- Source/Core/VideoCommon/Src/PixelShaderGen.h | 5 ++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index d20e6ca755..6ee5a72994 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -289,7 +289,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", numStages, numTexgen/*, bpmem.genMode.numindstages*/); - SetUidField(components, components); +// SetUidField(components, components); // TODO: Enable once per pixel lighting is implemented again SetUidField(dstAlphaMode, dstAlphaMode); SetUidField(genMode.numindstages, bpmem.genMode.numindstages); @@ -620,8 +620,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // Note: depth textures are disabled if early depth test is enabled SetUidField(ztex.op, bpmem.ztex2.op); - SetUidField(early_z, bpmem.zcontrol.early_ztest); // TODO: Should be per_pixel_depth instead... - SetUidField(ztestenable, bpmem.zmode.testenable); // TODO: Should be fog instead... + SetUidField(per_pixel_depth, per_pixel_depth); + SetUidField(fog.fsel, bpmem.fog.c_proj_fsel.fsel); // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel; @@ -632,12 +632,13 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : ""); - // scale to make result from frac correct + // U24 overflow emulation out.Write("zCoord = zCoord * (16777215.0f/16777216.0f);\n"); out.Write("zCoord = frac(zCoord);\n"); out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n"); + // Note: depth texture output is only written to depth buffer if late depth test is used - // TODO: Should this be outside the ztex if-block? + // final depth value is used for fog calculation, though if (per_pixel_depth) out.Write("depth = zCoord;\n"); } @@ -1167,6 +1168,7 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, // when the alpha test fail. This is not a correct implementation because // even if the depth test fails the fragment could be alpha blended, but // we don't have a choice. + SetUidField(alpha_test.use_zcomploc_hack, bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable); if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { out.Write("\t\tdiscard;\n"); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 4dc3e6c1e0..4f9cba0c37 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -163,6 +163,7 @@ struct pixel_shader_uid_data u32 comp1 : 3; u32 logic : 2; // TODO: ref??? + u32 use_zcomploc_hack : 1; } alpha_test; union { @@ -182,9 +183,7 @@ struct pixel_shader_uid_data u32 hex : 2; } ztex; - u32 early_z : 1; - u32 ztestenable : 1; - + u32 per_pixel_depth : 1; u32 bHasIndStage : 16; u32 xfregs_numTexGen_numTexGens : 4; From 41c4108ce66d73b81c254165f18a23f72aabf09a Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 14:54:44 +0100 Subject: [PATCH 022/352] OpenGL: Reimplement shader uid debugging. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 5 ++ .../Src/ProgramShaderCache.cpp | 64 ++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 8606a4e5b9..d41a9c6c46 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -51,6 +51,11 @@ public: return memcmp(this->values, obj.values, sizeof(values)) == 0; } + bool operator != (const ShaderUid& obj) const + { + return memcmp(this->values, obj.values, sizeof(values)) != 0; + } + // TODO: Store last frame used and order by that? makes much more sense anyway... bool operator < (const ShaderUid& obj) const { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 53b0210919..6ce4e1e04c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -23,6 +23,9 @@ #include "ImageWrite.h" #include "Render.h" +#include +#include + namespace OGL { @@ -353,14 +356,71 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code ) return result; } +template UidT GetPartialUid(const SHADERUID& uid); +template<> PixelShaderUid GetPartialUid(const SHADERUID& uid) { return uid.puid; } +template<> VertexShaderUid GetPartialUid(const SHADERUID& uid) { return uid.vuid; } + +template const std::string& GetShaderCode(const SHADER& shader); +template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strpprog; } +template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strvprog; } + +template +void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_code, const UidT& new_uid) +{ + static std::map s_shaders; + static std::vector s_uids; + + bool uid_is_indexed = std::find(s_uids.begin(), s_uids.end(), new_uid) != s_uids.end(); + if (!uid_is_indexed) + { + s_uids.push_back(new_uid); + s_shaders[new_uid] = new_code.GetBuffer(); + } + else + { + // uid is already in the index => check if there's a shader with the same uid but different code + auto& old_code = s_shaders[new_uid]; + if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0) + { + static int num_failures = 0; + + char szTemp[MAX_PATH]; + sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), + std::is_same::value ? "p" : std::is_same::value ? "v" : "o", + ++num_failures); + + // TODO: Should also dump uids + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); + file << "Old shader code:\n" << old_code; + file << "\n\nNew shader code:\n" << new_code.GetBuffer(); + file.close(); + + // TODO: Make this more idiot-proof + ERROR_LOG(VIDEO, "%s shader uid mismatch!", + std::is_same::value ? "Pixel" : std::is_same::value ? "Vertex" : "Other"); + } + } +} -void ProgramShaderCache::GetShaderId ( SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components ) +void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components) { GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components); GetVertexShaderUid(uid->vuid, components, API_OPENGL); -} + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode pcode; + VertexShaderCode vcode; + + GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); + GenerateVertexShaderCode(vcode, components, API_OPENGL); + + CheckForUidMismatch(pshaders, pcode, uid->puid); + CheckForUidMismatch(pshaders, vcode, uid->vuid); + } +} ProgramShaderCache::PCacheEntry ProgramShaderCache::GetShaderProgram(void) From 4e9c3db545b2ff9dc4469f3440dc6caffd3f1832 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 15:02:48 +0100 Subject: [PATCH 023/352] OSX build fix. --- Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 6ce4e1e04c..79bcc1abbd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -24,7 +24,7 @@ #include "Render.h" #include -#include +#include namespace OGL { @@ -386,7 +386,7 @@ void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_cod char szTemp[MAX_PATH]; sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), - std::is_same::value ? "p" : std::is_same::value ? "v" : "o", + (typeid(UidT) == typeid(PixelShaderUid)) ? "p" : (typeid(UidT) == typeid(VertexShaderUid)) ? "v" : "o", ++num_failures); // TODO: Should also dump uids @@ -398,7 +398,7 @@ void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_cod // TODO: Make this more idiot-proof ERROR_LOG(VIDEO, "%s shader uid mismatch!", - std::is_same::value ? "Pixel" : std::is_same::value ? "Vertex" : "Other"); + (typeid(UidT) == typeid(PixelShaderUid)) ? "Pixel" : (typeid(UidT) == typeid(VertexShaderUid)) ? "Vertex" : "Other"); } } } From b2517c0308e992c7e3c13e0fe17140e422ae770d Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 15:08:00 +0100 Subject: [PATCH 024/352] More build fixes. --- Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h index 615daa685d..b7b757172a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h @@ -90,6 +90,8 @@ public: } }; + typedef std::map PCache; + static PCacheEntry GetShaderProgram(void); static GLuint GetCurrentProgram(void); static SHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); @@ -113,8 +115,6 @@ private: void Read(const SHADERUID &key, const u8 *value, u32 value_size); }; - typedef std::map PCache; - static PCache pshaders; static PCacheEntry* last_entry; static SHADERUID last_uid; From 3c02f227db1e02f233f3aac8dc42476bd0b17f7a Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 20:33:28 +0100 Subject: [PATCH 025/352] PixelShaderManager: Disable constant cache (won't work in the non-UBO path of the opengl backend). ShaderGen: Replace typeid usage with more general code. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 2 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 15 ++++++------ .../VideoCommon/Src/PixelShaderManager.cpp | 24 +++++++++---------- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 5 ++-- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 12 ++++------ .../Src/ProgramShaderCache.cpp | 12 +++++----- 6 files changed, 33 insertions(+), 37 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index 5945bc09ca..a58809942a 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -28,7 +28,7 @@ template void GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) { -#define SetUidField(name, value) if (typeid(T) == typeid(UidType)) { object.GetUidData().name = value; }; +#define SetUidField(name, value) if (&object.GetUidData() != NULL) { object.GetUidData().name = value; }; const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; if (coloralpha == 1 ) swizzle = "xyz"; diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 6ee5a72994..49b77274a8 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "LightingShaderGen.h" #include "PixelShaderGen.h" @@ -271,13 +270,12 @@ template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { // TODO: Can be optimized if using alpha pass -#define SetUidField(name, value) if (typeid(T) == typeid(PixelShaderUid)) {out.GetUidData().name = value; }; -#define OR_UidField(name, value) if (typeid(T) == typeid(PixelShaderUid)) {out.GetUidData().name |= value; }; - if (typeid(T) == typeid(PixelShaderCode)) - { +#define SetUidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name = value; }; +#define OR_UidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name |= value; }; + out.SetBuffer(text); + if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, "C"); // Reset locale for compilation - out.SetBuffer(text); - } + /// text[sizeof(text) - 1] = 0x7C; // canary unsigned int numStages = bpmem.genMode.numtevstages + 1; @@ -669,7 +667,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u /// if (text[sizeof(text) - 1] != 0x7C) /// PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); - setlocale(LC_NUMERIC, ""); // restore locale + if (out.GetBuffer() != NULL) + setlocale(LC_NUMERIC, ""); // restore locale } diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 273d82ea7c..1aceafa17d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -46,9 +46,9 @@ static float s_constant_cache[C_PENVCONST_END*4]; inline void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - if (s_constant_cache[const_number*4] == f1 && s_constant_cache[const_number*4+1] == f2 && - s_constant_cache[const_number*4+2] == f3 && s_constant_cache[const_number*4+3] == f4) - return; +// if (s_constant_cache[const_number*4] == f1 && s_constant_cache[const_number*4+1] == f2 && +// s_constant_cache[const_number*4+2] == f3 && s_constant_cache[const_number*4+3] == f4) +// return; g_renderer->SetPSConstant4f(const_number, f1, f2, f3, f4); s_constant_cache[const_number*4] = f1; @@ -59,9 +59,9 @@ inline void SetPSConstant4f(unsigned int const_number, float f1, float f2, float inline void SetPSConstant4fv(unsigned int const_number, const float *f) { - if (s_constant_cache[const_number*4] == f[0] && s_constant_cache[const_number*4+1] == f[1] && - s_constant_cache[const_number*4+2] == f[2] && s_constant_cache[const_number*4+3] == f[3]) - return; +// if (s_constant_cache[const_number*4] == f[0] && s_constant_cache[const_number*4+1] == f[1] && +// s_constant_cache[const_number*4+2] == f[2] && s_constant_cache[const_number*4+3] == f[3]) +// return; g_renderer->SetPSConstant4fv(const_number, f); s_constant_cache[const_number*4] = f[0]; @@ -72,11 +72,11 @@ inline void SetPSConstant4fv(unsigned int const_number, const float *f) inline void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { - for (unsigned int i = 0; i < 4*count; ++i) - if (s_constant_cache[const_number*4+i] != f[i]) - break; - else if (i == 4*count-1) - return; +// for (unsigned int i = 0; i < 4*count; ++i) +// if (s_constant_cache[const_number*4+i] != f[i]) +// break; +// else if (i == 4*count-1) +// return; g_renderer->SetMultiPSConstant4fv(const_number, count, f); for (unsigned int i = 0; i < 4*count; ++i) @@ -149,7 +149,7 @@ void PixelShaderManager::SetConstants(u32 components) { for (int i = 0; i < 8; ++i) { - if (s_nTexDimsChanged & (1< instead }; template @@ -122,7 +122,8 @@ public: inline bool ConstantIsUsed(unsigned int index) { - return constant_usage[index]; + return true; +// return constant_usage[index]; } private: std::vector constant_usage; // TODO: Is vector appropriate here? diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 88fe24f627..869b84a4ed 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -17,7 +17,6 @@ #include #include -#include #include "NativeVertexFormat.h" @@ -85,14 +84,11 @@ template void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { #undef SetUidField -#define SetUidField(name, value) if (typeid(T) == typeid(VertexShaderUid)) {out.GetUidData().name = value; }; +#define SetUidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name = value; }; - if (typeid(T) == typeid(VertexShaderCode)) - { - out.SetBuffer(text); + out.SetBuffer(text); + if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, "C"); // Reset locale for compilation - } - // text[sizeof(text) - 1] = 0x7C; // canary @@ -523,7 +519,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) /// if (text[sizeof(text) - 1] != 0x7C) /// PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); - if (typeid(T) == typeid(VertexShaderCode)) + if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, ""); // restore locale } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 79bcc1abbd..188145ebcf 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -201,9 +201,9 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen return &last_entry->shader; } } - + last_uid = uid; - + // Check if shader is already in cache PCache::iterator iter = pshaders.find(uid); if (iter != pshaders.end()) @@ -215,17 +215,17 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen last_entry->shader.Bind(); return &last_entry->shader; } - + // Make an entry in the table PCacheEntry& newentry = pshaders[uid]; last_entry = &newentry; newentry.in_cache = 0; - + VertexShaderCode vcode; PixelShaderCode pcode; GenerateVertexShaderCode(vcode, components, API_OPENGL); GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); - + if (g_ActiveConfig.bEnableShaderDebugging) { newentry.shader.strvprog = vcode.GetBuffer(); @@ -260,7 +260,7 @@ bool ProgramShaderCache::CompileShader ( SHADER& shader, const char* vcode, cons { GLuint vsid = CompileSingleShader(GL_VERTEX_SHADER, vcode); GLuint psid = CompileSingleShader(GL_FRAGMENT_SHADER, pcode); - + if(!vsid || !psid) { glDeleteShader(vsid); From 9eccd56ef08d1fd2d8a1e3b1d82d0c6f70347db2 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 20:59:03 +0100 Subject: [PATCH 026/352] PixelShaderGen: Some cleanups. --- Source/Core/VideoCommon/Src/BPMemory.h | 5 ++ .../Core/VideoCommon/Src/PixelShaderGen.cpp | 47 ++++++++----------- .../VideoCommon/Src/PixelShaderManager.cpp | 1 + 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index 1a29439b36..5154e2f5b0 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -157,6 +157,11 @@ #define TEVALPHAARG_KONST 6 #define TEVALPHAARG_ZERO 7 +#define GX_TEVPREV 0 +#define GX_TEVREG0 1 +#define GX_TEVREG1 2 +#define GX_TEVREG2 3 + #define ALPHACMP_NEVER 0 #define ALPHACMP_LESS 1 #define ALPHACMP_EQUAL 2 diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 49b77274a8..982f139fea 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -269,7 +269,9 @@ const char *WriteLocation(API_TYPE ApiType) template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { + // TODO: Where does this TODO belong again...? // TODO: Can be optimized if using alpha pass + #define SetUidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name = value; }; #define OR_UidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name |= value; }; out.SetBuffer(text); @@ -915,7 +917,6 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || cc.c == TEVCOLORARG_C0 || cc.c == TEVCOLORARG_A0 || ac.a == TEVALPHAARG_A0 || ac.b == TEVALPHAARG_A0 || ac.c == TEVALPHAARG_A0) { - // TODO: WTF? out.SetConstantsUsed(C_COLORS+1,C_COLORS+1); if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl) { @@ -971,26 +972,19 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) RegisterStates[cc.dest].ColorNeedOverflowControl = (cc.clamp == 0); RegisterStates[cc.dest].AuxStored = false; -/* if (cc.d == TEVCOLORARG_C0 || cc.d == TEVCOLORARG_A0 || ac.d == TEVALPHAARG_A0) - { + if (cc.d == TEVCOLORARG_C0 || cc.d == TEVCOLORARG_A0 || ac.d == TEVALPHAARG_A0) out.SetConstantsUsed(C_COLORS+1,C_COLORS+1); - // TODO: 11 bit signed overflow.. - } - if (cc.d == TEVCOLORARG_C1 || cc.d == TEVCOLORARG_A1 || ac.d == TEVALPHAARG_A1) - { - out.SetConstantsUsed(C_COLORS+2,C_COLORS+2); - // TODO: 11 bit signed overflow.. - } - if (cc.d == TEVCOLORARG_C2 || cc.d == TEVCOLORARG_A2 || ac.d == TEVALPHAARG_A2) - { - out.SetConstantsUsed(C_COLORS+3,C_COLORS+3); - // TODO: 11 bit signed overflow.. - }*/ - // TODO: Are there enums for this? - if (cc.dest >= 1 && cc.dest <= 3) + if (cc.d == TEVCOLORARG_C1 || cc.d == TEVCOLORARG_A1 || ac.d == TEVALPHAARG_A1) + out.SetConstantsUsed(C_COLORS+2,C_COLORS+2); + + if (cc.d == TEVCOLORARG_C2 || cc.d == TEVCOLORARG_A2 || ac.d == TEVALPHAARG_A2) + out.SetConstantsUsed(C_COLORS+3,C_COLORS+3); + + if (cc.dest >= GX_TEVREG0 && cc.dest <= GX_TEVREG2) out.SetConstantsUsed(C_COLORS+cc.dest, C_COLORS+cc.dest); - if (ac.dest >= 1 && ac.dest <= 3) + + if (ac.dest >= GX_TEVREG0 && ac.dest <= GX_TEVREG2) out.SetConstantsUsed(C_COLORS+ac.dest, C_COLORS+ac.dest); out.Write("// color combine\n"); @@ -1103,14 +1097,14 @@ void SampleTexture(T& out, const char *destination, const char *texcoords, const static const char *tevAlphaFuncsTable[] = { - "(false)", //ALPHACMP_NEVER 0, TODO: Not safe? - "(prev.a <= %s - (0.25f/255.0f))", //ALPHACMP_LESS 1 - "(abs( prev.a - %s ) < (0.5f/255.0f))", //ALPHACMP_EQUAL 2 - "(prev.a < %s + (0.25f/255.0f))", //ALPHACMP_LEQUAL 3 - "(prev.a >= %s + (0.25f/255.0f))", //ALPHACMP_GREATER 4 - "(abs( prev.a - %s ) >= (0.5f/255.0f))", //ALPHACMP_NEQUAL 5 - "(prev.a > %s - (0.25f/255.0f))", //ALPHACMP_GEQUAL 6 - "(true)" //ALPHACMP_ALWAYS 7 + "(false)", // NEVER + "(prev.a <= %s - (0.25f/255.0f))", // LESS + "(abs( prev.a - %s ) < (0.5f/255.0f))", // EQUAL + "(prev.a < %s + (0.25f/255.0f))", // LEQUAL + "(prev.a >= %s + (0.25f/255.0f))", // GREATER + "(abs( prev.a - %s ) >= (0.5f/255.0f))", // NEQUAL + "(prev.a > %s - (0.25f/255.0f))", // GEQUAL + "(true)" // ALWAYS }; static const char *tevAlphaFunclogicTable[] = @@ -1132,7 +1126,6 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, out.SetConstantsUsed(C_ALPHA, C_ALPHA); - // using discard then return works the same in cg and dx9 but not in dx11 out.Write("\tif(!( "); diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 1aceafa17d..f63a1e59c6 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -419,6 +419,7 @@ void PixelShaderManager::SetPSTextureDims(int texid) // This one is high in profiles (0.5%). // TODO: Move conversion out, only store the raw color value // and update it when the shader constant is set, only. +// TODO: Conversion should be checked in the context of tev_fixes.. void PixelShaderManager::SetColorChanged(int type, int num, bool high) { float *pf = &lastRGBAfull[type][num][0]; From e31c2aa6013d6a95358251610c15820a34e65a35 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 21:53:57 +0100 Subject: [PATCH 027/352] ShaderGen: Cleanup uid data writing. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 50 +++---- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 141 +++++++++--------- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 38 ++--- 3 files changed, 116 insertions(+), 113 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index a58809942a..e8b30d86a8 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -24,18 +24,17 @@ #include "NativeVertexFormat.h" #include "XFMemory.h" -// T.uid_data needs to have a struct named lighting_uid -template -void GenerateLightShader(T& object, int index, int litchan_index, const char* lightsName, int coloralpha) +// uid_data needs to have a struct named lighting_uid +template +void GenerateLightShader(T& object, UidDataT& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) { -#define SetUidField(name, value) if (&object.GetUidData() != NULL) { object.GetUidData().name = value; }; const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; if (coloralpha == 1 ) swizzle = "xyz"; else if (coloralpha == 2 ) swizzle = "w"; - SetUidField(lit_chans[litchan_index].attnfunc, chan.attnfunc); - SetUidField(lit_chans[litchan_index].diffusefunc, chan.diffusefunc); + uid_data.lit_chans[litchan_index].attnfunc = chan.attnfunc; + uid_data.lit_chans[litchan_index].diffusefunc = chan.diffusefunc; if (!(chan.attnfunc & 1)) { // atten disabled switch (chan.diffusefunc) { @@ -94,8 +93,8 @@ void GenerateLightShader(T& object, int index, int litchan_index, const char* li // materials name is I_MATERIALS in vs and I_PMATERIALS in ps // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps -template -void GenerateLightingShader(T& object, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +template +void GenerateLightingShader(T& object, UidDataT& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) { @@ -104,7 +103,7 @@ void GenerateLightingShader(T& object, int components, const char* materialsName object.Write("{\n"); - SetUidField(lit_chans[j].matsource, xfregs.color[j].matsource); + uid_data.lit_chans[j].matsource = xfregs.color[j].matsource; if (color.matsource) {// from vertex if (components & (VB_HAS_COL0 << j)) object.Write("mat = %s%d;\n", inColorName, j); @@ -116,9 +115,9 @@ void GenerateLightingShader(T& object, int components, const char* materialsName else // from color object.Write("mat = %s[%d];\n", materialsName, j+2); - SetUidField(lit_chans[j].enablelighting, xfregs.color[j].enablelighting); + uid_data.lit_chans[j].enablelighting = xfregs.color[j].enablelighting; if (color.enablelighting) { - SetUidField(lit_chans[j].ambsource, xfregs.color[j].ambsource); + uid_data.lit_chans[j].ambsource = xfregs.color[j].ambsource; if (color.ambsource) { // from vertex if (components & (VB_HAS_COL0<(object, i, j, lightsName, 3); + GenerateLightShader(object, uid_data, i, j, lightsName, 3); } } } @@ -198,9 +197,9 @@ void GenerateLightingShader(T& object, int components, const char* materialsName for (int i = 0; i < 8; ++i) { if (!(mask&(1<(object, i, j, lightsName, 1); + GenerateLightShader(object, uid_data, i, j, lightsName, 1); if (!(mask&(1<(object, i, j+2, lightsName, 2); + GenerateLightShader(object, uid_data, i, j+2, lightsName, 2); } } else if (color.enablelighting || alpha.enablelighting) @@ -210,17 +209,16 @@ void GenerateLightingShader(T& object, int components, const char* materialsName const int lit_index = color.enablelighting ? j : (j+2); int coloralpha = color.enablelighting ? 1 : 2; - SetUidField(lit_chans[lit_index].light_mask, workingchannel.GetFullLightMask()); + uid_data.lit_chans[lit_index].light_mask = workingchannel.GetFullLightMask(); for (int i = 0; i < 8; ++i) { if (workingchannel.GetFullLightMask() & (1<(object, i, lit_index, lightsName, coloralpha); + GenerateLightShader(object, uid_data, i, lit_index, lightsName, coloralpha); } } object.Write("%s%d = mat * saturate(lacc);\n", dest, j); object.Write("}\n"); } } -#undef SetUidField #endif // _LIGHTINGSHADERGEN_H_ diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 982f139fea..d9d45902fe 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -37,10 +37,10 @@ // output is given by .outreg // tevtemp is set according to swapmodetables and -template static void WriteStage(char *&p, int n, API_TYPE ApiType); +template static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType); template static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); -template static void WriteAlphaTest(T& out, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); -template static void WriteFog(T& out); +template static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); +template static void WriteFog(T& out, pixel_shader_uid_data& uid_data); static const char *tevKSelTableC[] = // KCSEL { @@ -272,13 +272,15 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // TODO: Where does this TODO belong again...? // TODO: Can be optimized if using alpha pass -#define SetUidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name = value; }; -#define OR_UidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name |= value; }; + // Non-uid template parameters will write to the dummy data (=> gets optimized out) + pixel_shader_uid_data dummy_data; + pixel_shader_uid_data& uid_data = (&out.GetUidData() != NULL) ? out.GetUidData() : dummy_data; + out.SetBuffer(text); if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, "C"); // Reset locale for compilation -/// text[sizeof(text) - 1] = 0x7C; // canary + text[sizeof(text) - 1] = 0x7C; // canary unsigned int numStages = bpmem.genMode.numtevstages + 1; unsigned int numTexgen = bpmem.genMode.numtexgens; @@ -289,12 +291,12 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", numStages, numTexgen/*, bpmem.genMode.numindstages*/); -// SetUidField(components, components); // TODO: Enable once per pixel lighting is implemented again - SetUidField(dstAlphaMode, dstAlphaMode); +// uid_data.components = components; // TODO: Enable once per pixel lighting is implemented again + uid_data.dstAlphaMode = dstAlphaMode; - SetUidField(genMode.numindstages, bpmem.genMode.numindstages); - SetUidField(genMode.numtevstages, bpmem.genMode.numtevstages); - SetUidField(genMode.numtexgens, bpmem.genMode.numtexgens); + uid_data.genMode.numindstages = bpmem.genMode.numindstages; + uid_data.genMode.numtevstages = bpmem.genMode.numtevstages; + uid_data.genMode.numtexgens = bpmem.genMode.numtexgens; if (ApiType == API_OPENGL) { @@ -461,7 +463,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { - SetUidField(xfregs_numTexGen_numTexGens, xfregs.numTexGen.numTexGens); + uid_data.xfregs_numTexGen_numTexGens = xfregs.numTexGen.numTexGens; if (xfregs.numTexGen.numTexGens < 7) { out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n"); @@ -498,7 +500,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u for (unsigned int i = 0; i < numTexgen; ++i) { // optional perspective divides - SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); + uid_data.texMtxInfo[i].projection = xfregs.texMtxInfo[i].projection; if (xfregs.texMtxInfo[i].projection == XF_TEXPROJ_STQ) { out.Write("\tif (uv%d.z != 0.0f)", i); @@ -520,7 +522,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } } - SetUidField(nIndirectStagesUsed, nIndirectStagesUsed); + uid_data.nIndirectStagesUsed = nIndirectStagesUsed; for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) { if (nIndirectStagesUsed & (1 << i)) @@ -531,23 +533,23 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u /// TODO: Cleanup... if (i == 0) { - SetUidField(tevindref.bc0, texcoord); - SetUidField(tevindref.bi0, texmap); + uid_data.tevindref.bc0 = texcoord; + uid_data.tevindref.bi0 = texmap; } else if (i == 1) { - SetUidField(tevindref.bc1, texcoord); - SetUidField(tevindref.bi1, texmap); + uid_data.tevindref.bc1 = texcoord; + uid_data.tevindref.bi1 = texmap; } else if (i == 2) { - SetUidField(tevindref.bc3, texcoord); - SetUidField(tevindref.bi2, texmap); + uid_data.tevindref.bc3 = texcoord; + uid_data.tevindref.bi2 = texmap; } else { - SetUidField(tevindref.bc4, texcoord); - SetUidField(tevindref.bi4, texmap); + uid_data.tevindref.bc4 = texcoord; + uid_data.tevindref.bi4 = texmap; } if (texcoord < numTexgen) { @@ -576,17 +578,17 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // Uid fields for BuildSwapModeTable are set in WriteStage BuildSwapModeTable(); for (unsigned int i = 0; i < numStages; i++) - WriteStage(out, i, ApiType); // build the equation for this stage + WriteStage(out, uid_data, i, ApiType); // build the equation for this stage if (numStages) { // The results of the last texenv stage are put onto the screen, // regardless of the used destination register - SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); // TODO: These probably don't need to be set anymore here... - SetUidField(combiners[numStages-1].alphaC.dest, bpmem.combiners[numStages-1].alphaC.dest); + uid_data.combiners[numStages-1].colorC.dest = bpmem.combiners[numStages-1].colorC.dest; // TODO: These probably don't need to be set anymore here... + uid_data.combiners[numStages-1].alphaC.dest = bpmem.combiners[numStages-1].alphaC.dest; if(bpmem.combiners[numStages - 1].colorC.dest != 0) { -/// SetUidField(combiners[numStages-1].colorC.dest, bpmem.combiners[numStages-1].colorC.dest); +/// uid_data.combiners[numStages-1].colorC.dest = bpmem.combiners[numStages-1].colorC.dest; bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].AuxStored; out.Write("\tprev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]); RegisterStates[0].ColorNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl; @@ -603,9 +605,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("\tprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); - SetUidField(Pretest, Pretest); + uid_data.Pretest = Pretest; if (Pretest == AlphaTest::UNDETERMINED) - WriteAlphaTest(out, ApiType, dstAlphaMode, per_pixel_depth); + WriteAlphaTest(out, uid_data, ApiType, dstAlphaMode, per_pixel_depth); // the screen space depth value = far z + (clip z / clip w) * z range @@ -619,9 +621,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } // Note: depth textures are disabled if early depth test is enabled - SetUidField(ztex.op, bpmem.ztex2.op); - SetUidField(per_pixel_depth, per_pixel_depth); - SetUidField(fog.fsel, bpmem.fog.c_proj_fsel.fsel); + uid_data.ztex.op = bpmem.ztex2.op; + uid_data.per_pixel_depth = per_pixel_depth; + uid_data.fog.fsel = bpmem.fog.c_proj_fsel.fsel; // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel; @@ -650,7 +652,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } else { - WriteFog(out); + WriteFog(out, uid_data); out.Write("\tocol0 = prev;\n"); } @@ -666,8 +668,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } out.Write("}\n"); -/// if (text[sizeof(text) - 1] != 0x7C) -/// PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); + + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, ""); // restore locale @@ -720,7 +723,7 @@ static const char *TEVCMPAlphaOPTable[16] = template -static void WriteStage(T& out, int n, API_TYPE ApiType) +static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens; @@ -732,14 +735,14 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("// TEV stage %d\n", n); - OR_UidField(bHasIndStage, bHasIndStage << n); - if (n < 8) { OR_UidField(tevorders_n_texcoord1, texcoord << (3 * n)); } - else OR_UidField(tevorders_n_texcoord2, texcoord << (3 * n - 24)); + uid_data.bHasIndStage |= bHasIndStage << n; + if (n < 8) { uid_data.tevorders_n_texcoord1 |= texcoord << (3 * n); } + else uid_data.tevorders_n_texcoord2 |= texcoord << (3 * n - 24); if (bHasIndStage) { - OR_UidField(tevind_n_bs, bpmem.tevind[n].bs << (2*n)); - OR_UidField(tevind_n_bt, bpmem.tevind[n].bt << (2*n)); - OR_UidField(tevind_n_fmt, bpmem.tevind[n].fmt << (2*n)); + uid_data.tevind_n_bs |= bpmem.tevind[n].bs << (2*n); + uid_data.tevind_n_bt |= bpmem.tevind[n].bt << (2*n); + uid_data.tevind_n_fmt |= bpmem.tevind[n].fmt << (2*n); out.Write("// indirect op\n"); // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords @@ -754,14 +757,14 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) out.Write("float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]); // bias - if (n < 8) { OR_UidField(tevind_n_bias1, bpmem.tevind[n].bias << (3*n)); } /// XXX: brackets? - else OR_UidField(tevind_n_bias2, bpmem.tevind[n].bias << (3*n - 24)); + if (n < 8) { uid_data.tevind_n_bias1 |= bpmem.tevind[n].bias << (3*n); } /// XXX: brackets? + else uid_data.tevind_n_bias2 |= bpmem.tevind[n].bias << (3*n - 24); if (bpmem.tevind[n].bias != ITB_NONE ) out.Write("indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); // multiply by offset matrix and scale - if (n < 8) { OR_UidField(tevind_n_mid1, bpmem.tevind[n].mid << (4*n)); } /// XXX: brackets? - else OR_UidField(tevind_n_mid2, bpmem.tevind[n].mid << (4*n - 32)); + if (n < 8) { uid_data.tevind_n_mid1 |= bpmem.tevind[n].mid << (4*n); } /// XXX: brackets? + else uid_data.tevind_n_mid2 |= bpmem.tevind[n].mid << (4*n - 32); if (bpmem.tevind[n].mid != 0) { if (bpmem.tevind[n].mid <= 3) @@ -795,12 +798,12 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) // Wrapping // --------- - if (n < 8) { OR_UidField(tevind_n_sw1, bpmem.tevind[n].sw << (3 * n)); } - else OR_UidField(tevind_n_sw2, bpmem.tevind[n].sw << (3 * n - 24)); - if (n < 8) { OR_UidField(tevind_n_tw1, bpmem.tevind[n].tw << (3 * n)); } - else OR_UidField(tevind_n_tw2, bpmem.tevind[n].tw << (3 * n - 24)); + if (n < 8) { uid_data.tevind_n_sw1 |= bpmem.tevind[n].sw << (3 * n); } + else uid_data.tevind_n_sw2 |= bpmem.tevind[n].sw << (3 * n - 24); + if (n < 8) { uid_data.tevind_n_tw1 |= bpmem.tevind[n].tw << (3 * n); } + else uid_data.tevind_n_tw2 |= bpmem.tevind[n].tw << (3 * n - 24); - OR_UidField(tevind_n_fb_addprev, bpmem.tevind[n].fb_addprev << n); + uid_data.tevind_n_fb_addprev |= bpmem.tevind[n].fb_addprev << n; // wrap S if (bpmem.tevind[n].sw == ITW_OFF) @@ -827,8 +830,8 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) TevStageCombiner::ColorCombiner &cc = bpmem.combiners[n].colorC; TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[n].alphaC; - SetUidField(combiners[n].colorC.hex, cc.hex&0xFFFFFF); - SetUidField(combiners[n].alphaC.hex, ac.hex&0xFFFFFF); + uid_data.combiners[n].colorC.hex = cc.hex & 0xFFFFFF; + uid_data.combiners[n].alphaC.hex = ac.hex & 0xFFFFFF; if(cc.a == TEVCOLORARG_RASA || cc.a == TEVCOLORARG_RASC || cc.b == TEVCOLORARG_RASA || cc.b == TEVCOLORARG_RASC @@ -838,10 +841,10 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA) { const int i = bpmem.combiners[n].alphaC.rswap; - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap1 << (i*2)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap1 << (i*2 + 1)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap2 << (i*2 + 16)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap2 << (i*2 + 17)); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap1 << (i*2); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap1 << (i*2 + 1); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap2 << (i*2 + 16); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap2 << (i*2 + 17); char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; out.Write("rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); @@ -861,10 +864,10 @@ static void WriteStage(T& out, int n, API_TYPE ApiType) } const int i = bpmem.combiners[n].alphaC.tswap; - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap1 << (i*2)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap1 << (i*2 + 1)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2 ].swap2 << (i*2 + 16)); - OR_UidField(tevksel_n_swap, bpmem.tevksel[i*2+1].swap2 << (i*2 + 17)); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap1 << (i*2); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap1 << (i*2 + 1); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap2 << (i*2 + 16); + uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap2 << (i*2 + 17); char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); @@ -1116,7 +1119,7 @@ static const char *tevAlphaFunclogicTable[] = }; template -static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth) +static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth) { static const char *alphaRef[2] = { @@ -1129,9 +1132,9 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, // using discard then return works the same in cg and dx9 but not in dx11 out.Write("\tif(!( "); - SetUidField(alpha_test.comp0, bpmem.alpha_test.comp0); - SetUidField(alpha_test.logic, bpmem.alpha_test.comp1); - SetUidField(alpha_test.logic, bpmem.alpha_test.logic); + uid_data.alpha_test.comp0 = bpmem.alpha_test.comp0; + uid_data.alpha_test.logic = bpmem.alpha_test.comp1; + uid_data.alpha_test.logic = bpmem.alpha_test.logic; // Lookup the first component from the alpha function table int compindex = bpmem.alpha_test.comp0; @@ -1160,7 +1163,7 @@ static void WriteAlphaTest(T& out, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, // when the alpha test fail. This is not a correct implementation because // even if the depth test fails the fragment could be alpha blended, but // we don't have a choice. - SetUidField(alpha_test.use_zcomploc_hack, bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable); + uid_data.alpha_test.use_zcomploc_hack = bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable; if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { out.Write("\t\tdiscard;\n"); @@ -1184,13 +1187,13 @@ static const char *tevFogFuncsTable[] = }; template -static void WriteFog(T& out) +static void WriteFog(T& out, pixel_shader_uid_data& uid_data) { - SetUidField(fog.fsel, bpmem.fog.c_proj_fsel.fsel); + uid_data.fog.fsel = bpmem.fog.c_proj_fsel.fsel; if(bpmem.fog.c_proj_fsel.fsel == 0) return; // no Fog - SetUidField(fog.proj, bpmem.fog.c_proj_fsel.proj); + uid_data.fog.proj = bpmem.fog.c_proj_fsel.proj; out.SetConstantsUsed(C_FOG, C_FOG+1); if (bpmem.fog.c_proj_fsel.proj == 0) @@ -1209,7 +1212,7 @@ static void WriteFog(T& out) // x_adjust = sqrt((x-center)^2 + k^2)/k // ze *= x_adjust // this is completely theoretical as the real hardware seems to use a table intead of calculating the values. - SetUidField(fog.RangeBaseEnabled, bpmem.fogRange.Base.Enabled); + uid_data.fog.RangeBaseEnabled = bpmem.fogRange.Base.Enabled; if(bpmem.fogRange.Base.Enabled) { out.SetConstantsUsed(C_FOG+2, C_FOG+2); diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 869b84a4ed..5ed1a73569 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -83,14 +83,15 @@ extern const char *WriteLocation(API_TYPE api_type); template void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { -#undef SetUidField -#define SetUidField(name, value) if (&out.GetUidData() != NULL) {out.GetUidData().name = value; }; + // Non-uid template parameters will write to the dummy data (=> gets optimized out) + vertex_shader_uid_data dummy_data; + vertex_shader_uid_data& uid_data = (&out.GetUidData() != NULL) ? out.GetUidData() : dummy_data; out.SetBuffer(text); if (out.GetBuffer() != NULL) setlocale(LC_NUMERIC, "C"); // Reset locale for compilation -// text[sizeof(text) - 1] = 0x7C; // canary + text[sizeof(text) - 1] = 0x7C; // canary _assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens); _assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans); @@ -122,8 +123,8 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) GenerateVSOutputStruct(out, components, api_type); - SetUidField(numTexGens, xfregs.numTexGen.numTexGens); - SetUidField(components, components); + uid_data.numTexGens = xfregs.numTexGen.numTexGens; + uid_data.components = components; if(api_type == API_OPENGL) { @@ -262,7 +263,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) "float3 ldir, h;\n" "float dist, dist2, attn;\n"); - SetUidField(numColorChans, xfregs.numChan.numColorChans); + uid_data.numColorChans = xfregs.numChan.numColorChans; if (xfregs.numChan.numColorChans == 0) { if (components & VB_HAS_COL0) @@ -272,7 +273,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) } // TODO: This probably isn't necessary if pixel lighting is enabled. - GenerateLightingShader(out, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, uid_data, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); if (xfregs.numChan.numColorChans < 2) { @@ -297,7 +298,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) out.Write("{\n"); out.Write("coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); - SetUidField(texMtxInfo[i].sourcerow, xfregs.texMtxInfo[i].sourcerow); + uid_data.texMtxInfo[i].sourcerow = xfregs.texMtxInfo[i].sourcerow; switch (texinfo.sourcerow) { case XF_SRCGEOM_INROW: _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); @@ -332,21 +333,21 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) } // first transformation - SetUidField(texMtxInfo[i].texgentype, xfregs.texMtxInfo[i].texgentype); + uid_data.texMtxInfo[i].texgentype = xfregs.texMtxInfo[i].texgentype; switch (texinfo.texgentype) { case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { // transform the light dir into tangent space - SetUidField(texMtxInfo[i].embosslightshift, xfregs.texMtxInfo[i].embosslightshift); - SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + uid_data.texMtxInfo[i].embosslightshift = xfregs.texMtxInfo[i].embosslightshift; + uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift; out.Write("ldir = normalize(" I_LIGHTS"[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); } else { _assert_(0); // should have normals - SetUidField(texMtxInfo[i].embosssourceshift, xfregs.texMtxInfo[i].embosssourceshift); + uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift; out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); } @@ -361,7 +362,7 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) break; case XF_TEXGEN_REGULAR: default: - SetUidField(texMtxInfo[i].projection, xfregs.texMtxInfo[i].projection); + uid_data.texMtxInfo[i].projection = xfregs.texMtxInfo[i].projection; if (components & (VB_HAS_TEXMTXIDX0< Date: Fri, 29 Mar 2013 22:24:49 +0100 Subject: [PATCH 028/352] ShaderGen: More interface cleanups. Less wtfs :) --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 3 ++- Source/Core/VideoCommon/Src/PixelShaderGen.h | 4 ++-- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 20 ++++++++----------- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 7 ++++--- Source/Core/VideoCommon/Src/VertexShaderGen.h | 4 ++-- .../Src/LineGeometryShader.cpp | 2 +- .../Src/PointGeometryShader.cpp | 2 +- .../Src/ProgramShaderCache.cpp | 6 +++--- 8 files changed, 23 insertions(+), 25 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index d9d45902fe..e534e2a6ca 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -274,7 +274,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; - pixel_shader_uid_data& uid_data = (&out.GetUidData() != NULL) ? out.GetUidData() : dummy_data; + pixel_shader_uid_data& uid_data = (&out.template GetUidData() != NULL) + ? out.template GetUidData() : dummy_data; out.SetBuffer(text); if (out.GetBuffer() != NULL) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 4f9cba0c37..4881999206 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -190,8 +190,8 @@ struct pixel_shader_uid_data }; typedef ShaderUid PixelShaderUid; -typedef ShaderCode PixelShaderCode; -typedef ShaderConstantProfile PixelShaderConstantProfile; +typedef ShaderCode PixelShaderCode; // TODO: Obsolete +typedef ShaderConstantProfile PixelShaderConstantProfile; // TODO: Obsolete void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index a2616e0a6c..a904a8e635 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -25,7 +25,6 @@ #include -template class ShaderGeneratorInterface { public: @@ -33,11 +32,13 @@ public: const char* GetBuffer() { return NULL; } void SetBuffer(char* buffer) { } inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} - uid_data& GetUidData() { return *(uid_data*)NULL; } // TODO: can be moved out, just make this GetUidData instead + + template + uid_data& GetUidData() { return *(uid_data*)NULL; } }; template -class ShaderUid : public ShaderGeneratorInterface +class ShaderUid : public ShaderGeneratorInterface { public: ShaderUid() @@ -69,7 +70,8 @@ public: return false; } - inline uid_data& GetUidData() { return data; } + template + inline T& GetUidData() override { return data; } private: union @@ -79,9 +81,7 @@ private: }; }; -// Needs to be a template for hacks... -template -class ShaderCode : public ShaderGeneratorInterface +class ShaderCode : public ShaderGeneratorInterface { public: ShaderCode() : buf(NULL), write_ptr(NULL) @@ -105,15 +105,11 @@ private: char* write_ptr; }; -template -class ShaderConstantProfile : public ShaderGeneratorInterface +class ShaderConstantProfile : public ShaderGeneratorInterface { public: ShaderConstantProfile(int num_constants) { constant_usage.resize(num_constants); } - // has room for optimization (if it matters at all...) - void NumConstants() { return constant_usage.size(); } - inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) { for (unsigned int i = first_index; i < last_index+1; ++i) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 5ed1a73569..e27ced7b39 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -85,7 +85,8 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) vertex_shader_uid_data dummy_data; - vertex_shader_uid_data& uid_data = (&out.GetUidData() != NULL) ? out.GetUidData() : dummy_data; + vertex_shader_uid_data& uid_data = (&out.template GetUidData() != NULL) + ? out.template GetUidData() : dummy_data; out.SetBuffer(text); if (out.GetBuffer() != NULL) @@ -535,7 +536,7 @@ void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE GenerateVertexShader(object, components, api_type); } -void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type) +void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type) { - GenerateVSOutputStruct >(object, components, api_type); + GenerateVSOutputStruct(object, components, api_type); } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index b6b176c806..33d27ecdf0 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -110,10 +110,10 @@ struct vertex_shader_uid_data }; typedef ShaderUid VertexShaderUid; -typedef ShaderCode VertexShaderCode; +typedef ShaderCode VertexShaderCode; // TODO: Obsolete.. void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type); -void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type); +void GenerateVSOutputStructForGS(ShaderCode& object, u32 components, API_TYPE api_type); #endif // GCOGL_VERTEXSHADER_H diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index f22ebef0df..5d6b8eb5b5 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -183,7 +183,7 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, { // Generate new shader. Warning: not thread-safe. static char buffer[16384]; - ShaderCode code; + ShaderCode code; code.SetBuffer(buffer); GenerateVSOutputStructForGS(code, components, API_D3D11); code.Write("\n%s", LINE_GS_COMMON); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index 5976c09ab9..8f5300ff64 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -177,7 +177,7 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, { // Generate new shader. Warning: not thread-safe. static char buffer[16384]; - ShaderCode code; + ShaderCode code; code.SetBuffer(buffer); GenerateVSOutputStructForGS(code, components, API_D3D11); code.Write("\n%s", POINT_GS_COMMON); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 188145ebcf..81621d2d38 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -360,9 +360,9 @@ template UidT GetPartialUid(const SHADERUID& uid); template<> PixelShaderUid GetPartialUid(const SHADERUID& uid) { return uid.puid; } template<> VertexShaderUid GetPartialUid(const SHADERUID& uid) { return uid.vuid; } -template const std::string& GetShaderCode(const SHADER& shader); -template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strpprog; } -template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strvprog; } +template const std::string& GetShaderCode(const SHADER& shader); +template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strpprog; } +template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strvprog; } template void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_code, const UidT& new_uid) From cdddb26bbafce034143465da7d2e250cded5fd53 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 29 Mar 2013 22:29:37 +0100 Subject: [PATCH 029/352] Apparently override is less fun than I thought. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index a904a8e635..eabd6f7c07 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -71,7 +71,7 @@ public: } template - inline T& GetUidData() override { return data; } + inline T& GetUidData() { return data; } private: union From 248d56d930d8d6f7cae04efc0c1521c83676c074 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 31 Mar 2013 20:55:57 +0200 Subject: [PATCH 030/352] ShaderGen: Small optimization. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 4 +-- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 32 +++++++++++++++++-- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 28 +++++++--------- Source/Core/VideoCommon/Src/VertexShaderGen.h | 4 ++- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index e8b30d86a8..40a8fb2732 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -26,7 +26,7 @@ // uid_data needs to have a struct named lighting_uid template -void GenerateLightShader(T& object, UidDataT& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) +static void GenerateLightShader(T& object, UidDataT& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) { const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; @@ -94,7 +94,7 @@ void GenerateLightShader(T& object, UidDataT& uid_data, int index, int litchan_i // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps template -void GenerateLightingShader(T& object, UidDataT& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +static void GenerateLightingShader(T& object, UidDataT& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) { diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index eabd6f7c07..ef88d411ea 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -21,10 +21,11 @@ #include #include #include -#include "CommonTypes.h" - #include +#include "CommonTypes.h" +#include "VideoCommon.h" + class ShaderGeneratorInterface { public: @@ -125,4 +126,31 @@ private: std::vector constant_usage; // TODO: Is vector appropriate here? }; +template +static void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const u32 num) +{ + if (ApiType == API_OPENGL) + return; // Nothing to do here + + object.Write(" : register(%s%d)", prefix, num); +} + +template +static void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos) +{ + if (using_ubos) + return; + + object.Write("uniform "); +} + +template +static void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const u32 num, const char* type, const char* name) +{ + WriteLocation(object, api_type, using_ubos); + object.Write("%s %s ", type, name); + WriteRegister(object, api_type, "c", num); + object.Write(";\n"); +} + #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index e27ced7b39..44bad82471 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -29,7 +29,7 @@ static char text[16768]; template -void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic, int semantic_index = -1) +static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic, int semantic_index = -1) { object.Write(" %s %s", type, name); if (var_index != -1) @@ -48,7 +48,7 @@ void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* type, // TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? template -void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) +static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) { object.Write("struct VS_OUTPUT {\n"); DefineVSOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION"); @@ -76,12 +76,8 @@ void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) object.Write("};\n"); } -// TODO: Seriously? -.- -extern const char *WriteRegister(API_TYPE api_type, const char *prefix, const u32 num); -extern const char *WriteLocation(API_TYPE api_type); - template -void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) +static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) vertex_shader_uid_data dummy_data; @@ -108,16 +104,16 @@ void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("layout(std140) uniform VSBlock {\n"); - out.Write("%sfloat4 " I_POSNORMALMATRIX"[6] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_POSNORMALMATRIX)); - out.Write("%sfloat4 " I_PROJECTION"[4] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_PROJECTION)); - out.Write("%sfloat4 " I_MATERIALS"[4] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_MATERIALS)); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_POSNORMALMATRIX, "float4", I_POSNORMALMATRIX"[6]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PROJECTION, "float4", I_PROJECTION"[4]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_MATERIALS, "float4", I_MATERIALS"[4]"); out.Write("struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); - out.Write("%sLight " I_LIGHTS"[8] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_LIGHTS)); - out.Write("%sfloat4 " I_TEXMATRICES"[24] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_TEXMATRICES)); // also using tex matrices - out.Write("%sfloat4 " I_TRANSFORMMATRICES"[64] %s;\n", WriteLocation(api_type),WriteRegister(api_type, "c", C_TRANSFORMMATRICES)); - out.Write("%sfloat4 " I_NORMALMATRICES"[32] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_NORMALMATRICES)); - out.Write("%sfloat4 " I_POSTTRANSFORMMATRICES"[64] %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_POSTTRANSFORMMATRICES)); - out.Write("%sfloat4 " I_DEPTHPARAMS" %s;\n", WriteLocation(api_type), WriteRegister(api_type, "c", C_DEPTHPARAMS)); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_LIGHTS, "Light", I_LIGHTS"[8]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TEXMATRICES, "float4", I_TEXMATRICES"[24]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TRANSFORMMATRICES, "float4", I_TRANSFORMMATRICES"[64]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_NORMALMATRICES, "float4", I_NORMALMATRICES"[32]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_POSTTRANSFORMMATRICES, "float4", I_POSTTRANSFORMMATRICES"[64]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_DEPTHPARAMS, "float4", I_DEPTHPARAMS); if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("};\n"); diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index 33d27ecdf0..ea81aba468 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -76,7 +76,8 @@ const s_svar VSVar_Loc[] = { {I_POSNORMALMATRIX, C_POSNORMALMATRIX, 6 }, {I_DEPTHPARAMS, C_DEPTHPARAMS, 1 }, }; -// TODO: Need packing? +#pragma pack(4) + struct vertex_shader_uid_data { @@ -108,6 +109,7 @@ struct vertex_shader_uid_data u32 light_mask : 8; } lit_chans[4]; }; +#pragma pack() typedef ShaderUid VertexShaderUid; typedef ShaderCode VertexShaderCode; // TODO: Obsolete.. From f6d65a636ef9c8a75b410314b94384a2ae2d7e62 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 31 Mar 2013 23:29:33 +0200 Subject: [PATCH 031/352] ShaderGen: Fix per pixel lighting. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 19 ++++++++----------- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 10 +++++----- Source/Core/VideoCommon/Src/PixelShaderGen.h | 2 ++ Source/Core/VideoCommon/Src/ShaderGenCommon.h | 13 +++++++++++++ .../Core/VideoCommon/Src/VertexShaderGen.cpp | 2 +- Source/Core/VideoCommon/Src/VertexShaderGen.h | 11 ++--------- Source/Core/VideoCommon/Src/VideoConfig.h | 2 +- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index 40a8fb2732..ff19b737f4 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -18,15 +18,12 @@ #ifndef _LIGHTINGSHADERGEN_H_ #define _LIGHTINGSHADERGEN_H_ -#include - #include "ShaderGenCommon.h" #include "NativeVertexFormat.h" #include "XFMemory.h" -// uid_data needs to have a struct named lighting_uid -template -static void GenerateLightShader(T& object, UidDataT& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) +template +static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) { const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; @@ -93,8 +90,8 @@ static void GenerateLightShader(T& object, UidDataT& uid_data, int index, int li // materials name is I_MATERIALS in vs and I_PMATERIALS in ps // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps -template -static void GenerateLightingShader(T& object, UidDataT& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +template +static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) { @@ -187,7 +184,7 @@ static void GenerateLightingShader(T& object, UidDataT& uid_data, int components { if (mask & (1<(object, uid_data, i, j, lightsName, 3); + GenerateLightShader(object, uid_data, i, j, lightsName, 3); } } } @@ -197,9 +194,9 @@ static void GenerateLightingShader(T& object, UidDataT& uid_data, int components for (int i = 0; i < 8; ++i) { if (!(mask&(1<(object, uid_data, i, j, lightsName, 1); + GenerateLightShader(object, uid_data, i, j, lightsName, 1); if (!(mask&(1<(object, uid_data, i, j+2, lightsName, 2); + GenerateLightShader(object, uid_data, i, j+2, lightsName, 2); } } else if (color.enablelighting || alpha.enablelighting) @@ -213,7 +210,7 @@ static void GenerateLightingShader(T& object, UidDataT& uid_data, int components for (int i = 0; i < 8; ++i) { if (workingchannel.GetFullLightMask() & (1<(object, uid_data, i, lit_index, lightsName, coloralpha); + GenerateLightShader(object, uid_data, i, lit_index, lightsName, coloralpha); } } object.Write("%s%d = mat * saturate(lacc);\n", dest, j); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index e534e2a6ca..ceb2230684 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -341,12 +341,12 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("\t%sfloat4 " I_INDTEXSCALE"[2] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_INDTEXSCALE)); out.Write("\t%sfloat4 " I_INDTEXMTX"[6] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_INDTEXMTX)); out.Write("\t%sfloat4 " I_FOG"[3] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_FOG)); - + // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! out.Write("struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); out.Write("\t%sLight " I_PLIGHTS"[8] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); out.Write("\t%sfloat4 " I_PMATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PMATERIALS)); - + if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("};\n"); @@ -366,7 +366,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("float4 colors_1 = colors_12;\n"); // compute window position if needed because binding semantic WPOS is not widely supported - // Let's set up attributes + // Let's set up attributes if (xfregs.numTexGen.numTexGens < 7) { for (int i = 0; i < 8; ++i) @@ -479,10 +479,10 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("\tfloat4 mat, lacc;\n" "\tfloat3 ldir, h;\n" "\tfloat dist, dist2, attn;\n"); -/// TODO + out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+39); // TODO: Can be optimized further out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); -/// p = GenerateLightingShader(p, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); + GenerateLightingShader(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } if (numTexgen < 7) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 4881999206..98afec2c5b 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -187,6 +187,8 @@ struct pixel_shader_uid_data u32 bHasIndStage : 16; u32 xfregs_numTexGen_numTexGens : 4; + + LightingUidData lighting; }; typedef ShaderUid PixelShaderUid; diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index ef88d411ea..4d41cd62f1 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -153,4 +153,17 @@ static void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const object.Write(";\n"); } +struct LightingUidData +{ + struct + { + u32 matsource : 1; + u32 enablelighting : 1; + u32 ambsource : 1; + u32 diffusefunc : 2; + u32 attnfunc : 2; + u32 light_mask : 8; + } lit_chans[4]; +}; + #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 44bad82471..82e7a7fdce 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -270,7 +270,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) } // TODO: This probably isn't necessary if pixel lighting is enabled. - GenerateLightingShader(out, uid_data, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, uid_data.lighting, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); if (xfregs.numChan.numColorChans < 2) { diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index ea81aba468..9c44ba0448 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -79,7 +79,6 @@ const s_svar VSVar_Loc[] = { {I_POSNORMALMATRIX, C_POSNORMALMATRIX, 6 }, #pragma pack(4) struct vertex_shader_uid_data - { u32 components; u32 numColorChans : 2; @@ -100,14 +99,8 @@ struct vertex_shader_uid_data struct { u32 enabled : 1; } dualTexTrans; - struct { - u32 matsource : 1; - u32 enablelighting : 1; - u32 ambsource : 1; - u32 diffusefunc : 2; - u32 attnfunc : 2; - u32 light_mask : 8; - } lit_chans[4]; + + LightingUidData lighting; }; #pragma pack() diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 99fff0d167..442e95f9bf 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -135,7 +135,7 @@ struct VideoConfig int iAdapter; // Debugging - bool bEnableShaderDebugging; // TODO: Obsolete? + bool bEnableShaderDebugging; // Static config per API // TODO: Move this out of VideoConfig From f57b902d3369e1780d61283f0d04d0380923db2b Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 31 Mar 2013 23:53:46 +0200 Subject: [PATCH 032/352] PixelShaderGen: Cleanups. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 47 +++------------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 55 +++++++++++++++---- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index ceb2230684..8d1d268197 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -531,27 +531,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u unsigned int texcoord = bpmem.tevindref.getTexCoord(i); unsigned int texmap = bpmem.tevindref.getTexMap(i); - /// TODO: Cleanup... - if (i == 0) - { - uid_data.tevindref.bc0 = texcoord; - uid_data.tevindref.bi0 = texmap; - } - else if (i == 1) - { - uid_data.tevindref.bc1 = texcoord; - uid_data.tevindref.bi1 = texmap; - } - else if (i == 2) - { - uid_data.tevindref.bc3 = texcoord; - uid_data.tevindref.bi2 = texmap; - } - else - { - uid_data.tevindref.bc4 = texcoord; - uid_data.tevindref.bi4 = texmap; - } + uid_data.tevindref.SetValues(i, texcoord, texmap); if (texcoord < numTexgen) { out.SetConstantsUsed(C_INDTEXSCALE+i/2,C_INDTEXSCALE+i/2); @@ -585,11 +565,8 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u { // The results of the last texenv stage are put onto the screen, // regardless of the used destination register - uid_data.combiners[numStages-1].colorC.dest = bpmem.combiners[numStages-1].colorC.dest; // TODO: These probably don't need to be set anymore here... - uid_data.combiners[numStages-1].alphaC.dest = bpmem.combiners[numStages-1].alphaC.dest; if(bpmem.combiners[numStages - 1].colorC.dest != 0) { -/// uid_data.combiners[numStages-1].colorC.dest = bpmem.combiners[numStages-1].colorC.dest; bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].AuxStored; out.Write("\tprev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" , tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]); RegisterStates[0].ColorNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl; @@ -741,9 +718,9 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE else uid_data.tevorders_n_texcoord2 |= texcoord << (3 * n - 24); if (bHasIndStage) { - uid_data.tevind_n_bs |= bpmem.tevind[n].bs << (2*n); - uid_data.tevind_n_bt |= bpmem.tevind[n].bt << (2*n); - uid_data.tevind_n_fmt |= bpmem.tevind[n].fmt << (2*n); + uid_data.tevind_n.bs |= bpmem.tevind[n].bs << (2*n); + uid_data.tevind_n.bt |= bpmem.tevind[n].bt << (2*n); + uid_data.tevind_n.fmt |= bpmem.tevind[n].fmt << (2*n); out.Write("// indirect op\n"); // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords @@ -758,14 +735,12 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE out.Write("float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]); // bias - if (n < 8) { uid_data.tevind_n_bias1 |= bpmem.tevind[n].bias << (3*n); } /// XXX: brackets? - else uid_data.tevind_n_bias2 |= bpmem.tevind[n].bias << (3*n - 24); + uid_data.tevind_n.Set_bias(n, bpmem.tevind[n].bias); if (bpmem.tevind[n].bias != ITB_NONE ) out.Write("indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); // multiply by offset matrix and scale - if (n < 8) { uid_data.tevind_n_mid1 |= bpmem.tevind[n].mid << (4*n); } /// XXX: brackets? - else uid_data.tevind_n_mid2 |= bpmem.tevind[n].mid << (4*n - 32); + uid_data.tevind_n.Set_mid(n, bpmem.tevind[n].mid); if (bpmem.tevind[n].mid != 0) { if (bpmem.tevind[n].mid <= 3) @@ -798,13 +773,9 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE // --------- // Wrapping // --------- - - if (n < 8) { uid_data.tevind_n_sw1 |= bpmem.tevind[n].sw << (3 * n); } - else uid_data.tevind_n_sw2 |= bpmem.tevind[n].sw << (3 * n - 24); - if (n < 8) { uid_data.tevind_n_tw1 |= bpmem.tevind[n].tw << (3 * n); } - else uid_data.tevind_n_tw2 |= bpmem.tevind[n].tw << (3 * n - 24); - - uid_data.tevind_n_fb_addprev |= bpmem.tevind[n].fb_addprev << n; + uid_data.tevind_n.Set_sw(n, bpmem.tevind[n].sw); + uid_data.tevind_n.Set_tw(n, bpmem.tevind[n].tw); + uid_data.tevind_n.fb_addprev |= bpmem.tevind[n].fb_addprev << n; // wrap S if (bpmem.tevind[n].sw == ITW_OFF) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 98afec2c5b..3c6db3fa8f 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -99,23 +99,54 @@ struct pixel_shader_uid_data u32 bc3 : 3; u32 bi4 : 3; u32 bc4 : 3; + void SetValues(int index, u32 texcoord, u32 texmap) + { + if (index == 0) { bc0 = texcoord; bi0 = texmap; } + else if (index == 1) { bc1 = texcoord; bi1 = texmap; } + else if (index == 2) { bc3 = texcoord; bi2 = texmap; } + else if (index == 3) { bc4 = texcoord; bi4 = texmap; } + } } tevindref; u32 tevorders_n_texcoord1 : 24; // 8 x 3 bit u32 tevorders_n_texcoord2 : 24; // 8 x 3 bit - u32 tevind_n_sw1 : 24; // 8 x 3 bit - u32 tevind_n_sw2 : 24; // 8 x 3 bit - u32 tevind_n_tw1 : 24; // 8 x 3 bit - u32 tevind_n_tw2 : 24; // 8 x 3 bit - u32 tevind_n_fb_addprev : 16; // 16 x 1 bit + struct + { + u32 sw1 : 24; // 8 x 3 bit + u32 sw2 : 24; // 8 x 3 bit + u32 tw1 : 24; // 8 x 3 bit + u32 tw2 : 24; // 8 x 3 bit + u32 fb_addprev : 16; // 16 x 1 bit + u32 bs : 32; // 16 x 2 bit + u32 fmt : 32; // 16 x 2 bit + u32 bt : 32; // 16 x 2 bit + u32 bias1 : 24; // 8 x 3 bit + u32 bias2 : 24; // 8 x 3 bit + u32 mid1 : 32; // 8 x 4 bit + u32 mid2 : 32; // 8 x 4 bit - u32 tevind_n_bs : 32; // 16 x 2 bit - u32 tevind_n_fmt : 32; // 16 x 2 bit - u32 tevind_n_bt : 32; // 16 x 2 bit - u32 tevind_n_bias1 : 24; // 8 x 3 bit - u32 tevind_n_bias2 : 24; // 8 x 3 bit - u32 tevind_n_mid1 : 32; // 8 x 4 bit - u32 tevind_n_mid2 : 32; // 8 x 4 bit + // NOTE: These assume that the affected bits are zero before calling + void Set_sw(int index, u32 val) + { + if (index < 8) sw1 |= val << (3*index); + else sw2 |= val << (3*index - 24); + } + void Set_tw(int index, u32 val) + { + if (index < 8) tw1 |= val << (3*index); + else tw2 |= val << (3*index - 24); + } + void Set_bias(int index, u32 val) + { + if (index < 8) bias1 |= val << (3*index); + else bias2 |= val << (3*index - 24); + } + void Set_mid(int index, u32 val) + { + if (index < 8) mid1 |= val << (4*index); + else mid2 |= val << (4*index - 32); + } + } tevind_n; u32 tevksel_n_swap : 32; // 8 x 2 bit (swap1) + 8 x 2 bit (swap2) struct From a60e1a3db8baae58b759b8b905436a1e52fb81e2 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 31 Mar 2013 23:57:39 +0200 Subject: [PATCH 033/352] ShaderGen: Remove some TODOs and fix an issue with per pixel lighting. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 6 +----- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 8d1d268197..69c096f002 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -269,9 +269,6 @@ const char *WriteLocation(API_TYPE ApiType) template void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { - // TODO: Where does this TODO belong again...? - // TODO: Can be optimized if using alpha pass - // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; pixel_shader_uid_data& uid_data = (&out.template GetUidData() != NULL) @@ -292,9 +289,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", numStages, numTexgen/*, bpmem.genMode.numindstages*/); -// uid_data.components = components; // TODO: Enable once per pixel lighting is implemented again uid_data.dstAlphaMode = dstAlphaMode; - uid_data.genMode.numindstages = bpmem.genMode.numindstages; uid_data.genMode.numtevstages = bpmem.genMode.numtevstages; uid_data.genMode.numtexgens = bpmem.genMode.numtexgens; @@ -482,6 +477,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+39); // TODO: Can be optimized further out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); + uid_data.components = components; GenerateLightingShader(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 82e7a7fdce..48b09a9eac 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -46,7 +46,6 @@ static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* } } -// TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later?? template static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) { From ec5f596b3175e06c8d27ae2053213813db3693ef Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 12:17:28 +0200 Subject: [PATCH 034/352] VertexShaderGen: More per-pixel-lighting fixes. --- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 48b09a9eac..452ee7fd3f 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -420,7 +420,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) out.Write("o.tex3.w = o.pos.w;\n"); } -/* if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { if (xfregs.numTexGen.numTexGens < 7) { out.Write("o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n"); @@ -438,7 +438,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) if (components & VB_HAS_COL1) out.Write("o.colors_1 = color1;\n"); - }*/ + } //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed From ec08914905ca1c4fe3b2456a9cc037a3f7eedd49 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 12:54:22 +0200 Subject: [PATCH 035/352] Move Shader UID mismatch checking to VideoCommon. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 7 ++ Source/Core/VideoCommon/Src/PixelShaderGen.h | 1 - Source/Core/VideoCommon/Src/ShaderGenCommon.h | 47 ++++++++++++++ .../Core/VideoCommon/Src/VertexShaderGen.cpp | 7 ++ .../Src/ProgramShaderCache.cpp | 64 ------------------- 5 files changed, 61 insertions(+), 65 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 69c096f002..2d9121856c 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -1207,6 +1207,13 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data) void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { GeneratePixelShader(object, dstAlphaMode, ApiType, components); + + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_OPENGL, components); + CheckForUidMismatch(code, object); + } } void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 3c6db3fa8f..001ab53f0b 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -226,7 +226,6 @@ typedef ShaderUid PixelShaderUid; typedef ShaderCode PixelShaderCode; // TODO: Obsolete typedef ShaderConstantProfile PixelShaderConstantProfile; // TODO: Obsolete - void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 4d41cd62f1..07af93c295 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "CommonTypes.h" #include "VideoCommon.h" @@ -166,4 +168,49 @@ struct LightingUidData } lit_chans[4]; }; +struct pixel_shader_uid_data; +struct vertex_shader_uid_data; + +typedef ShaderUid PixelShaderUid; +typedef ShaderUid VertexShaderUid; + +template +void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid) +{ + static std::map s_shaders; + static std::vector s_uids; + + bool uid_is_indexed = std::find(s_uids.begin(), s_uids.end(), new_uid) != s_uids.end(); + if (!uid_is_indexed) + { + s_uids.push_back(new_uid); + s_shaders[new_uid] = new_code.GetBuffer(); + } + else + { + // uid is already in the index => check if there's a shader with the same uid but different code + auto& old_code = s_shaders[new_uid]; + if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0) + { + static int num_failures = 0; + + char szTemp[MAX_PATH]; + sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), + (typeid(UidT) == typeid(PixelShaderUid)) ? "p" : (typeid(UidT) == typeid(VertexShaderUid)) ? "v" : "o", + ++num_failures); + + // TODO: Should also dump uids + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); + file << "Old shader code:\n" << old_code; + file << "\n\nNew shader code:\n" << new_code.GetBuffer(); + file.close(); + + // TODO: Make this more idiot-proof + ERROR_LOG(VIDEO, "%s shader uid mismatch!", + (typeid(UidT) == typeid(PixelShaderUid)) ? "Pixel" : (typeid(UidT) == typeid(VertexShaderUid)) ? "Vertex" : "Other"); + } + } +} + #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 452ee7fd3f..7c1553890b 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -524,6 +524,13 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) { GenerateVertexShader(object, components, api_type); + + if (g_ActiveConfig.bEnableShaderDebugging) + { + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_OPENGL); + CheckForUidMismatch(code, object); + } } void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 81621d2d38..0d571c29a9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -23,9 +23,6 @@ #include "ImageWrite.h" #include "Render.h" -#include -#include - namespace OGL { @@ -356,73 +353,12 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code ) return result; } -template UidT GetPartialUid(const SHADERUID& uid); -template<> PixelShaderUid GetPartialUid(const SHADERUID& uid) { return uid.puid; } -template<> VertexShaderUid GetPartialUid(const SHADERUID& uid) { return uid.vuid; } - -template const std::string& GetShaderCode(const SHADER& shader); -template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strpprog; } -template<> const std::string& GetShaderCode(const SHADER& shader) { return shader.strvprog; } - -template -void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_code, const UidT& new_uid) -{ - static std::map s_shaders; - static std::vector s_uids; - - bool uid_is_indexed = std::find(s_uids.begin(), s_uids.end(), new_uid) != s_uids.end(); - if (!uid_is_indexed) - { - s_uids.push_back(new_uid); - s_shaders[new_uid] = new_code.GetBuffer(); - } - else - { - // uid is already in the index => check if there's a shader with the same uid but different code - auto& old_code = s_shaders[new_uid]; - if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0) - { - static int num_failures = 0; - - char szTemp[MAX_PATH]; - sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), - (typeid(UidT) == typeid(PixelShaderUid)) ? "p" : (typeid(UidT) == typeid(VertexShaderUid)) ? "v" : "o", - ++num_failures); - - // TODO: Should also dump uids - std::ofstream file; - OpenFStream(file, szTemp, std::ios_base::out); - file << "Old shader code:\n" << old_code; - file << "\n\nNew shader code:\n" << new_code.GetBuffer(); - file.close(); - - // TODO: Make this more idiot-proof - ERROR_LOG(VIDEO, "%s shader uid mismatch!", - (typeid(UidT) == typeid(PixelShaderUid)) ? "Pixel" : (typeid(UidT) == typeid(VertexShaderUid)) ? "Vertex" : "Other"); - } - } -} - - void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components) { GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components); GetVertexShaderUid(uid->vuid, components, API_OPENGL); - - if (g_ActiveConfig.bEnableShaderDebugging) - { - PixelShaderCode pcode; - VertexShaderCode vcode; - - GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); - GenerateVertexShaderCode(vcode, components, API_OPENGL); - - CheckForUidMismatch(pshaders, pcode, uid->puid); - CheckForUidMismatch(pshaders, vcode, uid->vuid); - } } - ProgramShaderCache::PCacheEntry ProgramShaderCache::GetShaderProgram(void) { return *last_entry; From 31d2cab8d3a6344043e00731d9892670e490129d Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 12:55:42 +0200 Subject: [PATCH 036/352] Add ShaderGenCommon to vcproj file list. --- Source/Core/VideoCommon/VideoCommon.vcxproj | 1 + Source/Core/VideoCommon/VideoCommon.vcxproj.filters | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index f785cb5c84..1baf417797 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -250,6 +250,7 @@ + diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index 330b23d370..e988d34e12 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -258,6 +258,9 @@ Util + + Shader Generators + @@ -291,4 +294,4 @@ {e2a527a2-ccc8-4ab8-a93e-dd2628c0f3b6} - + \ No newline at end of file From fab4f1d0a50c2c4c0a4e7e41b6ebe58118438dc0 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 13:38:31 +0200 Subject: [PATCH 037/352] LightingShaderGen: Improve code flexibility. --- .../Core/VideoCommon/Src/LightingShaderGen.h | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index ff19b737f4..2a354aaf8d 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -22,6 +22,41 @@ #include "NativeVertexFormat.h" #include "XFMemory.h" +static const char* LightCol(const char* lightsName, unsigned int index, const char* swizzle) +{ + static char result[16]; + snprintf(result, sizeof(result), "%s[%d].col.%s", lightsName, index, swizzle); + return result; +} + +static const char* LightCosAtt(const char* lightsName, unsigned int index) +{ + static char result[16]; + snprintf(result, sizeof(result), "%s[%d].cosatt", lightsName, index); + return result; +} + +static const char* LightDistAtt(const char* lightsName, unsigned int index) +{ + static char result[16]; + snprintf(result, sizeof(result), "%s[%d].distatt", lightsName, index); + return result; +} + +static const char* LightPos(const char* lightsName, unsigned int index) +{ + static char result[16]; + snprintf(result, sizeof(result), "%s[%d].pos", lightsName, index); + return result; +} + +static const char* LightDir(const char* lightsName, unsigned int index) +{ + static char result[16]; + snprintf(result, sizeof(result), "%s[%d].dir", lightsName, index); + return result; +} + template static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) { @@ -36,13 +71,13 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, // atten disabled switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += %s[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + object.Write("lacc.%s += %s;\n", swizzle, LightCol(lightsName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - object.Write("ldir = normalize(%s[%d].pos.xyz - pos.xyz);\n", lightsName, index); - object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s[%d].col.%s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", lightsName, index, swizzle); + object.Write("ldir = normalize(%s.xyz - pos.xyz);\n", LightPos(lightsName, index)); + object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s;\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", LightCol(lightsName, index, swizzle)); break; default: _assert_(0); } @@ -51,33 +86,31 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, if (chan.attnfunc == 3) { // spot - object.Write("ldir = %s[%d].pos.xyz - pos.xyz;\n", lightsName, index); + object.Write("ldir = %s.xyz - pos.xyz;\n", LightPos(lightsName, index)); object.Write("dist2 = dot(ldir, ldir);\n" "dist = sqrt(dist2);\n" "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s[%d].dir.xyz));\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot(%s[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", lightsName, index, lightsName, index); + "attn = max(0.0f, dot(ldir, %s.xyz));\n", LightDir(lightsName, index)); + object.Write("attn = max(0.0f, dot(%s.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.xyz, float3(1.0f,dist,dist2));\n", LightCosAtt(lightsName, index), LightDistAtt(lightsName, index)); } else if (chan.attnfunc == 1) { // specular - object.Write("ldir = normalize(%s[%d].pos.xyz);\n", lightsName, index); - object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s[%d].dir.xyz)) : 0.0f;\n", lightsName, index); - object.Write("attn = max(0.0f, dot(%s[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot(%s[%d].distatt.xyz, float3(1,attn,attn*attn));\n", lightsName, index, lightsName, index); + object.Write("ldir = normalize(%s.xyz);\n", LightPos(lightsName, index)); + object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.xyz)) : 0.0f;\n", LightDir(lightsName, index)); + object.Write("attn = max(0.0f, dot(%s.xyz, float3(1,attn,attn*attn))) / dot(%s.xyz, float3(1,attn,attn*attn));\n", LightCosAtt(lightsName, index), LightDistAtt(lightsName, index)); } switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += attn * %s[%d].col.%s;\n", swizzle, lightsName, index, swizzle); + object.Write("lacc.%s += attn * %s;\n", swizzle, LightCol(lightsName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s[%d].col.%s;\n", + object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s;\n", swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", - lightsName, - index, - swizzle); + LightCol(lightsName, index, swizzle)); break; default: _assert_(0); } From abde070f63f62a784dcb59fadd0e72013fa03acf Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 14:25:18 +0200 Subject: [PATCH 038/352] LightingShaderGen: Use a float4 array for lights instead of a struct (uniform management in the non-UBO path is a mess otherwise). Also fix a small bug (cf. revision 154c533e7632). --- .../Core/VideoCommon/Src/LightingShaderGen.h | 20 +++++++++---------- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 3 +-- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 2 +- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 5 ++--- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index 2a354aaf8d..b534d767cc 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -24,36 +24,36 @@ static const char* LightCol(const char* lightsName, unsigned int index, const char* swizzle) { - static char result[16]; - snprintf(result, sizeof(result), "%s[%d].col.%s", lightsName, index, swizzle); + static char result[32]; + snprintf(result, sizeof(result), "%s[5*%d].%s", lightsName, index, swizzle); return result; } static const char* LightCosAtt(const char* lightsName, unsigned int index) { - static char result[16]; - snprintf(result, sizeof(result), "%s[%d].cosatt", lightsName, index); + static char result[32]; + snprintf(result, sizeof(result), "%s[5*%d+1]", lightsName, index); return result; } static const char* LightDistAtt(const char* lightsName, unsigned int index) { - static char result[16]; - snprintf(result, sizeof(result), "%s[%d].distatt", lightsName, index); + static char result[32]; + snprintf(result, sizeof(result), "%s[5*%d+2]", lightsName, index); return result; } static const char* LightPos(const char* lightsName, unsigned int index) { - static char result[16]; - snprintf(result, sizeof(result), "%s[%d].pos", lightsName, index); + static char result[32]; + snprintf(result, sizeof(result), "%s[5*%d+3]", lightsName, index); return result; } static const char* LightDir(const char* lightsName, unsigned int index) { - static char result[16]; - snprintf(result, sizeof(result), "%s[%d].dir", lightsName, index); + static char result[32]; + snprintf(result, sizeof(result), "%s[5*%d+4]", lightsName, index); return result; } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 2d9121856c..4dbb56b320 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -338,8 +338,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u out.Write("\t%sfloat4 " I_FOG"[3] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_FOG)); // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! - out.Write("struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); - out.Write("\t%sLight " I_PLIGHTS"[8] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); + out.Write("\t%sfloat4 " I_PLIGHTS"[40] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); out.Write("\t%sfloat4 " I_PMATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PMATERIALS)); if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 07af93c295..8356b7defe 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 7c1553890b..52c3aeaf30 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -106,8 +106,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_POSNORMALMATRIX, "float4", I_POSNORMALMATRIX"[6]"); DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PROJECTION, "float4", I_PROJECTION"[4]"); DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_MATERIALS, "float4", I_MATERIALS"[4]"); - out.Write("struct Light { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; };\n"); - DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_LIGHTS, "Light", I_LIGHTS"[8]"); + DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_LIGHTS, "float4", I_LIGHTS"[40]"); DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TEXMATRICES, "float4", I_TEXMATRICES"[24]"); DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TRANSFORMMATRICES, "float4", I_TRANSFORMMATRICES"[64]"); DeclareUniform(out, api_type, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_NORMALMATRICES, "float4", I_NORMALMATRICES"[32]"); @@ -337,7 +336,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) // transform the light dir into tangent space uid_data.texMtxInfo[i].embosslightshift = xfregs.texMtxInfo[i].embosslightshift; uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift; - out.Write("ldir = normalize(" I_LIGHTS"[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift); + out.Write("ldir = normalize(%s.xyz - pos.xyz);\n", LightPos(I_LIGHTS, texinfo.embosslightshift)); out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); } else From e7a5847c304117c45cd1f9012101627043a58e95 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 14:44:09 +0200 Subject: [PATCH 039/352] ShaderGen: Build fix. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 2 +- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 7 +++---- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 4dbb56b320..918b8237d6 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -1211,7 +1211,7 @@ void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_T { PixelShaderCode code; GeneratePixelShaderCode(code, dstAlphaMode, API_OPENGL, components); - CheckForUidMismatch(code, object); + CheckForUidMismatch(code, object, "Pixel", "p"); } } diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 8356b7defe..5ad20aa3c7 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -175,7 +175,7 @@ typedef ShaderUid PixelShaderUid; typedef ShaderUid VertexShaderUid; template -void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid) +void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid, const char* shader_type, const char* dump_prefix) { static std::map s_shaders; static std::vector s_uids; @@ -196,7 +196,7 @@ void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid) char szTemp[MAX_PATH]; sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), - (typeid(UidT) == typeid(PixelShaderUid)) ? "p" : (typeid(UidT) == typeid(VertexShaderUid)) ? "v" : "o", + dump_prefix, ++num_failures); // TODO: Should also dump uids @@ -207,8 +207,7 @@ void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid) file.close(); // TODO: Make this more idiot-proof - ERROR_LOG(VIDEO, "%s shader uid mismatch!", - (typeid(UidT) == typeid(PixelShaderUid)) ? "Pixel" : (typeid(UidT) == typeid(VertexShaderUid)) ? "Vertex" : "Other"); + ERROR_LOG(VIDEO, "%s shader uid mismatch!", shader_type); } } } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 52c3aeaf30..294e363756 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -528,7 +528,7 @@ void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_ty { VertexShaderCode code; GenerateVertexShaderCode(code, components, API_OPENGL); - CheckForUidMismatch(code, object); + CheckForUidMismatch(code, object, "Vertex", "v"); } } From 7480f5dfd678bd5bb6b05b309155c81cfa2c42f5 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 10 Apr 2013 14:55:46 +0200 Subject: [PATCH 040/352] ShaderGenCommon: Clean up. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 5ad20aa3c7..e148fac54c 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -23,7 +23,6 @@ #include #include #include -#include #include "CommonTypes.h" #include "VideoCommon.h" @@ -168,12 +167,6 @@ struct LightingUidData } lit_chans[4]; }; -struct pixel_shader_uid_data; -struct vertex_shader_uid_data; - -typedef ShaderUid PixelShaderUid; -typedef ShaderUid VertexShaderUid; - template void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid, const char* shader_type, const char* dump_prefix) { From a03c35eb70ad88fecc69abb3605909ba1b8bb6fa Mon Sep 17 00:00:00 2001 From: skidau Date: Thu, 25 Apr 2013 10:33:57 +1000 Subject: [PATCH 041/352] Removed the old Accurate VBeam emulation setting from the game ini's. --- Data/User/GameConfig/G3FE69.ini | 1 - Data/User/GameConfig/G3FF69.ini | 1 - Data/User/GameConfig/G3FP69.ini | 1 - Data/User/GameConfig/GM4E01.ini | 1 - Data/User/GameConfig/GM4J01.ini | 1 - Data/User/GameConfig/GM4P01.ini | 1 - Data/User/GameConfig/GSWE64.ini | 1 - Data/User/GameConfig/GSWP64.ini | 1 - Data/User/GameConfig/GSWS64.ini | 1 - Data/User/GameConfig/RBHE08.ini | 1 - Data/User/GameConfig/RBHJ08.ini | 1 - Data/User/GameConfig/RBHP08.ini | 1 - 12 files changed, 12 deletions(-) diff --git a/Data/User/GameConfig/G3FE69.ini b/Data/User/GameConfig/G3FE69.ini index 2f628b7bab..6e902ad0fa 100644 --- a/Data/User/GameConfig/G3FE69.ini +++ b/Data/User/GameConfig/G3FE69.ini @@ -15,7 +15,6 @@ PH_ZFar = [Gecko] [Core] MMU = 1 -VBeam = 1 BlockMerging = 1 [Video_Settings] SafeTextureCacheColorSamples = 0 diff --git a/Data/User/GameConfig/G3FF69.ini b/Data/User/GameConfig/G3FF69.ini index 7367649d4b..37af95e657 100644 --- a/Data/User/GameConfig/G3FF69.ini +++ b/Data/User/GameConfig/G3FF69.ini @@ -15,7 +15,6 @@ PH_ZFar = [Gecko] [Core] MMU = 1 -VBeam = 1 BlockMerging = 1 [Video_Settings] SafeTextureCacheColorSamples = 0 diff --git a/Data/User/GameConfig/G3FP69.ini b/Data/User/GameConfig/G3FP69.ini index 0272d70fde..cd74b017bf 100644 --- a/Data/User/GameConfig/G3FP69.ini +++ b/Data/User/GameConfig/G3FP69.ini @@ -15,7 +15,6 @@ PH_ZFar = [Gecko] [Core] MMU = 1 -VBeam = 1 BlockMerging = 1 [Video_Settings] SafeTextureCacheColorSamples = 0 diff --git a/Data/User/GameConfig/GM4E01.ini b/Data/User/GameConfig/GM4E01.ini index c63b0d8a1b..5daa37570e 100644 --- a/Data/User/GameConfig/GM4E01.ini +++ b/Data/User/GameConfig/GM4E01.ini @@ -128,4 +128,3 @@ PH_ZNear = PH_ZFar = [Gecko] [Core] -VBeam = 1 diff --git a/Data/User/GameConfig/GM4J01.ini b/Data/User/GameConfig/GM4J01.ini index 9431bc933a..b9d39df920 100644 --- a/Data/User/GameConfig/GM4J01.ini +++ b/Data/User/GameConfig/GM4J01.ini @@ -14,4 +14,3 @@ PH_ZNear = PH_ZFar = [Gecko] [Core] -VBeam = 1 diff --git a/Data/User/GameConfig/GM4P01.ini b/Data/User/GameConfig/GM4P01.ini index f9cd8b3a71..1ab428de05 100644 --- a/Data/User/GameConfig/GM4P01.ini +++ b/Data/User/GameConfig/GM4P01.ini @@ -139,4 +139,3 @@ $Goraud Shading [Video] ProjectionHack = 0 [Core] -VBeam = 1 diff --git a/Data/User/GameConfig/GSWE64.ini b/Data/User/GameConfig/GSWE64.ini index 75f82caf63..95246f3c8f 100644 --- a/Data/User/GameConfig/GSWE64.ini +++ b/Data/User/GameConfig/GSWE64.ini @@ -3,7 +3,6 @@ MMU = 1 BAT = 1 FastDiscSpeed = 1 -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationIssues = EmulationStateId = 3 diff --git a/Data/User/GameConfig/GSWP64.ini b/Data/User/GameConfig/GSWP64.ini index c580edee4f..3083317042 100644 --- a/Data/User/GameConfig/GSWP64.ini +++ b/Data/User/GameConfig/GSWP64.ini @@ -3,7 +3,6 @@ MMU = 1 BAT = 1 FastDiscSpeed = 1 -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationIssues = EmulationStateId = 3 diff --git a/Data/User/GameConfig/GSWS64.ini b/Data/User/GameConfig/GSWS64.ini index 8bcb77f296..5f3512743a 100644 --- a/Data/User/GameConfig/GSWS64.ini +++ b/Data/User/GameConfig/GSWS64.ini @@ -3,7 +3,6 @@ MMU = 1 BAT = 1 FastDiscSpeed = 1 -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationIssues = EmulationStateId = 3 diff --git a/Data/User/GameConfig/RBHE08.ini b/Data/User/GameConfig/RBHE08.ini index 80fb2a796e..2def435787 100644 --- a/Data/User/GameConfig/RBHE08.ini +++ b/Data/User/GameConfig/RBHE08.ini @@ -1,6 +1,5 @@ # RBHE08 - Resident Evil Archives: Resident Evil Zero [Core] Values set here will override the main dolphin settings. -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 5 EmulationIssues = diff --git a/Data/User/GameConfig/RBHJ08.ini b/Data/User/GameConfig/RBHJ08.ini index 7ed45e1ee7..6ff5f267ba 100644 --- a/Data/User/GameConfig/RBHJ08.ini +++ b/Data/User/GameConfig/RBHJ08.ini @@ -1,6 +1,5 @@ # RBHJ08 - Biohazard 0 [Core] Values set here will override the main dolphin settings. -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 5 EmulationIssues = diff --git a/Data/User/GameConfig/RBHP08.ini b/Data/User/GameConfig/RBHP08.ini index ee4c6ec35f..0703e1fc4f 100644 --- a/Data/User/GameConfig/RBHP08.ini +++ b/Data/User/GameConfig/RBHP08.ini @@ -1,6 +1,5 @@ # RBHP08 - Resident Evil Archives: Resident Evil Zero [Core] Values set here will override the main dolphin settings. -VBeam = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 5 EmulationIssues = From a2b543d47f81af22cb70182bde84a23f719a35f0 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Thu, 25 Apr 2013 14:23:56 +1200 Subject: [PATCH 042/352] request_queue may not have anything in it on return from ExecuteCommand i.e. when calling ES_Launch and everything is reset. Don't call Update after queuing a request. --- Source/Core/Core/Src/HW/WII_IPC.cpp | 7 +++++-- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp index dce6c3481b..b77ba33ef9 100644 --- a/Source/Core/Core/Src/HW/WII_IPC.cpp +++ b/Source/Core/Core/Src/HW/WII_IPC.cpp @@ -212,8 +212,11 @@ void Write32(const u32 _Value, const u32 _Address) _dbg_assert_msg_(WII_IPC, 0, "w32 %08x @ %08x", _Value, _Address); break; } - - //WII_IPC_HLE_Interface::Update(); + + if((_Address & 0xFFFF) != IPC_PPCCTRL) + { + WII_IPC_HLE_Interface::Update(); + } CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 989c43aac9..fc77354947 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -566,7 +566,8 @@ void Update() INFO_LOG(WII_IPC_HLE, "||-- Acknowledge IPC Request @ 0x%08x", request_queue.front()); ExecuteCommand(request_queue.front()); - request_queue.pop_front(); + if(request_queue.size()) + request_queue.pop_front(); #if MAX_LOGLEVEL >= DEBUG_LEVEL Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); From 7c50ac931d79be9e1f4d62053af3764fdf93e9d6 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Thu, 25 Apr 2013 14:37:12 +1200 Subject: [PATCH 043/352] Update before enqueue. --- Source/Core/Core/Src/HW/WII_IPC.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp index b77ba33ef9..0a7c31110d 100644 --- a/Source/Core/Core/Src/HW/WII_IPC.cpp +++ b/Source/Core/Core/Src/HW/WII_IPC.cpp @@ -182,6 +182,7 @@ void Write32(const u32 _Value, const u32 _Address) if (ctrl.X1) { INFO_LOG(WII_IPC, "New pointer available: %08x", ppc_msg); + WII_IPC_HLE_Interface::Update(); // Let the HLE handle the request on it's own time WII_IPC_HLE_Interface::EnqRequest(ppc_msg); } From d18b71ccf91c9578236b44ae26e8bc35314cc180 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Thu, 25 Apr 2013 15:28:42 +1200 Subject: [PATCH 044/352] Back to broken ES_launch but 4 wiimotes working. --- Source/Core/Core/Src/HW/WII_IPC.cpp | 8 ++------ Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 7 +++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp index 0a7c31110d..b09d83f44b 100644 --- a/Source/Core/Core/Src/HW/WII_IPC.cpp +++ b/Source/Core/Core/Src/HW/WII_IPC.cpp @@ -182,7 +182,6 @@ void Write32(const u32 _Value, const u32 _Address) if (ctrl.X1) { INFO_LOG(WII_IPC, "New pointer available: %08x", ppc_msg); - WII_IPC_HLE_Interface::Update(); // Let the HLE handle the request on it's own time WII_IPC_HLE_Interface::EnqRequest(ppc_msg); } @@ -212,12 +211,9 @@ void Write32(const u32 _Value, const u32 _Address) default: _dbg_assert_msg_(WII_IPC, 0, "w32 %08x @ %08x", _Value, _Address); break; - } - - if((_Address & 0xFFFF) != IPC_PPCCTRL) - { - WII_IPC_HLE_Interface::Update(); } + + WII_IPC_HLE_Interface::Update(); CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index fc77354947..439d37c5d9 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -564,10 +564,9 @@ void Update() { WII_IPCInterface::GenerateAck(request_queue.front()); INFO_LOG(WII_IPC_HLE, "||-- Acknowledge IPC Request @ 0x%08x", request_queue.front()); - - ExecuteCommand(request_queue.front()); - if(request_queue.size()) - request_queue.pop_front(); + u32 command = request_queue.front(); + request_queue.pop_front(); + ExecuteCommand(command); #if MAX_LOGLEVEL >= DEBUG_LEVEL Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); From eef95fa4c5919bf93335e10dd61cd5a9fd6a5f6d Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Thu, 25 Apr 2013 13:30:41 +0200 Subject: [PATCH 045/352] ShaderGenCommon: Adding documentation. --- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index e148fac54c..4b3d16b8d7 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -27,18 +27,55 @@ #include "CommonTypes.h" #include "VideoCommon.h" +/** + * Common interface for classes that need to go through the shader generation path (GenerateVertexShader, GeneratePixelShader) + * In particular, this includes the shader code generator (ShaderCode). + * A different class (ShaderUid) can be used to uniquely identify each ShaderCode object. + * More interesting things can be done with this, e.g. ShaderConstantProfile checks what shader constants are being used. This can be used to optimize buffer management. + * Each of the ShaderCode, ShaderUid and ShaderConstantProfile child classes only implement the subset of ShaderGeneratorInterface methods that are required for the specific tasks. + */ class ShaderGeneratorInterface { public: + /* + * Used when the shader generator would write a piece of ShaderCode. + * Can be used like printf. + * @note In the ShaderCode implementation, this does indeed write the parameter string to an internal buffer. However, you're free to do whatever you like with the parameter. + */ void Write(const char* fmt, ...) {} + + /* + * Returns a read pointer to the internal buffer. + * @note When implementing this method in a child class, you likely want to return the argument of the last SetBuffer call here + * @note SetBuffer() should be called before using GetBuffer(). + */ const char* GetBuffer() { return NULL; } + + /* + * Can be used to give the object a place to write to. This should be called before using Write(). + * @param buffer pointer to a char buffer that the object can write to + */ void SetBuffer(char* buffer) { } + + /* + * Tells us that a specific constant range (including last_index) is being used by the shader + */ inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} + /* + * Returns a pointer to an internally stored object of the uid_data type. + * @warning since most child classes use the default implementation you shouldn't access this directly without adding precautions against NULL access (e.g. via adding a dummy structure, cf. the vertex/pixel shader generators) + */ template uid_data& GetUidData() { return *(uid_data*)NULL; } }; +/** + * Shader UID class used to uniquely identify the ShaderCode output written in the shader generator. + * uid_data can be any struct of parameters that uniquely identify each shader code output. + * Unless performance is not an issue, uid_data should be tightly packed to reduce memory footprint. + * Shader generators will write to specific uid_data fields; ShaderUid methods will only read raw u32 values from a union. + */ template class ShaderUid : public ShaderGeneratorInterface { @@ -59,9 +96,10 @@ public: return memcmp(this->values, obj.values, sizeof(values)) != 0; } - // TODO: Store last frame used and order by that? makes much more sense anyway... + // determines the storage order inside STL containers bool operator < (const ShaderUid& obj) const { + // TODO: Store last frame used and order by that? makes much more sense anyway... for (unsigned int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i) { if (this->values[i] < obj.values[i]) @@ -107,6 +145,9 @@ private: char* write_ptr; }; +/** + * Generates a shader constant profile which can be used to query which constants are used in a shader + */ class ShaderConstantProfile : public ShaderGeneratorInterface { public: @@ -120,6 +161,7 @@ public: inline bool ConstantIsUsed(unsigned int index) { + // TODO: Not ready for usage yet return true; // return constant_usage[index]; } @@ -154,6 +196,10 @@ static void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const object.Write(";\n"); } +/** + * Common uid data used for shader generators that use lighting calculations. + * Expected to be stored as a member called "lighting". + */ struct LightingUidData { struct @@ -167,9 +213,13 @@ struct LightingUidData } lit_chans[4]; }; +/** + * Checks if there has been + */ template void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid, const char* shader_type, const char* dump_prefix) { + // TODO: Might be sensitive to config changes static std::map s_shaders; static std::vector s_uids; From 3b732f695d7f06da54e97e517849be9e27e6ef13 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Thu, 25 Apr 2013 19:59:08 -0400 Subject: [PATCH 046/352] Show video backend and audio engine in title bar. Fixes issue 6276. --- Source/Core/Core/Src/Core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 0d8752195f..661271e829 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -680,7 +680,8 @@ void UpdateTitle() u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime); // Settings are shown the same for both extended and summary info - std::string SSettings = StringFromFormat("%s %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC"); + std::string SSettings = StringFromFormat("%s %s - %s - %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", + _CoreParameter.m_strVideoBackend.c_str(), _CoreParameter.bDSPHLE ? "DSPHLE" : "DSPLLE"); // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. From 03dfe7b816a16c976e0106b56c69c956b6cb9426 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 25 Apr 2013 23:41:45 -0500 Subject: [PATCH 047/352] The evdpy should be used for the X11 window creation and in the event thread. dpy should only be used for GL. --- Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp index dd04ee0c73..4177cecb85 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp @@ -157,7 +157,7 @@ void cX11Window::CreateXWindow(void) void cX11Window::DestroyXWindow(void) { - XUnmapWindow(GLWin.dpy, GLWin.win); + XUnmapWindow(GLWin.evdpy, GLWin.win); GLWin.win = 0; if (GLWin.xEventThread.joinable()) GLWin.xEventThread.join(); @@ -175,9 +175,9 @@ void cX11Window::XEventThread() { XEvent event; KeySym key; - for (int num_events = XPending(GLWin.dpy); num_events > 0; num_events--) + for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) { - XNextEvent(GLWin.dpy, &event); + XNextEvent(GLWin.evdpy, &event); switch(event.type) { case KeyPress: key = XLookupKeysym((XKeyEvent*)&event, 0); @@ -305,17 +305,17 @@ void cX11Window::XEventThread() case ConfigureNotify: Window winDummy; unsigned int borderDummy, depthDummy; - XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, + XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &depthDummy); GLInterface->SetBackBufferDimensions(GLWin.width, GLWin.height); break; case ClientMessage: if ((unsigned long) event.xclient.data.l[0] == - XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False)) + XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) Host_Message(WM_USER_STOP); if ((unsigned long) event.xclient.data.l[0] == - XInternAtom(GLWin.dpy, "RESIZE", False)) - XMoveResizeWindow(GLWin.dpy, GLWin.win, + XInternAtom(GLWin.evdpy, "RESIZE", False)) + XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1], event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); break; From 5afceca7a10a2d993e53ba348ee55836d7831f8e Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Fri, 26 Apr 2013 02:47:11 -0400 Subject: [PATCH 048/352] Apparently we can't trust m_strVideoBackend on osx. --- Source/Core/Core/Src/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 661271e829..20cbc5086a 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -681,7 +681,7 @@ void UpdateTitle() // Settings are shown the same for both extended and summary info std::string SSettings = StringFromFormat("%s %s - %s - %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", - _CoreParameter.m_strVideoBackend.c_str(), _CoreParameter.bDSPHLE ? "DSPHLE" : "DSPLLE"); + g_video_backend->GetName().c_str(), _CoreParameter.bDSPHLE ? "DSPHLE" : "DSPLLE"); // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. From 1666e091ef2f40c17005a134551c78b73521ca7d Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 26 Apr 2013 10:53:46 -0500 Subject: [PATCH 049/352] Make EGL and X11 dpy/evdpy usage consistent. EGL needs testing. --- Source/Core/DolphinWX/Src/GLInterface/GLX.cpp | 4 +- .../DolphinWX/Src/GLInterface/X11_Util.cpp | 38 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Source/Core/DolphinWX/Src/GLInterface/GLX.cpp b/Source/Core/DolphinWX/Src/GLInterface/GLX.cpp index 84a753c784..929d365081 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/GLX.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/GLX.cpp @@ -25,7 +25,7 @@ // Show the current FPS void cInterfaceGLX::UpdateFPSDisplay(const char *text) { - XStoreName(GLWin.dpy, GLWin.win, text); + XStoreName(GLWin.evdpy, GLWin.win, text); } void cInterfaceGLX::SwapInterval(int Interval) @@ -136,7 +136,7 @@ bool cInterfaceGLX::MakeCurrent() #if defined(HAVE_WX) && (HAVE_WX) Host_GetRenderWindowSize(GLWin.x, GLWin.y, (int&)GLWin.width, (int&)GLWin.height); - XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, + XMoveResizeWindow(GLWin.evdpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height); #endif return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); diff --git a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp index 4177cecb85..f6e678151f 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp @@ -24,9 +24,9 @@ #if USE_EGL bool cXInterface::ServerConnect(void) { - GLWin.evdpy = XOpenDisplay(NULL); + GLWin.dpy = XOpenDisplay(NULL); - if (!GLWin.evdpy) + if (!GLWin.dpy) return false; return true; @@ -39,7 +39,7 @@ bool cXInterface::Initialize(void *config) int num_visuals; EGLint vid; - if (!GLWin.evdpy) { + if (!GLWin.dpy) { printf("Error: couldn't open X display\n"); return false; } @@ -51,7 +51,7 @@ bool cXInterface::Initialize(void *config) /* The X window visual must match the EGL config */ visTemplate.visualid = vid; - GLWin.vi = XGetVisualInfo(GLWin.evdpy, VisualIDMask, &visTemplate, &num_visuals); + GLWin.vi = XGetVisualInfo(GLWin.dpy, VisualIDMask, &visTemplate, &num_visuals); if (!GLWin.vi) { printf("Error: couldn't get X visual\n"); exit(1); @@ -64,12 +64,12 @@ bool cXInterface::Initialize(void *config) GLWin.width = _twidth; GLWin.height = _theight; - GLWin.dpy = XOpenDisplay(NULL); + GLWin.evdpy = XOpenDisplay(NULL); GLWin.parent = GLWin.win; - GLWin.screen = DefaultScreen(GLWin.evdpy); + GLWin.screen = DefaultScreen(GLWin.dpy); if (GLWin.parent == 0) - GLWin.parent = RootWindow(GLWin.evdpy, GLWin.screen); + GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen); /* Set initial projection/viewing transformation. * We can't be sure we'll get a ConfigureNotify event when the window @@ -82,7 +82,7 @@ bool cXInterface::Initialize(void *config) void *cXInterface::EGLGetDisplay(void) { - return eglGetDisplay(GLWin.evdpy); + return eglGetDisplay(GLWin.dpy); } void *cXInterface::CreateWindow(void) @@ -90,22 +90,22 @@ void *cXInterface::CreateWindow(void) Atom wmProtocols[1]; // Setup window attributes - GLWin.attr.colormap = XCreateColormap(GLWin.dpy, + GLWin.attr.colormap = XCreateColormap(GLWin.evdpy, GLWin.parent, GLWin.vi->visual, AllocNone); GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask; - GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen); + GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen); GLWin.attr.border_pixel = 0; // Create the window - GLWin.win = XCreateWindow(GLWin.dpy, GLWin.parent, + GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent, GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual, CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr); - wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); - XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 1); - XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); - XMapRaised(GLWin.dpy, GLWin.win); - XSync(GLWin.dpy, True); + wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True); + XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1); + XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); + XMapRaised(GLWin.evdpy, GLWin.win); + XSync(GLWin.evdpy, True); GLWin.xEventThread = std::thread(&cXInterface::XEventThread, this); // Control window size and picture scaling @@ -116,16 +116,16 @@ void *cXInterface::CreateWindow(void) void cXInterface::DestroyWindow(void) { - XDestroyWindow(GLWin.dpy, GLWin.win); + XDestroyWindow(GLWin.evdpy, GLWin.win); GLWin.win = 0; if (GLWin.xEventThread.joinable()) GLWin.xEventThread.join(); - XFreeColormap(GLWin.dpy, GLWin.attr.colormap); + XFreeColormap(GLWin.evdpy, GLWin.attr.colormap); } void cXInterface::UpdateFPSDisplay(const char *text) { - XStoreName(GLWin.dpy, GLWin.win, text); + XStoreName(GLWin.evdpy, GLWin.win, text); } void cXInterface::XEventThread() From 2c8c6304d7b02e1e94ab7a8ebfc96f27864a7481 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 26 Apr 2013 11:35:42 -0500 Subject: [PATCH 050/352] Make sure the EGL evdpy is closed. --- Source/Core/DolphinWX/Src/GLInterface/Platform.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Core/DolphinWX/Src/GLInterface/Platform.cpp b/Source/Core/DolphinWX/Src/GLInterface/Platform.cpp index 83f064615c..64e32591d8 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/Platform.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/Platform.cpp @@ -115,7 +115,10 @@ out: #if HAVE_X11 if (selected_platform != EGL_PLATFORM_X11) { if (GLWin.dpy) + { XCloseDisplay(GLWin.dpy); + XCloseDisplay(GLWin.evdpy); + } } #endif if (selected_platform == EGL_PLATFORM_NONE) From 8dbe2366063f74b3f15dcdf18dcaea91e4bb1a61 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Mon, 29 Apr 2013 12:00:23 -0400 Subject: [PATCH 051/352] =?UTF-8?q?=EF=BB=BFFixing=20or=20disabling=20the?= =?UTF-8?q?=20"Download=20Codes=20(WiiRD=20Database)"=20button=20problem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Download Codes (WiiRD Database)" button is enabled (and its click return silently without an effect) when "Tools → Cheats Manager" is opened when there's a running emulation for which there's no "[Gecko]" ini section, confusing the user about the reason for not downloading codes or showing an error when there's no running emulation Solution when there's a running emulation: fix the button when there's no running emulation: disable the button (to indicate to the user that this button must be clicked elsewhere, in the ISO settings dialog, the user will realise or remember) --- Source/Core/DolphinWX/Src/CheatsWindow.cpp | 2 +- Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp | 6 +++++- Source/Core/DolphinWX/Src/GeckoCodeDiag.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.cpp b/Source/Core/DolphinWX/Src/CheatsWindow.cpp index e3a51208b4..ba4918c917 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.cpp +++ b/Source/Core/DolphinWX/Src/CheatsWindow.cpp @@ -39,7 +39,7 @@ wxCheatsWindow::wxCheatsWindow(wxWindow* const parent) { m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + vol->GetUniqueID() + ".ini"; m_gameini.Load(m_gameini_path); - m_geckocode_panel->LoadCodes(m_gameini); + m_geckocode_panel->LoadCodes(m_gameini, Core::g_CoreStartupParameter.GetUniqueID()); } } diff --git a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp index 9f96956abc..12685fac75 100644 --- a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp +++ b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp @@ -41,7 +41,8 @@ CodeConfigPanel::CodeConfigPanel(wxWindow* const parent) // button sizer wxBoxSizer* const sizer_buttons = new wxBoxSizer(wxHORIZONTAL); - wxButton* const btn_download = new wxButton(this, -1, _("Download Codes (WiiRD Database)"), wxDefaultPosition, wxSize(128, -1)); + btn_download = new wxButton(this, -1, _("Download Codes (WiiRD Database)"), wxDefaultPosition, wxSize(128, -1)); + btn_download->Enable(false); btn_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &CodeConfigPanel::DownloadCodes, this); sizer_buttons->AddStretchSpacer(1); sizer_buttons->Add(btn_download, 1, wxEXPAND); @@ -60,6 +61,9 @@ CodeConfigPanel::CodeConfigPanel(wxWindow* const parent) void CodeConfigPanel::UpdateCodeList() { + // disable the button if it doesn't have an effect + btn_download->Enable(!m_gameid.empty()); + m_listbox_gcodes->Clear(); // add the codes to the listbox std::vector::const_iterator diff --git a/Source/Core/DolphinWX/Src/GeckoCodeDiag.h b/Source/Core/DolphinWX/Src/GeckoCodeDiag.h index 8a59e09ce2..66bbdbd4bb 100644 --- a/Source/Core/DolphinWX/Src/GeckoCodeDiag.h +++ b/Source/Core/DolphinWX/Src/GeckoCodeDiag.h @@ -44,7 +44,7 @@ private: wxTextCtrl *textctrl_notes; wxListBox *listbox_codes; } m_infobox; - + wxButton* btn_download; }; From adab4e37f7dcfe9a60819a2ed1f8576b8a57a505 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 29 Apr 2013 19:37:32 +0200 Subject: [PATCH 052/352] Fix some mistakes from the master merge; some cleanups. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 10 +++++----- Source/Core/VideoCommon/Src/PixelShaderGen.h | 10 ++-------- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 7 +------ 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 4187c44d0f..1bf4ca25d8 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -254,7 +254,7 @@ const char *WriteLocation(API_TYPE ApiType) } template -void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; @@ -333,9 +333,9 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u if (ApiType == API_OPENGL) { - out.Write("COLOROUT(ocol0);\n"); + out.Write("COLOROUT(ocol0)\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) - out.Write("COLOROUT(ocol1);\n"); + out.Write("COLOROUT(ocol1)\n"); if (per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); @@ -572,7 +572,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u if (Pretest == AlphaTest::UNDETERMINED) WriteAlphaTest(out, uid_data, ApiType, dstAlphaMode, per_pixel_depth); - + // the screen space depth value = far z + (clip z / clip w) * z range if(ApiType == API_OPENGL || ApiType == API_D3D11) out.Write("float zCoord = rawpos.z;\n"); @@ -584,7 +584,7 @@ void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u } // Note: depth textures are disabled if early depth test is enabled - uid_data.ztex.op = bpmem.ztex2.op; + uid_data.ztex_op = bpmem.ztex2.op; uid_data.per_pixel_depth = per_pixel_depth; uid_data.fog.fsel = bpmem.fog.c_proj_fsel.fsel; diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 024bc170b5..783f50a301 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -86,7 +86,7 @@ struct pixel_shader_uid_data u32 bc3 : 3; u32 bi4 : 3; u32 bc4 : 3; - void SetValues(int index, u32 texcoord, u32 texmap) + inline void SetValues(int index, u32 texcoord, u32 texmap) { if (index == 0) { bc0 = texcoord; bi0 = texmap; } else if (index == 1) { bc1 = texcoord; bi1 = texmap; } @@ -180,7 +180,6 @@ struct pixel_shader_uid_data u32 comp0 : 3; u32 comp1 : 3; u32 logic : 2; - // TODO: ref??? u32 use_zcomploc_hack : 1; } alpha_test; @@ -194,12 +193,7 @@ struct pixel_shader_uid_data u32 hex : 4; } fog; - union { - struct { - u32 op : 2; - }; - u32 hex : 2; - } ztex; + u32 ztex_op : 2; u32 per_pixel_depth : 1; u32 bHasIndStage : 16; diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index eac041d5c9..81b8c79553 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -80,11 +80,6 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) _assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans); bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); - u32 lightMask = 0; - if (xfregs.numChan.numColorChans > 0) - lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask(); - if (xfregs.numChan.numColorChans > 1) - lightMask |= xfregs.color[1].GetFullLightMask() | xfregs.alpha[1].GetFullLightMask(); // uniforms if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) @@ -112,7 +107,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { out.Write("ATTRIN float4 rawpos; // ATTR%d,\n", SHADER_POSITION_ATTRIB); if (components & VB_HAS_POSMTXIDX) - out.Write("ATTRIN float posmtx; // ATTR%d,\n", SHADER_POSMTX_ATTRIB); + out.Write("ATTRIN float fposmtx; // ATTR%d,\n", SHADER_POSMTX_ATTRIB); if (components & VB_HAS_NRM0) out.Write("ATTRIN float3 rawnorm0; // ATTR%d,\n", SHADER_NORM0_ATTRIB); if (components & VB_HAS_NRM1) From 77dae3496a45b8f885119fc65da93cb0699c0bb2 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 29 Apr 2013 19:52:12 +0200 Subject: [PATCH 053/352] PixelShaderGen: Cleanups. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 46 ++++++------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 1bf4ca25d8..b9df2ebe8e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -233,26 +233,6 @@ static void BuildSwapModeTable() } } -const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num) -{ - if (ApiType == API_OPENGL) - return ""; // Nothing to do here - - static char result[64]; - sprintf(result, " : register(%s%d)", prefix, num); - return result; -} - -const char *WriteLocation(API_TYPE ApiType) -{ - if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) - return ""; - - static char result[64]; - sprintf(result, "uniform "); - return result; -} - template static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { @@ -273,8 +253,8 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable; out.Write("//Pixel Shader for TEV stages\n"); - out.Write("//%i TEV stages, %i texgens, XXX IND stages\n", - numStages, numTexgen/*, bpmem.genMode.numindstages*/); + out.Write("//%i TEV stages, %i texgens, %i IND stages\n", + numStages, numTexgen, bpmem.genMode.numindstages); uid_data.dstAlphaMode = dstAlphaMode; uid_data.genMode.numindstages = bpmem.genMode.numindstages; @@ -299,7 +279,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api { // Declare samplers for (int i = 0; i < 8; ++i) - out.Write("%s samp%d %s;\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", i, WriteRegister(ApiType, "s", i)); + out.Write("%s samp%d : register(s%d);\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", i, i); if (ApiType == API_D3D11) { @@ -315,18 +295,18 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("layout(std140) uniform PSBlock {\n"); - out.Write("\t%sfloat4 " I_COLORS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_COLORS)); // TODO: first element not used?? - out.Write("\t%sfloat4 " I_KCOLORS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_KCOLORS)); - out.Write("\t%sfloat4 " I_ALPHA"[1] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_ALPHA)); // TODO: Why is this an array...-.- - out.Write("\t%sfloat4 " I_TEXDIMS"[8] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_TEXDIMS)); - out.Write("\t%sfloat4 " I_ZBIAS"[2] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_ZBIAS)); - out.Write("\t%sfloat4 " I_INDTEXSCALE"[2] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_INDTEXSCALE)); - out.Write("\t%sfloat4 " I_INDTEXMTX"[6] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_INDTEXMTX)); - out.Write("\t%sfloat4 " I_FOG"[3] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_FOG)); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_COLORS, "float4", I_COLORS"[4]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_KCOLORS, "float4", I_KCOLORS"[4]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_ALPHA, "float4", I_ALPHA"[1]"); // TODO: Why is this an array...-.- + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TEXDIMS, "float4", I_TEXDIMS"[8]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_ZBIAS, "float4", I_ZBIAS"[2]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_INDTEXSCALE, "float4", I_INDTEXSCALE"[2]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_INDTEXMTX, "float4", I_INDTEXMTX"[6]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_FOG, "float4", I_FOG"[3]"); // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! - out.Write("\t%sfloat4 " I_PLIGHTS"[40] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PLIGHTS)); - out.Write("\t%sfloat4 " I_PMATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PMATERIALS)); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PLIGHTS, "float4", I_PLIGHTS"[40]"); + DeclareUniform(out, ApiType, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PMATERIALS, "float4", I_PMATERIALS"[4]"); if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("};\n"); From 02afec507622d2fcf705f9147de21f081f77aaa5 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 29 Apr 2013 21:00:39 +0200 Subject: [PATCH 054/352] Polish shader uid checking. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 9 +- Source/Core/VideoCommon/Src/ShaderGenCommon.h | 83 +++++++++++++------ .../Core/VideoCommon/Src/VertexShaderGen.cpp | 7 -- .../Plugin_VideoDX11/Src/PixelShaderCache.cpp | 10 ++- .../Plugin_VideoDX11/Src/PixelShaderCache.h | 2 + .../Src/VertexShaderCache.cpp | 9 ++ .../Plugin_VideoDX11/Src/VertexShaderCache.h | 2 + .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 8 ++ .../Plugin_VideoDX9/Src/PixelShaderCache.h | 2 + .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 9 ++ .../Plugin_VideoDX9/Src/VertexShaderCache.h | 3 + .../Src/ProgramShaderCache.cpp | 16 ++++ .../Plugin_VideoOGL/Src/ProgramShaderCache.h | 3 + 13 files changed, 120 insertions(+), 43 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index b9df2ebe8e..179560ddfa 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -392,7 +392,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api // compute window position if needed because binding semantic WPOS is not widely supported if (numTexgen < 7) { - for (int i = 0; i < numTexgen; ++i) + for (unsigned int i = 0; i < numTexgen; ++i) out.Write(",\n in %s float3 uv%d : TEXCOORD%d", optCentroid, i, i); out.Write(",\n in %s float4 clipPos : TEXCOORD%d", optCentroid, numTexgen); if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) @@ -1190,13 +1190,6 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data) void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { GeneratePixelShader(object, dstAlphaMode, ApiType, components); - - if (g_ActiveConfig.bEnableShaderDebugging) - { - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_OPENGL, components); - CheckForUidMismatch(code, object, "Pixel", "p"); - } } void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index 4b3d16b8d7..ebf2ae1b87 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -113,6 +113,9 @@ public: template inline T& GetUidData() { return data; } + const uid_data& GetUidData() const { return data; } + size_t GetUidDataSize() const { return sizeof(values); } + private: union { @@ -217,42 +220,68 @@ struct LightingUidData * Checks if there has been */ template -void CheckForUidMismatch(CodeT& new_code, const UidT& new_uid, const char* shader_type, const char* dump_prefix) +class UidChecker { - // TODO: Might be sensitive to config changes - static std::map s_shaders; - static std::vector s_uids; - - bool uid_is_indexed = std::find(s_uids.begin(), s_uids.end(), new_uid) != s_uids.end(); - if (!uid_is_indexed) +public: + void Invalidate() { - s_uids.push_back(new_uid); - s_shaders[new_uid] = new_code.GetBuffer(); + m_shaders.clear(); + m_uids.clear(); } - else + + void AddToIndexAndCheck(CodeT& new_code, const UidT& new_uid, const char* shader_type, const char* dump_prefix) { - // uid is already in the index => check if there's a shader with the same uid but different code - auto& old_code = s_shaders[new_uid]; - if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0) + bool uid_is_indexed = std::find(m_uids.begin(), m_uids.end(), new_uid) != m_uids.end(); + if (!uid_is_indexed) { - static int num_failures = 0; + m_uids.push_back(new_uid); + m_shaders[new_uid] = new_code.GetBuffer(); + } + else + { + // uid is already in the index => check if there's a shader with the same uid but different code + auto& old_code = m_shaders[new_uid]; + if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0) + { + static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), - dump_prefix, - ++num_failures); + char szTemp[MAX_PATH]; + sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), + dump_prefix, + ++num_failures); - // TODO: Should also dump uids - std::ofstream file; - OpenFStream(file, szTemp, std::ios_base::out); - file << "Old shader code:\n" << old_code; - file << "\n\nNew shader code:\n" << new_code.GetBuffer(); - file.close(); + // TODO: Should also dump uids + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); + file << "Old shader code:\n" << old_code; + file << "\n\nNew shader code:\n" << new_code.GetBuffer(); + file << "\n\nShader uid:\n"; + for (unsigned int i = 0; i < new_uid.GetUidDataSize(); ++i) + { + u32 value = ((u32*)&new_uid.GetUidData())[i]; + if ((i % 4) == 0) + { + unsigned int last_value = (i+3 < new_uid.GetUidDataSize()-1) ? i+3 : new_uid.GetUidDataSize(); + file << std::setfill(' ') << std::dec; + file << "Values " << std::setw(2) << i << " - " << last_value << ": "; + } - // TODO: Make this more idiot-proof - ERROR_LOG(VIDEO, "%s shader uid mismatch!", shader_type); + file << std::setw(8) << std::setfill('0') << std::hex << value << std::setw(1); + if ((i % 4) < 3) + file << ' '; + else + file << std::endl; + } + file.close(); + + ERROR_LOG(VIDEO, "%s shader uid mismatch! See %s for details", shader_type, szTemp); + } } } -} + +private: + std::map m_shaders; + std::vector m_uids; +}; #endif // _SHADERGENCOMMON_H diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 81b8c79553..6cbf273097 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -538,13 +538,6 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) { GenerateVertexShader(object, components, api_type); - - if (g_ActiveConfig.bEnableShaderDebugging) - { - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_OPENGL); - CheckForUidMismatch(code, object, "Vertex", "v"); - } } void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 9db0a53d13..0adf82fef9 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -29,6 +29,7 @@ namespace DX11 PixelShaderCache::PSCache PixelShaderCache::PixelShaders; const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry; PixelShaderUid PixelShaderCache::last_uid; +UidChecker PixelShaderCache::pixel_uid_checker; LinearDiskCache g_ps_disk_cache; @@ -412,7 +413,8 @@ void PixelShaderCache::Clear() { for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) iter->second.Destroy(); - PixelShaders.clear(); + PixelShaders.clear(); + pixel_uid_checker.Invalidate(); last_entry = NULL; } @@ -450,6 +452,12 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PixelShaderUid uid; GetPixelShaderUid(uid, dstAlphaMode, API_D3D11, components); + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D11, components); + pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); + } // Check if the shader is already set if (last_entry) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h index ace3a9ac6a..dee930ccfe 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h @@ -52,6 +52,8 @@ private: static PSCache PixelShaders; static const PSCacheEntry* last_entry; static PixelShaderUid last_uid; + + static UidChecker pixel_uid_checker; }; } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 19b276ddb6..2754267b09 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -25,6 +25,7 @@ namespace DX11 { VertexShaderCache::VSCache VertexShaderCache::vshaders; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; VertexShaderUid VertexShaderCache::last_uid; +UidChecker VertexShaderCache::vertex_uid_checker; static ID3D11VertexShader* SimpleVertexShader = NULL; static ID3D11VertexShader* ClearVertexShader = NULL; @@ -174,6 +175,7 @@ void VertexShaderCache::Clear() for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) iter->second.Destroy(); vshaders.clear(); + vertex_uid_checker.Invalidate(); last_entry = NULL; } @@ -197,6 +199,13 @@ bool VertexShaderCache::SetShader(u32 components) { VertexShaderUid uid; GetVertexShaderUid(uid, components, API_D3D11); + if (g_ActiveConfig.bEnableShaderDebugging) + { + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D11); + vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); + } + if (last_entry) { if (uid == last_uid) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h index 04f74bc055..b80dbcd7b1 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h @@ -59,6 +59,8 @@ private: static VSCache vshaders; static const VSCacheEntry* last_entry; static VertexShaderUid last_uid; + + static UidChecker vertex_uid_checker; }; } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index eb47614ae5..bbb46e4d56 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -31,6 +31,7 @@ namespace DX9 PixelShaderCache::PSCache PixelShaderCache::PixelShaders; const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry; PixelShaderUid PixelShaderCache::last_uid; +UidChecker PixelShaderCache::pixel_uid_checker; static LinearDiskCache g_ps_disk_cache; static std::set unique_shaders; @@ -284,6 +285,7 @@ void PixelShaderCache::Clear() for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) iter->second.Destroy(); PixelShaders.clear(); + pixel_uid_checker.Invalidate(); last_entry = NULL; } @@ -322,6 +324,12 @@ 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"); + } // Check if the shader is already set if (last_entry) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index aadd2c02f7..733a68233a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -44,6 +44,8 @@ private: static PSCache PixelShaders; static const PSCacheEntry *last_entry; static PixelShaderUid last_uid; + static UidChecker pixel_uid_checker; + static void Clear(); public: diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 9223533b3a..2d11368a6d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -26,6 +26,7 @@ namespace DX9 VertexShaderCache::VSCache VertexShaderCache::vshaders; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; VertexShaderUid VertexShaderCache::last_uid; +UidChecker VertexShaderCache::vertex_uid_checker; #define MAX_SSAA_SHADERS 3 @@ -150,6 +151,7 @@ void VertexShaderCache::Clear() for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) iter->second.Destroy(); vshaders.clear(); + vertex_uid_checker.Invalidate(); last_entry = NULL; } @@ -176,6 +178,13 @@ 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"); + } + if (last_entry) { if (uid == last_uid) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h index 88c295c435..32fbea92be 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h @@ -38,6 +38,9 @@ private: static VSCache vshaders; static const VSCacheEntry *last_entry; static VertexShaderUid last_uid; + + static UidChecker vertex_uid_checker; + static void Clear(); public: diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index bab52073fb..732c63ac67 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -29,6 +29,8 @@ static GLuint CurrentProgram = 0; ProgramShaderCache::PCache ProgramShaderCache::pshaders; ProgramShaderCache::PCacheEntry* ProgramShaderCache::last_entry; SHADERUID ProgramShaderCache::last_uid; +UidChecker ProgramShaderCache::pixel_uid_checker; +UidChecker ProgramShaderCache::vertex_uid_checker; static char s_glsl_header[1024] = ""; @@ -351,6 +353,17 @@ void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, { GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components); GetVertexShaderUid(uid->vuid, components, API_OPENGL); + + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode pcode; + GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); + pixel_uid_checker.AddToIndexAndCheck(pcode, uid->puid, "Pixel", "p"); + + VertexShaderCode vcode; + GenerateVertexShaderCode(vcode, components, API_OPENGL); + vertex_uid_checker.AddToIndexAndCheck(vcode, uid->vuid, "Vertex", "v"); + } } ProgramShaderCache::PCacheEntry ProgramShaderCache::GetShaderProgram(void) @@ -448,6 +461,9 @@ void ProgramShaderCache::Shutdown(void) iter->second.Destroy(); pshaders.clear(); + pixel_uid_checker.Invalidate(); + vertex_uid_checker.Invalidate(); + if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) { delete s_buffer; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h index 9cd9a9b12c..30428ad6de 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h @@ -106,6 +106,9 @@ private: static PCacheEntry* last_entry; static SHADERUID last_uid; + static UidChecker pixel_uid_checker; + static UidChecker vertex_uid_checker; + static GLintptr s_vs_data_size; static GLintptr s_ps_data_size; static GLintptr s_vs_data_offset; From 9cb263ad48b1b5f52f69e84b534807427110b145 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 29 Apr 2013 21:19:48 +0200 Subject: [PATCH 055/352] PixelShaderGen: Set some uid fields that I missed before. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 19 ++++++++++------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 21 ++++++++++++++++++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 179560ddfa..2be42bcf43 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -790,10 +790,10 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA) { const int i = bpmem.combiners[n].alphaC.rswap; - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap1 << (i*2); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap1 << (i*2 + 1); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap2 << (i*2 + 16); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap2 << (i*2 + 17); + uid_data.tevksel[i*2 ].swap1 = bpmem.tevksel[i*2 ].swap1; + uid_data.tevksel[i*2+1].swap1 = bpmem.tevksel[i*2+1].swap1; + uid_data.tevksel[i*2 ].swap2 = bpmem.tevksel[i*2 ].swap2; + uid_data.tevksel[i*2+1].swap2 = bpmem.tevksel[i*2+1].swap2; char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; out.Write("rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); @@ -813,13 +813,14 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE } const int i = bpmem.combiners[n].alphaC.tswap; - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap1 << (i*2); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap1 << (i*2 + 1); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2 ].swap2 << (i*2 + 16); - uid_data.tevksel_n_swap |= bpmem.tevksel[i*2+1].swap2 << (i*2 + 17); + uid_data.tevksel[i*2 ].swap1 = bpmem.tevksel[i*2 ].swap1; + uid_data.tevksel[i*2+1].swap1 = bpmem.tevksel[i*2+1].swap1; + uid_data.tevksel[i*2 ].swap2 = bpmem.tevksel[i*2 ].swap2; + uid_data.tevksel[i*2+1].swap2 = bpmem.tevksel[i*2+1].swap2; char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); + uid_data.tevindref.SetTexmap(i, texmap); SampleTexture(out, "textemp", "tevcoord", texswap, texmap, ApiType); } else @@ -833,6 +834,8 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE { int kc = bpmem.tevksel[n / 2].getKC(n & 1); int ka = bpmem.tevksel[n / 2].getKA(n & 1); + uid_data.tevksel[n/2].set_kcsel(n & 1, kc); + uid_data.tevksel[n/2].set_kasel(n & 1, ka); out.Write("konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]); if(kc > 7 || ka > 7) { diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 783f50a301..2340b96af7 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -93,6 +93,13 @@ struct pixel_shader_uid_data else if (index == 2) { bc3 = texcoord; bi2 = texmap; } else if (index == 3) { bc4 = texcoord; bi4 = texmap; } } + inline void SetTexmap(int index, u32 texmap) + { + if (index == 0) { bi0 = texmap; } + else if (index == 1) { bi1 = texmap; } + else if (index == 2) { bi2 = texmap; } + else if (index == 3) { bi4 = texmap; } + } } tevindref; u32 tevorders_n_texcoord1 : 24; // 8 x 3 bit @@ -135,7 +142,19 @@ struct pixel_shader_uid_data } } tevind_n; - u32 tevksel_n_swap : 32; // 8 x 2 bit (swap1) + 8 x 2 bit (swap2) + struct + { + u32 swap1 : 2; + u32 swap2 : 2; + u32 kcsel0 : 5; + u32 kasel0 : 5; + u32 kcsel1 : 5; + u32 kasel1 : 5; + + void set_kcsel(int i, u32 value) { if (i) kcsel1 = value; else kcsel0 = value; } + void set_kasel(int i, u32 value) { if( i) kasel1 = value; else kasel0 = value; } + } tevksel[8]; + struct { union { From 76a316ffab7c8a23bb70669d5b7a2b701f4093ba Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 29 Apr 2013 21:30:14 +0200 Subject: [PATCH 056/352] Don't exit when bluetooth support is not available on Windows. Fixes running Dolphin in Wine and on regular Windows setups where bthprops.cpl is not available. Fixes issue 6283. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index aa5b022a44..4aae05fa3a 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -87,8 +87,8 @@ inline void init_lib() hid_lib = LoadLibrary(_T("hid.dll")); if (!hid_lib) { - PanicAlertT("Failed to load hid.dll"); - exit(EXIT_FAILURE); + PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!"); + return; } HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid"); @@ -98,15 +98,15 @@ inline void init_lib() if (!HidD_GetHidGuid || !HidD_GetAttributes || !HidD_SetOutputReport || !HidD_GetProductString) { - PanicAlertT("Failed to load hid.dll"); - exit(EXIT_FAILURE); + PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!"); + return; } bthprops_lib = LoadLibrary(_T("bthprops.cpl")); if (!bthprops_lib) { - PanicAlertT("Failed to load bthprops.cpl"); - exit(EXIT_FAILURE); + PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!"); + return; } Bth_BluetoothFindDeviceClose = (PBth_BluetoothFindDeviceClose)GetProcAddress(bthprops_lib, "BluetoothFindDeviceClose"); @@ -128,8 +128,8 @@ inline void init_lib() !Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice || !Bth_BluetoothEnumerateInstalledServices) { - PanicAlertT("Failed to load bthprops.cpl"); - exit(EXIT_FAILURE); + PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!"); + return; } initialized = true; From ef2e0a87d06eb498f0e2eaebe6be2785740e54dd Mon Sep 17 00:00:00 2001 From: John Peterson Date: Thu, 8 Nov 2012 08:40:49 +0100 Subject: [PATCH 057/352] Adding option to save and load state by timestamp Load by timestamp: load last state is expanded from 1 to 8 actions, for newest to oldest state Save by timestamp: overwrite the oldest state (or use an empty slot if available) Adding remaining hardcoded state keys to hotkey dialog Adding a program exit hotkey --- Source/Core/Core/Src/ConfigManager.cpp | 15 +++ Source/Core/Core/Src/CoreParameter.h | 14 ++ Source/Core/Core/Src/State.cpp | 108 ++++++++++++--- Source/Core/Core/Src/State.h | 21 ++- Source/Core/DolphinWX/Src/Frame.cpp | 165 +++++++---------------- Source/Core/DolphinWX/Src/Frame.h | 1 + Source/Core/DolphinWX/Src/FrameTools.cpp | 50 +++++-- Source/Core/DolphinWX/Src/Globals.h | 10 +- Source/Core/DolphinWX/Src/HotkeyDlg.cpp | 16 ++- 9 files changed, 253 insertions(+), 147 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 485c1ab259..1eec9fd7b7 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -35,6 +35,7 @@ static const struct { { "ToggleFullscreen", 70 /* 'F' */, 2 /* wxMOD_CMD */ }, { "Screenshot", 83 /* 'S' */, 2 /* wxMOD_CMD */ }, + { "Exit", 0, 0 /* wxMOD_NONE */ }, { "Wiimote1Connect", 49 /* '1' */, 2 /* wxMOD_CMD */ }, { "Wiimote2Connect", 50 /* '2' */, 2 /* wxMOD_CMD */ }, @@ -57,6 +58,7 @@ static const struct { { "ToggleFullscreen", 13 /* WXK_RETURN */, 1 /* wxMOD_ALT */ }, { "Screenshot", 348 /* WXK_F9 */, 0 /* wxMOD_NONE */ }, + { "Exit", 0, 0 /* wxMOD_NONE */ }, { "Wiimote1Connect", 344 /* WXK_F5 */, 1 /* wxMOD_ALT */ }, { "Wiimote2Connect", 345 /* WXK_F6 */, 1 /* wxMOD_ALT */ }, @@ -81,6 +83,19 @@ static const struct { { "SaveStateSlot6", 345 /* WXK_F6 */, 4 /* wxMOD_SHIFT */ }, { "SaveStateSlot7", 346 /* WXK_F7 */, 4 /* wxMOD_SHIFT */ }, { "SaveStateSlot8", 347 /* WXK_F8 */, 4 /* wxMOD_SHIFT */ }, + + { "LoadLastState1", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState2", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState3", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState4", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState5", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState6", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState7", 0, 0 /* wxMOD_NONE */ }, + { "LoadLastState8", 0, 0 /* wxMOD_NONE */ }, + + { "SaveFirstState", 0, 0 /* wxMOD_NONE */ }, + { "UndoLoadState", 351 /* WXK_F12 */, 0 /* wxMOD_NONE */ }, + { "UndoSaveState", 351 /* WXK_F12 */, 4 /* wxMOD_SHIFT */ }, }; SConfig::SConfig() diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 9652b84618..6f2219e9f8 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -26,6 +26,7 @@ enum Hotkey HK_FULLSCREEN, HK_SCREENSHOT, + HK_EXIT, HK_WIIMOTE1_CONNECT, HK_WIIMOTE2_CONNECT, @@ -50,6 +51,19 @@ enum Hotkey HK_SAVE_STATE_SLOT_7, HK_SAVE_STATE_SLOT_8, + HK_LOAD_LAST_STATE_1, + HK_LOAD_LAST_STATE_2, + HK_LOAD_LAST_STATE_3, + HK_LOAD_LAST_STATE_4, + HK_LOAD_LAST_STATE_5, + HK_LOAD_LAST_STATE_6, + HK_LOAD_LAST_STATE_7, + HK_LOAD_LAST_STATE_8, + + HK_SAVE_FIRST_STATE, + HK_UNDO_LOAD_STATE, + HK_UNDO_SAVE_STATE, + NUM_HOTKEYS, }; diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 3be8470d14..09653ac9ad 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "Common.h" +#include "Timer.h" #include "State.h" #include "Core.h" #include "ConfigManager.h" @@ -58,13 +59,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 16; - -struct StateHeader -{ - u8 gameID[6]; - size_t size; -}; +static const u32 STATE_VERSION = 17; enum { @@ -159,17 +154,59 @@ void VerifyBuffer(std::vector& buffer) Core::PauseAndLock(false, wasUnpaused); } +// return state number not in map +int GetEmptySlot(std::map m) +{ + for (int i = 1; i <= NUM_STATES; i++) + { + bool found = false; + for (std::map::iterator it = m.begin(); it != m.end(); it++) + { + if (it->second == i) + { + found = true; + break; + } + } + if (!found) return i; + } + return -1; +} + +// read state timestamps +std::map GetSavedStates() +{ + StateHeader header; + std::map m; + for (int i = 1; i <= NUM_STATES; i++) + { + if (File::Exists(MakeStateFilename(i))) + { + if (ReadHeader(MakeStateFilename(i), header)) + { + double d = Common::Timer::GetDoubleTime() - header.time; + // increase time until unique value is obtained + while (m.find(d) != m.end()) d += .001; + m.insert(std::pair(d, i)); + } + } + } + return m; +} + struct CompressAndDumpState_args { std::vector* buffer_vector; std::mutex* buffer_mutex; std::string filename; + bool wait; }; void CompressAndDumpState(CompressAndDumpState_args save_args) { std::lock_guard lk(*save_args.buffer_mutex); - g_compressAndDumpStateSyncEvent.Set(); + if (!save_args.wait) + g_compressAndDumpStateSyncEvent.Set(); const u8* const buffer_data = &(*(save_args.buffer_vector))[0]; const size_t buffer_size = (save_args.buffer_vector)->size(); @@ -201,6 +238,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args) if (!f) { Core::DisplayMessage("Could not save state", 2000); + g_compressAndDumpStateSyncEvent.Set(); return; } @@ -208,6 +246,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args) StateHeader header; memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6); header.size = g_use_compression ? buffer_size : 0; + header.time = Common::Timer::GetDoubleTime(); f.WriteArray(&header, 1); @@ -244,9 +283,10 @@ void CompressAndDumpState(CompressAndDumpState_args save_args) Core::DisplayMessage(StringFromFormat("Saved State to %s", filename.c_str()).c_str(), 2000); + g_compressAndDumpStateSyncEvent.Set(); } -void SaveAs(const std::string& filename) +void SaveAs(const std::string& filename, bool wait) { // Pause the core while we save the state bool wasUnpaused = Core::PauseAndLock(true); @@ -274,6 +314,7 @@ void SaveAs(const std::string& filename) save_args.buffer_vector = &g_current_buffer; save_args.buffer_mutex = &g_cs_current_buffer; save_args.filename = filename; + save_args.wait = wait; Flush(); g_save_thread = std::thread(CompressAndDumpState, save_args); @@ -291,6 +332,20 @@ void SaveAs(const std::string& filename) Core::PauseAndLock(false, wasUnpaused); } +bool ReadHeader(const std::string filename, StateHeader& header) +{ + Flush(); + File::IOFile f(filename, "rb"); + if (!f) + { + Core::DisplayMessage("State not found", 2000); + return false; + } + + f.ReadArray(&header, 1); + return true; +} + void LoadFileStateData(const std::string& filename, std::vector& ret_data) { Flush(); @@ -496,9 +551,9 @@ static std::string MakeStateFilename(int number) SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), number); } -void Save(int slot) +void Save(int slot, bool wait) { - SaveAs(MakeStateFilename(slot)); + SaveAs(MakeStateFilename(slot), wait); } void Load(int slot) @@ -511,12 +566,35 @@ void Verify(int slot) VerifyAt(MakeStateFilename(slot)); } -void LoadLastSaved() +void LoadLastSaved(int i) { - if (g_last_filename.empty()) - Core::DisplayMessage("There is no last saved state", 2000); + std::map savedStates = GetSavedStates(); + + if (i > savedStates.size()) + Core::DisplayMessage("State doesn't exist", 2000); else - LoadAs(g_last_filename); + { + std::map::iterator it = savedStates.begin(); + std::advance(it, i-1); + Load(it->second); + } +} + +// must wait for state to be written because it must know if all slots are taken +void SaveFirstSaved() +{ + std::map savedStates = GetSavedStates(); + + // save to an empty slot + if (savedStates.size() < NUM_STATES) + Save(GetEmptySlot(savedStates), true); + // overwrite the oldest state + else + { + std::map::iterator it = savedStates.begin(); + std::advance(it, savedStates.size()-1); + Save(it->second, true); + } } void Flush() diff --git a/Source/Core/Core/Src/State.h b/Source/Core/Core/Src/State.h index db88cef766..14e77bae5c 100644 --- a/Source/Core/Core/Src/State.h +++ b/Source/Core/Core/Src/State.h @@ -14,22 +14,34 @@ namespace State { +// number of states +static const u32 NUM_STATES = 8; + +struct StateHeader +{ + u8 gameID[6]; + u32 size; + double time; +}; + void Init(); void Shutdown(); void EnableCompression(bool compression); +bool ReadHeader(const std::string filename, StateHeader& header); + // These don't happen instantly - they get scheduled as events. // ...But only if we're not in the main cpu thread. // If we're in the main cpu thread then they run immediately instead // because some things (like Lua) need them to run immediately. // Slots from 0-99. -void Save(int slot); +void Save(int slot, bool wait = false); void Load(int slot); void Verify(int slot); -void SaveAs(const std::string &filename); +void SaveAs(const std::string &filename, bool wait = false); void LoadAs(const std::string &filename); void VerifyAt(const std::string &filename); @@ -37,7 +49,10 @@ void SaveToBuffer(std::vector& buffer); void LoadFromBuffer(std::vector& buffer); void VerifyBuffer(std::vector& buffer); -void LoadLastSaved(); +static std::string MakeStateFilename(int number); + +void LoadLastSaved(int i = 1); +void SaveFirstSaved(); void UndoSaveState(); void UndoLoadState(); diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index 2ed76f6214..1e0e0c756c 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -204,13 +204,14 @@ EVT_MENU_RANGE(IDM_LOGWINDOW, IDM_VIDEOWINDOW, CFrame::OnToggleWindow) EVT_MENU(IDM_PURGECACHE, CFrame::GameListChanged) -EVT_MENU(IDM_LOADLASTSTATE, CFrame::OnLoadLastState) +EVT_MENU(IDM_SAVEFIRSTSTATE, CFrame::OnSaveFirstState) EVT_MENU(IDM_UNDOLOADSTATE, CFrame::OnUndoLoadState) EVT_MENU(IDM_UNDOSAVESTATE, CFrame::OnUndoSaveState) EVT_MENU(IDM_LOADSTATEFILE, CFrame::OnLoadStateFromFile) EVT_MENU(IDM_SAVESTATEFILE, CFrame::OnSaveStateToFile) EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT8, CFrame::OnLoadState) +EVT_MENU_RANGE(IDM_LOADLAST1, IDM_LOADLAST8, CFrame::OnLoadLastState) EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT8, CFrame::OnSaveState) EVT_MENU_RANGE(IDM_FRAMESKIP0, IDM_FRAMESKIP9, CFrame::OnFrameSkip) EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive) @@ -719,104 +720,56 @@ int GetCmdForHotkey(unsigned int key) { switch (key) { - case HK_OPEN: - return wxID_OPEN; + case HK_OPEN: return wxID_OPEN; + case HK_CHANGE_DISC: return IDM_CHANGEDISC; + case HK_REFRESH_LIST: return wxID_REFRESH; + case HK_PLAY_PAUSE: return IDM_PLAY; + case HK_STOP: return IDM_STOP; + case HK_RESET: return IDM_RESET; + case HK_FRAME_ADVANCE: return IDM_FRAMESTEP; + case HK_START_RECORDING: return IDM_RECORD; + case HK_PLAY_RECORDING: return IDM_PLAYRECORD; + case HK_EXPORT_RECORDING: return IDM_RECORDEXPORT; + case HK_READ_ONLY_MODE: return IDM_RECORDREADONLY; + case HK_FULLSCREEN: return IDM_TOGGLE_FULLSCREEN; + case HK_SCREENSHOT: return IDM_SCREENSHOT; + case HK_EXIT: return wxID_EXIT; - case HK_CHANGE_DISC: - return IDM_CHANGEDISC; + case HK_WIIMOTE1_CONNECT: return IDM_CONNECT_WIIMOTE1; + case HK_WIIMOTE2_CONNECT: return IDM_CONNECT_WIIMOTE2; + case HK_WIIMOTE3_CONNECT: return IDM_CONNECT_WIIMOTE3; + case HK_WIIMOTE4_CONNECT: return IDM_CONNECT_WIIMOTE4; - case HK_REFRESH_LIST: - return wxID_REFRESH; + case HK_LOAD_STATE_SLOT_1: return IDM_LOADSLOT1; + case HK_LOAD_STATE_SLOT_2: return IDM_LOADSLOT2; + case HK_LOAD_STATE_SLOT_3: return IDM_LOADSLOT3; + case HK_LOAD_STATE_SLOT_4: return IDM_LOADSLOT4; + case HK_LOAD_STATE_SLOT_5: return IDM_LOADSLOT5; + case HK_LOAD_STATE_SLOT_6: return IDM_LOADSLOT6; + case HK_LOAD_STATE_SLOT_7: return IDM_LOADSLOT7; + case HK_LOAD_STATE_SLOT_8: return IDM_LOADSLOT8; - case HK_PLAY_PAUSE: - return IDM_PLAY; + case HK_SAVE_STATE_SLOT_1: return IDM_SAVESLOT1; + case HK_SAVE_STATE_SLOT_2: return IDM_SAVESLOT2; + case HK_SAVE_STATE_SLOT_3: return IDM_SAVESLOT3; + case HK_SAVE_STATE_SLOT_4: return IDM_SAVESLOT4; + case HK_SAVE_STATE_SLOT_5: return IDM_SAVESLOT5; + case HK_SAVE_STATE_SLOT_6: return IDM_SAVESLOT6; + case HK_SAVE_STATE_SLOT_7: return IDM_SAVESLOT7; + case HK_SAVE_STATE_SLOT_8: return IDM_SAVESLOT8; - case HK_STOP: - return IDM_STOP; + case HK_LOAD_LAST_STATE_1: return IDM_LOADLAST1; + case HK_LOAD_LAST_STATE_2: return IDM_LOADLAST2; + case HK_LOAD_LAST_STATE_3: return IDM_LOADLAST3; + case HK_LOAD_LAST_STATE_4: return IDM_LOADLAST4; + case HK_LOAD_LAST_STATE_5: return IDM_LOADLAST5; + case HK_LOAD_LAST_STATE_6: return IDM_LOADLAST6; + case HK_LOAD_LAST_STATE_7: return IDM_LOADLAST7; + case HK_LOAD_LAST_STATE_8: return IDM_LOADLAST8; - case HK_RESET: - return IDM_RESET; - - case HK_FRAME_ADVANCE: - return IDM_FRAMESTEP; - - case HK_START_RECORDING: - return IDM_RECORD; - - case HK_PLAY_RECORDING: - return IDM_PLAYRECORD; - - case HK_EXPORT_RECORDING: - return IDM_RECORDEXPORT; - - case HK_READ_ONLY_MODE: - return IDM_RECORDREADONLY; - - case HK_FULLSCREEN: - return IDM_TOGGLE_FULLSCREEN; - - case HK_SCREENSHOT: - return IDM_SCREENSHOT; - - case HK_WIIMOTE1_CONNECT: - return IDM_CONNECT_WIIMOTE1; - - case HK_WIIMOTE2_CONNECT: - return IDM_CONNECT_WIIMOTE2; - - case HK_WIIMOTE3_CONNECT: - return IDM_CONNECT_WIIMOTE3; - - case HK_WIIMOTE4_CONNECT: - return IDM_CONNECT_WIIMOTE4; - - case HK_LOAD_STATE_SLOT_1: - return IDM_LOADSLOT1; - - case HK_LOAD_STATE_SLOT_2: - return IDM_LOADSLOT2; - - case HK_LOAD_STATE_SLOT_3: - return IDM_LOADSLOT3; - - case HK_LOAD_STATE_SLOT_4: - return IDM_LOADSLOT4; - - case HK_LOAD_STATE_SLOT_5: - return IDM_LOADSLOT5; - - case HK_LOAD_STATE_SLOT_6: - return IDM_LOADSLOT6; - - case HK_LOAD_STATE_SLOT_7: - return IDM_LOADSLOT7; - - case HK_LOAD_STATE_SLOT_8: - return IDM_LOADSLOT8; - - case HK_SAVE_STATE_SLOT_1: - return IDM_SAVESLOT1; - - case HK_SAVE_STATE_SLOT_2: - return IDM_SAVESLOT2; - - case HK_SAVE_STATE_SLOT_3: - return IDM_SAVESLOT3; - - case HK_SAVE_STATE_SLOT_4: - return IDM_SAVESLOT4; - - case HK_SAVE_STATE_SLOT_5: - return IDM_SAVESLOT5; - - case HK_SAVE_STATE_SLOT_6: - return IDM_SAVESLOT6; - - case HK_SAVE_STATE_SLOT_7: - return IDM_SAVESLOT7; - - case HK_SAVE_STATE_SLOT_8: - return IDM_SAVESLOT8; + case HK_SAVE_FIRST_STATE: return IDM_SAVEFIRSTSTATE; + case HK_UNDO_LOAD_STATE: return IDM_UNDOLOADSTATE; + case HK_UNDO_SAVE_STATE: return IDM_UNDOSAVESTATE; } return -1; @@ -859,6 +812,8 @@ void CFrame::OnKeyDown(wxKeyEvent& event) // Screenshot hotkey else if (IsHotkey(event, HK_SCREENSHOT)) Core::SaveScreenShot(); + else if (IsHotkey(event, HK_EXIT)) + wxPostEvent(this, wxCommandEvent(wxID_EXIT)); // Wiimote connect and disconnect hotkeys else if (IsHotkey(event, HK_WIIMOTE1_CONNECT)) WiimoteId = 0; @@ -868,28 +823,6 @@ void CFrame::OnKeyDown(wxKeyEvent& event) WiimoteId = 2; else if (IsHotkey(event, HK_WIIMOTE4_CONNECT)) WiimoteId = 3; - // State save and state load hotkeys - /*else if (event.GetKeyCode() >= WXK_F1 && event.GetKeyCode() <= WXK_F8) - { - int slot_number = event.GetKeyCode() - WXK_F1 + 1; - if (event.GetModifiers() == wxMOD_NONE) - State::Load(slot_number); - else if (event.GetModifiers() == wxMOD_SHIFT) - State::Save(slot_number); - else - event.Skip(); - }*/ - else if (event.GetKeyCode() == WXK_F11 && event.GetModifiers() == wxMOD_NONE) - State::LoadLastSaved(); - else if (event.GetKeyCode() == WXK_F12) - { - if (event.GetModifiers() == wxMOD_NONE) - State::UndoSaveState(); - else if (event.GetModifiers() == wxMOD_SHIFT) - State::UndoLoadState(); - else - event.Skip(); - } else { unsigned int i = NUM_HOTKEYS; diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h index 6657c62013..0a29fffd37 100644 --- a/Source/Core/DolphinWX/Src/Frame.h +++ b/Source/Core/DolphinWX/Src/Frame.h @@ -289,6 +289,7 @@ private: void OnLoadStateFromFile(wxCommandEvent& event); void OnSaveStateToFile(wxCommandEvent& event); void OnLoadLastState(wxCommandEvent& event); + void OnSaveFirstState(wxCommandEvent& event); void OnUndoLoadState(wxCommandEvent& event); void OnUndoSaveState(wxCommandEvent& event); diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index ef0aa81e9d..57c465abfa 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -150,26 +150,25 @@ void CFrame::CreateMenu() emulationMenu->Append(IDM_SAVESTATE, _("Sa&ve State"), saveMenu); saveMenu->Append(IDM_SAVESTATEFILE, _("Save State...")); - loadMenu->Append(IDM_UNDOSAVESTATE, _("Last Overwritten State") + wxString(wxT("\tF12"))); + saveMenu->Append(IDM_SAVEFIRSTSTATE, GetMenuLabel(HK_SAVE_FIRST_STATE)); + loadMenu->Append(IDM_UNDOSAVESTATE, GetMenuLabel(HK_UNDO_SAVE_STATE)); saveMenu->AppendSeparator(); loadMenu->Append(IDM_LOADSTATEFILE, _("Load State...")); - - // Reserve F11 for the "step into" function in the debugger - if (g_pCodeWindow) - loadMenu->Append(IDM_LOADLASTSTATE, _("Last Saved State")); - else - loadMenu->Append(IDM_LOADLASTSTATE, _("Last Saved State") + wxString(wxT("\tF11"))); - loadMenu->Append(IDM_UNDOLOADSTATE, _("Undo Load State") + wxString(wxT("\tShift+F12"))); + loadMenu->Append(IDM_UNDOLOADSTATE, GetMenuLabel(HK_UNDO_LOAD_STATE)); loadMenu->AppendSeparator(); - for (int i = 1; i <= 8; i++) + for (int i = 1; i <= State::NUM_STATES; i++) { loadMenu->Append(IDM_LOADSLOT1 + i - 1, GetMenuLabel(HK_LOAD_STATE_SLOT_1 + i - 1)); saveMenu->Append(IDM_SAVESLOT1 + i - 1, GetMenuLabel(HK_SAVE_STATE_SLOT_1 + i - 1)); } + loadMenu->AppendSeparator(); + for (int i = 1; i <= State::NUM_STATES; i++) + loadMenu->Append(IDM_LOADLAST1 + i - 1, GetMenuLabel(HK_LOAD_LAST_STATE_1 + i - 1)); + m_MenuBar->Append(emulationMenu, _("&Emulation")); // Options menu @@ -360,6 +359,9 @@ wxString CFrame::GetMenuLabel(int Id) case HK_SCREENSHOT: Label = _("Take Screenshot"); break; + case HK_EXIT: + Label = _("Exit"); + break; case HK_WIIMOTE1_CONNECT: case HK_WIIMOTE2_CONNECT: @@ -393,6 +395,22 @@ wxString CFrame::GetMenuLabel(int Id) Id - HK_SAVE_STATE_SLOT_1 + 1); break; + case HK_LOAD_LAST_STATE_1: + case HK_LOAD_LAST_STATE_2: + case HK_LOAD_LAST_STATE_3: + case HK_LOAD_LAST_STATE_4: + case HK_LOAD_LAST_STATE_5: + case HK_LOAD_LAST_STATE_6: + case HK_LOAD_LAST_STATE_7: + case HK_LOAD_LAST_STATE_8: + Label = wxString::Format(_("Last %i"), + Id - HK_LOAD_LAST_STATE_1 + 1); + break; + + case HK_SAVE_FIRST_STATE: Label = wxString("Save Oldest State"); break; + case HK_UNDO_LOAD_STATE: Label = wxString("Undo Load State"); break; + case HK_UNDO_SAVE_STATE: Label = wxString("Undo Save State"); break; + default: Label = wxString::Format(_("Undefined %i"), Id); } @@ -1437,10 +1455,20 @@ void CFrame::OnSaveStateToFile(wxCommandEvent& WXUNUSED (event)) State::SaveAs(WxStrToStr(path)); } -void CFrame::OnLoadLastState(wxCommandEvent& WXUNUSED (event)) +void CFrame::OnLoadLastState(wxCommandEvent& event) { if (Core::IsRunningAndStarted()) - State::LoadLastSaved(); + { + int id = event.GetId(); + int slot = id - IDM_LOADLAST1 + 1; + State::LoadLastSaved(slot); + } +} + +void CFrame::OnSaveFirstState(wxCommandEvent& WXUNUSED(event)) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + State::SaveFirstSaved(); } void CFrame::OnUndoLoadState(wxCommandEvent& WXUNUSED (event)) diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h index 8229af059a..144eafe40f 100644 --- a/Source/Core/DolphinWX/Src/Globals.h +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -25,7 +25,7 @@ enum { IDM_LOADSTATE = 200, // File menu IDM_SAVESTATE, - IDM_LOADLASTSTATE, + IDM_SAVEFIRSTSTATE, IDM_UNDOLOADSTATE, IDM_UNDOSAVESTATE, IDM_LOADSTATEFILE, @@ -46,6 +46,14 @@ enum IDM_LOADSLOT6, IDM_LOADSLOT7, IDM_LOADSLOT8, + IDM_LOADLAST1, + IDM_LOADLAST2, + IDM_LOADLAST3, + IDM_LOADLAST4, + IDM_LOADLAST5, + IDM_LOADLAST6, + IDM_LOADLAST7, + IDM_LOADLAST8, IDM_FRAMESKIP0, IDM_FRAMESKIP1, IDM_FRAMESKIP2, diff --git a/Source/Core/DolphinWX/Src/HotkeyDlg.cpp b/Source/Core/DolphinWX/Src/HotkeyDlg.cpp index f841b412c6..5ee94deb59 100644 --- a/Source/Core/DolphinWX/Src/HotkeyDlg.cpp +++ b/Source/Core/DolphinWX/Src/HotkeyDlg.cpp @@ -179,6 +179,7 @@ void HotkeyConfigDialog::CreateHotkeyGUIControls(void) _("Toggle Fullscreen"), _("Take Screenshot"), + _("Exit"), _("Connect Wiimote 1"), _("Connect Wiimote 2"), @@ -201,7 +202,20 @@ void HotkeyConfigDialog::CreateHotkeyGUIControls(void) _("Save State Slot 5"), _("Save State Slot 6"), _("Save State Slot 7"), - _("Save State Slot 8") + _("Save State Slot 8"), + + _("Load State Last 1"), + _("Load State Last 2"), + _("Load State Last 3"), + _("Load State Last 4"), + _("Load State Last 5"), + _("Load State Last 6"), + _("Load State Last 7"), + _("Load State Last 8"), + + _("Save Oldest State"), + _("Undo Load State"), + _("Undo Save State") }; const int page_breaks[3] = {HK_OPEN, HK_LOAD_STATE_SLOT_1, NUM_HOTKEYS}; From e70a277af2a3c1950af4e1fef06dc54f74958290 Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 30 Apr 2013 23:36:46 +1000 Subject: [PATCH 058/352] Added Dance Mat support for the Family Trainer/Active Life series. Select the dance mat via Configure > Gamecube > Port 1 > Dance Mat The dance mat is mapped to the GC Pad: D-Pad Up = Blue Arrow Up D-Pad Down = Blue Arrow Down D-Pad Left = Blue Arrow Left D-Pad Right = Blue Square Y Button = Orange Arrow Up A Button = Orange Arrow Down X Button = Orange Arrow Right B Button = Oranage Square --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/Core.vcxproj | 2 + Source/Core/Core/Core.vcxproj.filters | 6 + Source/Core/Core/Src/HW/SI_Device.cpp | 5 + Source/Core/Core/Src/HW/SI_Device.h | 2 + Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp | 264 ++++++++++++++++++ Source/Core/Core/Src/HW/SI_DeviceDanceMat.h | 105 +++++++ Source/Core/Core/Src/NetPlay.cpp | 11 + Source/Core/DolphinWX/Src/ConfigMain.cpp | 13 +- 9 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp create mode 100644 Source/Core/Core/Src/HW/SI_DeviceDanceMat.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 0fed2e0b8a..d0ad3c615d 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -111,6 +111,7 @@ set(SRCS Src/ActionReplay.cpp Src/HW/SI.cpp Src/HW/SI_DeviceAMBaseboard.cpp Src/HW/SI_Device.cpp + Src/HW/SI_DeviceDanceMat.cpp Src/HW/SI_DeviceGBA.cpp Src/HW/SI_DeviceGCController.cpp Src/HW/SI_DeviceGCSteeringWheel.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 5d0d3b2754..a191d86282 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -298,6 +298,7 @@ + @@ -498,6 +499,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index c38d68c303..75c592a685 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -289,6 +289,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\VI - Video Interface @@ -810,6 +813,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\SI - Serial Interface diff --git a/Source/Core/Core/Src/HW/SI_Device.cpp b/Source/Core/Core/Src/HW/SI_Device.cpp index baa144c83d..e9674bcab6 100644 --- a/Source/Core/Core/Src/HW/SI_Device.cpp +++ b/Source/Core/Core/Src/HW/SI_Device.cpp @@ -5,6 +5,7 @@ #include "SI_Device.h" #include "SI_DeviceGCController.h" #include "SI_DeviceGCSteeringWheel.h" +#include "SI_DeviceDanceMat.h" #include "SI_DeviceGBA.h" #include "SI_DeviceAMBaseboard.h" @@ -64,6 +65,10 @@ ISIDevice* SIDevice_Create(const SIDevices device, const int port_number) return new CSIDevice_GCController(device, port_number); break; + case SIDEVICE_DANCEMAT: + return new CSIDevice_DanceMat(device, port_number); + break; + case SIDEVICE_GC_STEERING: return new CSIDevice_GCSteeringWheel(device, port_number); break; diff --git a/Source/Core/Core/Src/HW/SI_Device.h b/Source/Core/Core/Src/HW/SI_Device.h index bf3e1fc506..62614656c7 100644 --- a/Source/Core/Core/Src/HW/SI_Device.h +++ b/Source/Core/Core/Src/HW/SI_Device.h @@ -34,6 +34,7 @@ enum TSIDevices SI_GC_CONTROLLER = (SI_TYPE_GC | SI_GC_STANDARD), SI_GC_KEYBOARD = (SI_TYPE_GC | 0x00200000), SI_GC_STEERING = SI_TYPE_GC, // (shuffle2)I think the "chainsaw" is the same (Or else it's just standard) + SI_DANCEMAT = (SI_TYPE_GC | SI_GC_STANDARD | 0x00000300), SI_AM_BASEBOARD = 0x10110800 // gets ORd with dipswitch state }; @@ -49,6 +50,7 @@ enum SIDevices SIDEVICE_GC_CONTROLLER, SIDEVICE_GC_KEYBOARD, SIDEVICE_GC_STEERING, + SIDEVICE_DANCEMAT, SIDEVICE_GC_TARUKONGA, SIDEVICE_AM_BASEBOARD }; diff --git a/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp b/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp new file mode 100644 index 0000000000..30237286e6 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp @@ -0,0 +1,264 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include +#include + +#include "SI.h" +#include "SI_Device.h" +#include "SI_DeviceDanceMat.h" + +#include "EXI_Device.h" +#include "EXI_DeviceMic.h" + +#include "GCPad.h" + +#include "../Movie.h" + +#include "../CoreTiming.h" +#include "SystemTimers.h" +#include "ProcessorInterface.h" +#include "../Core.h" + +// --- Dance mat gamecube controller --- +CSIDevice_DanceMat::CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber) + : ISIDevice(device, _iDeviceNumber) + , m_TButtonComboStart(0) + , m_TButtonCombo(0) + , m_LastButtonCombo(COMBO_NONE) +{ + memset(&m_Origin, 0, sizeof(SOrigin)); + m_Origin.uCommand = CMD_ORIGIN; + m_Origin.uOriginStickX = 0x80; // center + m_Origin.uOriginStickY = 0x80; + m_Origin.uSubStickStickX = 0x80; + m_Origin.uSubStickStickY = 0x80; + m_Origin.uTrigger_L = 0x00; + m_Origin.uTrigger_R = 0x00; + + // Dunno if we need to do this, game/lib should set it? + m_Mode = 0x03; +} + +int CSIDevice_DanceMat::RunBuffer(u8* _pBuffer, int _iLength) +{ + // For debug logging only + ISIDevice::RunBuffer(_pBuffer, _iLength); + + // Read the command + EBufferCommands command = static_cast(_pBuffer[3]); + + // Handle it + switch (command) + { + case CMD_RESET: + *(u32*)&_pBuffer[0] = SI_DANCEMAT; + break; + + case CMD_DIRECT: + { + INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength); + u32 high, low; + GetData(high, low); + for (int i = 0; i < (_iLength - 1) / 2; i++) + { + _pBuffer[0 + i] = (high >> (i * 8)) & 0xff; + _pBuffer[4 + i] = (low >> (i * 8)) & 0xff; + } + } + break; + + case CMD_ORIGIN: + { + INFO_LOG(SERIALINTERFACE, "PAD - Get Origin"); + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // Recalibrate (FiRES: i am not 100 percent sure about this) + case CMD_RECALIBRATE: + { + INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate"); + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // DEFAULT + default: + { + ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command); + PanicAlert("SI: Unknown command (0x%x)", command); + } + break; + } + + return _iLength; +} + + +// GetData + +// Return true on new data (max 7 Bytes and 6 bits ;) +// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] +// |\_ ERR_LATCH (error latched - check SISR) +// |_ ERR_STATUS (error on last GetData or SendCmd?) +bool CSIDevice_DanceMat::GetData(u32& _Hi, u32& _Low) +{ + SPADStatus PadStatus; + memset(&PadStatus, 0, sizeof(PadStatus)); + + Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); + Movie::CallInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); + + u32 netValues[2]; + if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues)) + { + _Hi = netValues[0]; // first 4 bytes + _Low = netValues[1]; // last 4 bytes + return true; + } + + Movie::SetPolledDevice(); + + if(Movie::IsPlayingInput()) + { + Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); + Movie::InputUpdate(); + } + else if(Movie::IsRecordingInput()) + { + Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); + Movie::InputUpdate(); + } + else + { + Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); + } + + // Map the dpad to the blue arrows, the buttons to the orange arrows + // Z = + button, Start = - button + u16 map = 0; + if (PadStatus.button & PAD_BUTTON_UP) + map |= 0x1000; + if (PadStatus.button & PAD_BUTTON_DOWN) + map |= 0x2; + if (PadStatus.button & PAD_BUTTON_LEFT) + map |= 0x8; + if (PadStatus.button & PAD_BUTTON_RIGHT) + map |= 0x4; + if (PadStatus.button & PAD_BUTTON_Y) + map |= 0x200; + if (PadStatus.button & PAD_BUTTON_A) + map |= 0x10; + if (PadStatus.button & PAD_BUTTON_B) + map |= 0x100; + if (PadStatus.button & PAD_BUTTON_X) + map |= 0x800; + if (PadStatus.button & PAD_TRIGGER_Z) + map |= 0x400; + if (PadStatus.button & PAD_BUTTON_START) + map |= 0x1; + + _Hi = (u32)(map << 16) | 0x8080; + + // Low bits are packed differently per mode + if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) + { + _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits + _Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits + } + else if (m_Mode == 1) + { + _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits + _Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits + _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits + } + else if (m_Mode == 2) + { + // Identifies the dance mat + _Low = 0x8080ffff; + } + else if (m_Mode == 3) + { + // Analog A/B are always 0 + _Low = (u8)PadStatus.triggerRight; // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits + } + else if (m_Mode == 4) + { + _Low = (u8)(PadStatus.analogB); // All 8 bits + _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits + // triggerLeft/Right are always 0 + _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits + } + return true; +} + + +// SendCommand +void CSIDevice_DanceMat::SendCommand(u32 _Cmd, u8 _Poll) +{ + UCommand command(_Cmd); + + switch (command.Command) + { + // Costis sent it in some demos :) + case 0x00: + break; + + case CMD_WRITE: + { + unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard + unsigned int uStrength = command.Parameter2; + + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber); + + if (numPAD < 4) + Pad::Rumble(numPAD, uType, uStrength); + + if (!_Poll) + { + m_Mode = command.Parameter2; + INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); + } + } + break; + + default: + { + ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd); + PanicAlert("SI: Unknown direct command"); + } + break; + } +} + +// Savestate support +void CSIDevice_DanceMat::DoState(PointerWrap& p) +{ + p.Do(m_Origin); + p.Do(m_Mode); + p.Do(m_TButtonComboStart); + p.Do(m_TButtonCombo); + p.Do(m_LastButtonCombo); +} diff --git a/Source/Core/Core/Src/HW/SI_DeviceDanceMat.h b/Source/Core/Core/Src/HW/SI_DeviceDanceMat.h new file mode 100644 index 0000000000..b30c107847 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceDanceMat.h @@ -0,0 +1,105 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#ifndef _SI_DEVICEDANCEMAT_H +#define _SI_DEVICEDANCEMAT_H + +#include "SI_Device.h" +#include "GCPadStatus.h" + + +// standard gamecube controller +class CSIDevice_DanceMat : public ISIDevice +{ +private: + + // Commands + enum EBufferCommands + { + CMD_RESET = 0x00, + CMD_DIRECT = 0x40, + CMD_ORIGIN = 0x41, + CMD_RECALIBRATE = 0x42, + }; + + struct SOrigin + { + u8 uCommand;// Maybe should be button bits? + u8 unk_1; // ..and this would be the other half + u8 uOriginStickX; + u8 uOriginStickY; + u8 uSubStickStickX; + u8 uSubStickStickY; + u8 uTrigger_L; + u8 uTrigger_R; + u8 unk_4; + u8 unk_5; + u8 unk_6; + u8 unk_7; + }; + + enum EDirectCommands + { + CMD_WRITE = 0x40 + }; + + union UCommand + { + u32 Hex; + struct + { + u32 Parameter1 : 8; + u32 Parameter2 : 8; + u32 Command : 8; + u32 : 8; + }; + UCommand() {Hex = 0;} + UCommand(u32 _iValue) {Hex = _iValue;} + }; + + enum EButtonCombo + { + COMBO_NONE = 0, + COMBO_ORIGIN, + COMBO_RESET + }; + + // struct to compare input against + // Set on connection and (standard pad only) on button combo + SOrigin m_Origin; + + // PADAnalogMode + u8 m_Mode; + + // Timer to track special button combos: + // y, X, start for 3 seconds updates origin with current status + // Technically, the above is only on standard pad, wavebird does not support it for example + // b, x, start for 3 seconds triggers reset (PI reset button interrupt) + u64 m_TButtonComboStart, m_TButtonCombo; + // Type of button combo from the last/current poll + EButtonCombo m_LastButtonCombo; + +public: + + // Constructor + CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber); + + // Run the SI Buffer + virtual int RunBuffer(u8* _pBuffer, int _iLength); + + // Send and Receive pad input from network + static bool NetPlay_GetInput(u8 numPAD, SPADStatus status, u32 *PADStatus); + static u8 NetPlay_GetPadNum(u8 numPAD); + + // Return true on new data + virtual bool GetData(u32& _Hi, u32& _Low); + + // Send a command directly + virtual void SendCommand(u32 _Cmd, u8 _Poll); + + // Savestate support + virtual void DoState(PointerWrap& p); +}; + +#endif diff --git a/Source/Core/Core/Src/NetPlay.cpp b/Source/Core/Core/Src/NetPlay.cpp index 96c4a69f98..7f4b838ffc 100644 --- a/Source/Core/Core/Src/NetPlay.cpp +++ b/Source/Core/Core/Src/NetPlay.cpp @@ -10,6 +10,7 @@ // for gcpad #include "HW/SI_DeviceGCController.h" #include "HW/SI_DeviceGCSteeringWheel.h" +#include "HW/SI_DeviceDanceMat.h" // for gctime #include "HW/EXI_DeviceIPL.h" // for wiimote/ OSD messages @@ -299,6 +300,11 @@ bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); } +bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) +{ + return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); +} + // called from ---CPU--- thread // so all players' games get the same time u32 CEXIIPL::NetPlay_GetGCTime() @@ -328,6 +334,11 @@ u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD) return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); } +u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) +{ + return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); +} + // called from ---CPU--- thread // wiimote update / used for frame counting //void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index edbc45a50d..4ae51d78a1 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -87,6 +87,7 @@ static const wxLanguage langIds[] = #define SIDEV_STDCONT_STR _trans("Standard Controller") #define SIDEV_STEERING_STR _trans("Steering Wheel") +#define SIDEV_DANCEMAT_STR _trans("Dance Mat") #define SIDEV_BONGO_STR _trans("TaruKonga (Bongos)") #define SIDEV_GBA_STR "GBA" #define SIDEV_AM_BB_STR _trans("AM-Baseboard") @@ -388,6 +389,7 @@ void CConfigMain::InitializeGUIValues() SIDevices.Add(_(DEV_NONE_STR)); SIDevices.Add(_(SIDEV_STDCONT_STR)); SIDevices.Add(_(SIDEV_STEERING_STR)); + SIDevices.Add(_(SIDEV_DANCEMAT_STR)); SIDevices.Add(_(SIDEV_BONGO_STR)); SIDevices.Add(_(SIDEV_GBA_STR)); SIDevices.Add(_(SIDEV_AM_BB_STR)); @@ -443,15 +445,18 @@ void CConfigMain::InitializeGUIValues() case SIDEVICE_GC_STEERING: GCSIDevice[i]->SetStringSelection(SIDevices[2]); break; - case SIDEVICE_GC_TARUKONGA: + case SIDEVICE_DANCEMAT: GCSIDevice[i]->SetStringSelection(SIDevices[3]); break; - case SIDEVICE_GC_GBA: + case SIDEVICE_GC_TARUKONGA: GCSIDevice[i]->SetStringSelection(SIDevices[4]); break; - case SIDEVICE_AM_BASEBOARD: + case SIDEVICE_GC_GBA: GCSIDevice[i]->SetStringSelection(SIDevices[5]); break; + case SIDEVICE_AM_BASEBOARD: + GCSIDevice[i]->SetStringSelection(SIDevices[6]); + break; default: GCSIDevice[i]->SetStringSelection(SIDevices[0]); break; @@ -1103,6 +1108,8 @@ void CConfigMain::ChooseSIDevice(wxString deviceName, int deviceNum) tempType = SIDEVICE_GC_CONTROLLER; else if (!deviceName.compare(WXSTR_TRANS(SIDEV_STEERING_STR))) tempType = SIDEVICE_GC_STEERING; + else if (!deviceName.compare(WXSTR_TRANS(SIDEV_DANCEMAT_STR))) + tempType = SIDEVICE_DANCEMAT; else if (!deviceName.compare(WXSTR_TRANS(SIDEV_BONGO_STR))) tempType = SIDEVICE_GC_TARUKONGA; else if (!deviceName.compare(wxT(SIDEV_GBA_STR))) From 2c7ed2a793c1c75cf68e051d1171ebf0a6425c46 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Wed, 1 May 2013 11:42:00 +0200 Subject: [PATCH 059/352] Apply color mask when alpha test parameters change. Required to make the changes in revision be706a397720 work properly. Fixes issue 6080. --- Source/Core/VideoCommon/Src/BPStructs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index 314041f894..31f873acc6 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -356,6 +356,7 @@ void BPWritten(const BPCmd& bp) PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0, bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic); PixelShaderManager::SetAlpha(bpmem.alpha_test); + g_renderer->SetColorMask(); break; case BPMEM_BIAS: // BIAS PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias); From 62065be7889d9dceba3d16e10674ac34abc65f38 Mon Sep 17 00:00:00 2001 From: lioncash Date: Wed, 1 May 2013 09:05:37 -0400 Subject: [PATCH 060/352] Fix a bug where FIFO recording could not work. Example (in step by step explanation): 1. Run Dolphin. 2. Go to Tools -> Fifo Player 3. Go to the Record tab and hit record and then stop without a game loaded. The button is now disabled and will not become active again for the whole time that Dolphin is running. Dolphin must be closed and then re-opened in order to use it again. This fixes that. I've tested it with multiple conditions to make sure this doesn't beef anything else related to the Fifo Player. ie) - Record then Stop without a game loaded (multiple times) - Record then Stop with a game loaded (multiple times, as well as testing playback. All of which work fine). --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 8b22166a81..8f14797fb0 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -34,8 +34,8 @@ FifoPlayerDlg::FifoPlayerDlg(wxWindow * const parent) : { CreateGUIControls(); - sMutex.lock(); - m_EvtHandler = GetEventHandler(); + sMutex.lock(); + m_EvtHandler = GetEventHandler(); sMutex.unlock(); FifoPlayer::GetInstance().SetFileLoadedCallback(FileLoaded); @@ -65,7 +65,7 @@ FifoPlayerDlg::~FifoPlayerDlg() FifoPlayer::GetInstance().SetFrameWrittenCallback(NULL); - sMutex.lock(); + sMutex.lock(); m_EvtHandler = NULL; sMutex.unlock(); } @@ -407,8 +407,8 @@ void FifoPlayerDlg::OnRecordStop(wxCommandEvent& WXUNUSED(event)) // Then stop recording recorder.StopRecording(); - // and disable the button to stop recording - m_RecordStop->Disable(); + // and change the button label accordingly. + m_RecordStop->SetLabel(_("Record")); } else // Recorder is actually about to start recording { From fbc77e956ae348e581bffca2b5b3fe654c03bc42 Mon Sep 17 00:00:00 2001 From: lioncash Date: Wed, 1 May 2013 09:35:31 -0400 Subject: [PATCH 061/352] Display the initial number of frames that are to be recorded in the Fifo Player. Before this commit, nothing would would be displayed in the "Frames to Record" text control. This fixes that by setting it to what m_FramesToRecord is initially set to, which is 1 (at the time of this commit). --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 8f14797fb0..09eb0b21db 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -192,7 +192,8 @@ void FifoPlayerDlg::CreateGUIControls() m_FramesToRecordLabel->Wrap(-1); sRecordingOptions->Add(m_FramesToRecordLabel, 0, wxALL, 5); - m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000, 1); + wxString initialNum = wxString::Format(_T("%d"), m_FramesToRecord); + m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, initialNum, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000); sRecordingOptions->Add(m_FramesToRecordCtrl, 0, wxALL, 5); sRecordPage->Add(sRecordingOptions, 0, wxEXPAND, 5); From c2859a52078ab5189633656af6c59bb0c42bdcb4 Mon Sep 17 00:00:00 2001 From: lioncash Date: Wed, 1 May 2013 09:41:45 -0400 Subject: [PATCH 062/352] Dammit Ctrl-Z. Restore a wxSpinCtrl parameter that accidentally got removed in the last commit. --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 09eb0b21db..eed63d7552 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -193,7 +193,7 @@ void FifoPlayerDlg::CreateGUIControls() sRecordingOptions->Add(m_FramesToRecordLabel, 0, wxALL, 5); wxString initialNum = wxString::Format(_T("%d"), m_FramesToRecord); - m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, initialNum, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000); + m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, initialNum, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000, 1); sRecordingOptions->Add(m_FramesToRecordCtrl, 0, wxALL, 5); sRecordPage->Add(sRecordingOptions, 0, wxEXPAND, 5); From 8bcd9a74c8f1c844dadd5b11f22dfaa659848f71 Mon Sep 17 00:00:00 2001 From: skidau Date: Wed, 1 May 2013 23:51:43 +1000 Subject: [PATCH 063/352] Clear the texture cache when a new dol is loaded via ES_LAUNCH. Fixes the black screen in The House of the Dead 2. Abbreviated some of the information in the window titlebar. --- Source/Core/Core/Src/Core.cpp | 12 ++++++------ Source/Core/Core/Src/HLE/HLE_Misc.cpp | 2 ++ Source/Plugins/Plugin_VideoDX11/Src/VideoBackend.h | 1 + Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 5 +++++ Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/VideoBackend.h | 1 + Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 5 +++++ 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 20cbc5086a..ffd2c35472 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -680,8 +680,8 @@ void UpdateTitle() u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime); // Settings are shown the same for both extended and summary info - std::string SSettings = StringFromFormat("%s %s - %s - %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", - g_video_backend->GetName().c_str(), _CoreParameter.bDSPHLE ? "DSPHLE" : "DSPLLE"); + std::string SSettings = StringFromFormat("%s %s | %s | %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", + g_video_backend->GetName().c_str(), _CoreParameter.bDSPHLE ? "HLE" : "LLE"); // Use extended or summary information. The summary information does not print the ticks data, // that's more of a debugging interest, it can always be optional of course if someone is interested. @@ -698,7 +698,7 @@ void UpdateTitle() float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100; - std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); + std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed); SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)", _CoreParameter.bSkipIdle ? "~" : "", (int)(diff), @@ -711,11 +711,11 @@ void UpdateTitle() #else // Summary information std::string SFPS; if (Movie::IsPlayingInput()) - SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); + SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); else if (Movie::IsRecordingInput()) - SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); + SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); else - SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); + SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed); #endif // This is our final "frame counter" string diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index a37fc44a97..6db9704be8 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -20,6 +20,7 @@ #include "PowerPC/SignatureDB.h" #include "PowerPC/PPCSymbolDB.h" #include "CommonPaths.h" +#include "TextureCacheBase.h" namespace HLE_Misc { @@ -310,6 +311,7 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) } PowerPC::ppcState.iCache.Reset(); + TextureCache::Invalidate(); CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); size_t size = s_Usb->m_WiiMotes.size(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoDX11/Src/VideoBackend.h index a76935da72..f714dbe05a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VideoBackend.h @@ -13,6 +13,7 @@ class VideoBackend : public VideoBackendHardware void Shutdown(); std::string GetName(); + std::string GetDisplayName(); void Video_Prepare(); void Video_Cleanup(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index 5d9a93067c..0561885b27 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -63,6 +63,11 @@ void VideoBackend::UpdateFPSDisplay(const char *text) } std::string VideoBackend::GetName() +{ + return "DX11"; +} + +std::string VideoBackend::GetDisplayName() { return "Direct3D11"; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index b7fb9c1d44..42011d1b9e 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -72,7 +72,7 @@ void VideoBackend::UpdateFPSDisplay(const char *text) std::string VideoBackend::GetName() { - return "Direct3D9"; + return "DX9"; } std::string VideoBackend::GetDisplayName() diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoOGL/Src/VideoBackend.h index 2520c72763..137c09a973 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VideoBackend.h @@ -13,6 +13,7 @@ class VideoBackend : public VideoBackendHardware void Shutdown(); std::string GetName(); + std::string GetDisplayName(); void Video_Prepare(); void Video_Cleanup(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 74393fe121..4356418c81 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -91,6 +91,11 @@ namespace OGL { std::string VideoBackend::GetName() +{ + return "OGL"; +} + +std::string VideoBackend::GetDisplayName() { return "OpenGL"; } From c80309ee1ad6116cb76c5ee557e0b203c2a3be0f Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Wed, 1 May 2013 11:28:02 -0700 Subject: [PATCH 064/352] GCMemcard: Initialize the current/previous DIR BAT pointers when creating a new memory card fixes issue 6288 --- Source/Core/Core/Src/HW/GCMemcard.cpp | 8 +++++++- Source/Core/Core/Src/HW/GCMemcard.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp index a13cdb4a2c..c51d3221e3 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.cpp +++ b/Source/Core/Core/Src/HW/GCMemcard.cpp @@ -215,7 +215,12 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) } mcdFile.Close(); + + initDirBatPointers(); +} +void GCMemcard::initDirBatPointers() +{ if (BE16(dir.UpdateCounter) > (BE16(dir_backup.UpdateCounter))) { CurrentDir = &dir; @@ -1273,7 +1278,8 @@ bool GCMemcard::Format(bool sjis, u16 SizeMb) GCMBlock b; mc_data_blocks.push_back(b); } - + + initDirBatPointers(); m_valid = true; return Save(); diff --git a/Source/Core/Core/Src/HW/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h index a25d8daacb..215402dd10 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.h +++ b/Source/Core/Core/Src/HW/GCMemcard.h @@ -171,6 +171,7 @@ private: u32 ImportGciInternal(FILE* gcih, const char *inputFile, const std::string &outputFile); static void FormatInternal(GCMC_Header &GCP); + void initDirBatPointers() ; public: GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false); From 18b0556e0dbc9c55fd54d91765468c1f3efcdcc7 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 3 May 2013 23:20:48 +1000 Subject: [PATCH 065/352] Immediately process ARAM DMA transfers if they are 1 block in length. Fixes the teleportation in Beyond Good and Evil. Fixes issue 6289. --- Source/Core/Core/Src/HW/DSP.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 809128225e..24a872da87 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -687,12 +687,27 @@ void UpdateAudioDMA() void Do_ARAM_DMA() { - g_dspState.DSPControl.DMAState = 1; - CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16)); + if (g_arDMA.Cnt.count == 32) + { + // Beyond Good and Evil (GGEE41) sends count 32 + GenerateDSPInterrupt(INT_ARAM); + } + else + { + g_dspState.DSPControl.DMAState = 1; + CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16)); - // Force an early exception check on large transfers. Fixes RE2 audio. - if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144) - CoreTiming::ForceExceptionCheck(100); + // Force an early exception check on large transfers. Fixes RE2 audio. + // NFS:HP2 (<= 6144) + // Viewtiful Joe (<= 6144) + // Sonic Mega Collection (> 2048) + // Paper Mario battles (> 32) + // Mario Super Baseball (> 32) + // Knockout Kings 2003 loading (> 32) + // WWE DOR (> 32) + if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144) + CoreTiming::ForceExceptionCheck(100); + } // Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks if (g_arDMA.Cnt.dir) From 719f18a12221f35ec4e6e1d8c4d506a851b36da0 Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 4 May 2013 00:19:02 +1000 Subject: [PATCH 066/352] Forced an exception check on short ARAM DMA transfers. --- Source/Core/Core/Src/HW/DSP.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 24a872da87..3ef62e5aaa 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -690,7 +690,9 @@ void Do_ARAM_DMA() if (g_arDMA.Cnt.count == 32) { // Beyond Good and Evil (GGEE41) sends count 32 + // Lost Kingdoms 2 needs the exception check here in DSP HLE mode GenerateDSPInterrupt(INT_ARAM); + CoreTiming::ForceExceptionCheck(100); } else { From a295a3eb56a3bd0fef815d640cc632af089cdf59 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 4 May 2013 23:30:13 +0200 Subject: [PATCH 067/352] ogl: report shader compilation issues in the same way as other backends --- .../Src/ProgramShaderCache.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 153fe748f1..8689ecbd4e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -23,6 +23,7 @@ u32 ProgramShaderCache::s_ubo_buffer_size; bool ProgramShaderCache::s_ubo_dirty; static StreamBuffer *s_buffer; +static int num_failures = 0; LinearDiskCache g_program_disk_cache; static GLuint CurrentProgram = 0; @@ -287,11 +288,19 @@ bool ProgramShaderCache::CompileShader ( SHADER& shader, const char* vcode, cons glGetProgramInfoLog(pid, length, &charsWritten, infoLog); ERROR_LOG(VIDEO, "Program info log:\n%s", infoLog); char szTemp[MAX_PATH]; - sprintf(szTemp, "%sp_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), pid); + sprintf(szTemp, "%sbad_p_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); std::ofstream file; OpenFStream(file, szTemp, std::ios_base::out); file << infoLog << s_glsl_header << vcode << s_glsl_header << pcode; file.close(); + + PanicAlert("Failed to link shaders!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%s, %s, %s):\n%s", + szTemp, + g_ogl_config.gl_vendor, + g_ogl_config.gl_renderer, + g_ogl_config.gl_version, + infoLog); + delete [] infoLog; } if (linkStatus != GL_TRUE) @@ -328,11 +337,24 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code ) glGetShaderInfoLog(result, length, &charsWritten, infoLog); ERROR_LOG(VIDEO, "PS Shader info log:\n%s", infoLog); char szTemp[MAX_PATH]; - sprintf(szTemp, "%sps_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), result); + sprintf(szTemp, + "%sbad_%s_%04i.txt", + File::GetUserPath(D_DUMP_IDX).c_str(), + type==GL_VERTEX_SHADER ? "vs" : "ps", + num_failures++); std::ofstream file; OpenFStream(file, szTemp, std::ios_base::out); file << infoLog << s_glsl_header << code; file.close(); + + PanicAlert("Failed to compile %s shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%s, %s, %s):\n%s", + type==GL_VERTEX_SHADER ? "vertex" : "pixel", + szTemp, + g_ogl_config.gl_vendor, + g_ogl_config.gl_renderer, + g_ogl_config.gl_version, + infoLog); + delete[] infoLog; } if (compileStatus != GL_TRUE) From 7cc2e3146b55a04cab23db42f832aa306ea6514e Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sat, 4 May 2013 19:27:39 +0200 Subject: [PATCH 068/352] Updating Cheats manager when the ISO is changed etc. The Cheats manager should be updated when the ISO is changed because it's non-modal Removing code that read the ID from file because the cheats manager only has a use when an emulation is running (when the ID doesn't need to be read from the ISO again because it's in a variable). This fixes loading Gecko codes for .wad during an emulation because "VolumeHandler::GetVolume()" return false in this case --- Source/Core/DolphinWX/Src/CheatsWindow.cpp | 47 ++++++++++++++------- Source/Core/DolphinWX/Src/CheatsWindow.h | 3 ++ Source/Core/DolphinWX/Src/FrameTools.cpp | 13 ++++++ Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp | 12 +++--- Source/Core/DolphinWX/Src/GeckoCodeDiag.h | 4 +- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.cpp b/Source/Core/DolphinWX/Src/CheatsWindow.cpp index ba4918c917..522d30c764 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.cpp +++ b/Source/Core/DolphinWX/Src/CheatsWindow.cpp @@ -14,6 +14,7 @@ #include "WxUtils.h" #define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256 +const std::string title = _("Cheats Manager"); extern std::vector arCodes; extern CFrame* main_frame; @@ -22,26 +23,15 @@ extern CFrame* main_frame; static wxCheatsWindow *g_cheat_window; wxCheatsWindow::wxCheatsWindow(wxWindow* const parent) - : wxDialog(parent, wxID_ANY, _("Cheats Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxDIALOG_NO_PARENT) + : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxDIALOG_NO_PARENT) { ::g_cheat_window = this; // Create the GUI controls Init_ChildControls(); - // Load Data - Load_ARCodes(); - - // Load Gecko Codes :/ - { - const DiscIO::IVolume* const vol = VolumeHandler::GetVolume(); - if (vol) - { - m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + vol->GetUniqueID() + ".ini"; - m_gameini.Load(m_gameini_path); - m_geckocode_panel->LoadCodes(m_gameini, Core::g_CoreStartupParameter.GetUniqueID()); - } - } + // load codes + UpdateGUI(); SetSize(wxSize(-1, 600)); Center(); @@ -119,7 +109,7 @@ void wxCheatsWindow::Init_ChildControls() m_Notebook_Main->AddPage(m_Tab_Log, _("Logging")); // Button Strip - wxButton* const button_apply = new wxButton(panel, wxID_APPLY, _("Apply"), wxDefaultPosition, wxDefaultSize); + button_apply = new wxButton(panel, wxID_APPLY, _("Apply"), wxDefaultPosition, wxDefaultSize); button_apply->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ApplyChanges_Press, this); wxButton* const button_cancel = new wxButton(panel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize); button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ButtonClose_Press, this); @@ -249,12 +239,34 @@ void wxCheatsWindow::OnEvent_Close(wxCloseEvent& ev) Destroy(); } +// load codes for a new ISO ID +void wxCheatsWindow::UpdateGUI() +{ + // load code + m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + Core::g_CoreStartupParameter.GetUniqueID() + ".ini"; + m_gameini.Load(m_gameini_path); + Load_ARCodes(); + Load_GeckoCodes(); + + // enable controls + button_apply->Enable(Core::IsRunning()); + + // write the ISO name in the title + if (Core::IsRunning()) + SetTitle(title + ": " + Core::g_CoreStartupParameter.GetUniqueID() + " - " + Core::g_CoreStartupParameter.m_strName); + else + SetTitle(title); +} + void wxCheatsWindow::Load_ARCodes() { using namespace ActionReplay; m_CheckListBox_CheatsList->Clear(); + if (!Core::IsRunning()) + return; + indexList.clear(); size_t size = GetCodeListSize(); for (size_t i = 0; i < size; i++) @@ -269,6 +281,11 @@ void wxCheatsWindow::Load_ARCodes() } } +void wxCheatsWindow::Load_GeckoCodes() +{ + m_geckocode_panel->LoadCodes(m_gameini, Core::g_CoreStartupParameter.GetUniqueID(), true); +} + void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& WXUNUSED (event)) { using namespace ActionReplay; diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.h b/Source/Core/DolphinWX/Src/CheatsWindow.h index 293236e005..244e4d5b48 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.h +++ b/Source/Core/DolphinWX/Src/CheatsWindow.h @@ -96,6 +96,7 @@ class wxCheatsWindow : public wxDialog public: wxCheatsWindow(wxWindow* const parent); ~wxCheatsWindow(); + void UpdateGUI(); protected: @@ -105,6 +106,7 @@ class wxCheatsWindow : public wxDialog }; // --- GUI Controls --- + wxButton* button_apply; wxNotebook *m_Notebook_Main; wxPanel *m_Tab_Cheats; @@ -134,6 +136,7 @@ class wxCheatsWindow : public wxDialog void Init_ChildControls(); void Load_ARCodes(); + void Load_GeckoCodes(); // --- Wx Events Handlers --- diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 57c465abfa..e183669c86 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -1133,6 +1133,7 @@ void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event)) CConfigMain ConfigMain(this); if (ConfigMain.ShowModal() == wxID_OK) m_GameListCtrl->Update(); + UpdateGUI(); } void CFrame::OnConfigGFX(wxCommandEvent& WXUNUSED (event)) @@ -1568,6 +1569,9 @@ void CFrame::UpdateGUI() if (DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU).IsValid()) GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->Enable(!Initialized); + // Tools + GetMenuBar()->FindItem(IDM_CHEATS)->Enable(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats); + GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Enable(RunningWii); GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Enable(RunningWii); GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Enable(RunningWii); @@ -1675,6 +1679,15 @@ void CFrame::UpdateGUI() // Commit changes to manager m_Mgr->Update(); + + // Update non-modal windows + if (g_CheatsWindow) + { + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats) + g_CheatsWindow->UpdateGUI(); + else + g_CheatsWindow->Close(); + } } void CFrame::UpdateGameList() diff --git a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp index 12685fac75..efd4a3a990 100644 --- a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp +++ b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "GeckoCodeDiag.h" +#include "Core.h" #include "WxUtils.h" #include @@ -59,10 +60,10 @@ CodeConfigPanel::CodeConfigPanel(wxWindow* const parent) SetSizerAndFit(sizer_main); } -void CodeConfigPanel::UpdateCodeList() +void CodeConfigPanel::UpdateCodeList(bool checkRunning) { // disable the button if it doesn't have an effect - btn_download->Enable(!m_gameid.empty()); + btn_download->Enable((!checkRunning || Core::IsRunning()) && !m_gameid.empty()); m_listbox_gcodes->Clear(); // add the codes to the listbox @@ -80,14 +81,15 @@ void CodeConfigPanel::UpdateCodeList() UpdateInfoBox(evt); } -void CodeConfigPanel::LoadCodes(const IniFile& inifile, const std::string& gameid) +void CodeConfigPanel::LoadCodes(const IniFile& inifile, const std::string& gameid, bool checkRunning) { m_gameid = gameid; m_gcodes.clear(); - Gecko::LoadCodes(inifile, m_gcodes); + if (!checkRunning || Core::IsRunning()) + Gecko::LoadCodes(inifile, m_gcodes); - UpdateCodeList(); + UpdateCodeList(checkRunning); } void CodeConfigPanel::ToggleCode(wxCommandEvent& evt) diff --git a/Source/Core/DolphinWX/Src/GeckoCodeDiag.h b/Source/Core/DolphinWX/Src/GeckoCodeDiag.h index 66bbdbd4bb..0140966c5e 100644 --- a/Source/Core/DolphinWX/Src/GeckoCodeDiag.h +++ b/Source/Core/DolphinWX/Src/GeckoCodeDiag.h @@ -20,7 +20,7 @@ public: CodeConfigPanel(wxWindow* const parent); - void LoadCodes(const IniFile& inifile, const std::string& gameid = ""); + void LoadCodes(const IniFile& inifile, const std::string& gameid = "", bool checkRunning = false); const std::vector& GetCodes() const { return m_gcodes; } protected: @@ -29,7 +29,7 @@ protected: void DownloadCodes(wxCommandEvent&); //void ApplyChanges(wxCommandEvent&); - void UpdateCodeList(); + void UpdateCodeList(bool checkRunning = false); private: std::vector m_gcodes; From 46cd91dc0d70178800deecf9867ae80b3d7884bf Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sun, 5 May 2013 21:23:16 +0200 Subject: [PATCH 069/352] Build fix --- Source/Core/DolphinWX/Src/CheatsWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.cpp b/Source/Core/DolphinWX/Src/CheatsWindow.cpp index 522d30c764..7d92d7cb04 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.cpp +++ b/Source/Core/DolphinWX/Src/CheatsWindow.cpp @@ -14,7 +14,7 @@ #include "WxUtils.h" #define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256 -const std::string title = _("Cheats Manager"); +const wxString title = _("Cheats Manager"); extern std::vector arCodes; extern CFrame* main_frame; From 12d791a6288704affa1627dd54fbf14bda77eb12 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Sun, 5 May 2013 23:22:57 -0500 Subject: [PATCH 070/352] Fix some of the compiler warnings that have appeared recently. --- Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp | 5 ++--- Source/Core/Core/Src/State.cpp | 8 +++++--- Source/Core/Core/Src/State.h | 2 -- Source/Core/DolphinWX/Src/FrameTools.cpp | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp index f7387154b2..e28d5a32ae 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp @@ -66,9 +66,8 @@ void CUCode_AX::LoadResamplingCoefficients() WARN_LOG(DSPHLE, "Loading polyphase resampling coeffs from %s", filename.c_str()); - FILE* fp = fopen(filename.c_str(), "rb"); - fread(m_coeffs, 1, 0x1000, fp); - fclose(fp); + File::IOFile fp(filename, "rb"); + fp.ReadBytes(m_coeffs, 0x1000); for (u32 i = 0; i < 0x800; ++i) m_coeffs[i] = Common::swap16(m_coeffs[i]); diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 09653ac9ad..40a48b4841 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -157,7 +157,7 @@ void VerifyBuffer(std::vector& buffer) // return state number not in map int GetEmptySlot(std::map m) { - for (int i = 1; i <= NUM_STATES; i++) + for (int i = 1; i <= (int)NUM_STATES; i++) { bool found = false; for (std::map::iterator it = m.begin(); it != m.end(); it++) @@ -173,12 +173,14 @@ int GetEmptySlot(std::map m) return -1; } +static std::string MakeStateFilename(int number); + // read state timestamps std::map GetSavedStates() { StateHeader header; std::map m; - for (int i = 1; i <= NUM_STATES; i++) + for (int i = 1; i <= (int)NUM_STATES; i++) { if (File::Exists(MakeStateFilename(i))) { @@ -570,7 +572,7 @@ void LoadLastSaved(int i) { std::map savedStates = GetSavedStates(); - if (i > savedStates.size()) + if (i > (int)savedStates.size()) Core::DisplayMessage("State doesn't exist", 2000); else { diff --git a/Source/Core/Core/Src/State.h b/Source/Core/Core/Src/State.h index 14e77bae5c..302e25d617 100644 --- a/Source/Core/Core/Src/State.h +++ b/Source/Core/Core/Src/State.h @@ -49,8 +49,6 @@ void SaveToBuffer(std::vector& buffer); void LoadFromBuffer(std::vector& buffer); void VerifyBuffer(std::vector& buffer); -static std::string MakeStateFilename(int number); - void LoadLastSaved(int i = 1); void SaveFirstSaved(); void UndoSaveState(); diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index e183669c86..c6d542bf85 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -159,14 +159,14 @@ void CFrame::CreateMenu() loadMenu->Append(IDM_UNDOLOADSTATE, GetMenuLabel(HK_UNDO_LOAD_STATE)); loadMenu->AppendSeparator(); - for (int i = 1; i <= State::NUM_STATES; i++) + for (unsigned int i = 1; i <= State::NUM_STATES; i++) { loadMenu->Append(IDM_LOADSLOT1 + i - 1, GetMenuLabel(HK_LOAD_STATE_SLOT_1 + i - 1)); saveMenu->Append(IDM_SAVESLOT1 + i - 1, GetMenuLabel(HK_SAVE_STATE_SLOT_1 + i - 1)); } loadMenu->AppendSeparator(); - for (int i = 1; i <= State::NUM_STATES; i++) + for (unsigned int i = 1; i <= State::NUM_STATES; i++) loadMenu->Append(IDM_LOADLAST1 + i - 1, GetMenuLabel(HK_LOAD_LAST_STATE_1 + i - 1)); m_MenuBar->Append(emulationMenu, _("&Emulation")); From b2d3dc8a681767d7da69dfd5932f0a9daecfdb3d Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 5 May 2013 22:42:13 -0500 Subject: [PATCH 071/352] [Android] Allow the user to select multiple browse paths. --- .../dolphinemu/DolphinEmulator.java | 4 +- .../dolphinemu/dolphinemu/GameListView.java | 76 ++++++++++--------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java index db647723ad..060807d63c 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -6,8 +6,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.simonvt.menudrawer.MenuDrawer; - import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -25,7 +23,7 @@ public class DolphinEmulator extends Activity private float screenWidth; private float screenHeight; - + public static native void onTouchEvent(int Action, float X, float Y); static diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java index d585ead372..df7d29e91f 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java @@ -28,7 +28,7 @@ import android.widget.Toast; public class GameListView extends ListActivity { private GameListAdapter adapter; - private static File currentDir = null; + private static List currentDir; private MenuDrawer mDrawer; private SideMenuAdapter mAdapter; @@ -37,38 +37,42 @@ public class GameListView extends ListActivity { public static native String GetConfig(String Key, String Value, String Default); public static native void SetConfig(String Key, String Value, String Default); - private void Fill(File f) + private void Fill() { - File[]dirs = f.listFiles(); + + this.setTitle("Game List"); - Listdir = new ArrayList(); Listfls = new ArrayList(); - - try + String Directories = GetConfig("General", "GCMPathes", "0"); + int intDirectories = Integer.parseInt(Directories); + for (int a = 0; a < intDirectories; ++a) { - for(File ff: dirs) + String BrowseDir = GetConfig("General", "GCMPaths" + Integer.toString(a), ""); + File currentDir = new File(BrowseDir); + File[]dirs = currentDir.listFiles(); + try { - if (ff.getName().charAt(0) != '.') - if(!ff.isDirectory()) - if (ff.getName().toLowerCase().contains(".gcm") || - ff.getName().toLowerCase().contains(".iso") || - ff.getName().toLowerCase().contains(".wbfs") || - ff.getName().toLowerCase().contains(".gcz") || - ff.getName().toLowerCase().contains(".dol") || - ff.getName().toLowerCase().contains(".elf")) - fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); - } - } - catch(Exception e) - { - } - - Collections.sort(dir); - Collections.sort(fls); - dir.addAll(fls); - - adapter = new GameListAdapter(this,R.layout.main,dir); - this.setListAdapter(adapter); + for(File ff: dirs) + { + if (ff.getName().charAt(0) != '.') + if(!ff.isDirectory()) + if (ff.getName().toLowerCase().contains(".gcm") || + ff.getName().toLowerCase().contains(".iso") || + ff.getName().toLowerCase().contains(".wbfs") || + ff.getName().toLowerCase().contains(".gcz") || + ff.getName().toLowerCase().contains(".dol") || + ff.getName().toLowerCase().contains(".elf")) + fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); + } + } + catch(Exception e) + { + } + } + Collections.sort(fls); + + adapter = new GameListAdapter(this,R.layout.main, fls); + this.setListAdapter(adapter); } @Override @@ -103,11 +107,13 @@ public class GameListView extends ListActivity { { String FileName = data.getStringExtra("Select"); Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show(); - SetConfig("General", "GCMPathes", "1"); - SetConfig("General", "GCMPaths0", FileName); + String Directories = GetConfig("General", "GCMPathes", "0"); + int intDirectories = Integer.parseInt(Directories); + Directories = Integer.toString(intDirectories + 1); + SetConfig("General", "GCMPathes", Directories); + SetConfig("General", "GCMPaths" + Integer.toString(intDirectories), FileName); - currentDir = new File(FileName); - Fill(currentDir); + Fill(); } } @@ -119,10 +125,8 @@ public class GameListView extends ListActivity { mDrawer = MenuDrawer.attach(this, MenuDrawer.MENU_DRAG_CONTENT); - String BrowseDir = GetConfig("General", "GCMPaths0", ""); - if(currentDir == null) - currentDir = new File(BrowseDir); - Fill(currentDir); + + Fill(); Listdir = new ArrayList(); dir.add(new SideMenuItem("Browse Folder", 0)); From 09def3ed3f4dc746ffa9c0b6ebd749ff751ec6f5 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 5 May 2013 22:47:15 -0500 Subject: [PATCH 072/352] [Android] Add in a compiling option for GLES3 --- CMakeLists.txt | 19 ++++++++++++++----- Source/Core/Common/Src/VideoBackendBase.cpp | 4 ++-- Source/Core/Core/CMakeLists.txt | 2 +- Source/Core/DolphinWX/Src/GLInterface/EGL.cpp | 4 ++++ Source/Plugins/CMakeLists.txt | 2 +- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e8b26e254..1ddf6c1581 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,8 @@ option(ANDROID "Enables a build for Android" OFF) option(USE_EGL "Enables EGL OpenGL Interface" OFF) option(USE_X11 "Enables X11 Support" ON) option(USE_WAYLAND "Enables Wayland Support" OFF) -option(USE_GLES "Enables GLES And EGL, disables OGL" OFF) +option(USE_GLES "Enables GLES2 And EGL, disables OGL" OFF) +option(USE_GLES3 "Enables GLES3 and EGL" OFF) option(DISABLE_WX "Disable wxWidgets (use CLI interface)" OFF) option(FASTLOG "Enable all logs" OFF) @@ -261,11 +262,19 @@ endif() # For now GLES and EGL are tied to each other. # Enabling GLES also disables the OpenGL plugin. -if(USE_GLES) - message("GLES rendering enabled") - add_definitions(-DUSE_GLES=1) - add_definitions(-DUSE_EGL=1) +if(USE_GLES3) + message("GLES3 rendering enabled") + add_definitions(-DUSE_GLES=1 -DUSE_EGL=1 -DUSE_GLES3=1) + include_directories(Externals/GLES3) set(USE_EGL True) + set(USE_GLES True) +else() + if(USE_GLES) + message("GLES2 rendering enabled. OpenGL disabled") + add_definitions(-DUSE_GLES=1) + add_definitions(-DUSE_EGL=1) + set(USE_EGL True) + endif() endif() # For now Wayland and EGL are tied to each other. # The alternative would be an shm path diff --git a/Source/Core/Common/Src/VideoBackendBase.cpp b/Source/Core/Common/Src/VideoBackendBase.cpp index 8db4e2ff79..99bce01156 100644 --- a/Source/Core/Common/Src/VideoBackendBase.cpp +++ b/Source/Core/Common/Src/VideoBackendBase.cpp @@ -9,7 +9,7 @@ #include "../../../Plugins/Plugin_VideoDX9/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoDX11/Src/VideoBackend.h" #endif -#ifndef USE_GLES +#if !defined(USE_GLES) || USE_GLES3 #include "../../../Plugins/Plugin_VideoOGL/Src/VideoBackend.h" #endif #include "../../../Plugins/Plugin_VideoSoftware/Src/VideoBackend.h" @@ -45,7 +45,7 @@ void VideoBackend::PopulateList() if (IsGteVista()) g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend); #endif -#ifndef USE_GLES +#if !defined(USE_GLES) || USE_GLES3 g_available_video_backends.push_back(backends[1] = new OGL::VideoBackend); #endif g_available_video_backends.push_back(backends[3] = new SW::VideoSoftware); diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index d0ad3c615d..5474083132 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -217,7 +217,7 @@ endif() set(LIBS bdisasm inputcommon videosoftware sfml-network) -if(NOT USE_GLES) +if(NOT USE_GLES OR USE_GLES3) set(LIBS ${LIBS} videoogl) endif() diff --git a/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp b/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp index aa26c40b6f..6c12c1156c 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp @@ -52,7 +52,11 @@ bool cInterfaceEGL::Create(void *&window_handle) EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 24, #ifdef USE_GLES +#ifdef USE_GLES3 + EGL_RENDERABLE_TYPE, (1 << 6) /* EGL_OPENGL_ES3_BIT */, +#else EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#endif #else EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, #endif diff --git a/Source/Plugins/CMakeLists.txt b/Source/Plugins/CMakeLists.txt index 7dfdbaca83..3a58c3aab1 100644 --- a/Source/Plugins/CMakeLists.txt +++ b/Source/Plugins/CMakeLists.txt @@ -1,4 +1,4 @@ -if(NOT USE_GLES) +if(NOT USE_GLES OR USE_GLES3) add_subdirectory(Plugin_VideoOGL) endif() add_subdirectory(Plugin_VideoSoftware) From b6963ce1cbf6ad8db42ccefbf04d9bf7da306063 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 5 May 2013 23:10:58 -0500 Subject: [PATCH 073/352] [Android] Use vsnprintf for the log messages. --- Source/Core/DolphinWX/Src/MainAndroid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/MainAndroid.cpp b/Source/Core/DolphinWX/Src/MainAndroid.cpp index 4d623d5d0b..f1297e8026 100644 --- a/Source/Core/DolphinWX/Src/MainAndroid.cpp +++ b/Source/Core/DolphinWX/Src/MainAndroid.cpp @@ -113,7 +113,7 @@ void Host_SysMessage(const char *fmt, ...) char msg[512]; va_start(list, fmt); - vsprintf(msg, fmt, list); + vsnprintf(msg, 512, fmt, list); va_end(list); size_t len = strlen(msg); From 028a1a49715f52436d4c18282c7488037cdfe98c Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 5 May 2013 23:20:46 -0500 Subject: [PATCH 074/352] GL_DEPTH_COMPONENT can't have type of GL_UNSIGNED_BYTE with glTexImage2D. Qualcomm drivers get hit with this but all else don't care. --- Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index f590208fc3..2638a43fe6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -73,7 +73,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE, m_efbDepth); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); glBindTexture(GL_TEXTURE_RECTANGLE, 0); @@ -160,7 +160,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glViewport(0, 0, m_targetWidth, m_targetHeight); glScissor(0, 0, m_targetWidth, m_targetHeight); glClearColor(0.f, 0.f, 0.f, 1.f); - glClearDepth(1.0); + glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); } From cb5b9c0327c1223975b2fdae28b0db7ef5a92b77 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 5 May 2013 23:22:21 -0500 Subject: [PATCH 075/352] [Android] Add GLSLES3 to the GLSL version enums. Add in the version and precision qualifier to the shader header. --- Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp | 6 ++++-- Source/Plugins/Plugin_VideoOGL/Src/Render.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 8689ecbd4e..d24ab5a6a0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -501,6 +501,7 @@ void ProgramShaderCache::CreateHeader ( void ) GLSL_VERSION v = g_ogl_config.eSupportedGLSLVersion; snprintf(s_glsl_header, sizeof(s_glsl_header), "#version %s\n" + "%s\n" // default precision "%s\n" // tex_rect "%s\n" // ubo @@ -528,9 +529,10 @@ void ProgramShaderCache::CreateHeader ( void ) "%s\n" "#define COLOROUT(name) %s\n" - , v==GLSL_120 ? "120" : v==GLSL_130 ? "130" : "140" + , v==GLSLES3 ? "300 es" : v==GLSL_120 ? "120" : v==GLSL_130 ? "130" : "140" + , v==GLSLES3 ? "precision highp float;" : "" , v<=GLSL_130 ? "#extension GL_ARB_texture_rectangle : enable" : "#define texture2DRect texture" - , g_ActiveConfig.backend_info.bSupportsGLSLUBO && v!=GLSL_140 ? "#extension GL_ARB_uniform_buffer_object : enable" : "" + , g_ActiveConfig.backend_info.bSupportsGLSLUBO && v Date: Sun, 5 May 2013 23:33:49 -0500 Subject: [PATCH 076/352] [Android] Beginning of GLES3 support. --- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 74 ++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 60b3f38079..19472b5249 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -201,6 +201,8 @@ int GetNumMSAACoverageSamples(int MSAAMode) } void ApplySSAASettings() { + // GLES3 doesn't support SSAA +#ifndef USE_GLES3 if(g_ActiveConfig.iMultisampleMode == MULTISAMPLE_SSAA_4X) { if(g_ogl_config.bSupportSampleShading) { glEnable(GL_SAMPLE_SHADING_ARB); @@ -211,13 +213,17 @@ void ApplySSAASettings() { } else if(g_ogl_config.bSupportSampleShading) { glDisable(GL_SAMPLE_SHADING_ARB); } +#endif } void ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, void* userParam) { + // GLES3 doesn't natively support this + // XXX: Include GLES2 extensions header so we can use this +#ifndef USE_GLES3 const char *s_source; const char *s_type; - + switch(source) { case GL_DEBUG_SOURCE_API_ARB: s_source = "API"; break; @@ -245,6 +251,7 @@ void ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsi case GL_DEBUG_SEVERITY_LOW_ARB: WARN_LOG(VIDEO, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message); break; default: ERROR_LOG(VIDEO, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message); break; } +#endif } // Init functions @@ -259,6 +266,29 @@ Renderer::Renderer() InitFPSCounter(); bool bSuccess = true; + + g_ogl_config.gl_vendor = (const char*)glGetString(GL_VENDOR); + g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER); + g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION); + g_ogl_config.glsl_version = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); + + // Init extension support. +#ifdef USE_GLES3 + // Set default GLES3 options + WARN_LOG(VIDEO, "Running the OpenGL ES 3 backend!"); + g_Config.backend_info.bSupportsDualSourceBlend = false; + g_Config.backend_info.bSupportsGLSLUBO = true; + g_Config.backend_info.bSupportsPrimitiveRestart = false; + + g_ogl_config.bSupportsGLSLCache = false; // XXX: Reenable once shaders compile correctly + g_ogl_config.bSupportsGLPinnedMemory = false; + g_ogl_config.bSupportsGLSync = true; + g_ogl_config.bSupportsGLBaseVertex = false; + g_ogl_config.bSupportCoverageMSAA = false; // XXX: GLES3 spec has MSAA + g_ogl_config.bSupportSampleShading = false; + g_ogl_config.bSupportOGL31 = false; + g_ogl_config.eSupportedGLSLVersion = GLSLES3; +#else GLint numvertexattribs = 0; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &numvertexattribs); if (numvertexattribs < 16) @@ -268,8 +298,6 @@ Renderer::Renderer() numvertexattribs); bSuccess = false; } - - // Init extension support. #ifdef __APPLE__ glewExperimental = 1; #endif @@ -323,6 +351,8 @@ Renderer::Renderer() "Please report this issue, then there will be a workaround"); bSuccess = false; } + if (!GLEW_ARB_texture_non_power_of_two) + WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported."); if (!bSuccess) return; // TODO: fail @@ -338,12 +368,7 @@ Renderer::Renderer() g_ogl_config.bSupportCoverageMSAA = GLEW_NV_framebuffer_multisample_coverage; g_ogl_config.bSupportSampleShading = GLEW_ARB_sample_shading; g_ogl_config.bSupportOGL31 = GLEW_VERSION_3_1; - - g_ogl_config.gl_vendor = (const char*)glGetString(GL_VENDOR); - g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER); - g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION); - g_ogl_config.glsl_version = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); - + if(strstr(g_ogl_config.glsl_version, "1.00") || strstr(g_ogl_config.glsl_version, "1.10")) { ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need at least GLSL 1.20\n" @@ -364,6 +389,7 @@ Renderer::Renderer() { g_ogl_config.eSupportedGLSLVersion = GLSL_140; } +#endif glGetIntegerv(GL_MAX_SAMPLES, &g_ogl_config.max_samples); if(g_ogl_config.max_samples < 1) @@ -425,9 +451,6 @@ Renderer::Renderer() if (GL_REPORT_ERROR() != GL_NO_ERROR) bSuccess = false; - if (!GLEW_ARB_texture_non_power_of_two) - WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported."); - // TODO: Move these somewhere else? FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); @@ -457,7 +480,7 @@ Renderer::Renderer() glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClearDepth(1.0f); + glClearDepthf(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); @@ -468,8 +491,9 @@ Renderer::Renderer() glScissor(0, 0, GetTargetWidth(), GetTargetHeight()); glBlendColor(0, 0, 0, 0.5f); - glClearDepth(1.0f); - + glClearDepthf(1.0f); + +#ifndef USE_GLES3 if(g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) { if(g_ogl_config.bSupportOGL31) @@ -483,7 +507,7 @@ Renderer::Renderer() glPrimitiveRestartIndexNV(65535); } } - +#endif UpdateActiveConfig(); } @@ -884,8 +908,14 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; +#ifdef USE_GLES3 + // XXX: Swap colours + glReadPixels(targetPixelRc.left, targetPixelRc.bottom, targetPixelRcWidth, targetPixelRcHeight, + GL_RGBA, GL_UNSIGNED_INT, colorMap); +#else glReadPixels(targetPixelRc.left, targetPixelRc.bottom, targetPixelRcWidth, targetPixelRcHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, colorMap); +#endif GL_REPORT_ERRORD(); UpdateEFBCache(type, cacheRectIdx, efbPixelRc, targetPixelRc, colorMap); @@ -970,7 +1000,7 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) // Update the view port glViewport(X, Y, Width, Height); - glDepthRange(GLNear, GLFar); + glDepthRangef(GLNear, GLFar); } void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) @@ -992,7 +1022,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE // depth glDepthMask(zEnable ? GL_TRUE : GL_FALSE); - glClearDepth(float(z & 0xFFFFFF) / float(0xFFFFFF)); + glClearDepthf(float(z & 0xFFFFFF) / float(0xFFFFFF)); // Update rect for clearing the picture glEnable(GL_SCISSOR_TEST); @@ -1487,7 +1517,9 @@ void Renderer::RestoreAPIState() SetBlendMode(true); VertexShaderManager::SetViewportChanged(); +#ifndef USE_GLES3 glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL); +#endif VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); @@ -1539,6 +1571,9 @@ void Renderer::SetDepthMode() void Renderer::SetLogicOpMode() { + + // Logic ops aren't available in GLES3/GLES2 +#ifndef USE_GLES3 const GLenum glLogicOpCodes[16] = { GL_CLEAR, @@ -1568,6 +1603,7 @@ void Renderer::SetLogicOpMode() { glDisable(GL_COLOR_LOGIC_OP); } +#endif } void Renderer::SetDitherMode() @@ -1585,8 +1621,10 @@ void Renderer::SetLineWidth() if (bpmem.lineptwidth.linesize > 0) // scale by ratio of widths glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); +#ifndef USE_GLES3 if (bpmem.lineptwidth.pointsize > 0) glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f); +#endif } void Renderer::SetSamplerState(int stage, int texindex) From 0247b2a97a1dc4edf56a035cf7d128a636a8460e Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 6 May 2013 06:43:04 -0500 Subject: [PATCH 077/352] [Android] More GLES3 things. Disable Framedumping and MSAA rendering. Remove the HLSL->GLSL shader defines since Qualcomm doesn't support this in their shader compiler. Now they get chosen in our shader generator instead. --- .../VideoCommon/Src/LightingShaderGen.cpp | 2 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 57 +++++++++++-------- .../Src/FramebufferManager.cpp | 3 +- .../Src/ProgramShaderCache.cpp | 8 +-- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 4 +- 5 files changed, 42 insertions(+), 32 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index a9c602ad3d..4be33e9eac 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -213,7 +213,7 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName, p = GenerateLightShader(p, i, workingchannel, lightsName, coloralpha); } } - WRITE(p, "%s%d = mat * saturate(lacc);\n", dest, j); + WRITE(p, "%s%d = mat * clamp(lacc, 0.0, 1.0);\n", dest, j); WRITE(p, "}\n"); } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index efc16566eb..9ab5752e88 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -272,7 +272,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType); static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); // static void WriteAlphaCompare(char *&p, int num, int comp); static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); -static void WriteFog(char *&p); +static void WriteFog(char *&p, API_TYPE ApiType); static const char *tevKSelTableC[] = // KCSEL { @@ -480,6 +480,17 @@ static void BuildSwapModeTable() } } +// We can't use function defines since the Qualcomm shader compiler doesn't support it +static const char *GLSLConvertFunctions[] = +{ + "frac", // HLSL + "fract", // GLSL + "lerp", + "mix" +}; +#define FUNC_FRAC 0 +#define FUNC_LERP 2 + const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num) { if (ApiType == API_OPENGL) @@ -508,7 +519,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType int numTexgen = bpmem.genMode.numtexgens; bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable; - + bool bOpenGL = ApiType == API_OPENGL; char *p = text; WRITE(p, "//Pixel Shader for TEV stages\n"); WRITE(p, "//%i TEV stages, %i texgens, XXX IND stages\n", @@ -802,7 +813,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType } // emulation of unsigned 8 overflow when casting if needed if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) - WRITE(p, "\tprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "\tprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); if (Pretest == AlphaTest::UNDETERMINED) @@ -826,7 +837,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType // scale to make result from frac correct WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); - WRITE(p, "zCoord = frac(zCoord);\n"); + WRITE(p, "zCoord = %s(zCoord);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); // Note: depth texture out put is only written to depth buffer if late depth test is used @@ -840,7 +851,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType } else { - WriteFog(p); + WriteFog(p, ApiType); WRITE(p, "\tocol0 = prev;\n"); } @@ -913,16 +924,14 @@ static const char *TEVCMPAlphaOPTable[16] = " %s.a + (abs(dot(%s.rgb, comp24) - dot(%s.rgb, comp24)) < (0.5f/255.0f) ? %s.a : 0.0f)",//#define TEVCMP_BGR24_EQ 13 " %s.a + ((%s.a >= (%s.a + (0.25f/255.0f))) ? %s.a : 0.0f)",//#define TEVCMP_A8_GT 14 " %s.a + (abs(%s.a - %s.a) < (0.5f/255.0f) ? %s.a : 0.0f)"//#define TEVCMP_A8_EQ 15 - }; - static void WriteStage(char *&p, int n, API_TYPE ApiType) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens; bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages; - + bool bOpenGL = ApiType == API_OPENGL; // HACK to handle cases where the tex gen is not enabled if (!bHasTexCoord) texcoord = 0; @@ -1016,7 +1025,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; WRITE(p, "rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); - WRITE(p, "crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "crastemp = %s(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); } @@ -1049,7 +1058,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) WRITE(p, "konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]); if (kc > 7 || ka > 7) { - WRITE(p, "ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "ckonsttemp = %s(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); } else { @@ -1064,7 +1073,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) { - WRITE(p, "cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[0].AlphaNeedOverflowControl = false; RegisterStates[0].ColorNeedOverflowControl = false; } @@ -1082,7 +1091,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl) { - WRITE(p, "cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc0 = %s(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[1].AlphaNeedOverflowControl = false; RegisterStates[1].ColorNeedOverflowControl = false; } @@ -1100,7 +1109,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl) { - WRITE(p, "cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc1 = %s(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[2].AlphaNeedOverflowControl = false; RegisterStates[2].ColorNeedOverflowControl = false; } @@ -1118,7 +1127,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl) { - WRITE(p, "cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc2 = %s(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[3].AlphaNeedOverflowControl = false; RegisterStates[3].ColorNeedOverflowControl = false; } @@ -1135,7 +1144,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) // combine the color channel WRITE(p, "// color combine\n"); if (cc.clamp) - WRITE(p, "%s = saturate(", tevCOutputTable[cc.dest]); + WRITE(p, "%s = clamp(", tevCOutputTable[cc.dest]); else WRITE(p, "%s = ", tevCOutputTable[cc.dest]); @@ -1160,7 +1169,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) else if (cc.b == TEVCOLORARG_ZERO) WRITE(p, "%s*(float3(1.0f, 1.0f, 1.0f)-%s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.c + 16]); else - WRITE(p, "lerp(%s, %s, %s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); + WRITE(p, "%s(%s, %s, %s)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); WRITE(p, "%s", tevBiasTable[cc.bias]); @@ -1177,7 +1186,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) tevCInputTable[cc.c + 16]); } if (cc.clamp) - WRITE(p, ")"); + WRITE(p, ", 0.0, 1.0)"); WRITE(p,";\n"); RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0); @@ -1186,7 +1195,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) // combine the alpha channel WRITE(p, "// alpha combine\n"); if (ac.clamp) - WRITE(p, "%s = saturate(", tevAOutputTable[ac.dest]); + WRITE(p, "%s = clamp(", tevAOutputTable[ac.dest]); else WRITE(p, "%s = ", tevAOutputTable[ac.dest]); @@ -1208,7 +1217,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) else if (ac.b == TEVALPHAARG_ZERO) WRITE(p, "%s.a*(1.0f-%s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.c + 8]); else - WRITE(p, "lerp(%s.a, %s.a, %s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); + WRITE(p, "%s(%s.a, %s.a, %s.a)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); WRITE(p, "%s",tevBiasTable[ac.bias]); @@ -1227,7 +1236,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) tevAInputTable[ac.c + 8]); } if (ac.clamp) - WRITE(p, ")"); + WRITE(p, ", 0.0, 1.0)"); WRITE(p, ";\n\n"); WRITE(p, "// TEV done\n"); } @@ -1319,8 +1328,10 @@ static const char *tevFogFuncsTable[] = "\tfog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" // backward exp2 }; -static void WriteFog(char *&p) +static void WriteFog(char *&p, API_TYPE ApiType) { + bool bOpenGL = ApiType == API_OPENGL; + if (bpmem.fog.c_proj_fsel.fsel == 0) return; // no Fog @@ -1347,7 +1358,7 @@ static void WriteFog(char *&p) WRITE (p, "\tze *= x_adjust;\n"); } - WRITE (p, "\tfloat fog = saturate(ze - " I_FOG"[1].z);\n"); + WRITE (p, "\tfloat fog = clamp(ze - " I_FOG"[1].z, 0.0, 1.0);\n"); if (bpmem.fog.c_proj_fsel.fsel > 3) { @@ -1359,5 +1370,5 @@ static void WriteFog(char *&p) WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel); } - WRITE(p, "\tprev.rgb = lerp(prev.rgb, " I_FOG"[0].rgb, fog);\n"); + WRITE(p, "\tprev.rgb = %s(prev.rgb, " I_FOG"[0].rgb, fog);\n", GLSLConvertFunctions[FUNC_LERP + bOpenGL]); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index 2638a43fe6..5ce106601f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -86,6 +86,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms GL_REPORT_FBO_ERROR(); } +#ifndef USE_GLES3 else { // EFB targets will be renderbuffers in MSAA mode (required by OpenGL). @@ -151,7 +152,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer); } - +#endif // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffers(1, &m_xfbFramebuffer); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index d24ab5a6a0..1b5ab26c73 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -103,6 +103,7 @@ void SHADER::SetProgramVariables() void SHADER::SetProgramBindings() { +#ifndef USE_GLES3 if (g_ActiveConfig.backend_info.bSupportsDualSourceBlend) { // So we do support extended blending @@ -120,7 +121,7 @@ void SHADER::SetProgramBindings() // ogl2 shaders don't need to bind output colors. // gl_FragColor already point to color channel } - +#endif // Need to set some attribute locations glBindAttribLocation(glprogid, SHADER_POSITION_ATTRIB, "rawpos"); @@ -516,11 +517,6 @@ void ProgramShaderCache::CreateHeader ( void ) "#define float3 vec3\n" "#define float4 vec4\n" - // hlsl to glsl function translation - "#define frac(x) fract(x)\n" - "#define saturate(x) clamp(x, 0.0f, 1.0f)\n" - "#define lerp(x, y, z) mix(x, y, z)\n" - // glsl 120 hack "%s\n" "%s\n" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 19472b5249..db628a8f54 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1276,6 +1276,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } // Frame dumps are handled a little differently in Windows + // Frame dumping disabled entirely on GLES3 +#ifndef USE_GLES3 #if defined _WIN32 || defined HAVE_LIBAV if (g_ActiveConfig.bDumpFrames) { @@ -1372,7 +1374,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons bLastFrameDumped = false; } #endif - +#endif // Finish up the current frame, print some stats SetWindowSize(fbWidth, fbHeight); From 6871cc9700c9916fc602dd460e6451711990e5de Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 6 May 2013 22:18:46 +0200 Subject: [PATCH 078/352] FifoPlayerDlg: Improve navigating through search results. --- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 30 ++++++++++++++------- Source/Core/DolphinWX/Src/FifoPlayerDlg.h | 1 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index eed63d7552..63781008b3 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -55,7 +55,7 @@ FifoPlayerDlg::~FifoPlayerDlg() m_ObjectToCtrl->Unbind(wxEVT_COMMAND_SPINCTRL_UPDATED, &FifoPlayerDlg::OnObjectTo, this); m_EarlyMemoryUpdates->Unbind(wxEVT_COMMAND_CHECKBOX_CLICKED, &FifoPlayerDlg::OnCheckEarlyMemoryUpdates, this); m_RecordStop->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnRecordStop, this); - m_Save->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnSaveFile, this); + m_Save->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnSaveFile, this); m_FramesToRecordCtrl->Unbind(wxEVT_COMMAND_SPINCTRL_UPDATED, &FifoPlayerDlg::OnNumFramesToRecord, this); m_Close->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnCloseClick, this); @@ -253,9 +253,7 @@ void FifoPlayerDlg::CreateGUIControls() m_findNext = new wxButton(m_AnalyzePage, wxID_ANY, _("Find next")); m_findPrevious = new wxButton(m_AnalyzePage, wxID_ANY, _("Find previous")); - m_beginSearch->Disable(); - m_findNext->Disable(); - m_findPrevious->Disable(); + ResetSearch(); sSearchButtons->Add(m_beginSearch, 0, wxALL, 5); sSearchButtons->Add(m_findNext, 0, wxALL, 5); @@ -500,16 +498,12 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event) ChangeSearchResult(0); m_beginSearch->Disable(); - m_findNext->Enable(); - m_findPrevious->Enable(); m_numResultsText->SetLabel(wxString::Format(_("Found %d results for \'"), search_results.size()) + m_searchField->GetValue() + _("\'")); } void FifoPlayerDlg::OnSearchFieldTextChanged(wxCommandEvent& event) { - m_beginSearch->Enable(m_searchField->GetLineLength(0) > 0); - m_findNext->Disable(); - m_findPrevious->Disable(); + ResetSearch(); } void FifoPlayerDlg::OnFindNextClick(wxCommandEvent& event) @@ -552,7 +546,7 @@ void FifoPlayerDlg::OnFindPreviousClick(wxCommandEvent& event) void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx) { - if (search_results.size() > result_idx) + if (result_idx < search_results.size()) // if index is valid { m_search_result_idx = result_idx; int prev_frame = m_framesList->GetSelection(); @@ -578,6 +572,9 @@ void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx) ev.SetInt(m_objectCmdList->GetSelection()); OnObjectCmdListSelectionChanged(ev); } + + m_findNext->Enable(result_idx+1 < search_results.size()); + m_findPrevious->Enable(result_idx != 0); } else if (search_results.size()) { @@ -585,6 +582,15 @@ void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx) } } +void FifoPlayerDlg::ResetSearch() +{ + m_beginSearch->Enable(m_searchField->GetLineLength(0) > 0); + m_findNext->Disable(); + m_findPrevious->Disable(); + + search_results.clear(); +} + void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) { FifoPlayer& player = FifoPlayer::GetInstance(); @@ -601,6 +607,8 @@ void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event) wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED); ev.SetInt(-1); OnObjectListSelectionChanged(ev); + + ResetSearch(); } void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) @@ -728,6 +736,8 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event) wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED); ev.SetInt(-1); OnObjectCmdListSelectionChanged(ev); + + ResetSearch(); } void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h index 9b0098a92e..6f4a8074b9 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.h +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.h @@ -37,6 +37,7 @@ private: void OnFindPreviousClick(wxCommandEvent& event); void OnSearchFieldTextChanged(wxCommandEvent& event); void ChangeSearchResult(unsigned int result_idx); + void ResetSearch(); void OnRecordingFinished(wxEvent& event); void OnFrameWritten(wxEvent& event); From 9365187f8942f21ab3d35d37b786eacb1146cd67 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 6 May 2013 22:19:21 +0200 Subject: [PATCH 079/352] BPMemory: Add register documentation for texture source adress and EFB configuration. --- Source/Core/VideoCommon/Src/BPMemory.cpp | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index e917632e1f..4828972cae 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -89,6 +89,19 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size } break; + case BPMEM_ZCOMPARE: + { + SetRegName(BPMEM_ZCOMPARE); + PE_CONTROL config; config.hex = cmddata; + const char* pixel_formats[] = { "RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24", "Y8", "U8", "V8", "YUV420" }; + const char* zformats[] = { "linear", "compressed (near)", "compressed (mid)", "compressed (far)", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)" }; + snprintf(desc, desc_size, "EFB pixel format: %s\n" + "Depth format: %s\n" + "Early depth test: %s\n", + pixel_formats[config.pixel_format], zformats[config.zformat], no_yes[config.early_ztest]); + } + break; + case BPMEM_EFB_BR: // 0x4A { // TODO: Misleading name, should be BPMEM_EFB_WH instead @@ -162,6 +175,21 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size // TODO: Description break; + case BPMEM_TX_SETIMAGE3: // 0x94 + case BPMEM_TX_SETIMAGE3+1: + case BPMEM_TX_SETIMAGE3+2: + case BPMEM_TX_SETIMAGE3+3: + case BPMEM_TX_SETIMAGE3_4: // 0xB4 + case BPMEM_TX_SETIMAGE3_4+1: + case BPMEM_TX_SETIMAGE3_4+2: + case BPMEM_TX_SETIMAGE3_4+3: + { + SetRegName(BPMEM_TX_SETIMAGE3); + TexImage3 teximg; teximg.hex = cmddata; + snprintf(desc, desc_size, "Source address (32 byte aligned): 0x%06X", teximg.image_base << 5); + } + break; + case BPMEM_TEV_COLOR_ENV: // 0xC0 case BPMEM_TEV_COLOR_ENV+2: case BPMEM_TEV_COLOR_ENV+4: From a031351eb2cfe635b4970ebcf24b547c3190e16d Mon Sep 17 00:00:00 2001 From: calc84maniac Date: Tue, 7 May 2013 23:22:28 -0400 Subject: [PATCH 080/352] Use SOUNDTOUCH_INTEGER_SAMPLES only on Android build. Some audio backends (i.e. OpenAL) only support floating-point samples. --- Externals/soundtouch/STTypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/soundtouch/STTypes.h b/Externals/soundtouch/STTypes.h index 9855939119..39bc68bd69 100644 --- a/Externals/soundtouch/STTypes.h +++ b/Externals/soundtouch/STTypes.h @@ -80,7 +80,7 @@ namespace soundtouch #undef SOUNDTOUCH_INTEGER_SAMPLES #undef SOUNDTOUCH_FLOAT_SAMPLES - #if (defined(__SOFTFP__)) + #if (defined(ANDROID) && defined(__SOFTFP__)) // For Android compilation: Force use of Integer samples in case that // compilation uses soft-floating point emulation - soft-fp is way too slow #undef SOUNDTOUCH_FLOAT_SAMPLES From c7486609fa26626beca76e1f018a120ee406f14d Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 9 May 2013 10:17:12 +0200 Subject: [PATCH 081/352] fix underflow in IndexGenerator::AddFan fix issue 6282 The Last Story seems to render a fan with two vertices. It is non-sense as it shouldn't do anything, but the code underflows at (u32)numVerts-3 --- Source/Core/VideoCommon/Src/IndexGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index 15b2311f89..3970d8c82f 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -142,7 +142,7 @@ template void IndexGenerator::AddFan(u32 numVerts) if(pr) { - for(; i<=numVerts-3; i+=3) + for(; i+3<=numVerts; i+=3) { *Tptr++ = index + i - 1; *Tptr++ = index + i + 0; @@ -153,7 +153,7 @@ template void IndexGenerator::AddFan(u32 numVerts) numT += 3; } - for(; i<=numVerts-2; i+=2) + for(; i+2<=numVerts; i+=2) { *Tptr++ = index + i - 1; *Tptr++ = index + i + 0; From 98e8f8d7d052be619545f9acc0d79c9145a7e14c Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 10 May 2013 00:03:00 +1000 Subject: [PATCH 082/352] Forced an external exception check on DI interrupts. Fixes Summoner: A Goddess Reborn. Fixes issue 6301. --- Source/Core/Core/Src/HW/DVDInterface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Core/Core/Src/HW/DVDInterface.cpp b/Source/Core/Core/Src/HW/DVDInterface.cpp index 03a856662e..0e77b2a443 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.cpp +++ b/Source/Core/Core/Src/HW/DVDInterface.cpp @@ -530,6 +530,9 @@ void UpdateInterrupts() { ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, false); } + + // Required for Summoner: A Goddess Reborn + CoreTiming::ForceExceptionCheck(50); } void GenerateDIInterrupt(DI_InterruptType _DVDInterrupt) From 89be1cbf511591dba1e0e33868a67ca393d687fc Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 9 May 2013 17:48:48 +0200 Subject: [PATCH 083/352] recreate "per pixel depth" option and renamed it to fast depth calculation --- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 3 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 56 ++++++++++--------- Source/Core/VideoCommon/Src/PixelShaderGen.h | 2 +- Source/Core/VideoCommon/Src/VideoConfig.cpp | 4 ++ Source/Core/VideoCommon/Src/VideoConfig.h | 1 + 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 8ad34bed08..531fbe2cc4 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -87,6 +87,7 @@ wxString aa_desc = wxTRANSLATE("Reduces the amount of aliasing caused by rasteri wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of textures generated using render to texture effects.\nRaising the internal resolution will improve the effect of this setting.\nSlightly decreases performance and possibly causes issues (although unlikely).\n\nIf unsure, leave this checked."); wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked."); wxString hacked_buffer_upload_desc = wxTRANSLATE("Use a hacked upload strategy to stream vertices.\nThis usually speed up, but is forbidden by OpenGL specification and may causes heavy glitches.\n\nIf unsure, leave this unchecked."); +wxString fast_depth_calc_desc = wxTRANSLATE("Use the hardware perspective division to calculate the depth value.\nThis speed up the GPU a lot as the pixel shader only need to calculate the samples which pass the depth test.\nBut as this doesn't have to be accurate enough, flickering may happen on some gpus."); wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked."); wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked."); wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528."); @@ -502,7 +503,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); szr_other->Add(hacked_buffer_upload_cb = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); - + szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calucation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); if (Core::GetState() != Core::CORE_UNINITIALIZED) hacked_buffer_upload_cb->Disable(); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 9ab5752e88..c97cd889ea 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -95,22 +95,23 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo uid->values[0] |= bpmem.genMode.numtevstages; // 4 uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4 uid->values[0] |= dstAlphaMode << 8; // 2 + uid->values[0] |= g_ActiveConfig.bFastDepthCalc << 10; // 1 bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; - uid->values[0] |= enablePL << 10; // 1 + uid->values[0] |= enablePL << 11; // 1 if (!enablePL) { - uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4 + uid->values[0] |= xfregs.numTexGen.numTexGens << 12; // 4 } AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult(); - uid->values[0] |= alphaPreTest << 15; // 2 + uid->values[0] |= alphaPreTest << 16; // 2 // numtexgens should be <= 8 for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) { - uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1 + uid->values[0] |= xfregs.texMtxInfo[i].projection << (18+i); // 1 } uid->values[1] = bpmem.genMode.numindstages; // 3 @@ -180,8 +181,9 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.ztex2.hex; // 2 *ptr++ = bpmem.zcontrol.hex; // 3 *ptr++ = bpmem.zmode.hex; // 4 - *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 5 - *ptr++ = xfregs.numTexGen.hex; // 6 + *ptr++ = g_ActiveConfig.bFastDepthCalc; // 5 + *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6 + *ptr++ = xfregs.numTexGen.hex; // 7 if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { @@ -193,28 +195,28 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u } for (unsigned int i = 0; i < 8; ++i) - *ptr++ = xfregs.texMtxInfo[i].hex; // 7-14 + *ptr++ = xfregs.texMtxInfo[i].hex; // 8-15 for (unsigned int i = 0; i < 16; ++i) - *ptr++ = bpmem.tevind[i].hex; // 15-30 + *ptr++ = bpmem.tevind[i].hex; // 16-31 - *ptr++ = bpmem.tevindref.hex; // 31 + *ptr++ = bpmem.tevindref.hex; // 32 for (u32 i = 0; i < bpmem.genMode.numtevstages+1u; ++i) // up to 16 times { - *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i - *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i - *ptr++ = bpmem.tevind[i].hex; // 34+5*i - *ptr++ = bpmem.tevksel[i/2].hex; // 35+5*i - *ptr++ = bpmem.tevorders[i/2].hex; // 36+5*i + *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i + *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i + *ptr++ = bpmem.tevind[i].hex; // 35+5*i + *ptr++ = bpmem.tevksel[i/2].hex; // 36+5*i + *ptr++ = bpmem.tevorders[i/2].hex; // 37+5*i } - ptr = &uid->values[112]; + ptr = &uid->values[113]; - *ptr++ = bpmem.alpha_test.hex; // 112 + *ptr++ = bpmem.alpha_test.hex; // 113 - *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113 - *ptr++ = bpmem.fogRange.Base.hex; // 114 + *ptr++ = bpmem.fog.c_proj_fsel.hex; // 114 + *ptr++ = bpmem.fogRange.Base.hex; // 115 _assert_((ptr - uid->values) == uid->GetNumValues()); } @@ -518,7 +520,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType int numStages = bpmem.genMode.numtevstages + 1; int numTexgen = bpmem.genMode.numtexgens; - bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable; + bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) || !g_ActiveConfig.bFastDepthCalc; bool bOpenGL = ApiType == API_OPENGL; char *p = text; WRITE(p, "//Pixel Shader for TEV stages\n"); @@ -820,15 +822,18 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WriteAlphaTest(p, ApiType, dstAlphaMode, per_pixel_depth); - // the screen space depth value = far z + (clip z / clip w) * z range - if(ApiType == API_OPENGL || ApiType == API_D3D11) + // dx9 doesn't support readback of depth in pixel shader, so we always have to calculate it again + // shouldn't be a performance issue as early_z is still possible, but there may be depth issues with z-textures + if((ApiType == API_OPENGL || ApiType == API_D3D11) && g_ActiveConfig.bFastDepthCalc) WRITE(p, "float zCoord = rawpos.z;\n"); else - // dx9 doesn't support 4 component position, so we have to calculate it again + // the screen space depth value = far z + (clip z / clip w) * z range WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel; + + // Note: depth texture out put is only written to depth buffer if late depth test is used if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !skip_ztexture) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... @@ -839,11 +844,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); WRITE(p, "zCoord = %s(zCoord);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); - - // Note: depth texture out put is only written to depth buffer if late depth test is used - if (per_pixel_depth) - WRITE(p, "depth = zCoord;\n"); } + + if (per_pixel_depth) + WRITE(p, "depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) { diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index b93659c01c..d2a3046939 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -32,7 +32,7 @@ #define C_PMATERIALS (C_PLIGHTS + 40) #define C_PENVCONST_END (C_PMATERIALS + 4) #define PIXELSHADERUID_MAX_VALUES 70 -#define PIXELSHADERUID_MAX_VALUES_SAFE 115 +#define PIXELSHADERUID_MAX_VALUES_SAFE 116 // Annoying sure, can be removed once we get up to GLSL ~1.3 const s_svar PSVar_Loc[] = { {I_COLORS, C_COLORS, 4 }, diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 0b70b5440f..85fac2da19 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -64,6 +64,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0); iniFile.Get("Settings", "HackedBufferUpload", &bHackedBufferUpload, 0); + iniFile.Get("Settings", "FastDepthCalc", &bFastDepthCalc, 0); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "EFBScale", &iEFBScale, (int) SCALE_1X); // native @@ -123,6 +124,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle); iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting); iniFile.GetIfExists("Video_Settings", "HackedBufferUpload", &bHackedBufferUpload); + iniFile.GetIfExists("Video_Settings", "FastDepthCalc", &bFastDepthCalc); iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode); int tmp = -9000; iniFile.GetIfExists("Video_Settings", "EFBScale", &tmp); // integral @@ -219,6 +221,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting); iniFile.Set("Settings", "HackedBufferUpload", bHackedBufferUpload); + iniFile.Set("Settings", "FastDepthCalc", bFastDepthCalc); iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); iniFile.Set("Settings", "MSAA", iMultisampleMode); @@ -283,6 +286,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation); SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting); + SET_IF_DIFFERS("Video_Settings", "FastDepthCalc", bFastDepthCalc); SET_IF_DIFFERS("Video_Settings", "MSAA", iMultisampleMode); SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 9b5076df8c..ec4ad3ed3d 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -123,6 +123,7 @@ struct VideoConfig bool bUseBBox; bool bEnablePixelLighting; bool bHackedBufferUpload; + bool bFastDepthCalc; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped From f7c3cacb5cff2d02ee74ed7602ba3aae4f3278ba Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 10 May 2013 12:51:06 +0200 Subject: [PATCH 084/352] ppd: fix small issues in my last commit --- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 4 ++-- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 10 +++++++--- Source/Core/VideoCommon/Src/VideoConfig.cpp | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 531fbe2cc4..45bf35046e 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -87,7 +87,7 @@ wxString aa_desc = wxTRANSLATE("Reduces the amount of aliasing caused by rasteri wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of textures generated using render to texture effects.\nRaising the internal resolution will improve the effect of this setting.\nSlightly decreases performance and possibly causes issues (although unlikely).\n\nIf unsure, leave this checked."); wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked."); wxString hacked_buffer_upload_desc = wxTRANSLATE("Use a hacked upload strategy to stream vertices.\nThis usually speed up, but is forbidden by OpenGL specification and may causes heavy glitches.\n\nIf unsure, leave this unchecked."); -wxString fast_depth_calc_desc = wxTRANSLATE("Use the hardware perspective division to calculate the depth value.\nThis speed up the GPU a lot as the pixel shader only need to calculate the samples which pass the depth test.\nBut as this doesn't have to be accurate enough, flickering may happen on some gpus."); +wxString fast_depth_calc_desc = wxTRANSLATE("Use a less accurate algorithm to calculate depth values.\nCauses issues in a few games but might give a decent speedup.\n\nIf unsure, leave this checked."); wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked."); wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked."); wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528."); @@ -503,7 +503,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); szr_other->Add(hacked_buffer_upload_cb = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); - szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calucation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); + szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calculation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); if (Core::GetState() != Core::CORE_UNINITIALIZED) hacked_buffer_upload_cb->Disable(); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index c97cd889ea..9fd71c0e09 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -823,7 +823,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType // dx9 doesn't support readback of depth in pixel shader, so we always have to calculate it again - // shouldn't be a performance issue as early_z is still possible, but there may be depth issues with z-textures + // shouldn't be a performance issue as the written depth is usually still from perspective division + // but this isn't true for z-textures, so there will be depth issues between enabled and disabled z-textures fragments if((ApiType == API_OPENGL || ApiType == API_D3D11) && g_ActiveConfig.bFastDepthCalc) WRITE(p, "float zCoord = rawpos.z;\n"); else @@ -833,7 +834,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel; - // Note: depth texture out put is only written to depth buffer if late depth test is used + // Note: z-textures are not written to depth buffer if early depth test is used + if (per_pixel_depth && bpmem.zcontrol.early_ztest) + WRITE(p, "depth = zCoord;\n"); + if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !skip_ztexture) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... @@ -846,7 +850,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); } - if (per_pixel_depth) + if (per_pixel_depth && !bpmem.zcontrol.early_ztest) WRITE(p, "depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 85fac2da19..6e1bc31e55 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -64,7 +64,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0); iniFile.Get("Settings", "HackedBufferUpload", &bHackedBufferUpload, 0); - iniFile.Get("Settings", "FastDepthCalc", &bFastDepthCalc, 0); + iniFile.Get("Settings", "FastDepthCalc", &bFastDepthCalc, true); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "EFBScale", &iEFBScale, (int) SCALE_1X); // native From f348712d3a8dd6c6bfc262081dbbbb6d429c18b6 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 10 May 2013 11:47:06 +0000 Subject: [PATCH 085/352] BPMemory: Fix a small documentation mistake from revision 9365187f8942. --- Source/Core/VideoCommon/Src/BPMemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index 4828972cae..77f2f6bab3 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -94,7 +94,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size SetRegName(BPMEM_ZCOMPARE); PE_CONTROL config; config.hex = cmddata; const char* pixel_formats[] = { "RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24", "Y8", "U8", "V8", "YUV420" }; - const char* zformats[] = { "linear", "compressed (near)", "compressed (mid)", "compressed (far)", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)" }; + const char* zformats[] = { "linear", "compressed (near)", "compressed (mid)", "compressed (far)", "inv linear", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)" }; snprintf(desc, desc_size, "EFB pixel format: %s\n" "Depth format: %s\n" "Early depth test: %s\n", From 82cd91e944a4c95dfff83be770b5d6b6c39c49d0 Mon Sep 17 00:00:00 2001 From: Pierre Date: Fri, 10 May 2013 20:07:58 +0200 Subject: [PATCH 086/352] DSPJIT: the shift value must still be loaded into the correct register Fixes issue 6295 --- Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp index 04cc3aa753..dbb185844e 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp @@ -1563,6 +1563,7 @@ void DSPEmitter::lsrn(const UDSPInstruction opc) FixupBranch noShift = J_CC(CC_Z); //CL gets automatically masked with 0x3f on IA32/AMD64 //MOVZX(64, 16, RCX, R(RAX)); + MOV(64, R(RCX), R(RAX)); //AND(16, R(RCX), Imm16(0x3f)); TEST(16, R(RAX), Imm16(0x40)); FixupBranch shiftLeft = J_CC(CC_Z); From bf67378812931dc607ea42dba41bc06969ec7eda Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 11 May 2013 00:16:02 -0500 Subject: [PATCH 087/352] Fix the integer compare in our GLSL fmod function --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 9ab5752e88..c1e57815f4 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -544,7 +544,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "float fmod( float x, float y )\n"); WRITE(p, "{\n"); WRITE(p, "\tfloat z = fract( abs( x / y) ) * abs( y );\n"); - WRITE(p, "\treturn (x < 0) ? -z : z;\n"); + WRITE(p, "\treturn (x < 0.0) ? -z : z;\n"); WRITE(p, "}\n"); for (int i = 0; i < 8; ++i) From 6113cc12a27e375e765cfb02d9be4c6a68bf56cf Mon Sep 17 00:00:00 2001 From: "kostamarino@hotmail.com" Date: Sun, 12 May 2013 00:17:48 +0300 Subject: [PATCH 088/352] Gameini database update. Fixes issue 6258, Where's Waldo? The Fantastic Journey missing ingame pointer, and Battleship font. Various small changes. --- Data/User/GameConfig/GHMD4F.ini | 16 ++++++++++++++++ Data/User/GameConfig/GHME4F.ini | 8 ++++++++ Data/User/GameConfig/GHMF4F.ini | 16 ++++++++++++++++ Data/User/GameConfig/GHMP4F.ini | 16 ++++++++++++++++ Data/User/GameConfig/JAAE01.ini | 25 +++++++++++++++++-------- Data/User/GameConfig/SB3E08.ini | 2 +- Data/User/GameConfig/SB3J08.ini | 2 +- Data/User/GameConfig/SB3P08.ini | 2 +- Data/User/GameConfig/SLWE41.ini | 18 ++++++++++++++++++ Data/User/GameConfig/SVBE52.ini | 17 +++++++++++++++++ Data/User/GameConfig/SVBP52.ini | 17 +++++++++++++++++ Data/User/GameConfig/W8CEXS.ini | 9 +++++++-- Data/User/GameConfig/WILETL.ini | 8 +++++++- 13 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 Data/User/GameConfig/GHMD4F.ini create mode 100644 Data/User/GameConfig/GHMF4F.ini create mode 100644 Data/User/GameConfig/GHMP4F.ini create mode 100644 Data/User/GameConfig/SLWE41.ini create mode 100644 Data/User/GameConfig/SVBE52.ini create mode 100644 Data/User/GameConfig/SVBP52.ini diff --git a/Data/User/GameConfig/GHMD4F.ini b/Data/User/GameConfig/GHMD4F.ini new file mode 100644 index 0000000000..804c7ce141 --- /dev/null +++ b/Data/User/GameConfig/GHMD4F.ini @@ -0,0 +1,16 @@ +# GHMD4F - Hitman 2: Silent Assassin +[Core] Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 5 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GHME4F.ini b/Data/User/GameConfig/GHME4F.ini index 9ad65bde82..dfce92de40 100644 --- a/Data/User/GameConfig/GHME4F.ini +++ b/Data/User/GameConfig/GHME4F.ini @@ -30,3 +30,11 @@ $Press Left + Y For Nailgun 52889D30 00000801 0406D250 418201BC 0406D288 408000C4 +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GHMF4F.ini b/Data/User/GameConfig/GHMF4F.ini new file mode 100644 index 0000000000..cf6dbb5494 --- /dev/null +++ b/Data/User/GameConfig/GHMF4F.ini @@ -0,0 +1,16 @@ +# GHMF4F - Hitman 2: Silent Assassin +[Core] Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 5 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GHMP4F.ini b/Data/User/GameConfig/GHMP4F.ini new file mode 100644 index 0000000000..b9a7263c92 --- /dev/null +++ b/Data/User/GameConfig/GHMP4F.ini @@ -0,0 +1,16 @@ +# GHMP4F - Hitman 2: Silent Assassin +[Core] Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 5 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/JAAE01.ini b/Data/User/GameConfig/JAAE01.ini index ad577becc9..96dab75a98 100644 --- a/Data/User/GameConfig/JAAE01.ini +++ b/Data/User/GameConfig/JAAE01.ini @@ -1,8 +1,17 @@ -# JAAE01 - Super Mario World -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = No Sound -EmulationStateId = 4 -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] \ No newline at end of file +# JAAE01 - Super Mario World +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 4 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +SafeTextureCacheColorSamples = 512 diff --git a/Data/User/GameConfig/SB3E08.ini b/Data/User/GameConfig/SB3E08.ini index 110fee08ed..ce8e25554e 100644 --- a/Data/User/GameConfig/SB3E08.ini +++ b/Data/User/GameConfig/SB3E08.ini @@ -1,7 +1,7 @@ # SB3E08 - BASARA [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = Audio synch issues during dialogues, otherwise perfect +EmulationIssues = EmulationStateId = 5 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. diff --git a/Data/User/GameConfig/SB3J08.ini b/Data/User/GameConfig/SB3J08.ini index e7b6b6a3ef..70805a3243 100644 --- a/Data/User/GameConfig/SB3J08.ini +++ b/Data/User/GameConfig/SB3J08.ini @@ -1,7 +1,7 @@ # SB3J08 - BASARA [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = Audio synch issues during dialogues, otherwise perfect +EmulationIssues = EmulationStateId = 5 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. diff --git a/Data/User/GameConfig/SB3P08.ini b/Data/User/GameConfig/SB3P08.ini index e6d3b168ea..bd1677f5eb 100644 --- a/Data/User/GameConfig/SB3P08.ini +++ b/Data/User/GameConfig/SB3P08.ini @@ -1,7 +1,7 @@ # SB3P08 - BASARA [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = Audio synch issues during dialogues, otherwise perfect +EmulationIssues = EmulationStateId = 5 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. diff --git a/Data/User/GameConfig/SLWE41.ini b/Data/User/GameConfig/SLWE41.ini new file mode 100644 index 0000000000..8c6c850c01 --- /dev/null +++ b/Data/User/GameConfig/SLWE41.ini @@ -0,0 +1,18 @@ +# SLWE41 - Where's Waldo? The Fantastic Journey +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs Real Xfb for the pointer to appear. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = True diff --git a/Data/User/GameConfig/SVBE52.ini b/Data/User/GameConfig/SVBE52.ini new file mode 100644 index 0000000000..30756bcb27 --- /dev/null +++ b/Data/User/GameConfig/SVBE52.ini @@ -0,0 +1,17 @@ +# SVBE52 - Battleship +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +SafeTextureCacheColorSamples = 0 diff --git a/Data/User/GameConfig/SVBP52.ini b/Data/User/GameConfig/SVBP52.ini new file mode 100644 index 0000000000..8095983a48 --- /dev/null +++ b/Data/User/GameConfig/SVBP52.ini @@ -0,0 +1,17 @@ +# SVBP52 - Battleship +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +SafeTextureCacheColorSamples = 0 diff --git a/Data/User/GameConfig/W8CEXS.ini b/Data/User/GameConfig/W8CEXS.ini index dcaeed3473..7607ca4e5f 100644 --- a/Data/User/GameConfig/W8CEXS.ini +++ b/Data/User/GameConfig/W8CEXS.ini @@ -1,10 +1,15 @@ # W8CEXS - BIT.TRIP CORE [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 1 -EmulationIssues = Requires a Wii save game to boot +EmulationStateId = 4 +EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = [Gecko] diff --git a/Data/User/GameConfig/WILETL.ini b/Data/User/GameConfig/WILETL.ini index e8823e2ae1..0be2cca3c9 100644 --- a/Data/User/GameConfig/WILETL.ini +++ b/Data/User/GameConfig/WILETL.ini @@ -2,8 +2,14 @@ [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationIssues = -EmulationStateId = 1 +EmulationStateId = 4 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] From c30d00e904e4aeabc1e8e18a1cb52b19496148a1 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 17 May 2013 21:07:25 -0500 Subject: [PATCH 089/352] [Android] Support DFF files in the interface. --- Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java index df7d29e91f..d90bb32016 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java @@ -61,7 +61,8 @@ public class GameListView extends ListActivity { ff.getName().toLowerCase().contains(".wbfs") || ff.getName().toLowerCase().contains(".gcz") || ff.getName().toLowerCase().contains(".dol") || - ff.getName().toLowerCase().contains(".elf")) + ff.getName().toLowerCase().contains(".elf") || + ff.getName().toLowerCase().contains(".dff")) fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); } } From 39c9516197c208bb918ce87b968ad32e703b4413 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 17 May 2013 21:12:21 -0500 Subject: [PATCH 090/352] [Android] Qualcomm driver has a bug where it returns an invalid length for GL_INFO_LOG_LENGTH with glGetShaderiv. Qualcomm drivers seem to max out at ~512bytes returned from glGetShaderInfoLog so this is a reasonable max. --- Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 1b5ab26c73..1c85177352 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -334,6 +334,12 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code ) if (compileStatus != GL_TRUE || (length > 1 && DEBUG_GLSL)) { GLsizei charsWritten; +#ifdef USE_GLES3 + // This is a bug in the Qualcomm OpenGL Driver + // The length returned is garbage length so we need to set a default max + // XXX: Check if qualcomm driver here + length = 1024; // Qualcomm driver maxes out at 512 bytes returned from glGetShaderInfoLog anyway +#endif GLchar* infoLog = new GLchar[length]; glGetShaderInfoLog(result, length, &charsWritten, infoLog); ERROR_LOG(VIDEO, "PS Shader info log:\n%s", infoLog); @@ -527,7 +533,7 @@ void ProgramShaderCache::CreateHeader ( void ) , v==GLSLES3 ? "300 es" : v==GLSL_120 ? "120" : v==GLSL_130 ? "130" : "140" , v==GLSLES3 ? "precision highp float;" : "" - , v<=GLSL_130 ? "#extension GL_ARB_texture_rectangle : enable" : "#define texture2DRect texture" + , v==GLSLES3 ? "" : v<=GLSL_130 ? "#extension GL_ARB_texture_rectangle : enable" : "#define texture2DRect texture" , g_ActiveConfig.backend_info.bSupportsGLSLUBO && v Date: Sat, 18 May 2013 20:31:37 +1200 Subject: [PATCH 091/352] Initial commit with balance board working on Linux. Will not work on any other platform currently. Missing any sort of config, and definitely no emulation mode. --- Source/Core/Core/Src/Core.cpp | 6 +- Source/Core/Core/Src/HW/Wiimote.cpp | 9 +- Source/Core/Core/Src/HW/Wiimote.h | 13 +- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 25 ++-- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 137 +++++++++++++----- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 7 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 66 ++++++--- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h | 6 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 6 +- Source/Core/Core/Src/Movie.cpp | 2 +- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 4 +- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 4 +- 12 files changed, 196 insertions(+), 89 deletions(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index ffd2c35472..268d474ae6 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -394,10 +394,10 @@ void EmuThread() Wiimote::Initialize(g_pWindowHandle); // Activate wiimotes which don't have source set to "None" - for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + for (unsigned int i = 0; i != MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) - GetUsbPointer()->AccessWiiMote(i | 0x100)-> - Activate(true); + GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true); + } // The hardware is initialized. diff --git a/Source/Core/Core/Src/HW/Wiimote.cpp b/Source/Core/Core/Src/HW/Wiimote.cpp index 20e10b5fb8..6723a26d28 100644 --- a/Source/Core/Core/Src/HW/Wiimote.cpp +++ b/Source/Core/Core/Src/HW/Wiimote.cpp @@ -42,9 +42,10 @@ void Shutdown() void Initialize(void* const hwnd) { // add 4 wiimotes - for (unsigned int i = 0; i<4; ++i) + for (unsigned int i = WIIMOTE_CHAN_0; iDoState(p); } diff --git a/Source/Core/Core/Src/HW/Wiimote.h b/Source/Core/Core/Src/HW/Wiimote.h index fa4ec895bd..51ab018417 100644 --- a/Source/Core/Core/Src/HW/Wiimote.h +++ b/Source/Core/Core/Src/HW/Wiimote.h @@ -8,7 +8,16 @@ #include "../../InputCommon/Src/InputConfig.h" #include "ChunkFile.h" -#define MAX_WIIMOTES 4 +enum { + WIIMOTE_CHAN_0 = 0, + WIIMOTE_CHAN_1, + WIIMOTE_CHAN_2, + WIIMOTE_CHAN_3, + WIIMOTE_BALANCE_BOARD, + MAX_WIIMOTES = WIIMOTE_BALANCE_BOARD, + MAX_BBMOTES = 5, +}; + #define WIIMOTE_INI_NAME "WiimoteNew" @@ -20,7 +29,7 @@ enum WIIMOTE_SRC_HYBRID = 3, // emu + real }; -extern unsigned int g_wiimote_sources[MAX_WIIMOTES]; +extern unsigned int g_wiimote_sources[MAX_BBMOTES]; namespace Wiimote { diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 87ddc5086b..edd79f2bf6 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -63,23 +63,22 @@ WiimoteScanner::~WiimoteScanner() void WiimoteScanner::Update() {} -std::vector WiimoteScanner::FindWiimotes() +void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimote* & found_board) { - std::vector found_wiimotes; - // supposedly 1.28 seconds int const wait_len = 1; int const max_infos = 255; inquiry_info scan_infos[max_infos] = {}; auto* scan_infos_ptr = scan_infos; - + found_board = NULL; + // Scan for bluetooth devices int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH); if (found_devices < 0) { ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices."); - return found_wiimotes; + return; } DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices); @@ -91,7 +90,7 @@ std::vector WiimoteScanner::FindWiimotes() // BT names are a maximum of 248 bytes apparently char name[255] = {}; - if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 0) < 0) + if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 1000) < 0) { ERROR_LOG(WIIMOTE, "name request failed"); continue; @@ -119,14 +118,20 @@ std::vector WiimoteScanner::FindWiimotes() auto* const wm = new Wiimote; wm->bdaddr = scan_infos[i].bdaddr; - found_wiimotes.push_back(wm); - - NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); + if(IsBalanceBoardName(name)) + { + found_board = wm; + NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str); + } + else + { + found_wiimotes.push_back(wm); + NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); + } } } } - return found_wiimotes; } // Connect to a wiimote with a known address. diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index aaaaff6301..1d3be13cc5 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -17,12 +17,13 @@ #include "../WiimoteEmu/WiimoteHid.h" -unsigned int g_wiimote_sources[MAX_WIIMOTES]; +unsigned int g_wiimote_sources[MAX_BBMOTES]; namespace WiimoteReal { void HandleFoundWiimotes(const std::vector&); +void TryToConnectBalanceBoard(Wiimote*); void TryToConnectWiimote(Wiimote*); void HandleWiimoteDisconnect(int index); void DoneWithWiimote(int index); @@ -31,8 +32,7 @@ bool g_real_wiimotes_initialized = false; std::recursive_mutex g_refresh_lock; -Wiimote* g_wiimotes[MAX_WIIMOTES]; - +Wiimote* g_wiimotes[MAX_BBMOTES]; WiimoteScanner g_wiimote_scanner; Wiimote::Wiimote() @@ -285,7 +285,7 @@ bool Wiimote::Prepare(int _index) u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REPORT_MODE, 0, WM_REPORT_CORE}; // Set the active LEDs and turn on rumble. - u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << index | 0x1)}; + u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << (index%WIIMOTE_BALANCE_BOARD) | 0x1)}; // Turn off rumble u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0}; @@ -325,11 +325,25 @@ unsigned int CalculateWantedWiimotes() return wanted_wiimotes; } +unsigned int CalculateWantedBB() +{ + unsigned int wanted_bb = 0; + if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] && !g_wiimotes[WIIMOTE_BALANCE_BOARD]) + ++wanted_bb; + return wanted_bb; +} + void WiimoteScanner::WantWiimotes(bool do_want) { m_want_wiimotes = do_want; } + +void WiimoteScanner::WantBB(bool do_want) +{ + m_want_bb = do_want; +} + void WiimoteScanner::StartScanning() { if (!m_run_thread) @@ -352,7 +366,7 @@ void CheckForDisconnectedWiimotes() { std::lock_guard lk(g_refresh_lock); - for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + for (unsigned int i = 0; i < MAX_BBMOTES; ++i) if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected()) HandleWiimoteDisconnect(i); } @@ -366,12 +380,13 @@ void WiimoteScanner::ThreadFunc() while (m_run_thread) { std::vector found_wiimotes; + Wiimote* found_board = NULL; //NOTICE_LOG(WIIMOTE, "In loop"); - if (m_want_wiimotes) + if (m_want_wiimotes || m_want_bb) { - found_wiimotes = FindWiimotes(); + FindWiimotes(found_wiimotes, found_board); } else { @@ -384,7 +399,10 @@ void WiimoteScanner::ThreadFunc() // TODO: this is a fairly lame place for this CheckForDisconnectedWiimotes(); - HandleFoundWiimotes(found_wiimotes); + if(m_want_wiimotes) + HandleFoundWiimotes(found_wiimotes); + if(m_want_bb && found_board) + TryToConnectBalanceBoard(found_board); //std::this_thread::yield(); Common::SleepCurrentThread(500); @@ -439,6 +457,7 @@ void LoadSettings() sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU); } + g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = WIIMOTE_SRC_REAL; } // config dialog calls this when some settings change @@ -452,6 +471,7 @@ void Initialize() std::lock_guard lk(g_refresh_lock); g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); if (g_real_wiimotes_initialized) return; @@ -474,7 +494,7 @@ void Shutdown(void) g_real_wiimotes_initialized = false; - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) + for (unsigned int i = 0; i < MAX_BBMOTES; ++i) HandleWiimoteDisconnect(i); } @@ -482,9 +502,10 @@ void ChangeWiimoteSource(unsigned int index, int source) { { std::lock_guard lk(g_refresh_lock); - g_wiimote_sources[index] = source; g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); + // kill real connection (or swap to different slot) DoneWithWiimote(index); @@ -500,7 +521,7 @@ void TryToConnectWiimote(Wiimote* wm) { std::unique_lock lk(g_refresh_lock); - for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) { if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) @@ -525,16 +546,41 @@ void TryToConnectWiimote(Wiimote* wm) delete wm; } +void TryToConnectBalanceBoard(Wiimote* wm) +{ + std::unique_lock lk(g_refresh_lock); + + if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] + && !g_wiimotes[WIIMOTE_BALANCE_BOARD]) + { + if (wm->Connect() && wm->Prepare(WIIMOTE_BALANCE_BOARD)) + { + NOTICE_LOG(WIIMOTE, "Connected to Balance Board %i.", WIIMOTE_BALANCE_BOARD + 1); + + std::swap(g_wiimotes[WIIMOTE_BALANCE_BOARD], wm); + g_wiimotes[WIIMOTE_BALANCE_BOARD]->StartThread(); + + Host_ConnectWiimote(WIIMOTE_BALANCE_BOARD, true); + } + } + + g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); + + lk.unlock(); + + delete wm; +} + void DoneWithWiimote(int index) { std::lock_guard lk(g_refresh_lock); - + if (g_wiimotes[index]) { g_wiimotes[index]->StopThread(); // First see if we can use this real Wiimote in another slot. - for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) { if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) @@ -560,9 +606,11 @@ void HandleWiimoteDisconnect(int index) Wiimote* wm = NULL; { - std::lock_guard lk(g_refresh_lock); - std::swap(wm, g_wiimotes[index]); - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + std::lock_guard lk(g_refresh_lock); + + std::swap(wm, g_wiimotes[index]); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); } if (wm) @@ -583,31 +631,34 @@ void Refresh() g_wiimote_scanner.StopScanning(); { - std::unique_lock lk(g_refresh_lock); - std::vector found_wiimotes; - - if (0 != CalculateWantedWiimotes()) - { - // Don't hang Dolphin when searching - lk.unlock(); - found_wiimotes = g_wiimote_scanner.FindWiimotes(); - lk.lock(); - } - - CheckForDisconnectedWiimotes(); - - // Brief rumble for already connected Wiimotes. - for (int i = 0; i != MAX_WIIMOTES; ++i) - { - if (g_wiimotes[i]) + std::unique_lock lk(g_refresh_lock); + std::vector found_wiimotes; + Wiimote* found_board = NULL; + + if (0 != CalculateWantedWiimotes()) { - g_wiimotes[i]->StopThread(); - g_wiimotes[i]->Prepare(i); - g_wiimotes[i]->StartThread(); + // Don't hang Dolphin when searching + lk.unlock(); + g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board); + lk.lock(); } - } - HandleFoundWiimotes(found_wiimotes); + CheckForDisconnectedWiimotes(); + + // Brief rumble for already connected Wiimotes. + for (int i = 0; i < MAX_BBMOTES; ++i) + { + if (g_wiimotes[i]) + { + g_wiimotes[i]->StopThread(); + g_wiimotes[i]->Prepare(i); + g_wiimotes[i]->StartThread(); + } + } + + HandleFoundWiimotes(found_wiimotes); + if(found_board) + TryToConnectBalanceBoard(found_board); } Initialize(); @@ -616,7 +667,6 @@ void Refresh() void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) { std::lock_guard lk(g_refresh_lock); - if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size); } @@ -656,7 +706,14 @@ bool IsValidBluetoothName(const std::string& name) { return "Nintendo RVL-CNT-01" == name || - "Nintendo RVL-CNT-01-TR" == name; + "Nintendo RVL-CNT-01-TR" == name || + IsBalanceBoardName(name); +} + +bool IsBalanceBoardName(const std::string& name) +{ + return + "Nintendo RVL-WBC-01" == name; } }; // end of namespace diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index b57e1be2f4..695dc86b82 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -117,11 +117,12 @@ public: bool IsReady() const; void WantWiimotes(bool do_want); + void WantBB(bool do_want); void StartScanning(); void StopScanning(); - std::vector FindWiimotes(); + void FindWiimotes(std::vector&, Wiimote*&); // function called when not looking for more wiimotes void Update(); @@ -133,6 +134,7 @@ private: volatile bool m_run_thread; volatile bool m_want_wiimotes; + volatile bool m_want_bb; #if defined(_WIN32) @@ -145,7 +147,7 @@ private: extern std::recursive_mutex g_refresh_lock; extern WiimoteScanner g_wiimote_scanner; -extern Wiimote *g_wiimotes[4]; +extern Wiimote *g_wiimotes[MAX_BBMOTES]; void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); @@ -158,6 +160,7 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes); void ChangeWiimoteSource(unsigned int index, int source); bool IsValidBluetoothName(const std::string& name); +bool IsBalanceBoardName(const std::string& name); }; // WiimoteReal diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 41f751cb77..daa28b340d 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -32,7 +32,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De } else { - u8 maxWM = min(BT_DINF.num_registered, CONF_PAD_MAX_ACTIVE); + u8 maxWM = min(BT_DINF.num_registered, MAX_BBMOTES); bdaddr_t tmpBD = BDADDR_ANY; u8 i = 0; while (i < maxWM) @@ -43,28 +43,60 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3]; tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4]; tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5]; + if(i == WIIMOTE_BALANCE_BOARD) + { + const char * wmName = "Nintendo RVL-WBC-01"; + memcpy(BT_DINF.registered[i].name, wmName, 20); + memcpy(BT_DINF.balance_board.name, wmName, 20); + } + else + { + const char * wmName = "Nintendo RVL-CNT-01"; + memcpy(BT_DINF.registered[i].name, wmName, 20); + memcpy(BT_DINF.active[i].name, wmName, 20); + } INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); i++; } - while (i < CONF_PAD_MAX_ACTIVE) + while (i < MAX_BBMOTES) { - const char * wmName = "Nintendo RVL-CNT-01"; - ++BT_DINF.num_registered; - BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i; - BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0; - BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79; - BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19; - BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2; - BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11; - memcpy(BT_DINF.registered[i].name, wmName, 20); + if(i == WIIMOTE_BALANCE_BOARD) + { + const char * wmName = "Nintendo RVL-WBC-01"; + ++BT_DINF.num_registered; + BT_DINF.balance_board.bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i; + BT_DINF.balance_board.bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0; + BT_DINF.balance_board.bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79; + BT_DINF.balance_board.bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19; + BT_DINF.balance_board.bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2; + BT_DINF.balance_board.bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11; + memcpy(BT_DINF.registered[i].name, wmName, 20); + memcpy(BT_DINF.balance_board.name, wmName, 20); + + INFO_LOG(WII_IPC_WIIMOTE, "Balance Board %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); + m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); + } + else + { + const char * wmName = "Nintendo RVL-CNT-01"; + ++BT_DINF.num_registered; + BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i; + BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0; + BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79; + BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19; + BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2; + BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11; + memcpy(BT_DINF.registered[i].name, wmName, 20); - INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); - m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); + INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); + m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); + + } i++; } - + // save now so that when games load sysconf file it includes the new wiimotes // and the correct order for connected wiimotes if (!SConfig::GetInstance().m_SYSCONF->SetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)) || !SConfig::GetInstance().m_SYSCONF->Save()) @@ -99,18 +131,18 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p) p.DoPOD(m_HCIEndpoint); p.DoPOD(m_ACLEndpoint); p.Do(m_last_ticks); - p.DoArray(m_PacketCount,4); + p.DoArray(m_PacketCount,MAX_BBMOTES); p.Do(m_ScanEnable); p.Do(m_EventQueue); m_acl_pool.DoState(p); - for (unsigned int i = 0; i < 4; i++) + for (unsigned int i = 0; i < MAX_BBMOTES; i++) m_WiiMotes[i].DoState(p); // Reset the connection of real and hybrid wiimotes if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad) { - for (unsigned int i = 0; i < 4; i++) + for (unsigned int i = 0; i < MAX_BBMOTES; i++) { if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i]) continue; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index f3d79b0fb8..7ac93b5be1 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -12,6 +12,7 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_WiiMote.h" +#include "../HW/Wiimote.h" struct SQueuedEvent { @@ -193,7 +194,7 @@ private: } } m_acl_pool; - u32 m_PacketCount[4]; + u32 m_PacketCount[MAX_BBMOTES]; u64 m_last_ticks; // Send ACL data to a device (wiimote) @@ -274,7 +275,6 @@ private: #pragma pack(push,1) #define CONF_PAD_MAX_REGISTERED 10 -#define CONF_PAD_MAX_ACTIVE 4 struct _conf_pad_device { @@ -286,7 +286,7 @@ private: { u8 num_registered; _conf_pad_device registered[CONF_PAD_MAX_REGISTERED]; - _conf_pad_device active[CONF_PAD_MAX_ACTIVE]; + _conf_pad_device active[MAX_WIIMOTES]; _conf_pad_device balance_board; u8 unknown[0x45]; }; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index 22930eb94c..9386682106 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -37,7 +37,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* , m_HIDInterruptChannel_Config(false) , m_HIDInterruptChannel_ConfigWait(false) , m_BD(_BD) - , m_Name("Nintendo RVL-CNT-01") + , m_Name(_Number == WIIMOTE_BALANCE_BOARD ? "Nintendo RVL-WBC-01" : "Nintendo RVL-CNT-01") , m_pHost(_pHost) { DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number); @@ -277,13 +277,13 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size) break; case L2CAP_PSM_HID_CNTL: - if (number < 4) + if (number < MAX_BBMOTES) Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize); break; case L2CAP_PSM_HID_INTR: { - if (number < 4) + if (number < MAX_BBMOTES) { DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel"); DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid); diff --git a/Source/Core/Core/Src/Movie.cpp b/Source/Core/Core/Src/Movie.cpp index c57ce8d4cc..75951df67d 100644 --- a/Source/Core/Core/Src/Movie.cpp +++ b/Source/Core/Core/Src/Movie.cpp @@ -392,7 +392,7 @@ void ChangeWiiPads(bool instantly) if (instantly && (g_numPads >> 4) == controllers) return; - for (int i = 0; i < 4; i++) + for (int i = 0; i < MAX_BBMOTES; i++) { g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE; GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(IsUsingWiimote(i)); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index f039fe4938..1a1544373c 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -15,7 +15,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin wxStaticText* wiimote_label[4]; wxChoice* wiimote_source_ch[4]; - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) { wxString str; str.Printf(_("Wiimote %i"), i + 1); @@ -206,7 +206,7 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event) void WiimoteConfigDiag::RevertSource() { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_WIIMOTES; ++i) g_wiimote_sources[i] = m_orig_wiimote_sources[i]; } diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index 4c33661ca2..88fea037a9 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -76,9 +76,9 @@ private: wxNotebook* m_pad_notebook; std::map m_wiimote_index_from_ctrl_id; - unsigned int m_orig_wiimote_sources[4]; + unsigned int m_orig_wiimote_sources[MAX_WIIMOTES]; - wxButton* wiimote_configure_bt[4]; + wxButton* wiimote_configure_bt[MAX_WIIMOTES]; std::map m_wiimote_index_from_conf_bt_id; }; From fccf37718072cc6ff63cdc10a62d0a5c3588bfbc Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 18 May 2013 20:35:37 +1200 Subject: [PATCH 092/352] Fix IODummy FindWiimote method. --- Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 3a017354eb..59025f9040 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -32,9 +32,10 @@ WiimoteScanner::~WiimoteScanner() void WiimoteScanner::Update() {} -std::vector WiimoteScanner::FindWiimotes() +void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimote* & found_board) { - return std::vector(); + found_wiimotes.clear(); + found_board = NULL; } bool WiimoteScanner::IsReady() const From 2c7f9b1b78f47a6d84e5c54a1fa3761af0485aba Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 18 May 2013 03:56:45 -0500 Subject: [PATCH 093/352] [Android] Copy over the Dolphin shared library to the Android APK build directory so it doesn't need to be manually copied each time. --- Source/Core/DolphinWX/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt index 9508f75a36..e3f8789634 100644 --- a/Source/Core/DolphinWX/CMakeLists.txt +++ b/Source/Core/DolphinWX/CMakeLists.txt @@ -172,6 +172,9 @@ if(ANDROID) ${LIBS} "-Wl,--no-whole-archive" ) + add_custom_command(TARGET ${DOLPHIN_EXE} POST_BUILD + COMMAND cp ARGS ${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/lib${DOLPHIN_EXE}.so ${CMAKE_SOURCE_DIR}/Source/Android/libs/armeabi-v7a + ) else() add_executable(${DOLPHIN_EXE} ${SRCS}) target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS}) From 10018cfe9a4e5effc8470998734a63ac6a3ccda6 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 18 May 2013 04:04:07 -0500 Subject: [PATCH 094/352] [Android] Add in the Android Studio project files so one can use Android Studio instead of ADT. --- Source/Android/.idea/.name | 1 + Source/Android/.idea/compiler.xml | 23 + .../.idea/copyright/profiles_settings.xml | 5 + Source/Android/.idea/encodings.xml | 5 + Source/Android/.idea/libraries/dexedLibs.xml | 10 + Source/Android/.idea/misc.xml | 26 + Source/Android/.idea/modules.xml | 10 + .../Android/.idea/scopes/scope_settings.xml | 5 + Source/Android/.idea/vcs.xml | 8 + Source/Android/.idea/workspace.xml | 493 ++++++++++++++++++ Source/Android/Android.iml | 19 + 11 files changed, 605 insertions(+) create mode 100644 Source/Android/.idea/.name create mode 100644 Source/Android/.idea/compiler.xml create mode 100644 Source/Android/.idea/copyright/profiles_settings.xml create mode 100644 Source/Android/.idea/encodings.xml create mode 100644 Source/Android/.idea/libraries/dexedLibs.xml create mode 100644 Source/Android/.idea/misc.xml create mode 100644 Source/Android/.idea/modules.xml create mode 100644 Source/Android/.idea/scopes/scope_settings.xml create mode 100644 Source/Android/.idea/vcs.xml create mode 100644 Source/Android/.idea/workspace.xml create mode 100644 Source/Android/Android.iml diff --git a/Source/Android/.idea/.name b/Source/Android/.idea/.name new file mode 100644 index 0000000000..1429c13e57 --- /dev/null +++ b/Source/Android/.idea/.name @@ -0,0 +1 @@ +Android \ No newline at end of file diff --git a/Source/Android/.idea/compiler.xml b/Source/Android/.idea/compiler.xml new file mode 100644 index 0000000000..217af471a9 --- /dev/null +++ b/Source/Android/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/Source/Android/.idea/copyright/profiles_settings.xml b/Source/Android/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000000..3572571ad8 --- /dev/null +++ b/Source/Android/.idea/copyright/profiles_settings.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Android/.idea/encodings.xml b/Source/Android/.idea/encodings.xml new file mode 100644 index 0000000000..e206d70d85 --- /dev/null +++ b/Source/Android/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Source/Android/.idea/libraries/dexedLibs.xml b/Source/Android/.idea/libraries/dexedLibs.xml new file mode 100644 index 0000000000..d8e5061380 --- /dev/null +++ b/Source/Android/.idea/libraries/dexedLibs.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/.idea/misc.xml b/Source/Android/.idea/misc.xml new file mode 100644 index 0000000000..4304d8b8c8 --- /dev/null +++ b/Source/Android/.idea/misc.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + Android 4.2.2 + + + + + + + + + diff --git a/Source/Android/.idea/modules.xml b/Source/Android/.idea/modules.xml new file mode 100644 index 0000000000..e28a283f98 --- /dev/null +++ b/Source/Android/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Source/Android/.idea/scopes/scope_settings.xml b/Source/Android/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000000..922003b843 --- /dev/null +++ b/Source/Android/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Source/Android/.idea/vcs.xml b/Source/Android/.idea/vcs.xml new file mode 100644 index 0000000000..a5dd08645f --- /dev/null +++ b/Source/Android/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Source/Android/.idea/workspace.xml b/Source/Android/.idea/workspace.xml new file mode 100644 index 0000000000..5482878f58 --- /dev/null +++ b/Source/Android/.idea/workspace.xml @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + + 1368695084085 + 1368695084085 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/Android.iml b/Source/Android/Android.iml new file mode 100644 index 0000000000..5f8bb57f26 --- /dev/null +++ b/Source/Android/Android.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + From 0b869cf12d914773d78fb5ee5234f208661d9280 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 18 May 2013 22:26:00 +1200 Subject: [PATCH 095/352] Add mac support for balance board. --- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index cec18ed63a..9f9192423c 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -116,22 +116,21 @@ WiimoteScanner::~WiimoteScanner() void WiimoteScanner::Update() {} -std::vector WiimoteScanner::FindWiimotes() +void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimote* & found_board) { // TODO: find the device in the constructor and save it for later - - std::vector wiimotes; IOBluetoothHostController *bth; IOBluetoothDeviceInquiry *bti; SearchBT *sbt; NSEnumerator *en; + found_board = NULL; bth = [[IOBluetoothHostController alloc] init]; if ([bth addressAsString] == nil) { WARN_LOG(WIIMOTE, "No bluetooth host controller"); [bth release]; - return wiimotes; + return; } sbt = [[SearchBT alloc] init]; @@ -162,14 +161,22 @@ std::vector WiimoteScanner::FindWiimotes() Wiimote *wm = new Wiimote(); wm->btd = dev; - wiimotes.push_back(wm); + + if(IsBalanceBoardName(name)) + { + found_board = wm; + NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str); + } + else + { + found_wiimotes.push_back(wm); + NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); + } } [bth release]; [bti release]; [sbt release]; - - return wiimotes; } bool WiimoteScanner::IsReady() const From 08f6ba8274b39ca9b0edc31f0b65e5182e0622cc Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 18 May 2013 22:29:51 +1200 Subject: [PATCH 096/352] I'm bad at mac.. sorry. Used the correct name string. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 9f9192423c..4eac3ca5ff 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -162,7 +162,7 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot Wiimote *wm = new Wiimote(); wm->btd = dev; - if(IsBalanceBoardName(name)) + if(IsBalanceBoardName([[dev name] UTF8String])) { found_board = wm; NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str); From 59924d0291ec78a5763c675e2c943702fedfefb3 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 18 May 2013 22:31:22 +1200 Subject: [PATCH 097/352] It never had logging here anyway... --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 4eac3ca5ff..6f85f62a82 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -165,12 +165,10 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot if(IsBalanceBoardName([[dev name] UTF8String])) { found_board = wm; - NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str); } else { found_wiimotes.push_back(wm); - NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); } } From 7208823396762ae9659ec03addabe696fa93256b Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 19 May 2013 00:30:20 +1200 Subject: [PATCH 098/352] Added config for enabling Balance Board. Fixed other structures that still assumed 4 of everything. --- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 26 +++++++----- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 42 +++++++++++++++---- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 2 +- Source/Core/InputCommon/Src/InputConfig.cpp | 9 ++-- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 1d3be13cc5..40c6ee0554 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -457,7 +457,10 @@ void LoadSettings() sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU); } - g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = WIIMOTE_SRC_REAL; + + std::string secname("BalanceBoard"); + IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str()); + sec.Get("Source", &g_wiimote_sources[WIIMOTE_BALANCE_BOARD], WIIMOTE_SRC_NONE); } // config dialog calls this when some settings change @@ -501,14 +504,14 @@ void Shutdown(void) void ChangeWiimoteSource(unsigned int index, int source) { { - std::lock_guard lk(g_refresh_lock); - g_wiimote_sources[index] = source; - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); - g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); - - - // kill real connection (or swap to different slot) - DoneWithWiimote(index); + std::lock_guard lk(g_refresh_lock); + g_wiimote_sources[index] = source; + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); + + + // kill real connection (or swap to different slot) + DoneWithWiimote(index); } // reconnect to the emulator @@ -635,7 +638,7 @@ void Refresh() std::vector found_wiimotes; Wiimote* found_board = NULL; - if (0 != CalculateWantedWiimotes()) + if (0 != CalculateWantedWiimotes() || 0 != CalculateWantedBB()) { // Don't hang Dolphin when searching lk.unlock(); @@ -646,7 +649,8 @@ void Refresh() CheckForDisconnectedWiimotes(); // Brief rumble for already connected Wiimotes. - for (int i = 0; i < MAX_BBMOTES; ++i) + // Don't do this for Balance Board as it doesn't have rumble anyway. + for (int i = 0; i < MAX_WIIMOTES; ++i) { if (g_wiimotes[i]) { diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index 1a1544373c..be29f11015 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -54,8 +54,25 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin wiimote_sizer->Add(wiimote_configure_bt[i]); } wiimote_group->Add(wiimote_sizer, 1, wxEXPAND, 5 ); + + + // "BalanceBoard" layout + wxStaticBoxSizer* const bb_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Balance Board")); + wxFlexGridSizer* const bb_sizer = new wxFlexGridSizer(1, 5, 5); + int source_ctrl_id = wxWindow::NewControlId(); + m_wiimote_index_from_ctrl_id.insert(std::pair(source_ctrl_id, WIIMOTE_BALANCE_BOARD)); + const wxString src_choices[] = { _("None"), _("Real Balance Board") }; + wxChoice* bb_source = new wxChoice(this, source_ctrl_id, wxDefaultPosition, wxDefaultSize, sizeof(src_choices)/sizeof(*src_choices), src_choices); + bb_source->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &WiimoteConfigDiag::SelectSource, this); + + m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] = g_wiimote_sources[WIIMOTE_BALANCE_BOARD]; + bb_source->Select(m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] ? 1 : 0); + + bb_sizer->Add(bb_source, 0, wxALIGN_CENTER_VERTICAL); + + bb_group->Add(bb_sizer, 1, wxEXPAND, 5 ); - + // "Real wiimotes" controls wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition); refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this); @@ -166,6 +183,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin // Dialog layout main_sizer->Add(wiimote_group, 0, wxEXPAND | wxALL, 5); + main_sizer->Add(bb_group, 0, wxEXPAND | wxALL, 5); main_sizer->Add(real_wiimotes_group, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); main_sizer->Add(general_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); @@ -196,17 +214,23 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event) // Revert if the dialog is canceled. int index = m_wiimote_index_from_ctrl_id[event.GetId()]; - WiimoteReal::ChangeWiimoteSource(index, event.GetInt()); - - if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID) - wiimote_configure_bt[index]->Disable(); + if(index != WIIMOTE_BALANCE_BOARD) + { + WiimoteReal::ChangeWiimoteSource(index, event.GetInt()); + if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID) + wiimote_configure_bt[index]->Disable(); + else + wiimote_configure_bt[index]->Enable(); + } else - wiimote_configure_bt[index]->Enable(); + { + WiimoteReal::ChangeWiimoteSource(index, event.GetInt() ? WIIMOTE_SRC_REAL : WIIMOTE_SRC_NONE); + } } void WiimoteConfigDiag::RevertSource() { - for (int i = 0; i < MAX_WIIMOTES; ++i) + for (int i = 0; i < MAX_BBMOTES; ++i) g_wiimote_sources[i] = m_orig_wiimote_sources[i]; } @@ -225,6 +249,10 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event) sec.Set("Source", (int)g_wiimote_sources[i]); } + + std::string secname("BalanceBoard"); + IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str()); + sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]); inifile.Save(ini_filename); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index 88fea037a9..dac963d9f3 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -76,7 +76,7 @@ private: wxNotebook* m_pad_notebook; std::map m_wiimote_index_from_ctrl_id; - unsigned int m_orig_wiimote_sources[MAX_WIIMOTES]; + unsigned int m_orig_wiimote_sources[MAX_BBMOTES]; wxButton* wiimote_configure_bt[MAX_WIIMOTES]; std::map m_wiimote_index_from_conf_bt_id; diff --git a/Source/Core/InputCommon/Src/InputConfig.cpp b/Source/Core/InputCommon/Src/InputConfig.cpp index 65529b0a3f..e1af00f41d 100644 --- a/Source/Core/InputCommon/Src/InputConfig.cpp +++ b/Source/Core/InputCommon/Src/InputConfig.cpp @@ -3,7 +3,8 @@ // Refer to the license.txt file included. #include "InputConfig.h" -#include "../../Core/Src/ConfigManager.h" +#include "../Src/ConfigManager.h" +#include "../Src/HW/Wiimote.h" InputPlugin::~InputPlugin() { @@ -18,9 +19,9 @@ bool InputPlugin::LoadConfig(bool isGC) { IniFile inifile; IniFile game_ini; - bool useProfile[4] = {false, false, false, false}; - std::string num[4] = {"1", "2", "3", "4"}; - std::string profile[4]; + bool useProfile[MAX_BBMOTES] = {false, false, false, false, false}; + std::string num[MAX_BBMOTES] = {"1", "2", "3", "4", "BB"}; + std::string profile[MAX_BBMOTES]; std::string path; if (SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() != "00000000") From 065d772696fd66720574fadbcbf4ce8190ff5d20 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 19 May 2013 14:45:24 +1200 Subject: [PATCH 099/352] Windows should have support for Balance Board now. Needs to be tested. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 25 +++++++++++++++---- Source/Core/InputCommon/Src/InputConfig.cpp | 4 +-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 4aae05fa3a..cf47315066 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -183,7 +183,7 @@ void WiimoteScanner::Update() // Does not replace already found wiimotes even if they are disconnected. // wm is an array of max_wiimotes wiimotes // Returns the total number of found and connected wiimotes. -std::vector WiimoteScanner::FindWiimotes() +void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimote* & found_board) { ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { @@ -198,8 +198,6 @@ std::vector WiimoteScanner::FindWiimotes() // Get all hid devices connected HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); - std::vector wiimotes; - SP_DEVICE_INTERFACE_DATA device_data; device_data.cbSize = sizeof(device_data); PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; @@ -217,7 +215,25 @@ std::vector WiimoteScanner::FindWiimotes() { auto const wm = new Wiimote; wm->devicepath = detail_data->DevicePath; - wiimotes.push_back(wm); + + TCHAR name[128] = {}; + HANDLE dev_handle = CreateFile(wm->devicepath.c_str(), + GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + + if (dev_handle != INVALID_HANDLE_VALUE && HidD_GetProductString(dev_handle, name, 128) && IsBalanceBoardName(TStrToUTF8(name))) + { + found_board = wm; + } + else + { + found_wiimotes.push_back(wm); + } + + if(dev_handle != INVALID_HANDLE_VALUE) + { + CloseHandle(dev_handle); + } } free(detail_data); @@ -229,7 +245,6 @@ std::vector WiimoteScanner::FindWiimotes() //if (!wiimotes.empty()) // SLEEP(2000); - return wiimotes; } bool WiimoteScanner::IsReady() const diff --git a/Source/Core/InputCommon/Src/InputConfig.cpp b/Source/Core/InputCommon/Src/InputConfig.cpp index e1af00f41d..96fc6205db 100644 --- a/Source/Core/InputCommon/Src/InputConfig.cpp +++ b/Source/Core/InputCommon/Src/InputConfig.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include "InputConfig.h" -#include "../Src/ConfigManager.h" -#include "../Src/HW/Wiimote.h" +#include "../../Core/Src/ConfigManager.h" +#include "../../Core/Src/HW/Wiimote.h" InputPlugin::~InputPlugin() { From 56976ad6ea5491809732129b54221bc5674e68b6 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 19 May 2013 14:57:04 +1200 Subject: [PATCH 100/352] Fix coding style. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index cf47315066..4eded21d2d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -217,11 +217,17 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot wm->devicepath = detail_data->DevicePath; TCHAR name[128] = {}; - HANDLE dev_handle = CreateFile(wm->devicepath.c_str(), - GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + HANDLE dev_handle = CreateFile(wm->devicepath.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); - if (dev_handle != INVALID_HANDLE_VALUE && HidD_GetProductString(dev_handle, name, 128) && IsBalanceBoardName(TStrToUTF8(name))) + if (dev_handle != INVALID_HANDLE_VALUE && + HidD_GetProductString(dev_handle, name, 128) && + IsBalanceBoardName(TStrToUTF8(name))) { found_board = wm; } @@ -230,7 +236,7 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot found_wiimotes.push_back(wm); } - if(dev_handle != INVALID_HANDLE_VALUE) + if (dev_handle != INVALID_HANDLE_VALUE) { CloseHandle(dev_handle); } From 252edb942dac4828ed0b76b1cf9a98f088d59234 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 19 May 2013 05:25:02 -0500 Subject: [PATCH 101/352] [Android] Beginning of setting menu, doesn't do anything yet. --- Source/Android/.idea/vcs.xml | 1 - Source/Android/.idea/workspace.xml | 417 ++++++++++++------ Source/Android/AndroidManifest.xml | 8 +- .../dolphinemu/dolphinemu/GameListView.java | 51 +-- .../dolphinemu/dolphinemu/SettingBrowser.java | 56 +++ .../dolphinemu/SettingMenuAdapter.java | 60 +++ .../dolphinemu/SettingMenuItem.java | 37 ++ .../dolphinemu/dolphinemu/SideMenuItem.java | 6 + 8 files changed, 472 insertions(+), 164 deletions(-) create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java diff --git a/Source/Android/.idea/vcs.xml b/Source/Android/.idea/vcs.xml index a5dd08645f..def6a6a184 100644 --- a/Source/Android/.idea/vcs.xml +++ b/Source/Android/.idea/vcs.xml @@ -2,7 +2,6 @@ - diff --git a/Source/Android/.idea/workspace.xml b/Source/Android/.idea/workspace.xml index 5482878f58..49334515f9 100644 --- a/Source/Android/.idea/workspace.xml +++ b/Source/Android/.idea/workspace.xml @@ -9,15 +9,16 @@ - - - - - + - + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -106,13 +143,19 @@ - @@ -121,14 +164,14 @@ - + - + @@ -140,6 +183,26 @@ + + + + + + + + + + + + + + @@ -148,101 +211,59 @@ + + + + + + + + + + + + + + + + - - - - - - - + + + + - - - - - - - + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - @@ -357,32 +447,32 @@ - + - - + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + @@ -417,7 +507,7 @@ - + - + - - - - - - - - @@ -481,9 +563,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/AndroidManifest.xml b/Source/Android/AndroidManifest.xml index 82573aa8aa..2eb749d1a2 100644 --- a/Source/Android/AndroidManifest.xml +++ b/Source/Android/AndroidManifest.xml @@ -31,12 +31,18 @@ android:theme="@android:style/Theme" android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" > - + + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java index d90bb32016..96b67c2130 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java @@ -1,38 +1,26 @@ package org.dolphinemu.dolphinemu; +import android.app.Activity; +import android.app.ListActivity; +import android.content.Intent; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; +import net.simonvt.menudrawer.MenuDrawer; + import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import net.simonvt.menudrawer.MenuDrawer; - -import android.app.Activity; -import android.app.ListActivity; -import android.content.Intent; -import android.os.Bundle; -import android.os.Environment; -import android.util.DisplayMetrics; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.Surface; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - public class GameListView extends ListActivity { private GameListAdapter adapter; - private static List currentDir; private MenuDrawer mDrawer; private SideMenuAdapter mAdapter; - private ListView mList; private static GameListView me; public static native String GetConfig(String Key, String Value, String Default); public static native void SetConfig(String Key, String Value, String Default); @@ -66,7 +54,7 @@ public class GameListView extends ListActivity { fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); } } - catch(Exception e) + catch(Exception ignored) { } } @@ -78,13 +66,10 @@ public class GameListView extends ListActivity { @Override protected void onListItemClick(ListView l, View v, int position, long id) { - // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); GameListItem o = adapter.getItem(position); - if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){ - } - else - { + if(!(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory"))) + { onFileClick(o.getPath()); } } @@ -131,8 +116,9 @@ public class GameListView extends ListActivity { Listdir = new ArrayList(); dir.add(new SideMenuItem("Browse Folder", 0)); + dir.add(new SideMenuItem("Settings", 1)); - mList = new ListView(this); + ListView mList = new ListView(this); mAdapter = new SideMenuAdapter(this,R.layout.sidemenu,dir); mList.setAdapter(mAdapter); mList.setOnItemClickListener(mItemClickListener); @@ -150,6 +136,11 @@ public class GameListView extends ListActivity { Intent ListIntent = new Intent(me, FolderBrowser.class); startActivityForResult(ListIntent, 1); break; + case 1: + Toast.makeText(me, "Loading up settings", Toast.LENGTH_SHORT).show(); + Intent SettingIntent = new Intent(me, SettingBrowser.class); + startActivityForResult(SettingIntent, 1); + break; default: break; } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java new file mode 100644 index 0000000000..123bb174ed --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java @@ -0,0 +1,56 @@ +package org.dolphinemu.dolphinemu; + +import android.app.ListActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.ListView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +public class SettingBrowser extends ListActivity { + private SettingMenuAdapter adapter; + private void Fill() + { + this.setTitle("Settings"); + List dir = new ArrayList(); + + dir.add(new SettingMenuItem("Setting 1", "SubTitle 1", 0)); + Collections.sort(dir); + + adapter = new SettingMenuAdapter(this,R.layout.folderbrowser,dir); + this.setListAdapter(adapter); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + SettingMenuItem o = adapter.getItem(position); + switch (o.getID()) + { + default: + // Do nothing yet + break; + } + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + Fill(); + } + @Override + public void onBackPressed() { + this.finish(); + super.onBackPressed(); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java new file mode 100644 index 0000000000..8fb0b237f6 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java @@ -0,0 +1,60 @@ +package org.dolphinemu.dolphinemu; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import java.util.List; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +public class SettingMenuAdapter extends ArrayAdapter{ + + private Context c; + private int id; + private Listitems; + + public SettingMenuAdapter(Context context, int textViewResourceId, + List objects) { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + public SettingMenuItem getItem(int i) + { + return items.get(i); + } + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + if (v == null) + return null; // This should never be hit, but have it to clear a warning + } + final SettingMenuItem o = items.get(position); + if (o != null) { + TextView t1 = (TextView) v.findViewById(R.id.TextView01); + TextView t2 = (TextView) v.findViewById(R.id.TextView02); + + if (t1 != null) + t1.setText(o.getName()); + if (t2 != null) + t2.setText(o.getSubtitle()); + } + return v; + } + + + +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java new file mode 100644 index 0000000000..fcb0da942c --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java @@ -0,0 +1,37 @@ +package org.dolphinemu.dolphinemu; + +public class SettingMenuItem implements Comparable{ + private String name; + private String subtitle; + private int m_id; + + public SettingMenuItem(String n,String d, int id) + { + name = n; + subtitle = d; + m_id = id; + } + + public String getName() + { + return name; + } + + public String getSubtitle() + { + return subtitle; + } + public int getID() + { + return m_id; + } + + public int compareTo(SettingMenuItem o) + { + if(this.name != null) + return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java index 80f3eaec64..e24842bed1 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java @@ -1,5 +1,11 @@ package org.dolphinemu.dolphinemu; +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + public class SideMenuItem implements Comparable{ private String m_name; private int m_id; From 9a1b9e9b3b6960cdb0723b73a4a224cee9a7c1bf Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sun, 19 May 2013 19:44:37 +0200 Subject: [PATCH 102/352] Removing ISO ini presence requirement for reading movie settings because it's not necessary for running a movie --- Source/Core/Core/Src/BootManager.cpp | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index f829f3f4d6..cf67b6f310 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -108,20 +108,6 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2); VideoBackend::ActivateBackend(StartUp.m_strVideoBackend); - if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) - { - StartUp.bCPUThread = Movie::IsDualCore(); - StartUp.bSkipIdle = Movie::IsSkipIdle(); - StartUp.bDSPHLE = Movie::IsDSPHLE(); - StartUp.bProgressive = Movie::IsProgressive(); - StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed(); - StartUp.iCPUCore = Movie::GetCPUMode(); - if (Movie::IsUsingMemcard() && Movie::IsStartingFromClearSave() && !StartUp.bWii) - { - if (File::Exists("Movie.raw")) - File::Delete("Movie.raw"); - } - } // Wii settings if (StartUp.bWii) { @@ -130,6 +116,22 @@ bool BootCore(const std::string& _rFilename) } } + // movie settings + if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) + { + StartUp.bCPUThread = Movie::IsDualCore(); + StartUp.bSkipIdle = Movie::IsSkipIdle(); + StartUp.bDSPHLE = Movie::IsDSPHLE(); + StartUp.bProgressive = Movie::IsProgressive(); + StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed(); + StartUp.iCPUCore = Movie::GetCPUMode(); + if (Movie::IsUsingMemcard() && Movie::IsStartingFromClearSave() && !StartUp.bWii) + { + if (File::Exists("Movie.raw")) + File::Delete("Movie.raw"); + } + } + // Run the game // Init the core if (!Core::Init()) From f8a5d05c07e6a3f10b9bf5f5e17e9fe59e60107c Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 20 May 2013 02:57:39 -0500 Subject: [PATCH 103/352] [Android] Redo the Settings menu, Can now change the CPU Core, dual core setting, and video backend in the settings" --- Source/Android/.idea/workspace.xml | 456 +++++++++++------- Source/Android/AndroidManifest.xml | 8 +- Source/Android/res/layout/prefs.xml | 28 ++ Source/Android/res/values/prefvalues.xml | 22 + .../dolphinemu/dolphinemu/GameListView.java | 82 +++- .../dolphinemu/dolphinemu/PrefsActivity.java | 40 ++ .../dolphinemu/dolphinemu/SettingBrowser.java | 56 --- .../dolphinemu/SettingMenuAdapter.java | 60 --- .../dolphinemu/SettingMenuItem.java | 37 -- 9 files changed, 443 insertions(+), 346 deletions(-) create mode 100644 Source/Android/res/layout/prefs.xml create mode 100644 Source/Android/res/values/prefvalues.xml create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/PrefsActivity.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java diff --git a/Source/Android/.idea/workspace.xml b/Source/Android/.idea/workspace.xml index 49334515f9..87d98b0e1e 100644 --- a/Source/Android/.idea/workspace.xml +++ b/Source/Android/.idea/workspace.xml @@ -1,9 +1,26 @@ + + + - + + android-17 + + + + + Nexus 4 + @android:style/Theme.Holo + + + @@ -14,11 +31,17 @@ - - + + - + + + + + + + + + + + + @@ -82,25 +110,25 @@ - + - + - + - - + + - + @@ -109,19 +137,22 @@ - + - - + + - + + + + @@ -143,15 +174,26 @@ + + + - - - - - - - - - + + + + + - - - + + - + + + + + + + + + + + + - - - @@ -450,29 +581,30 @@ - - - - - - - - - - + - - + + + + + + + + + + + + + + + + - - + - - - - + @@ -536,107 +668,85 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + - + + + + + + + + + + + - + - + + + + + - + - + + + - + + + + - + - + + + + + + + + diff --git a/Source/Android/AndroidManifest.xml b/Source/Android/AndroidManifest.xml index 2eb749d1a2..2812e35815 100644 --- a/Source/Android/AndroidManifest.xml +++ b/Source/Android/AndroidManifest.xml @@ -37,11 +37,9 @@ android:theme="@android:style/Theme" android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" > - + diff --git a/Source/Android/res/layout/prefs.xml b/Source/Android/res/layout/prefs.xml new file mode 100644 index 0000000000..bceb581c36 --- /dev/null +++ b/Source/Android/res/layout/prefs.xml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/res/values/prefvalues.xml b/Source/Android/res/values/prefvalues.xml new file mode 100644 index 0000000000..77354f76a4 --- /dev/null +++ b/Source/Android/res/values/prefvalues.xml @@ -0,0 +1,22 @@ + + + + Interpreter + ARM JIT Recompiler + + + + 0 + 3 + + + + Software Renderer + OpenGL + + + + Software Renderer + OGL + + \ No newline at end of file diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java index 96b67c2130..760f0445ec 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java @@ -3,7 +3,9 @@ package org.dolphinemu.dolphinemu; import android.app.Activity; import android.app.ListActivity; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; @@ -24,6 +26,8 @@ public class GameListView extends ListActivity { private static GameListView me; public static native String GetConfig(String Key, String Value, String Default); public static native void SetConfig(String Key, String Value, String Default); + + enum keyTypes {TYPE_STRING, TYPE_BOOL}; private void Fill() { @@ -88,19 +92,67 @@ public class GameListView extends ListActivity { public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - - if (resultCode == Activity.RESULT_OK) - { - String FileName = data.getStringExtra("Select"); - Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show(); - String Directories = GetConfig("General", "GCMPathes", "0"); - int intDirectories = Integer.parseInt(Directories); - Directories = Integer.toString(intDirectories + 1); - SetConfig("General", "GCMPathes", Directories); - SetConfig("General", "GCMPaths" + Integer.toString(intDirectories), FileName); - - Fill(); - } + + switch (requestCode) + { + // Browse + case 1: + if (resultCode == Activity.RESULT_OK) + { + String FileName = data.getStringExtra("Select"); + Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show(); + String Directories = GetConfig("General", "GCMPathes", "0"); + int intDirectories = Integer.parseInt(Directories); + Directories = Integer.toString(intDirectories + 1); + SetConfig("General", "GCMPathes", Directories); + SetConfig("General", "GCMPaths" + Integer.toString(intDirectories), FileName); + + Fill(); + } + break; + // Settings + case 2: + + String Keys[] = { + "cpupref", + "dualcorepref", + "gpupref", + }; + String ConfigKeys[] = { + "Core-CPUCore", + "Core-CPUThread", + "Core-GFXBackend", + }; + + keyTypes KeysTypes[] = { + keyTypes.TYPE_STRING, + keyTypes.TYPE_BOOL, + keyTypes.TYPE_STRING, + }; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + + // Set our preferences here + for (int a = 0; a < Keys.length; ++a) + { + String ConfigValues[] = ConfigKeys[a].split("-"); + String Key = ConfigValues[0]; + String Value = ConfigValues[1]; + + switch(KeysTypes[a]) + { + case TYPE_STRING: + String strPref = prefs.getString(Keys[a], ""); + SetConfig(Key, Value, strPref); + break; + case TYPE_BOOL: + boolean boolPref = prefs.getBoolean(Keys[a], true); + SetConfig(Key, Value, boolPref ? "True" : "False"); + break; + } + + } + break; + } } @Override @@ -138,8 +190,8 @@ public class GameListView extends ListActivity { break; case 1: Toast.makeText(me, "Loading up settings", Toast.LENGTH_SHORT).show(); - Intent SettingIntent = new Intent(me, SettingBrowser.class); - startActivityForResult(SettingIntent, 1); + Intent SettingIntent = new Intent(me, PrefsActivity.class); + startActivityForResult(SettingIntent, 2); break; default: break; diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/PrefsActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/PrefsActivity.java new file mode 100644 index 0000000000..e12e37c10a --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/PrefsActivity.java @@ -0,0 +1,40 @@ +package org.dolphinemu.dolphinemu; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.preference.PreferenceFragment; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ +public class PrefsActivity extends PreferenceActivity { + + public class PrefsFragment extends PreferenceFragment { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.layout.prefs); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getFragmentManager().beginTransaction().replace(android.R.id.content, + new PrefsFragment()).commit(); + } + @Override + public void onBackPressed() { + Intent intent = new Intent(); + setResult(Activity.RESULT_OK, intent); + this.finish(); + super.onBackPressed(); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java deleted file mode 100644 index 123bb174ed..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SettingBrowser.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.ListActivity; -import android.os.Bundle; -import android.view.View; -import android.widget.ListView; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ - -public class SettingBrowser extends ListActivity { - private SettingMenuAdapter adapter; - private void Fill() - { - this.setTitle("Settings"); - List dir = new ArrayList(); - - dir.add(new SettingMenuItem("Setting 1", "SubTitle 1", 0)); - Collections.sort(dir); - - adapter = new SettingMenuAdapter(this,R.layout.folderbrowser,dir); - this.setListAdapter(adapter); - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - super.onListItemClick(l, v, position, id); - SettingMenuItem o = adapter.getItem(position); - switch (o.getID()) - { - default: - // Do nothing yet - break; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - Fill(); - } - @Override - public void onBackPressed() { - this.finish(); - super.onBackPressed(); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java deleted file mode 100644 index 8fb0b237f6..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; - -import java.util.List; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ - -public class SettingMenuAdapter extends ArrayAdapter{ - - private Context c; - private int id; - private Listitems; - - public SettingMenuAdapter(Context context, int textViewResourceId, - List objects) { - super(context, textViewResourceId, objects); - c = context; - id = textViewResourceId; - items = objects; - } - public SettingMenuItem getItem(int i) - { - return items.get(i); - } - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); - if (v == null) - return null; // This should never be hit, but have it to clear a warning - } - final SettingMenuItem o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.TextView01); - TextView t2 = (TextView) v.findViewById(R.id.TextView02); - - if (t1 != null) - t1.setText(o.getName()); - if (t2 != null) - t2.setText(o.getSubtitle()); - } - return v; - } - - - -} - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java deleted file mode 100644 index fcb0da942c..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SettingMenuItem.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.dolphinemu.dolphinemu; - -public class SettingMenuItem implements Comparable{ - private String name; - private String subtitle; - private int m_id; - - public SettingMenuItem(String n,String d, int id) - { - name = n; - subtitle = d; - m_id = id; - } - - public String getName() - { - return name; - } - - public String getSubtitle() - { - return subtitle; - } - public int getID() - { - return m_id; - } - - public int compareTo(SettingMenuItem o) - { - if(this.name != null) - return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); - else - throw new IllegalArgumentException(); - } -} - From e2b0632334622ed9eacd5955ce90e150ccf59c30 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 21 May 2013 21:42:19 +1200 Subject: [PATCH 104/352] Added a method for detecting Wiimote extension. This is run before a Wiimote will be considered. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 327 +++++++++++++----- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 3 +- 2 files changed, 250 insertions(+), 80 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 4eded21d2d..84cbe93bfa 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -138,6 +138,10 @@ inline void init_lib() namespace WiimoteReal { + + +int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len); +int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index); template void ProcessWiimotes(bool new_scan, T& callback); @@ -212,33 +216,23 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot // Query the data for this device if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) - { + { auto const wm = new Wiimote; wm->devicepath = detail_data->DevicePath; - - TCHAR name[128] = {}; - HANDLE dev_handle = CreateFile(wm->devicepath.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (dev_handle != INVALID_HANDLE_VALUE && - HidD_GetProductString(dev_handle, name, 128) && - IsBalanceBoardName(TStrToUTF8(name))) + bool real_wiimote = false, is_bb = false; + + CheckDeviceType(wm->devicepath, real_wiimote, is_bb); + if (is_bb) { found_board = wm; } - else + else if (real_wiimote) { found_wiimotes.push_back(wm); } - - if (dev_handle != INVALID_HANDLE_VALUE) + else { - CloseHandle(dev_handle); + free(wm); } } @@ -252,6 +246,169 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot // SLEEP(2000); } +int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, int size, int attempts) +{ + OVERLAPPED hid_overlap_write = OVERLAPPED(); + hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL); + enum win_bt_stack_t stack = MSBT_STACK_UNKNOWN; + + DWORD written = 0; + + for (; attempts>0; --attempts) + { + if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size)) + { + auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + if (WAIT_TIMEOUT == wait_result) + { + WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A timeout occurred on writing to Wiimote."); + CancelIo(dev_handle); + continue; + } + else if (WAIT_FAILED == wait_result) + { + WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A wait error occurred on writing to Wiimote."); + CancelIo(dev_handle); + continue; + } + if (GetOverlappedResult(dev_handle, &hid_overlap_write, &written, TRUE)) + { + break; + } + } + } + + CloseHandle(hid_overlap_write.hEvent); + + return written; +} + +int CheckDeviceType_Read(HANDLE &dev_handle, u8* buf, int attempts) +{ + OVERLAPPED hid_overlap_read = OVERLAPPED(); + hid_overlap_read.hEvent = CreateEvent(NULL, true, false, NULL); + int read = 0; + for (; attempts>0; --attempts) + { + read = _IORead(dev_handle, hid_overlap_read, buf, 1); + if (read > 0) + break; + } + + CloseHandle(hid_overlap_read.hEvent); + + return read; +} + +// A convoluted way of checking if a device is a Wii Balance Board and if it is a connectable Wiimote. +// Because nothing on Windows should be easy. +// (We can't seem to easily identify the bluetooth device an HID device belongs to...) +void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool &real_wiimote, bool &is_bb) +{ + real_wiimote = false; + is_bb = false; + +#ifdef SHARE_WRITE_WIIMOTES + std::lock_guard lk(g_connected_wiimotes_lock); + if (g_connected_wiimotes.count(devicepath) != 0) + return; +#endif + + HANDLE dev_handle = CreateFile(devicepath.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, + NULL); + if (dev_handle == INVALID_HANDLE_VALUE) + return; + // enable to only check for official nintendo wiimotes/bb's + bool check_vidpid = false; + HIDD_ATTRIBUTES attrib; + attrib.Size = sizeof(attrib); + if (!check_vidpid || + (HidD_GetAttributes(dev_handle, &attrib) && + (attrib.VendorID == 0x057e) && + (attrib.ProductID == 0x0306))) + { + int rc = 0; + // max_cycles insures we are never stuck here due to bad coding... + int max_cycles = 20; + u8 buf[MAX_PAYLOAD] = {0}; + + u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0}; + + rc = CheckDeviceType_Write(dev_handle, + req_status_report, + sizeof(req_status_report), + 1); + while (rc > 0 && --max_cycles > 0) + { + if ((rc = CheckDeviceType_Read(dev_handle, buf, 1)) <= 0) + break; + + switch (buf[1]) + { + case WM_STATUS_REPORT: + { + real_wiimote = true; + wm_status_report * wsr = (wm_status_report*)&buf[2]; + if (wsr->extension) + { + // Wiimote with extension, we ask it what kind. + u8 read_ext[MAX_PAYLOAD] = {0}; + read_ext[0] = WM_SET_REPORT | WM_BT_OUTPUT; + read_ext[1] = WM_READ_DATA; + // Extension type register. + *(u32*)&read_ext[2] = Common::swap32(0x4a400fa); + // Size. + *(u16*)&read_ext[6] = Common::swap16(6); + rc = CheckDeviceType_Write(dev_handle, read_ext, 8, 1); + } + else + { + // Normal Wiimote, exit while and be happy. + rc = -1; + } + break; + } + case WM_ACK_DATA: + { + real_wiimote = true; + break; + } + case WM_READ_DATA_REPLY: + { + wm_read_data_reply * wrdr + = (wm_read_data_reply*)&buf[2]; + // Check if it has returned what we asked. + if (Common::swap16(wrdr->address) == 0x00fa) + { + // 0x020420A40000ULL means balance board. + u64 ext_type = (*(u64*)&wrdr->data[0]); + is_bb = ext_type == 0x020420A40000ULL; + } + else + { + ERROR_LOG(WIIMOTE, + "CheckDeviceType: GOT UNREQUESTED ADDRESS %X", + Common::swap16(wrdr->address)); + } + // force end + rc = -1; + + break; + } + default: + { + // We let read try again incase there is another packet waiting. + // ERROR_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]); + break; + } + } + } + } + CloseHandle(dev_handle); +} bool WiimoteScanner::IsReady() const { @@ -376,7 +533,7 @@ bool Wiimote::IsConnected() const // positive = read packet // negative = didn't read packet // zero = error -int Wiimote::IORead(u8* buf) +int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index) { // Add data report indicator byte (here, 0xa1) buf[0] = 0xa1; @@ -429,78 +586,92 @@ int Wiimote::IORead(u8* buf) return bytes + 1; } -int Wiimote::IOWrite(const u8* buf, int len) +// positive = read packet +// negative = didn't read packet +// zero = error +int Wiimote::IORead(u8* buf) +{ + return _IORead(dev_handle, hid_overlap_read, buf, index); +} + + +int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len) { switch (stack) { - case MSBT_STACK_UNKNOWN: - { - // Try to auto-detect the stack type - stack = MSBT_STACK_BLUESOLEIL; - if (IOWrite(buf, len)) - return 1; - - stack = MSBT_STACK_MS; - if (IOWrite(buf, len)) - return 1; - - stack = MSBT_STACK_UNKNOWN; - break; - } - case MSBT_STACK_MS: - { - auto result = HidD_SetOutputReport(dev_handle, const_cast(buf) + 1, len - 1); - //FlushFileBuffers(dev_handle); - - if (!result) + case MSBT_STACK_UNKNOWN: { - auto err = GetLastError(); - if (err == 121) + // Try to auto-detect the stack type + stack = MSBT_STACK_BLUESOLEIL; + if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len)) + return 1; + + stack = MSBT_STACK_MS; + if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len)) + return 1; + + stack = MSBT_STACK_UNKNOWN; + break; + } + case MSBT_STACK_MS: + { + auto result = HidD_SetOutputReport(dev_handle, const_cast(buf) + 1, len - 1); + //FlushFileBuffers(dev_handle); + + if (!result) { - // Semaphore timeout - NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); + auto err = GetLastError(); + if (err == 121) + { + // Semaphore timeout + NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); + } + else + { + WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); + } + } + + return result; + break; + } + case MSBT_STACK_BLUESOLEIL: + { + u8 big_buf[MAX_PAYLOAD]; + if (len < MAX_PAYLOAD) + { + std::copy(buf, buf + len, big_buf); + std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); + buf = big_buf; + } + + ResetEvent(hid_overlap_write.hEvent); + DWORD bytes = 0; + if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) + { + // WriteFile always returns true with bluesoleil. + return 1; } else { - WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); + auto const err = GetLastError(); + if (ERROR_IO_PENDING == err) + { + CancelIo(dev_handle); + } } + break; } - - return result; - break; } - case MSBT_STACK_BLUESOLEIL: - { - u8 big_buf[MAX_PAYLOAD]; - if (len < MAX_PAYLOAD) - { - std::copy(buf, buf + len, big_buf); - std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); - buf = big_buf; - } - - ResetEvent(hid_overlap_write.hEvent); - DWORD bytes = 0; - if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) - { - // WriteFile always returns true with bluesoleil. - return 1; - } - else - { - auto const err = GetLastError(); - if (ERROR_IO_PENDING == err) - { - CancelIo(dev_handle); - } - } - break; - } - } - + return 0; } +int Wiimote::IOWrite(const u8* buf, int len) +{ + return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len); +} + // invokes callback for each found wiimote bluetooth device template void ProcessWiimotes(bool new_scan, T& callback) @@ -519,7 +690,7 @@ void ProcessWiimotes(bool new_scan, T& callback) BLUETOOTH_FIND_RADIO_PARAMS radioParam; radioParam.dwSize = sizeof(radioParam); - + HANDLE hRadio; // TODO: save radio(s) in the WiimoteScanner constructor? diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 695dc86b82..d195f92120 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -137,8 +137,7 @@ private: volatile bool m_want_bb; #if defined(_WIN32) - - + void CheckDeviceType(std::basic_string &devicepath, bool &real_wiimote, bool &is_bb); #elif defined(__linux__) && HAVE_BLUEZ int device_id; int device_sock; From f178015461a558bfde468611e203757098af1740 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 21 May 2013 22:54:01 +1200 Subject: [PATCH 105/352] Better checking for extension. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 84cbe93bfa..5e4f32caab 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -344,13 +344,16 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool while (rc > 0 && --max_cycles > 0) { if ((rc = CheckDeviceType_Read(dev_handle, buf, 1)) <= 0) + { + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Read failed..."); break; + } switch (buf[1]) { case WM_STATUS_REPORT: { - real_wiimote = true; + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Status Report"); wm_status_report * wsr = (wm_status_report*)&buf[2]; if (wsr->extension) { @@ -366,6 +369,7 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool } else { + real_wiimote = true; // Normal Wiimote, exit while and be happy. rc = -1; } @@ -373,18 +377,23 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool } case WM_ACK_DATA: { - real_wiimote = true; + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack"); break; } case WM_READ_DATA_REPLY: { + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Data Reply"); wm_read_data_reply * wrdr = (wm_read_data_reply*)&buf[2]; // Check if it has returned what we asked. if (Common::swap16(wrdr->address) == 0x00fa) { + real_wiimote = true; // 0x020420A40000ULL means balance board. u64 ext_type = (*(u64*)&wrdr->data[0]); + // DEBUG_LOG(WIIMOTE, + // "CheckDeviceType: GOT EXT TYPE %llX", + // ext_type); is_bb = ext_type == 0x020420A40000ULL; } else @@ -401,7 +410,7 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool default: { // We let read try again incase there is another packet waiting. - // ERROR_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]); + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]); break; } } From d642abce46fa3a999f762b329ae0154891c7170a Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 21 May 2013 23:31:41 +1200 Subject: [PATCH 106/352] Only show 4 config dialogs in wiimote config. --- Source/Core/DolphinWX/Src/InputConfigDiag.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp index cd17c4c682..ef4ae8d29b 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp @@ -5,6 +5,7 @@ #include "InputConfigDiag.h" #include "UDPConfigDiag.h" #include "WxUtils.h" +#include "HW/Wiimote.h" void GamepadPage::ConfigUDPWii(wxCommandEvent &event) { @@ -947,7 +948,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin , m_plugin(plugin) { m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT); - for (unsigned int i = 0; i < plugin.controllers.size(); ++i) + for (unsigned int i = 0; i < std::min(plugin.controllers.size(), (size_t)MAX_WIIMOTES); ++i) { GamepadPage* gp = new GamepadPage(m_pad_notebook, m_plugin, i, this); m_padpages.push_back(gp); From 10d1d194092a019aa755c84ae4648bae76ceab37 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 21 May 2013 19:20:22 -0400 Subject: [PATCH 107/352] Set graphics settings while playing a movie in UpdateActiveConfig(), so settings can't be changed for a frame. --- Source/Core/Core/Src/Movie.cpp | 5 ----- Source/Core/VideoCommon/Src/VideoConfig.cpp | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Src/Movie.cpp b/Source/Core/Core/Src/Movie.cpp index 75951df67d..2f165d1d44 100644 --- a/Source/Core/Core/Src/Movie.cpp +++ b/Source/Core/Core/Src/Movie.cpp @@ -126,11 +126,6 @@ void FrameUpdate() g_totalFrames = g_currentFrame; g_totalLagCount = g_currentLagCount; } - if (IsPlayingInput() && IsConfigSaved()) - { - SetGraphicsConfig(); - } - if (g_bFrameStep) { Core::SetState(Core::CORE_PAUSE); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 6e1bc31e55..7827c0008a 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -10,12 +10,15 @@ #include "VideoCommon.h" #include "FileUtil.h" #include "Core.h" +#include "Movie.h" VideoConfig g_Config; VideoConfig g_ActiveConfig; void UpdateActiveConfig() { + if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) + Movie::SetGraphicsConfig(); g_ActiveConfig = g_Config; } From 5e801fd6ef194e99eb72dfa01c5bba686b52865e Mon Sep 17 00:00:00 2001 From: John Peterson Date: Wed, 22 May 2013 01:09:13 +0200 Subject: [PATCH 108/352] Adding DSP state values to state because that allow the DSP state to be loaded --- Source/Core/Core/Src/DSP/DSPCore.cpp | 1 + Source/Core/Core/Src/DSP/DSPHWInterface.cpp | 9 ++------- Source/Core/Core/Src/DSP/DSPHost.h | 2 +- Source/Core/Core/Src/HW/DSPLLE/DSPHost.cpp | 17 +++++++++++------ Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp | 5 ++++- Source/Core/Core/Src/State.cpp | 2 +- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index 59e5063af6..64206b3ee0 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -137,6 +137,7 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename, { g_dsp.step_counter = 0; cyclesLeft = 0; + init_hax = false; dspjit = NULL; g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE); diff --git a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp index 371bec572c..56e998d3c0 100644 --- a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp @@ -246,14 +246,9 @@ static void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size) } WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); - g_dsp.iram_crc = DSPHost_CodeLoaded(g_dsp.cpu_ram + (addr & 0x0fffffff), size); - - NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc); + DSPHost_CodeLoaded((const u8*)g_dsp.iram + dsp_addr, size); - if (dspjit) - dspjit->ClearIRAM(); - - DSPAnalyzer::Analyze(); + NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc); } static void gdsp_idma_out(u16 dsp_addr, u32 addr, u32 size) diff --git a/Source/Core/Core/Src/DSP/DSPHost.h b/Source/Core/Core/Src/DSP/DSPHost.h index 86033b0724..cef329a7ec 100644 --- a/Source/Core/Core/Src/DSP/DSPHost.h +++ b/Source/Core/Core/Src/DSP/DSPHost.h @@ -15,7 +15,7 @@ void DSPHost_WriteHostMemory(u8 value, u32 addr); bool DSPHost_OnThread(); bool DSPHost_Wii(); void DSPHost_InterruptRequest(); -u32 DSPHost_CodeLoaded(const u8 *ptr, int size); +void DSPHost_CodeLoaded(const u8 *ptr, int size); void DSPHost_UpdateDebugger(); #endif diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPHost.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPHost.cpp index 9349820450..26e7110d6e 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPHost.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPHost.cpp @@ -4,6 +4,8 @@ #include "Common.h" #include "Hash.h" +#include "DSP/DSPAnalyzer.h" +#include "DSP/DSPCore.h" #include "DSP/DSPHost.h" #include "DSPSymbols.h" #include "DSPLLETools.h" @@ -45,23 +47,23 @@ void DSPHost_InterruptRequest() DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); } -u32 DSPHost_CodeLoaded(const u8 *ptr, int size) +void DSPHost_CodeLoaded(const u8 *ptr, int size) { - u32 ector_crc = HashEctor(ptr, size); + g_dsp.iram_crc = HashEctor(ptr, size); #if defined(_DEBUG) || defined(DEBUGFAST) - DumpDSPCode(ptr, size, ector_crc); + DumpDSPCode(ptr, size, g_dsp.iram_crc); #endif DSPSymbols::Clear(); // Auto load text file - if none just disassemble. - NOTICE_LOG(DSPLLE, "ector_crc: %08x", ector_crc); + NOTICE_LOG(DSPLLE, "g_dsp.iram_crc: %08x", g_dsp.iram_crc); DSPSymbols::Clear(); bool success = false; - switch (ector_crc) + switch (g_dsp.iram_crc) { case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.txt"); break; case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Luigi.txt"); break; @@ -86,7 +88,10 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size) DSPHost_UpdateDebugger(); - return ector_crc; + if (dspjit) + dspjit->ClearIRAM(); + + DSPAnalyzer::Analyze(); } void DSPHost_UpdateDebugger() diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index df43441c03..d16af5f601 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -16,6 +16,7 @@ #include "Core.h" #include "DSPLLEGlobals.h" // Local +#include "DSP/DSPHost.h" #include "DSP/DSPInterpreter.h" #include "DSP/DSPHWInterface.h" #include "DSP/disassemble.h" @@ -67,7 +68,6 @@ void DSPLLE::DoState(PointerWrap &p) p.Do(g_dsp.reg_stack[i]); } - p.Do(g_dsp.iram_crc); p.Do(g_dsp.step_counter); p.Do(g_dsp.ifx_regs); p.Do(g_dsp.mbox[0]); @@ -75,8 +75,11 @@ void DSPLLE::DoState(PointerWrap &p) UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); p.DoArray(g_dsp.iram, DSP_IRAM_SIZE); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); + if (p.GetMode() == PointerWrap::MODE_READ) + DSPHost_CodeLoaded((const u8*)g_dsp.iram, DSP_IRAM_BYTE_SIZE); p.DoArray(g_dsp.dram, DSP_DRAM_SIZE); p.Do(cyclesLeft); + p.Do(init_hax); p.Do(m_cycle_count); bool prevInitMixer = m_InitMixer; diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 40a48b4841..5923ba6917 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -59,7 +59,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 17; +static const u32 STATE_VERSION = 18; enum { From 2412b2287a66ae1a84ab71edc396be1563ac49fc Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 21 May 2013 20:30:09 -0400 Subject: [PATCH 109/352] Buildfix for dsptool. --- Source/DSPTool/Src/DSPTool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DSPTool/Src/DSPTool.cpp b/Source/DSPTool/Src/DSPTool.cpp index ba0ce665ca..78335d3026 100644 --- a/Source/DSPTool/Src/DSPTool.cpp +++ b/Source/DSPTool/Src/DSPTool.cpp @@ -13,7 +13,7 @@ u8 DSPHost_ReadHostMemory(u32 addr) { return 0; } void DSPHost_WriteHostMemory(u8 value, u32 addr) {} bool DSPHost_OnThread() { return false; } bool DSPHost_Wii() { return false; } -u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;} +void DSPHost_CodeLoaded(const u8 *ptr, int size) {} void DSPHost_InterruptRequest() {} void DSPHost_UpdateDebugger() {} From 9ab63aba886ff9b02c4b3680a7fdd77e100c8633 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Wed, 22 May 2013 02:40:00 +0200 Subject: [PATCH 110/352] Adding unit test project to VS solution because that inform about compile errors because of changes in function identity DSP unit test build fix --- Source/Dolphin_2010.sln | 819 +++++++++++---------- Source/UnitTests/AudioJitTests.cpp | 2 +- Source/UnitTests/UnitTests.vcproj | 358 --------- Source/UnitTests/UnitTests.vcxproj | 217 ++++++ Source/UnitTests/UnitTests.vcxproj.filters | 22 + 5 files changed, 656 insertions(+), 762 deletions(-) delete mode 100644 Source/UnitTests/UnitTests.vcproj create mode 100644 Source/UnitTests/UnitTests.vcxproj create mode 100644 Source/UnitTests/UnitTests.vcxproj.filters diff --git a/Source/Dolphin_2010.sln b/Source/Dolphin_2010.sln index a65ba2e894..6e304983dc 100644 --- a/Source/Dolphin_2010.sln +++ b/Source/Dolphin_2010.sln @@ -1,403 +1,416 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\Dolphin.vcxproj", "{1B099EF8-6F87-47A2-A3E7-898A24584F49}" - ProjectSection(ProjectDependencies) = postProject - {8C60E805-0DA5-4E25-8F84-038DB504BB0D} = {8C60E805-0DA5-4E25-8F84-038DB504BB0D} - {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} - {9E9DA440-E9AD-413C-B648-91030E792211} = {9E9DA440-E9AD-413C-B648-91030E792211} - {93D73454-2512-424E-9CDA-4BB357FE13DD} = {93D73454-2512-424E-9CDA-4BB357FE13DD} - {B6398059-EBB6-4C34-B547-95F365B71FF4} = {B6398059-EBB6-4C34-B547-95F365B71FF4} - {AA862E5E-A993-497A-B6A0-0E8E94B10050} = {AA862E5E-A993-497A-B6A0-0E8E94B10050} - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} = {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Common.vcxproj", "{C87A4178-44F6-49B2-B7AA-C79AF1B8C534}" - ProjectSection(ProjectDependencies) = postProject - {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCommon", "Core\AudioCommon\AudioCommon.vcxproj", "{37D007BD-D66C-4EAF-B56C-BD1AAC340A05}" - ProjectSection(ProjectDependencies) = postProject - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SOIL", "..\Externals\SOIL\SOIL.vcxproj", "{8544F1FF-F2A5-42D8-A568-C56B5D3B4181}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\Externals\SFML\build\vc2010\SFML_Network.vcxproj", "{93D73454-2512-424E-9CDA-4BB357FE13DD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZO", "..\Externals\LZO\LZO.vcxproj", "{D8890B98-26F7-4CFF-BBFB-B95F371B5F20}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\Externals\zlib\zlib.vcxproj", "{3E1339F5-9311-4122-9442-369702E8FCAD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoCommon", "Core\VideoCommon\VideoCommon.vcxproj", "{3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}" - ProjectSection(ProjectDependencies) = postProject - {AA862E5E-A993-497A-B6A0-0E8E94B10050} = {AA862E5E-A993-497A-B6A0-0E8E94B10050} - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181} = {8544F1FF-F2A5-42D8-A568-C56B5D3B4181} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLRun", "..\Externals\CLRun\clrun\CLRun.vcxproj", "{AA862E5E-A993-497A-B6A0-0E8E94B10050}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core\Core.vcxproj", "{8C60E805-0DA5-4E25-8F84-038DB504BB0D}" - ProjectSection(ProjectDependencies) = postProject - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6} = {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6} - {93D73454-2512-424E-9CDA-4BB357FE13DD} = {93D73454-2512-424E-9CDA-4BB357FE13DD} - {B6398059-EBB6-4C34-B547-95F365B71FF4} = {B6398059-EBB6-4C34-B547-95F365B71FF4} - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} = {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20} = {D8890B98-26F7-4CFF-BBFB-B95F371B5F20} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bochs_disasm", "..\Externals\Bochs_disasm\Bochs_disasm.vcxproj", "{CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiscIO", "Core\DiscIO\DiscIO.vcxproj", "{B6398059-EBB6-4C34-B547-95F365B71FF4}" - ProjectSection(ProjectDependencies) = postProject - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX9", "Plugins\Plugin_VideoDX9\Plugin_VideoDX9.vcxproj", "{DC7D7AF4-CE47-49E8-8B63-265CB6233A49}" - ProjectSection(ProjectDependencies) = postProject - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX11", "Plugins\Plugin_VideoDX11\Plugin_VideoDX11.vcxproj", "{9A4C733C-BADE-4AC6-B58A-6E274395E90E}" - ProjectSection(ProjectDependencies) = postProject - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoOGL", "Plugins\Plugin_VideoOGL\Plugin_VideoOGL.vcxproj", "{1909CD2D-1707-456F-86CA-0DF42A727C99}" - ProjectSection(ProjectDependencies) = postProject - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoSoftware", "Plugins\Plugin_VideoSoftware\Plugin_VideoSoftware.vcxproj", "{9E9DA440-E9AD-413C-B648-91030E792211}" - ProjectSection(ProjectDependencies) = postProject - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputCommon", "Core\InputCommon\InputCommon.vcxproj", "{B39AC394-5DB5-4DA9-9D98-09D46CA3701F}" - ProjectSection(ProjectDependencies) = postProject - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Languages", "..\Languages\Languages.vcxproj", "{0B8D0A82-C520-46BA-849D-3BB8F637EE0C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSPTool", "DSPTool\DSPTool.vcxproj", "{1970D175-3DE8-4738-942A-4D98D1CDBF64}" - ProjectSection(ProjectDependencies) = postProject - {8C60E805-0DA5-4E25-8F84-038DB504BB0D} = {8C60E805-0DA5-4E25-8F84-038DB504BB0D} - {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxWidgets", "..\Externals\wxWidgets3\build\msw\wx_base.vcxproj", "{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}" - ProjectSection(ProjectDependencies) = postProject - {01573C36-AC6E-49F6-94BA-572517EB9740} = {01573C36-AC6E-49F6-94BA-572517EB9740} - {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "png", "..\Externals\libpng\png\png.vcxproj", "{01573C36-AC6E-49F6-94BA-572517EB9740}" - ProjectSection(ProjectDependencies) = postProject - {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SCMRevGen", "Core\Common\SVNRevGen.vcxproj", "{69F00340-5C3D-449F-9A80-958435C6CF06}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\Externals\SoundTouch\SoundTouch.vcxproj", "{68A5DD20-7057-448B-8FE0-B6AC8D205509}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - DebugFast|Win32 = DebugFast|Win32 - DebugFast|x64 = DebugFast|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|Win32.ActiveCfg = Debug|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|Win32.Build.0 = Debug|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|x64.ActiveCfg = Debug|x64 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|x64.Build.0 = Debug|x64 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|x64.Build.0 = DebugFast|x64 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|Win32.ActiveCfg = Release|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|Win32.Build.0 = Release|Win32 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|x64.ActiveCfg = Release|x64 - {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|x64.Build.0 = Release|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|Win32.ActiveCfg = Debug|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|Win32.Build.0 = Debug|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|x64.ActiveCfg = Debug|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|x64.Build.0 = Debug|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|x64.Build.0 = DebugFast|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|Win32.ActiveCfg = Release|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|Win32.Build.0 = Release|Win32 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|x64.ActiveCfg = Release|x64 - {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|x64.Build.0 = Release|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|Win32.ActiveCfg = Debug|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|Win32.Build.0 = Debug|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|x64.ActiveCfg = Debug|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|x64.Build.0 = Debug|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|x64.Build.0 = DebugFast|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|Win32.ActiveCfg = Release|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|Win32.Build.0 = Release|Win32 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|x64.ActiveCfg = Release|x64 - {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|x64.Build.0 = Release|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|Win32.ActiveCfg = Debug|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|Win32.Build.0 = Debug|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|x64.ActiveCfg = Debug|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|x64.Build.0 = Debug|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|x64.Build.0 = DebugFast|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|Win32.ActiveCfg = Release|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|Win32.Build.0 = Release|Win32 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|x64.ActiveCfg = Release|x64 - {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|x64.Build.0 = Release|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|Win32.ActiveCfg = Debug|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|Win32.Build.0 = Debug|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|x64.ActiveCfg = Debug|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|x64.Build.0 = Debug|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|x64.Build.0 = DebugFast|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|Win32.ActiveCfg = Release|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|Win32.Build.0 = Release|Win32 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|x64.ActiveCfg = Release|x64 - {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|x64.Build.0 = Release|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|Win32.ActiveCfg = Debug|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|Win32.Build.0 = Debug|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|x64.ActiveCfg = Debug|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|x64.Build.0 = Debug|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|x64.Build.0 = DebugFast|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|Win32.ActiveCfg = Release|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|Win32.Build.0 = Release|Win32 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|x64.ActiveCfg = Release|x64 - {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|x64.Build.0 = Release|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|Win32.ActiveCfg = Debug|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|Win32.Build.0 = Debug|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|x64.ActiveCfg = Debug|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|x64.Build.0 = Debug|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|x64.Build.0 = DebugFast|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|Win32.ActiveCfg = Release|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|Win32.Build.0 = Release|Win32 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|x64.ActiveCfg = Release|x64 - {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|x64.Build.0 = Release|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|Win32.ActiveCfg = Debug|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|Win32.Build.0 = Debug|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|x64.ActiveCfg = Debug|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|x64.Build.0 = Debug|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|x64.Build.0 = DebugFast|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|Win32.ActiveCfg = Release|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|Win32.Build.0 = Release|Win32 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|x64.ActiveCfg = Release|x64 - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|x64.Build.0 = Release|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|Win32.ActiveCfg = Debug|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|Win32.Build.0 = Debug|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|x64.ActiveCfg = Debug|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|x64.Build.0 = Debug|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|x64.Build.0 = DebugFast|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|Win32.ActiveCfg = Release|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|Win32.Build.0 = Release|Win32 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|x64.ActiveCfg = Release|x64 - {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|x64.Build.0 = Release|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|Win32.ActiveCfg = Debug|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|Win32.Build.0 = Debug|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|x64.ActiveCfg = Debug|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|x64.Build.0 = Debug|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|x64.Build.0 = DebugFast|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|Win32.ActiveCfg = Release|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|Win32.Build.0 = Release|Win32 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|x64.ActiveCfg = Release|x64 - {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|x64.Build.0 = Release|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|Win32.ActiveCfg = Debug|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|Win32.Build.0 = Debug|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|x64.ActiveCfg = Debug|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|x64.Build.0 = Debug|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|x64.Build.0 = DebugFast|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|Win32.ActiveCfg = Release|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|Win32.Build.0 = Release|Win32 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|x64.ActiveCfg = Release|x64 - {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|x64.Build.0 = Release|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|Win32.ActiveCfg = Debug|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|Win32.Build.0 = Debug|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|x64.ActiveCfg = Debug|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|x64.Build.0 = Debug|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|x64.Build.0 = DebugFast|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|Win32.ActiveCfg = Release|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|Win32.Build.0 = Release|Win32 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.ActiveCfg = Release|x64 - {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.Build.0 = Release|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.ActiveCfg = Debug|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.Build.0 = Debug|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.ActiveCfg = Debug|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.Build.0 = Debug|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.Build.0 = DebugFast|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.ActiveCfg = Release|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.Build.0 = Release|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.ActiveCfg = Release|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.Build.0 = Release|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.ActiveCfg = Debug|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.Build.0 = Debug|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|x64.ActiveCfg = Debug|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|x64.Build.0 = Debug|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|x64.Build.0 = DebugFast|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|Win32.ActiveCfg = Release|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|Win32.Build.0 = Release|Win32 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|x64.ActiveCfg = Release|x64 - {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|x64.Build.0 = Release|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|Win32.ActiveCfg = Debug|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|Win32.Build.0 = Debug|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|x64.ActiveCfg = Debug|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|x64.Build.0 = Debug|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|x64.Build.0 = DebugFast|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|Win32.ActiveCfg = Release|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|Win32.Build.0 = Release|Win32 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|x64.ActiveCfg = Release|x64 - {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|x64.Build.0 = Release|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|Win32.Build.0 = Debug|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|x64.ActiveCfg = Debug|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|x64.Build.0 = Debug|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|x64.Build.0 = DebugFast|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.Release|Win32.ActiveCfg = Release|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.Release|Win32.Build.0 = Release|Win32 - {9E9DA440-E9AD-413C-B648-91030E792211}.Release|x64.ActiveCfg = Release|x64 - {9E9DA440-E9AD-413C-B648-91030E792211}.Release|x64.Build.0 = Release|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|Win32.ActiveCfg = Debug|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|Win32.Build.0 = Debug|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|x64.ActiveCfg = Debug|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|x64.Build.0 = Debug|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|x64.Build.0 = DebugFast|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|Win32.ActiveCfg = Release|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|Win32.Build.0 = Release|Win32 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|x64.ActiveCfg = Release|x64 - {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|x64.Build.0 = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|Win32.ActiveCfg = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|Win32.Build.0 = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|x64.ActiveCfg = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|x64.Build.0 = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|Win32.ActiveCfg = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|Win32.Build.0 = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|x64.ActiveCfg = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|x64.Build.0 = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|Win32.ActiveCfg = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|Win32.Build.0 = Release|Win32 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|x64.ActiveCfg = Release|x64 - {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|x64.Build.0 = Release|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|Win32.ActiveCfg = Debug|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|Win32.Build.0 = Debug|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|x64.ActiveCfg = Debug|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|x64.Build.0 = Debug|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|x64.Build.0 = DebugFast|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|Win32.ActiveCfg = Release|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|Win32.Build.0 = Release|Win32 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|x64.ActiveCfg = Release|x64 - {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|x64.Build.0 = Release|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|Win32.ActiveCfg = Debug|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|Win32.Build.0 = Debug|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|x64.ActiveCfg = Debug|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|x64.Build.0 = Debug|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|x64.Build.0 = DebugFast|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|Win32.ActiveCfg = Release|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|Win32.Build.0 = Release|Win32 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|x64.ActiveCfg = Release|x64 - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|x64.Build.0 = Release|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|Win32.ActiveCfg = Debug|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|Win32.Build.0 = Debug|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|x64.ActiveCfg = Debug|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|x64.Build.0 = Debug|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|x64.Build.0 = DebugFast|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|Win32.ActiveCfg = Release|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|Win32.Build.0 = Release|Win32 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|x64.ActiveCfg = Release|x64 - {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|x64.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|Win32.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|Win32.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|x64.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|x64.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|Win32.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|Win32.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|x64.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|x64.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|Win32.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|Win32.Build.0 = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|x64.ActiveCfg = Release|x64 - {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|x64.Build.0 = Release|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.ActiveCfg = Debug|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.Build.0 = Debug|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|x64.ActiveCfg = Debug|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|x64.Build.0 = Debug|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|Win32.ActiveCfg = Debug|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|Win32.Build.0 = Debug|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|x64.ActiveCfg = Release|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|x64.Build.0 = Release|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.ActiveCfg = Release|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.Build.0 = Release|Win32 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|x64.ActiveCfg = Release|x64 - {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\Dolphin.vcxproj", "{1B099EF8-6F87-47A2-A3E7-898A24584F49}" + ProjectSection(ProjectDependencies) = postProject + {8C60E805-0DA5-4E25-8F84-038DB504BB0D} = {8C60E805-0DA5-4E25-8F84-038DB504BB0D} + {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} + {9E9DA440-E9AD-413C-B648-91030E792211} = {9E9DA440-E9AD-413C-B648-91030E792211} + {93D73454-2512-424E-9CDA-4BB357FE13DD} = {93D73454-2512-424E-9CDA-4BB357FE13DD} + {B6398059-EBB6-4C34-B547-95F365B71FF4} = {B6398059-EBB6-4C34-B547-95F365B71FF4} + {AA862E5E-A993-497A-B6A0-0E8E94B10050} = {AA862E5E-A993-497A-B6A0-0E8E94B10050} + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} = {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Common.vcxproj", "{C87A4178-44F6-49B2-B7AA-C79AF1B8C534}" + ProjectSection(ProjectDependencies) = postProject + {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCommon", "Core\AudioCommon\AudioCommon.vcxproj", "{37D007BD-D66C-4EAF-B56C-BD1AAC340A05}" + ProjectSection(ProjectDependencies) = postProject + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SOIL", "..\Externals\SOIL\SOIL.vcxproj", "{8544F1FF-F2A5-42D8-A568-C56B5D3B4181}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\Externals\SFML\build\vc2010\SFML_Network.vcxproj", "{93D73454-2512-424E-9CDA-4BB357FE13DD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZO", "..\Externals\LZO\LZO.vcxproj", "{D8890B98-26F7-4CFF-BBFB-B95F371B5F20}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\Externals\zlib\zlib.vcxproj", "{3E1339F5-9311-4122-9442-369702E8FCAD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoCommon", "Core\VideoCommon\VideoCommon.vcxproj", "{3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}" + ProjectSection(ProjectDependencies) = postProject + {AA862E5E-A993-497A-B6A0-0E8E94B10050} = {AA862E5E-A993-497A-B6A0-0E8E94B10050} + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181} = {8544F1FF-F2A5-42D8-A568-C56B5D3B4181} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLRun", "..\Externals\CLRun\clrun\CLRun.vcxproj", "{AA862E5E-A993-497A-B6A0-0E8E94B10050}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core\Core.vcxproj", "{8C60E805-0DA5-4E25-8F84-038DB504BB0D}" + ProjectSection(ProjectDependencies) = postProject + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6} = {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6} + {93D73454-2512-424E-9CDA-4BB357FE13DD} = {93D73454-2512-424E-9CDA-4BB357FE13DD} + {B6398059-EBB6-4C34-B547-95F365B71FF4} = {B6398059-EBB6-4C34-B547-95F365B71FF4} + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} = {B39AC394-5DB5-4DA9-9D98-09D46CA3701F} + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20} = {D8890B98-26F7-4CFF-BBFB-B95F371B5F20} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bochs_disasm", "..\Externals\Bochs_disasm\Bochs_disasm.vcxproj", "{CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiscIO", "Core\DiscIO\DiscIO.vcxproj", "{B6398059-EBB6-4C34-B547-95F365B71FF4}" + ProjectSection(ProjectDependencies) = postProject + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX9", "Plugins\Plugin_VideoDX9\Plugin_VideoDX9.vcxproj", "{DC7D7AF4-CE47-49E8-8B63-265CB6233A49}" + ProjectSection(ProjectDependencies) = postProject + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX11", "Plugins\Plugin_VideoDX11\Plugin_VideoDX11.vcxproj", "{9A4C733C-BADE-4AC6-B58A-6E274395E90E}" + ProjectSection(ProjectDependencies) = postProject + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoOGL", "Plugins\Plugin_VideoOGL\Plugin_VideoOGL.vcxproj", "{1909CD2D-1707-456F-86CA-0DF42A727C99}" + ProjectSection(ProjectDependencies) = postProject + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoSoftware", "Plugins\Plugin_VideoSoftware\Plugin_VideoSoftware.vcxproj", "{9E9DA440-E9AD-413C-B648-91030E792211}" + ProjectSection(ProjectDependencies) = postProject + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputCommon", "Core\InputCommon\InputCommon.vcxproj", "{B39AC394-5DB5-4DA9-9D98-09D46CA3701F}" + ProjectSection(ProjectDependencies) = postProject + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Languages", "..\Languages\Languages.vcxproj", "{0B8D0A82-C520-46BA-849D-3BB8F637EE0C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSPTool", "DSPTool\DSPTool.vcxproj", "{1970D175-3DE8-4738-942A-4D98D1CDBF64}" + ProjectSection(ProjectDependencies) = postProject + {8C60E805-0DA5-4E25-8F84-038DB504BB0D} = {8C60E805-0DA5-4E25-8F84-038DB504BB0D} + {69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06} + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} = {C87A4178-44F6-49B2-B7AA-C79AF1B8C534} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxWidgets", "..\Externals\wxWidgets3\build\msw\wx_base.vcxproj", "{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}" + ProjectSection(ProjectDependencies) = postProject + {01573C36-AC6E-49F6-94BA-572517EB9740} = {01573C36-AC6E-49F6-94BA-572517EB9740} + {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "png", "..\Externals\libpng\png\png.vcxproj", "{01573C36-AC6E-49F6-94BA-572517EB9740}" + ProjectSection(ProjectDependencies) = postProject + {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SCMRevGen", "Core\Common\SVNRevGen.vcxproj", "{69F00340-5C3D-449F-9A80-958435C6CF06}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\Externals\SoundTouch\SoundTouch.vcxproj", "{68A5DD20-7057-448B-8FE0-B6AC8D205509}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests", "UnitTests\UnitTests.vcxproj", "{40C636FA-B5BF-4D67-ABC8-376B524A7551}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugFast|Win32 = DebugFast|Win32 + DebugFast|x64 = DebugFast|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|Win32.ActiveCfg = Debug|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|Win32.Build.0 = Debug|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|x64.ActiveCfg = Debug|x64 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Debug|x64.Build.0 = Debug|x64 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.DebugFast|x64.Build.0 = DebugFast|x64 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|Win32.ActiveCfg = Release|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|Win32.Build.0 = Release|Win32 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|x64.ActiveCfg = Release|x64 + {1B099EF8-6F87-47A2-A3E7-898A24584F49}.Release|x64.Build.0 = Release|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|Win32.ActiveCfg = Debug|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|Win32.Build.0 = Debug|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|x64.ActiveCfg = Debug|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Debug|x64.Build.0 = Debug|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.DebugFast|x64.Build.0 = DebugFast|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|Win32.ActiveCfg = Release|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|Win32.Build.0 = Release|Win32 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|x64.ActiveCfg = Release|x64 + {C87A4178-44F6-49B2-B7AA-C79AF1B8C534}.Release|x64.Build.0 = Release|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|Win32.ActiveCfg = Debug|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|Win32.Build.0 = Debug|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|x64.ActiveCfg = Debug|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Debug|x64.Build.0 = Debug|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.DebugFast|x64.Build.0 = DebugFast|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|Win32.ActiveCfg = Release|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|Win32.Build.0 = Release|Win32 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|x64.ActiveCfg = Release|x64 + {37D007BD-D66C-4EAF-B56C-BD1AAC340A05}.Release|x64.Build.0 = Release|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|Win32.ActiveCfg = Debug|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|Win32.Build.0 = Debug|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|x64.ActiveCfg = Debug|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Debug|x64.Build.0 = Debug|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.DebugFast|x64.Build.0 = DebugFast|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|Win32.ActiveCfg = Release|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|Win32.Build.0 = Release|Win32 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|x64.ActiveCfg = Release|x64 + {8544F1FF-F2A5-42D8-A568-C56B5D3B4181}.Release|x64.Build.0 = Release|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|Win32.ActiveCfg = Debug|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|Win32.Build.0 = Debug|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|x64.ActiveCfg = Debug|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Debug|x64.Build.0 = Debug|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.DebugFast|x64.Build.0 = DebugFast|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|Win32.ActiveCfg = Release|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|Win32.Build.0 = Release|Win32 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|x64.ActiveCfg = Release|x64 + {93D73454-2512-424E-9CDA-4BB357FE13DD}.Release|x64.Build.0 = Release|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|Win32.Build.0 = Debug|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|x64.ActiveCfg = Debug|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Debug|x64.Build.0 = Debug|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.DebugFast|x64.Build.0 = DebugFast|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|Win32.ActiveCfg = Release|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|Win32.Build.0 = Release|Win32 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|x64.ActiveCfg = Release|x64 + {D8890B98-26F7-4CFF-BBFB-B95F371B5F20}.Release|x64.Build.0 = Release|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|Win32.Build.0 = Debug|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|x64.ActiveCfg = Debug|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Debug|x64.Build.0 = Debug|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.DebugFast|x64.Build.0 = DebugFast|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|Win32.ActiveCfg = Release|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|Win32.Build.0 = Release|Win32 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|x64.ActiveCfg = Release|x64 + {3E1339F5-9311-4122-9442-369702E8FCAD}.Release|x64.Build.0 = Release|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|Win32.Build.0 = Debug|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|x64.ActiveCfg = Debug|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Debug|x64.Build.0 = Debug|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.DebugFast|x64.Build.0 = DebugFast|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|Win32.ActiveCfg = Release|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|Win32.Build.0 = Release|Win32 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|x64.ActiveCfg = Release|x64 + {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF}.Release|x64.Build.0 = Release|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|Win32.Build.0 = Debug|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|x64.ActiveCfg = Debug|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Debug|x64.Build.0 = Debug|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.DebugFast|x64.Build.0 = DebugFast|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|Win32.ActiveCfg = Release|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|Win32.Build.0 = Release|Win32 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|x64.ActiveCfg = Release|x64 + {AA862E5E-A993-497A-B6A0-0E8E94B10050}.Release|x64.Build.0 = Release|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|Win32.Build.0 = Debug|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|x64.ActiveCfg = Debug|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Debug|x64.Build.0 = Debug|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.DebugFast|x64.Build.0 = DebugFast|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|Win32.ActiveCfg = Release|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|Win32.Build.0 = Release|Win32 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|x64.ActiveCfg = Release|x64 + {8C60E805-0DA5-4E25-8F84-038DB504BB0D}.Release|x64.Build.0 = Release|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|Win32.Build.0 = Debug|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|x64.ActiveCfg = Debug|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Debug|x64.Build.0 = Debug|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.DebugFast|x64.Build.0 = DebugFast|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|Win32.ActiveCfg = Release|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|Win32.Build.0 = Release|Win32 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|x64.ActiveCfg = Release|x64 + {CD3D4C3C-1027-4D33-B047-AEC7B56D0BF6}.Release|x64.Build.0 = Release|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|Win32.Build.0 = Debug|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|x64.ActiveCfg = Debug|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Debug|x64.Build.0 = Debug|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.DebugFast|x64.Build.0 = DebugFast|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|Win32.ActiveCfg = Release|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|Win32.Build.0 = Release|Win32 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.ActiveCfg = Release|x64 + {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.Build.0 = Release|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.ActiveCfg = Debug|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.Build.0 = Debug|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.ActiveCfg = Debug|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.Build.0 = Debug|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.Build.0 = DebugFast|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.ActiveCfg = Release|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.Build.0 = Release|Win32 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.ActiveCfg = Release|x64 + {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.Build.0 = Release|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.ActiveCfg = Debug|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.Build.0 = Debug|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|x64.ActiveCfg = Debug|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|x64.Build.0 = Debug|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.DebugFast|x64.Build.0 = DebugFast|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|Win32.ActiveCfg = Release|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|Win32.Build.0 = Release|Win32 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|x64.ActiveCfg = Release|x64 + {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Release|x64.Build.0 = Release|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|Win32.ActiveCfg = Debug|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|Win32.Build.0 = Debug|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|x64.ActiveCfg = Debug|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Debug|x64.Build.0 = Debug|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.DebugFast|x64.Build.0 = DebugFast|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|Win32.ActiveCfg = Release|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|Win32.Build.0 = Release|Win32 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|x64.ActiveCfg = Release|x64 + {1909CD2D-1707-456F-86CA-0DF42A727C99}.Release|x64.Build.0 = Release|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|Win32.Build.0 = Debug|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|x64.ActiveCfg = Debug|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.Debug|x64.Build.0 = Debug|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.DebugFast|x64.Build.0 = DebugFast|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.Release|Win32.ActiveCfg = Release|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.Release|Win32.Build.0 = Release|Win32 + {9E9DA440-E9AD-413C-B648-91030E792211}.Release|x64.ActiveCfg = Release|x64 + {9E9DA440-E9AD-413C-B648-91030E792211}.Release|x64.Build.0 = Release|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|Win32.ActiveCfg = Debug|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|Win32.Build.0 = Debug|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|x64.ActiveCfg = Debug|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Debug|x64.Build.0 = Debug|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.DebugFast|x64.Build.0 = DebugFast|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|Win32.ActiveCfg = Release|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|Win32.Build.0 = Release|Win32 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|x64.ActiveCfg = Release|x64 + {B39AC394-5DB5-4DA9-9D98-09D46CA3701F}.Release|x64.Build.0 = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|Win32.ActiveCfg = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|Win32.Build.0 = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|x64.ActiveCfg = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Debug|x64.Build.0 = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|Win32.ActiveCfg = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|Win32.Build.0 = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|x64.ActiveCfg = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.DebugFast|x64.Build.0 = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|Win32.ActiveCfg = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|Win32.Build.0 = Release|Win32 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|x64.ActiveCfg = Release|x64 + {0B8D0A82-C520-46BA-849D-3BB8F637EE0C}.Release|x64.Build.0 = Release|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|Win32.ActiveCfg = Debug|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|Win32.Build.0 = Debug|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|x64.ActiveCfg = Debug|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Debug|x64.Build.0 = Debug|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.DebugFast|x64.Build.0 = DebugFast|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|Win32.ActiveCfg = Release|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|Win32.Build.0 = Release|Win32 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|x64.ActiveCfg = Release|x64 + {1970D175-3DE8-4738-942A-4D98D1CDBF64}.Release|x64.Build.0 = Release|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|Win32.ActiveCfg = Debug|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|Win32.Build.0 = Debug|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|x64.ActiveCfg = Debug|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Debug|x64.Build.0 = Debug|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.DebugFast|x64.Build.0 = DebugFast|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|Win32.ActiveCfg = Release|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|Win32.Build.0 = Release|Win32 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|x64.ActiveCfg = Release|x64 + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}.Release|x64.Build.0 = Release|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|Win32.ActiveCfg = Debug|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|Win32.Build.0 = Debug|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|x64.ActiveCfg = Debug|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Debug|x64.Build.0 = Debug|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.DebugFast|x64.Build.0 = DebugFast|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|Win32.ActiveCfg = Release|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|Win32.Build.0 = Release|Win32 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|x64.ActiveCfg = Release|x64 + {01573C36-AC6E-49F6-94BA-572517EB9740}.Release|x64.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|Win32.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|Win32.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|x64.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Debug|x64.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|Win32.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|Win32.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|x64.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.DebugFast|x64.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|Win32.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|Win32.Build.0 = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|x64.ActiveCfg = Release|x64 + {69F00340-5C3D-449F-9A80-958435C6CF06}.Release|x64.Build.0 = Release|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.ActiveCfg = Debug|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.Build.0 = Debug|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|x64.ActiveCfg = Debug|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|x64.Build.0 = Debug|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|Win32.ActiveCfg = Debug|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|Win32.Build.0 = Debug|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|x64.ActiveCfg = Release|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.DebugFast|x64.Build.0 = Release|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.ActiveCfg = Release|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.Build.0 = Release|Win32 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|x64.ActiveCfg = Release|x64 + {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|x64.Build.0 = Release|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.ActiveCfg = Debug|Win32 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.Build.0 = Debug|Win32 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|x64.ActiveCfg = Debug|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|x64.Build.0 = Debug|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|Win32.ActiveCfg = Debug|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.ActiveCfg = Debug|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.Build.0 = Debug|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.ActiveCfg = Release|Win32 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.Build.0 = Release|Win32 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|x64.ActiveCfg = Release|x64 + {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source/UnitTests/AudioJitTests.cpp b/Source/UnitTests/AudioJitTests.cpp index 4991eeb485..7712f59fc3 100644 --- a/Source/UnitTests/AudioJitTests.cpp +++ b/Source/UnitTests/AudioJitTests.cpp @@ -341,7 +341,7 @@ void AudioJitTests() //required to be able to link against DSPCore void DSPHost_UpdateDebugger() { } -unsigned int DSPHost_CodeLoaded(unsigned const char*, int) { return 0; } +void DSPHost_CodeLoaded(unsigned const char*, int) { } void DSPHost_InterruptRequest() { } bool DSPHost_OnThread() { return false; } void DSPHost_WriteHostMemory(unsigned char, unsigned int) { } diff --git a/Source/UnitTests/UnitTests.vcproj b/Source/UnitTests/UnitTests.vcproj deleted file mode 100644 index a93651b3e4..0000000000 --- a/Source/UnitTests/UnitTests.vcproj +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/UnitTests/UnitTests.vcxproj b/Source/UnitTests/UnitTests.vcxproj new file mode 100644 index 0000000000..d1a72a9979 --- /dev/null +++ b/Source/UnitTests/UnitTests.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {40C636FA-B5BF-4D67-ABC8-376B524A7551} + UnitTests + Win32Proj + + + + Application + Unicode + false + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + false + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + false + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ../Core/Core/Src;../Core/Common/Src;../Core/InputCommon/Src;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + Iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + true + Console + MachineX86 + + + xcopy "$(TargetPath)" "$(SolutionDir)..\Binary\$(Platform)\" /e /s /y /d + + + + + X64 + + + Disabled + ../Core/Core/Src;../Core/Common/Src;../Core/InputCommon/Src;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + Iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + true + Console + MachineX64 + + + xcopy "$(TargetPath)" "$(SolutionDir)..\Binary\$(Platform)\" /e /s /y /d + + + + + MaxSpeed + true + ../Core/Core/Src;../Core/Common/Src;../Core/InputCommon/Src;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + Iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + true + Console + true + true + MachineX86 + + + xcopy "$(TargetPath)" "$(SolutionDir)..\Binary\$(Platform)\" /e /s /y /d + + + + + X64 + + + /MP %(AdditionalOptions) + MaxSpeed + true + ../Core/Core/Src;../Core/Common/Src;../Core/InputCommon/Src;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + Iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + true + Console + true + true + MachineX64 + + + xcopy "$(TargetPath)" "$(SolutionDir)..\Binary\$(Platform)\" /e /s /y /d + + + + + + + + + + + + + {cd3d4c3c-1027-4d33-b047-aec7b56d0bf6} + + + {c87a4178-44f6-49b2-b7aa-c79af1b8c534} + + + {8c60e805-0da5-4e25-8f84-038db504bb0d} + + + + + + \ No newline at end of file diff --git a/Source/UnitTests/UnitTests.vcxproj.filters b/Source/UnitTests/UnitTests.vcxproj.filters new file mode 100644 index 0000000000..b38fc876e5 --- /dev/null +++ b/Source/UnitTests/UnitTests.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {cde9a42c-90d9-4bc9-9182-3fcc0cf9f7a4} + + + + + Audio + + + Audio + + + + + + Audio + + + \ No newline at end of file From 2effab9a9f84a906bae68a3d82acf6bf44090cc9 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 22 May 2013 05:29:47 -0500 Subject: [PATCH 111/352] [Android] Make it less stupid to add a folder to the search list. Now just hit the menu button and select 'Add current folder' --- Source/Android/.idea/workspace.xml | 322 ++++++++++-------- .../dolphinemu/DolphinEmulator.java | 8 +- .../dolphinemu/dolphinemu/FolderBrowser.java | 36 +- .../dolphinemu/dolphinemu/GameListView.java | 4 +- 4 files changed, 203 insertions(+), 167 deletions(-) diff --git a/Source/Android/.idea/workspace.xml b/Source/Android/.idea/workspace.xml index 87d98b0e1e..b6b28566ce 100644 --- a/Source/Android/.idea/workspace.xml +++ b/Source/Android/.idea/workspace.xml @@ -13,14 +13,6 @@ android-17 - - - - Nexus 4 - @android:style/Theme.Holo - - - @@ -40,8 +32,9 @@ - + + - + @@ -110,26 +103,19 @@ - + - + - - - - - - - - - - - + + + + @@ -137,8 +123,10 @@ - - + + + + @@ -146,7 +134,7 @@ - + @@ -173,7 +161,6 @@ @@ -225,6 +214,7 @@ + @@ -263,7 +253,6 @@ - @@ -375,56 +364,25 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - @@ -579,32 +570,32 @@ - + - - - - - - - - - - - - - + + + + - + + + + - + + + + - - + + + + + @@ -668,6 +659,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -704,13 +737,6 @@ - - - - - - - @@ -720,30 +746,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -751,6 +753,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java index 060807d63c..c3d6d8ae06 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -1,11 +1,5 @@ package org.dolphinemu.dolphinemu; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -16,6 +10,8 @@ import android.util.Log; import android.view.MotionEvent; import android.view.WindowManager; +import java.io.*; + public class DolphinEmulator extends Activity { static private NativeGLSurfaceView GLview = null; diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java index 68203413b7..15afb36c3c 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java @@ -1,29 +1,19 @@ package org.dolphinemu.dolphinemu; -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import net.simonvt.menudrawer.MenuDrawer; - import android.app.Activity; import android.app.ListActivity; import android.content.Intent; import android.os.Bundle; import android.os.Environment; -import android.view.Gravity; -import android.view.LayoutInflater; +import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.BaseAdapter; -import android.widget.LinearLayout; import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class FolderBrowser extends ListActivity { private GameListAdapter adapter; @@ -87,12 +77,18 @@ public class FolderBrowser extends ListActivity { Fill(currentDir); } @Override - public void onBackPressed() { + public boolean onCreateOptionsMenu(Menu menu) + { + menu.add("Add current folder"); + return true; + } + @Override + public boolean onOptionsItemSelected(MenuItem item) { Intent intent = new Intent(); intent.putExtra("Select", currentDir.getPath()); setResult(Activity.RESULT_OK, intent); - - this.finish(); - super.onBackPressed(); + + this.finish(); + return true; } } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java index 760f0445ec..ad2df58fa3 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java @@ -39,7 +39,7 @@ public class GameListView extends ListActivity { int intDirectories = Integer.parseInt(Directories); for (int a = 0; a < intDirectories; ++a) { - String BrowseDir = GetConfig("General", "GCMPaths" + Integer.toString(a), ""); + String BrowseDir = GetConfig("General", "GCMPath" + Integer.toString(a), ""); File currentDir = new File(BrowseDir); File[]dirs = currentDir.listFiles(); try @@ -105,7 +105,7 @@ public class GameListView extends ListActivity { int intDirectories = Integer.parseInt(Directories); Directories = Integer.toString(intDirectories + 1); SetConfig("General", "GCMPathes", Directories); - SetConfig("General", "GCMPaths" + Integer.toString(intDirectories), FileName); + SetConfig("General", "GCMPath" + Integer.toString(intDirectories), FileName); Fill(); } From 3778c96d48fcca61293b3046e70ecc249cfe2acd Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Wed, 22 May 2013 22:39:55 +1200 Subject: [PATCH 112/352] Edge case where balance board returns corrupt extension type... --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 5e4f32caab..fc497c29a3 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -353,6 +353,8 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool { case WM_STATUS_REPORT: { + real_wiimote = true; + // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Status Report"); wm_status_report * wsr = (wm_status_report*)&buf[2]; if (wsr->extension) @@ -369,7 +371,6 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool } else { - real_wiimote = true; // Normal Wiimote, exit while and be happy. rc = -1; } @@ -377,7 +378,9 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool } case WM_ACK_DATA: { - // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack"); + real_wiimote = true; + //wm_acknowledge * wm = (wm_acknowledge*)&buf[2]; + //DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack Error: %X ReportID: %X", wm->errorID, wm->reportID); break; } case WM_READ_DATA_REPLY: @@ -394,7 +397,9 @@ void WiimoteScanner::CheckDeviceType(std::basic_string &devicepath, bool // DEBUG_LOG(WIIMOTE, // "CheckDeviceType: GOT EXT TYPE %llX", // ext_type); - is_bb = ext_type == 0x020420A40000ULL; + is_bb = (ext_type == 0x020420A40000ULL) || + ((ext_type & 0xf00000000000ULL) && + ext_type != 0xffffffffffffULL); } else { From 2f00f87e8e058f276ccf8900f678b5afd2922ee6 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Wed, 22 May 2013 23:34:02 +1200 Subject: [PATCH 113/352] Use working directory for executions. Fixes issue 6318 --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ddf6c1581..ecc8e6ea61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,11 +85,11 @@ endfunction(enable_precompiled_headers) include(FindGit OPTIONAL) if(GIT_FOUND AND NOT DOLPHIN_WC_REVISION) # defines DOLPHIN_WC_REVISION - EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE DOLPHIN_WC_REVISION OUTPUT_STRIP_TRAILING_WHITESPACE) # defines DOLPHIN_WC_DESCRIBE - EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty + EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty OUTPUT_VARIABLE DOLPHIN_WC_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -97,7 +97,7 @@ if(GIT_FOUND AND NOT DOLPHIN_WC_REVISION) STRING(REGEX REPLACE "-[^-]+((-dirty)?)$" "\\1" DOLPHIN_WC_DESCRIBE "${DOLPHIN_WC_DESCRIBE}") # defines DOLPHIN_WC_BRANCH - EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD OUTPUT_VARIABLE DOLPHIN_WC_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE) endif() @@ -604,7 +604,7 @@ if(NOT DISABLE_WX AND NOT ANDROID) FIND_PACKAGE(wxWidgets COMPONENTS core aui adv) if(wxWidgets_FOUND) - EXECUTE_PROCESS( + EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" ${wxWidgets_CONFIG_OPTIONS} --version OUTPUT_VARIABLE wxWidgets_VERSION @@ -619,7 +619,7 @@ if(NOT DISABLE_WX AND NOT ANDROID) endif(wxWidgets_FOUND) if(wxWidgets_FOUND) - EXECUTE_PROCESS( + EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" ${wxWidgets_CONFIG_OPTIONS} --version OUTPUT_VARIABLE wxWidgets_VERSION From f452a6442f395587d7c57e1603319ff47891b678 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sun, 19 May 2013 17:14:29 +0200 Subject: [PATCH 114/352] Adding MMU state values to state because that allow the MMU state to be loaded --- Source/Core/Core/Src/HW/MemmapFunctions.cpp | 11 ++++------- Source/Core/Core/Src/PowerPC/PowerPC.cpp | 2 ++ Source/Core/Core/Src/PowerPC/PowerPC.h | 3 +++ Source/Core/Core/Src/State.cpp | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/Src/HW/MemmapFunctions.cpp b/Source/Core/Core/Src/HW/MemmapFunctions.cpp index 39c852ec22..0e899079c5 100644 --- a/Source/Core/Core/Src/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/Src/HW/MemmapFunctions.cpp @@ -598,9 +598,6 @@ union UPTE2 u32 Hex; }; -u32 pagetable_base = 0; -u32 pagetable_hashmask = 0; - void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite) { if (_bWrite) @@ -644,8 +641,8 @@ void SDRUpdated() { return; } - pagetable_base = htaborg<<16; - pagetable_hashmask = ((xx<<10)|0x3ff); + PowerPC::ppcState.pagetable_base = htaborg<<16; + PowerPC::ppcState.pagetable_hashmask = ((xx<<10)|0x3ff); } @@ -821,7 +818,7 @@ u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag) // hash function no 1 "xor" .360 u32 hash1 = (VSID ^ page_index); - u32 pteg_addr = ((hash1 & pagetable_hashmask) << 6) | pagetable_base; + u32 pteg_addr = ((hash1 & PowerPC::ppcState.pagetable_hashmask) << 6) | PowerPC::ppcState.pagetable_base; // hash1 for (int i = 0; i < 8; i++) @@ -856,7 +853,7 @@ u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag) // hash function no 2 "not" .360 hash1 = ~hash1; - pteg_addr = ((hash1 & pagetable_hashmask) << 6) | pagetable_base; + pteg_addr = ((hash1 & PowerPC::ppcState.pagetable_hashmask) << 6) | PowerPC::ppcState.pagetable_base; for (int i = 0; i < 8; i++) { u32 pte = bswap(*(u32*)&pRAM[pteg_addr]); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 7628e1298e..4f45d08ede 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -138,6 +138,8 @@ void Init(int cpu_core) ppcState.itlb_last = 0; memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va)); memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa)); + ppcState.pagetable_base = 0; + ppcState.pagetable_hashmask = 0; ResetRegisters(); PPCTables::InitTables(cpu_core); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index 219dcc192f..82c912d213 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -64,6 +64,9 @@ struct GC_ALIGNED64(PowerPCState) u32 itlb_va[128]; u32 itlb_pa[128]; + u32 pagetable_base; + u32 pagetable_hashmask; + InstructionCache iCache; }; diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 5923ba6917..f41b32485e 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -59,7 +59,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 18; +static const u32 STATE_VERSION = 19; enum { From ae55d82e4337ed19ec8646c00fc3edb8ad6719ea Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 23 May 2013 11:08:07 +0200 Subject: [PATCH 115/352] disable hacked buffer option for d3d --- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 5 +---- Source/Core/DolphinWX/Src/VideoConfigDiag.h | 5 +++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 45bf35046e..b3b0e1b123 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -497,15 +497,12 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con // - other hacks { wxGridSizer* const szr_other = new wxGridSizer(2, 5, 5); - SettingCheckBox* hacked_buffer_upload_cb; szr_other->Add(CreateCheckBox(page_hacks, _("Cache Display Lists"), wxGetTranslation(dlc_desc), vconfig.bDlistCachingEnable)); szr_other->Add(CreateCheckBox(page_hacks, _("Disable Destination Alpha"), wxGetTranslation(disable_dstalpha_desc), vconfig.bDstAlphaPass)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); - szr_other->Add(hacked_buffer_upload_cb = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); + szr_other->Add(hacked_buffer_upload = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calculation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); - if (Core::GetState() != Core::CORE_UNINITIALIZED) - hacked_buffer_upload_cb->Disable(); wxStaticBoxSizer* const group_other = new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other")); group_other->Add(szr_other, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index 90a42c34a1..1c8963b908 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -8,6 +8,7 @@ #include "ConfigManager.h" #include "VideoConfig.h" +#include "Core.h" #include #include @@ -165,6 +166,9 @@ protected: // XFB virtual_xfb->Enable(vconfig.bUseXFB); real_xfb->Enable(vconfig.bUseXFB); + + // OGL Hacked buffer + hacked_buffer_upload->Enable(Core::GetState() == Core::CORE_UNINITIALIZED && vconfig.backend_info.APIType == API_OPENGL); ev.Skip(); } @@ -194,6 +198,7 @@ protected: SettingRadioButton* efbcopy_ram; SettingCheckBox* cache_efb_copies; SettingCheckBox* emulate_efb_format_changes; + SettingCheckBox* hacked_buffer_upload; SettingRadioButton* virtual_xfb; SettingRadioButton* real_xfb; From 6a5e7d7be40cc8f06aa2e4d382204bc169488234 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 23 May 2013 13:58:37 +0200 Subject: [PATCH 116/352] also hide hacked buffer option on d3d --- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 2 +- Source/Core/DolphinWX/Src/VideoConfigDiag.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index b3b0e1b123..8c4ee9ebb4 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -501,8 +501,8 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_other->Add(CreateCheckBox(page_hacks, _("Disable Destination Alpha"), wxGetTranslation(disable_dstalpha_desc), vconfig.bDstAlphaPass)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); - szr_other->Add(hacked_buffer_upload = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calculation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); + szr_other->Add(hacked_buffer_upload = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload)); wxStaticBoxSizer* const group_other = new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other")); group_other->Add(szr_other, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index 1c8963b908..563f5076d6 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -169,6 +169,7 @@ protected: // OGL Hacked buffer hacked_buffer_upload->Enable(Core::GetState() == Core::CORE_UNINITIALIZED && vconfig.backend_info.APIType == API_OPENGL); + hacked_buffer_upload->Show(vconfig.backend_info.APIType == API_OPENGL); ev.Skip(); } From a51d6a6dddc99b91a19025988a3e91bb2bc02acb Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 23 May 2013 21:07:01 +0200 Subject: [PATCH 117/352] add new statistics for gpu buffer streaming --- Source/Core/VideoCommon/Src/Statistics.cpp | 3 +++ Source/Core/VideoCommon/Src/Statistics.h | 4 ++++ Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp | 2 ++ Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp | 3 +++ Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp | 2 ++ Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp | 2 ++ Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp | 2 ++ Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp | 3 +++ 8 files changed, 21 insertions(+) diff --git a/Source/Core/VideoCommon/Src/Statistics.cpp b/Source/Core/VideoCommon/Src/Statistics.cpp index 3dcd281b7f..0c69499355 100644 --- a/Source/Core/VideoCommon/Src/Statistics.cpp +++ b/Source/Core/VideoCommon/Src/Statistics.cpp @@ -55,6 +55,9 @@ char *Statistics::ToString(char *ptr) ptr+=sprintf(ptr,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL); ptr+=sprintf(ptr,"BP loads: %i\n",stats.thisFrame.numBPLoads); ptr+=sprintf(ptr,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL); + ptr+=sprintf(ptr,"Vertex streamed: %i kB\n",stats.thisFrame.bytesVertexStreamed/1024); + ptr+=sprintf(ptr,"Index streamed: %i kB\n",stats.thisFrame.bytesIndexStreamed/1024); + ptr+=sprintf(ptr,"Uniform streamed: %i kB\n",stats.thisFrame.bytesUniformStreamed/1024); ptr+=sprintf(ptr,"Vertex Loaders: %i\n",stats.numVertexLoaders); std::string text1; diff --git a/Source/Core/VideoCommon/Src/Statistics.h b/Source/Core/VideoCommon/Src/Statistics.h index cb8a3afdc5..a7976651a5 100644 --- a/Source/Core/VideoCommon/Src/Statistics.h +++ b/Source/Core/VideoCommon/Src/Statistics.h @@ -60,6 +60,10 @@ struct Statistics int numBufferSplits; int numDListsCalled; + + int bytesVertexStreamed; + int bytesIndexStreamed; + int bytesUniformStreamed; }; ThisFrame thisFrame; void ResetFrame(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index bc5004d0c2..a2bdd360c2 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -345,6 +345,8 @@ ID3D11Buffer* &PixelShaderCache::GetConstantBuffer() memcpy(map.pData, psconstants, sizeof(psconstants)); D3D::context->Unmap(pscbuf, 0); pscbufchanged = false; + + ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(psconstants)); } return pscbuf; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 1f2a662b53..46161e25a5 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -128,6 +128,9 @@ void VertexManager::PrepareDrawBuffers() memcpy((u16*)map.pData + m_point_draw_index, GetPointIndexBuffer(), sizeof(u16) * IndexGenerator::GetPointindexLen()); D3D::context->Unmap(m_index_buffers[m_current_index_buffer], 0); m_index_buffer_cursor += iCount; + + ADDSTAT(stats.thisFrame.bytesVertexStreamed, vSize); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, iCount*sizeof(u16)); } static const float LINE_PT_TEX_OFFSETS[8] = { diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index ade8d7697c..267f7c9642 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -50,6 +50,8 @@ ID3D11Buffer* &VertexShaderCache::GetConstantBuffer() memcpy(map.pData, vsconstants, sizeof(vsconstants)); D3D::context->Unmap(vscbuf, 0); vscbufchanged = false; + + ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(vsconstants)); } return vscbuf; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 348f2d89a2..e0592b12e0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -197,6 +197,8 @@ void VertexManager::PrepareDrawBuffers(u32 stride) D3D::SetIndices(m_index_buffers[m_current_index_buffer]); } + ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); } void VertexManager::DrawVertexBuffer(int stride) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index 1c85177352..2df1f47760 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -171,6 +171,8 @@ void ProgramShaderCache::UploadConstants() glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset, s_ps_data_size); glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset + s_vs_data_offset, s_vs_data_size); s_ubo_dirty = false; + + ADDSTAT(stats.thisFrame.bytesUniformStreamed, s_ubo_buffer_size); } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 6e1590c1c6..59ea68504b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -104,6 +104,9 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { s_offset[2] = s_indexBuffer->Upload((u8*)GetPointIndexBuffer(), point_index_size * sizeof(u16)); } + + ADDSTAT(stats.thisFrame.bytesVertexStreamed, vertex_data_size); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, index_size); } void VertexManager::Draw(u32 stride) From 026ab26755487de4693b73f7079c164cd56cda2f Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Fri, 24 May 2013 19:04:06 -0400 Subject: [PATCH 118/352] Save settings to file when booting a game. Fixes issue 6310. --- Source/Core/Core/Src/BootManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index cf67b6f310..e4ce413926 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -60,6 +60,7 @@ bool BootCore(const std::string& _rFilename) StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO; StartUp.m_strFilename = _rFilename; SConfig::GetInstance().m_LastFilename = _rFilename; + SConfig::GetInstance().SaveSettings(); StartUp.bRunCompareClient = false; StartUp.bRunCompareServer = false; From 743230500f1bdd2bdf29787fb84feaff407faca5 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Sat, 25 May 2013 03:03:12 -0400 Subject: [PATCH 119/352] Add auto fullscreen resolution option. Not tested on Linux, let me know if it doesn't work (it probably does). Fixes issue 6082. --- Source/Core/DolphinWX/Src/FrameTools.cpp | 5 +++-- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index c6d542bf85..8607fdb110 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -798,7 +798,7 @@ void CFrame::OnRenderParentResize(wxSizeEvent& event) void CFrame::ToggleDisplayMode(bool bFullscreen) { #ifdef _WIN32 - if (bFullscreen) + if (bFullscreen && SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution != "Auto") { DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); @@ -817,7 +817,8 @@ void CFrame::ToggleDisplayMode(bool bFullscreen) ChangeDisplaySettings(NULL, CDS_FULLSCREEN); } #elif defined(HAVE_XRANDR) && HAVE_XRANDR - m_XRRConfig->ToggleDisplayMode(bFullscreen); + if (SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution != "Auto") + m_XRRConfig->ToggleDisplayMode(bFullscreen); #elif defined __APPLE__ if(bFullscreen) CGDisplayHideCursor(CGMainDisplayID()); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 8c4ee9ebb4..5a7d11f96e 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -131,6 +131,7 @@ wxString shader_errors_desc = wxTRANSLATE("Usually if shader compilation fails, wxArrayString GetListOfResolutions() { wxArrayString retlist; + retlist.Add("Auto"); #ifdef _WIN32 DWORD iModeNum = 0; DEVMODE dmi; From 3378f7d6a7a87e995c2fba7bf0b9822cef8be65e Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 25 May 2013 11:43:56 +0200 Subject: [PATCH 120/352] fix auto fullscreen resolution on linux --- Source/Core/DolphinWX/Src/X11Utils.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Core/DolphinWX/Src/X11Utils.cpp b/Source/Core/DolphinWX/Src/X11Utils.cpp index 6c4282cceb..9be4d23fbf 100644 --- a/Source/Core/DolphinWX/Src/X11Utils.cpp +++ b/Source/Core/DolphinWX/Src/X11Utils.cpp @@ -200,6 +200,9 @@ XRRConfiguration::~XRRConfiguration() void XRRConfiguration::Update() { + if(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution == "Auto") + return; + if (!bValid) return; From ca12e7ee8f05da66743abe0d9826a7d145e8b28e Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Sat, 25 May 2013 13:51:52 -0400 Subject: [PATCH 121/352] Make auto fullscreen resolution the default. --- Source/Core/Core/Src/ConfigManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 1eec9fd7b7..2d4f566485 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -334,7 +334,7 @@ void SConfig::LoadSettings() // Display ini.Get("Display", "Fullscreen", &m_LocalCoreStartupParameter.bFullscreen, false); - ini.Get("Display", "FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "640x480"); + ini.Get("Display", "FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "Auto"); ini.Get("Display", "RenderToMain", &m_LocalCoreStartupParameter.bRenderToMain, false); ini.Get("Display", "RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, -1); ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, -1); From 61aa272bfb71ace8823a86ad08813f644db7cad2 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 25 May 2013 22:17:05 -0500 Subject: [PATCH 122/352] [Android] Qualcomm drivers require that the EGL context is created on the same thread that the OpenGL commands are run on. Crappy driver limitation since eglMakeCurrent should work to let it be on a different thread. --- .../Plugin_VideoSoftware/Src/SWmain.cpp | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 82aa72ab2e..c63ad2e446 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -39,7 +39,7 @@ namespace SW static volatile bool fifoStateRun = false; static volatile bool emuRunningState = false; static std::mutex m_csSWVidOccupied; - +static void* m_windowhandle; std::string VideoSoftware::GetName() { @@ -62,15 +62,9 @@ void VideoSoftware::ShowConfig(void *_hParent) bool VideoSoftware::Initialize(void *&window_handle) { g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_software.ini").c_str()); - InitInterface(); - - if (!GLInterface->Create(window_handle)) - { - INFO_LOG(VIDEO, "%s", "SWRenderer::Create failed\n"); - return false; - } - // Do our OSD callbacks - OSD::DoCallbacks(OSD::OSD_INIT); + InitInterface(); + + m_windowhandle = window_handle; InitBPMemory(); InitXFMemory(); @@ -166,6 +160,12 @@ void VideoSoftware::Video_Cleanup() // This is called after Video_Initialize() from the Core void VideoSoftware::Video_Prepare() { + if (!GLInterface->Create(m_windowhandle)) + { + INFO_LOG(VIDEO, "%s", "SWRenderer::Create failed\n"); + return; + } + GLInterface->MakeCurrent(); // Init extension support. #ifndef USE_GLES @@ -180,6 +180,9 @@ void VideoSoftware::Video_Prepare() // Handle VSync on/off GLInterface->SwapInterval(VSYNC_ENABLED); + // Do our OSD callbacks + OSD::DoCallbacks(OSD::OSD_INIT); + HwRasterizer::Prepare(); SWRenderer::Prepare(); From 92bea77e56cfdcd9b7304719379a0ee4b67e57c3 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 25 May 2013 22:20:10 -0500 Subject: [PATCH 123/352] [Android] Disable OpenGL in the settings menu since it doesn't work yet. Change some theme settings so the back button shows up on screen where needed. --- Source/Android/.idea/workspace.xml | 422 +++++++++--------- Source/Android/AndroidManifest.xml | 7 +- Source/Android/res/values/prefvalues.xml | 2 +- .../dolphinemu/DolphinEmulator.java | 2 +- 4 files changed, 211 insertions(+), 222 deletions(-) diff --git a/Source/Android/.idea/workspace.xml b/Source/Android/.idea/workspace.xml index b6b28566ce..fa89dca9a9 100644 --- a/Source/Android/.idea/workspace.xml +++ b/Source/Android/.idea/workspace.xml @@ -13,6 +13,20 @@ android-17 + + + + Nexus 4 + @android:style/Theme.Holo + + + + + Nexus 4 + @android:style/Theme.Holo + + + @@ -27,7 +41,7 @@ - + @@ -35,6 +49,10 @@ + + + + + - @@ -103,19 +121,26 @@ - + - + + + + + + + + + + - - - - + + @@ -124,22 +149,40 @@ - - - + + + + - + - - + + + + + + + + + + + + + + + + + + + @@ -167,16 +210,16 @@ @@ -188,6 +231,22 @@