Merge branch 'master' of https://code.google.com/p/dolphin-emu into dx9-ssaa-fix

This commit is contained in:
Rodolfo Bogado 2013-08-12 21:32:25 -03:00
commit 9e0fc8b42d
12 changed files with 166 additions and 195 deletions

View File

@ -37,10 +37,9 @@ public class AboutFragment extends Fragment {
mMainList = (ListView) rootView.findViewById(R.id.gamelist);
List<GameListItem> Input = new ArrayList<GameListItem>();
int a = 0;
Input.add(new GameListItem(m_activity, "Build Revision", NativeLibrary.GetVersionString(), "", true));
Input.add(new GameListItem(m_activity, "Supports OpenGL ES 3", PrefsFragment.SupportsGLES3() ? "Yes" : "No", "", true));
Input.add(a++, new GameListItem(m_activity, "Build Revision", NativeLibrary.GetVersionString(), "", true));
Input.add(a++, new GameListItem(m_activity, "Supports OpenGL ES 3", PrefsFragment.SupportsGLES3() ? "Yes" : "No", "", true));
adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, Input);
mMainList.setAdapter(adapter);

View File

@ -47,29 +47,27 @@ public class InputConfigFragment extends Fragment
Bundle savedInstanceState)
{
List<InputConfigItem> Input = new ArrayList<InputConfigItem>();
int a = 0;
Input.add(a++, new InputConfigItem("Draw on-screen controls", "Android-ScreenControls", "True"));
Input.add(a++, new InputConfigItem("Button A", "Android-InputA"));
Input.add(a++, new InputConfigItem("Button B", "Android-InputB"));
Input.add(a++, new InputConfigItem("Button Start", "Android-InputStart"));
Input.add(a++, new InputConfigItem("Button X", "Android-InputX"));
Input.add(a++, new InputConfigItem("Button Y", "Android-InputY"));
Input.add(a++, new InputConfigItem("Button Z", "Android-InputZ"));
Input.add(a++, new InputConfigItem("D-Pad Up", "Android-DPadUp"));
Input.add(a++, new InputConfigItem("D-Pad Down", "Android-DPadDown"));
Input.add(a++, new InputConfigItem("D-Pad Left", "Android-DPadLeft"));
Input.add(a++, new InputConfigItem("D-Pad Right", "Android-DPadRight"));
Input.add(a++, new InputConfigItem("Main Stick Up", "Android-MainUp"));
Input.add(a++, new InputConfigItem("Main Stick Down", "Android-MainDown"));
Input.add(a++, new InputConfigItem("Main Stick Left", "Android-MainLeft"));
Input.add(a++, new InputConfigItem("Main Stick Right", "Android-MainRight"));
Input.add(a++, new InputConfigItem("C Stick Up", "Android-CStickUp"));
Input.add(a++, new InputConfigItem("C Stick Down", "Android-CStickDown"));
Input.add(a++, new InputConfigItem("C Stick Left", "Android-CStickLeft"));
Input.add(a++, new InputConfigItem("C Stick Right", "Android-CStickRight"));
Input.add(a++, new InputConfigItem("Trigger L", "Android-InputL"));
Input.add(a++, new InputConfigItem("Trigger R", "Android-InputR"));
Input.add(new InputConfigItem("Draw on-screen controls", "Android-ScreenControls", "True"));
Input.add(new InputConfigItem("Button A", "Android-InputA"));
Input.add(new InputConfigItem("Button B", "Android-InputB"));
Input.add(new InputConfigItem("Button Start", "Android-InputStart"));
Input.add(new InputConfigItem("Button X", "Android-InputX"));
Input.add(new InputConfigItem("Button Y", "Android-InputY"));
Input.add(new InputConfigItem("Button Z", "Android-InputZ"));
Input.add(new InputConfigItem("D-Pad Up", "Android-DPadUp"));
Input.add(new InputConfigItem("D-Pad Down", "Android-DPadDown"));
Input.add(new InputConfigItem("D-Pad Left", "Android-DPadLeft"));
Input.add(new InputConfigItem("D-Pad Right", "Android-DPadRight"));
Input.add(new InputConfigItem("Main Stick Up", "Android-MainUp"));
Input.add(new InputConfigItem("Main Stick Down", "Android-MainDown"));
Input.add(new InputConfigItem("Main Stick Left", "Android-MainLeft"));
Input.add(new InputConfigItem("Main Stick Right", "Android-MainRight"));
Input.add(new InputConfigItem("C Stick Up", "Android-CStickUp"));
Input.add(new InputConfigItem("C Stick Down", "Android-CStickDown"));
Input.add(new InputConfigItem("C Stick Left", "Android-CStickLeft"));
Input.add(new InputConfigItem("C Stick Right", "Android-CStickRight"));
Input.add(new InputConfigItem("Trigger L", "Android-InputL"));
Input.add(new InputConfigItem("Trigger R", "Android-InputR"));
adapter = new InputConfigAdapter(m_activity, R.layout.folderbrowser, Input);
View rootView = inflater.inflate(R.layout.gamelist_listview, container, false);

View File

@ -1,5 +1,7 @@
package org.dolphinemu.dolphinemu;
import java.util.HashMap;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
@ -138,36 +140,28 @@ public class PrefsFragment extends PreferenceFragment {
addPreferencesFromResource(R.layout.prefs);
final ListPreference etp = new ListPreference(m_activity);
CharSequence[] _entries;
CharSequence[] _entryvalues;
final HashMap<CharSequence, CharSequence> entries = new HashMap<CharSequence, CharSequence>();
if (Build.CPU_ABI.contains("x86"))
{
_entries = new CharSequence[] {
"Interpreter",
"JIT64 Recompiler",
"JITIL Recompiler",
};
_entryvalues = new CharSequence[] {"0", "1", "2"};
entries.put("Interpreter", "0");
entries.put("JIT64 Recompiler", "1");
entries.put("JITIL Recompiler", "2");
}
else if (Build.CPU_ABI.contains("arm"))
{
_entries = new CharSequence[] {
"Interpreter",
"JIT ARM Recompiler",
};
_entryvalues = new CharSequence[] {"0", "3"};
entries.put("Interpreter", "0");
entries.put("JIT ARM Recompiler", "3");
}
else
{
_entries = new CharSequence[] {
"Interpreter",
};
_entryvalues = new CharSequence[] {"0"};
entries.put("Interpreter", "0");
}
etp.setEntries(_entries);
etp.setEntryValues(_entryvalues);
// Convert the key/value sections to arrays respectively so the list can be set.
// If Java had proper generics it wouldn't look this disgusting.
etp.setEntries(entries.keySet().toArray(new CharSequence[entries.size()]));
etp.setEntryValues(entries.values().toArray(new CharSequence[entries.size()]));
etp.setKey("cpupref");
etp.setTitle("CPU Core");
etp.setSummary("Emulation core to use");
@ -185,17 +179,16 @@ public class PrefsFragment extends PreferenceFragment {
final ListPreference videobackend = new ListPreference(m_activity);
_entries = new CharSequence[] {
"Software Renderer",
};
_entryvalues = new CharSequence[] {"Software Renderer"};
// Add available graphics renderers to the hashmap to add to the list.
entries.clear();
entries.put("Software Renderer", "Software Renderer"); // TODO: I think this is a bug? The value shouldn't be the same as the key?
videobackend.setKey("gpupref");
videobackend.setTitle("Video Backend");
videobackend.setSummary("Video backend to use");
videobackend.setEntries(_entries);
videobackend.setEntryValues(_entryvalues);
videobackend.setEntries(entries.keySet().toArray(new CharSequence[entries.size()]));
videobackend.setEntryValues(entries.values().toArray(new CharSequence[entries.size()]));
mCategory.addPreference(videobackend);
}

View File

@ -299,38 +299,3 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
#undef SetRegName
}
}
AlphaTest::TEST_RESULT AlphaTest::TestResult()
{
switch(logic)
{
case 0: // AND
if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 1: // OR
if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 2: // XOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return PASS;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return FAIL;
break;
case 3: // XNOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return FAIL;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return PASS;
break;
}
return UNDETERMINED;
}

View File

@ -885,7 +885,40 @@ union AlphaTest
PASS = 2,
};
TEST_RESULT TestResult();
inline TEST_RESULT TestResult() const
{
switch(logic)
{
case 0: // AND
if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 1: // OR
if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 2: // XOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return PASS;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return FAIL;
break;
case 3: // XNOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return FAIL;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return PASS;
break;
}
return UNDETERMINED;
}
};
union UPE_Copy

View File

@ -9,40 +9,22 @@
#include "NativeVertexFormat.h"
#include "XFMemory.h"
static const char* LightCol(const char* lightsName, unsigned int index, const char* 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[32];
snprintf(result, sizeof(result), "%s[5*%d+1]", lightsName, index);
return result;
}
#define LIGHT_COL "%s[5*%d].%s"
#define LIGHT_COL_PARAMS(lightsName, index, swizzle) (lightsName), (index), (swizzle)
static const char* LightDistAtt(const char* lightsName, unsigned int index)
{
static char result[32];
snprintf(result, sizeof(result), "%s[5*%d+2]", lightsName, index);
return result;
}
#define LIGHT_COSATT "%s[5*%d+1]"
#define LIGHT_COSATT_PARAMS(lightsName, index) (lightsName), (index)
static const char* LightPos(const char* lightsName, unsigned int index)
{
static char result[32];
snprintf(result, sizeof(result), "%s[5*%d+3]", lightsName, index);
return result;
}
#define LIGHT_DISTATT "%s[5*%d+2]"
#define LIGHT_DISTATT_PARAMS(lightsName, index) (lightsName), (index)
#define LIGHT_POS "%s[5*%d+3]"
#define LIGHT_POS_PARAMS(lightsName, index) (lightsName), (index)
#define LIGHT_DIR "%s[5*%d+4]"
#define LIGHT_DIR_PARAMS(lightsName, index) (lightsName), (index)
static const char* LightDir(const char* lightsName, unsigned int index)
{
static char result[32];
snprintf(result, sizeof(result), "%s[5*%d+4]", lightsName, index);
return result;
}
template<class T>
static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha)
@ -62,13 +44,13 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
object.Write("lacc.%s += %s;\n", swizzle, LightCol(lightsName, index, swizzle));
object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle));
break;
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
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));
object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index));
object.Write("lacc.%s += %sdot(ldir, _norm0)) * " LIGHT_COL";\n",
swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", LIGHT_COL_PARAMS(lightsName, index, swizzle));
break;
default: _assert_(0);
}
@ -77,31 +59,34 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
{
if (chan.attnfunc == 3)
{ // spot
object.Write("ldir = %s.xyz - pos.xyz;\n", LightPos(lightsName, index));
object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(lightsName, index));
object.Write("dist2 = dot(ldir, ldir);\n"
"dist = sqrt(dist2);\n"
"ldir = ldir / dist;\n"
"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));
"attn = max(0.0f, dot(ldir, " LIGHT_DIR".xyz));\n",
LIGHT_DIR_PARAMS(lightsName, index));
object.Write("attn = max(0.0f, dot(" LIGHT_COSATT".xyz, float3(1.0f, attn, attn*attn))) / dot(" LIGHT_DISTATT".xyz, float3(1.0f,dist,dist2));\n",
LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index));
}
else if (chan.attnfunc == 1)
{ // specular
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));
object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(lightsName, index));
object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0f;\n", LIGHT_DIR_PARAMS(lightsName, index));
object.Write("attn = max(0.0f, dot(" LIGHT_COSATT".xyz, float3(1,attn,attn*attn))) / dot(" LIGHT_DISTATT".xyz, float3(1,attn,attn*attn));\n",
LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index));
}
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
object.Write("lacc.%s += attn * %s;\n", swizzle, LightCol(lightsName, index, swizzle));
object.Write("lacc.%s += attn * " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle));
break;
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s;\n",
object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * " LIGHT_COL";\n",
swizzle,
chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(",
LightCol(lightsName, index, swizzle));
LIGHT_COL_PARAMS(lightsName, index, swizzle));
break;
default: _assert_(0);
}

View File

@ -216,7 +216,7 @@ static char swapModeTable[4][5];
static char text[16384];
static void BuildSwapModeTable()
static inline void BuildSwapModeTable()
{
static const char *swapColors = "rgba";
for (int i = 0; i < 4; i++)
@ -229,13 +229,13 @@ static void BuildSwapModeTable()
}
}
template<class T> static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]);
template<class T> static void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
template<class T> static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
template<class T> static void WriteFog(T& out, pixel_shader_uid_data& uid_data);
template<class T> static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]);
template<class T> static inline void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
template<class T> static inline void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
template<class T> static inline void WriteFog(T& out, pixel_shader_uid_data& uid_data);
template<class T>
static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)
static inline 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;
@ -243,17 +243,19 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
? out.template GetUidData<pixel_shader_uid_data>() : dummy_data;
out.SetBuffer(text);
const bool is_writing_shadercode = (out.GetBuffer() != NULL);
#ifndef ANDROID
locale_t locale;
locale_t old_locale;
if (out.GetBuffer() != NULL)
if (is_writing_shadercode)
{
locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
old_locale = uselocale(locale); // Apply the locale for this thread
}
#endif
text[sizeof(text) - 1] = 0x7C; // canary
if (is_writing_shadercode)
text[sizeof(text) - 1] = 0x7C; // canary
unsigned int numStages = bpmem.genMode.numtevstages + 1;
unsigned int numTexgen = bpmem.genMode.numtexgens;
@ -331,7 +333,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
out.Write("VARYIN float4 colors_02;\n");
out.Write("VARYIN float4 colors_12;\n");
// compute window position if needed because binding semantic WPOS is not widely supported
// Let's set up attributes
if (xfregs.numTexGen.numTexGens < 7)
@ -372,7 +374,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
// It just allows it, but it seems that all drivers do.
out.Write("layout(early_fragment_tests) in;\n");
}
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) && is_writing_shadercode)
{
static bool warn_once = true;
if (warn_once)
@ -388,7 +390,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
{
out.Write("[earlydepthstencil]\n");
}
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) && is_writing_shadercode)
{
static bool warn_once = true;
if (warn_once)
@ -500,7 +502,6 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
uid_data.xfregs_numTexGen_numTexGens = xfregs.numTexGen.numTexGens;
if (xfregs.numTexGen.numTexGens < 7)
{
out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n");
@ -706,16 +707,16 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
out.Write("}\n");
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
if (is_writing_shadercode)
{
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
#ifndef ANDROID
if (out.GetBuffer() != NULL)
{
uselocale(old_locale); // restore locale
freelocale(locale);
}
#endif
}
}
@ -763,7 +764,7 @@ static const char *TEVCMPAlphaOPTable[16] =
};
template<class T>
static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4])
static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4])
{
int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1);
bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens;
@ -906,7 +907,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap];
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
uid_data.SetTevindrefTexmap(i, texmap);
out.Write("textemp = ");
SampleTexture<T>(out, "tevcoord", texswap, texmap, ApiType);
}
@ -1133,7 +1134,7 @@ template<class T>
void SampleTexture(T& out, 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("Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", texmap,texmap, texcoords, texmap, texswap);
else
@ -1161,7 +1162,7 @@ static const char *tevAlphaFunclogicTable[] =
};
template<class T>
static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth)
static inline 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] =
{
@ -1232,7 +1233,7 @@ static const char *tevFogFuncsTable[] =
};
template<class T>
static void WriteFog(T& out, pixel_shader_uid_data& uid_data)
static inline void WriteFog(T& out, pixel_shader_uid_data& uid_data)
{
uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel;
if(bpmem.fog.c_proj_fsel.fsel == 0)
@ -1274,7 +1275,7 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data)
}
else
{
if (bpmem.fog.c_proj_fsel.fsel != 2)
if (bpmem.fog.c_proj_fsel.fsel != 2 && out.GetBuffer() != NULL)
WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel);
}

View File

@ -63,18 +63,30 @@ struct pixel_shader_uid_data
u32 num_values; // TODO: Shouldn't be a u32
u32 NumValues() const { return num_values; }
u32 components;
u32 components : 23;
u32 dstAlphaMode : 2;
u32 Pretest : 2;
u32 nIndirectStagesUsed : 4;
u32 pad0 : 1;
u32 genMode_numtexgens : 4;
u32 genMode_numtevstages : 4;
u32 genMode_numindstages : 3;
u32 nIndirectStagesUsed : 8;
u32 alpha_test_comp0 : 3;
u32 alpha_test_comp1 : 3;
u32 alpha_test_logic : 2;
u32 alpha_test_use_zcomploc_hack : 1;
u32 fog_proj : 1;
u32 fog_fsel : 3;
u32 fog_RangeBaseEnabled : 1;
u32 ztex_op : 2;
u32 fast_depth_calc : 1;
u32 per_pixel_depth : 1;
u32 forced_early_z : 1;
u32 early_ztest : 1;
u32 pad1 : 1;
u32 texMtxInfo_n_projection : 8; // 8x1 bit
u32 tevindref_bi0 : 3;
u32 tevindref_bc0 : 3;
u32 tevindref_bi1 : 3;
@ -83,6 +95,7 @@ struct pixel_shader_uid_data
u32 tevindref_bc3 : 3;
u32 tevindref_bi4 : 3;
u32 tevindref_bc4 : 3;
inline void SetTevindrefValues(int index, u32 texcoord, u32 texmap)
{
if (index == 0) { tevindref_bc0 = texcoord; tevindref_bi0 = texmap; }
@ -98,25 +111,6 @@ struct pixel_shader_uid_data
else if (index == 3) { tevindref_bi4 = texmap; }
}
u32 alpha_test_comp0 : 3;
u32 alpha_test_comp1 : 3;
u32 alpha_test_logic : 2;
u32 alpha_test_use_zcomploc_hack : 1;
u32 fog_proj : 1;
u32 fog_fsel : 3;
u32 fog_RangeBaseEnabled : 1;
u32 ztex_op : 2;
u32 fast_depth_calc : 1;
u32 per_pixel_depth : 1;
u32 forced_early_z : 1;
u32 early_ztest : 1;
u32 xfregs_numTexGen_numTexGens : 4;
struct {
// TODO: Can save a lot space by removing the padding bits
u32 cc : 24;

View File

@ -173,7 +173,7 @@ private:
};
template<class T>
static void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const u32 num)
static inline void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const u32 num)
{
if (ApiType == API_OPENGL)
return; // Nothing to do here
@ -182,7 +182,7 @@ static void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const
}
template<class T>
static void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos)
static inline void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos)
{
if (using_ubos)
return;
@ -191,7 +191,7 @@ static void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos)
}
template<class T>
static void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const u32 num, const char* type, const char* name)
static inline 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);

View File

@ -38,7 +38,7 @@ static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char*
}
template<class T>
static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type)
static inline void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type)
{
object.Write("struct VS_OUTPUT {\n");
DefineVSOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION");
@ -67,7 +67,7 @@ static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type)
}
template<class T>
static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
static inline 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;
@ -75,16 +75,19 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
? out.template GetUidData<vertex_shader_uid_data>() : dummy_data;
out.SetBuffer(text);
const bool is_writing_shadercode = (out.GetBuffer() != NULL);
#ifndef ANDROID
locale_t locale;
locale_t old_locale;
if (out.GetBuffer() != NULL)
if (is_writing_shadercode)
{
locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
old_locale = uselocale(locale); // Apply the locale for this thread
}
#endif
text[sizeof(text) - 1] = 0x7C; // canary
if (is_writing_shadercode)
text[sizeof(text) - 1] = 0x7C; // canary
_assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans);
@ -225,7 +228,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
out.Write("int posmtx = int(fposmtx);\n");
}
if (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS))
if (is_writing_shadercode && DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS))
{
// This'll cause issues, but it can't be helped
out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[0], rawpos), dot(" I_TRANSFORMMATRICES"[1], rawpos), dot(" I_TRANSFORMMATRICES"[2], rawpos), 1);\n");
@ -353,7 +356,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(%s.xyz - pos.xyz);\n", LightPos(I_LIGHTS, texinfo.embosslightshift));
out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(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
@ -547,16 +550,16 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
out.Write("return o;\n}\n");
}
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
if (is_writing_shadercode)
{
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
#ifndef ANDROID
if (out.GetBuffer() != NULL)
{
uselocale(old_locale); // restore locale
freelocale(locale);
}
#endif
}
}
void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type)

View File

@ -69,12 +69,12 @@ struct vertex_shader_uid_data
{
u32 NumValues() const { return sizeof(vertex_shader_uid_data); }
u32 components;
u32 numColorChans : 2;
u32 components : 23;
u32 numTexGens : 4;
u32 numColorChans : 2;
u32 dualTexTrans_enabled : 1;
u32 pixel_lighting : 1;
u32 pad0 : 1;
u32 texMtxInfo_n_projection : 16; // Stored separately to guarantee that the texMtxInfo struct is 8 bits wide
struct {

View File

@ -51,7 +51,7 @@ VideoConfigDialog::VideoConfigDialog(wxWindow* parent, const std::string& title,
it = g_available_video_backends.begin(),
itend = g_available_video_backends.end();
for (; it != itend; ++it)
choice_backend->AppendString(StrToWxStr((*it)->GetName()));
choice_backend->AppendString(StrToWxStr((*it)->GetDisplayName()));
// TODO: How to get the translated plugin name?
choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName()));