summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.cpp178
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.h13
-rw-r--r--Source/Core/VideoCommon/Src/VertexShaderGen.cpp189
-rw-r--r--Source/Core/VideoCommon/Src/VertexShaderGen.h11
-rw-r--r--Source/Core/VideoCommon/Src/VideoCommon.h6
-rw-r--r--Source/Core/VideoCommon/Src/VideoConfig.cpp4
-rw-r--r--Source/Core/VideoCommon/Src/VideoConfig.h2
7 files changed, 292 insertions, 111 deletions
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
index 1726855d54..4cdf562182 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
@@ -500,6 +500,15 @@ static void BuildSwapModeTable()
}
}
+const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num)
+{
+ if(ApiType == API_GLSL)
+ return ""; // Nothing to do here
+ static char result[64];
+ sprintf(result, " : register(%s%d)", prefix, num);
+ return result;
+}
+
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)
{
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
@@ -524,6 +533,21 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}
}
DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth ;
+
+ if(ApiType == API_GLSL)
+ {
+ // A few required defines and ones that will make our lives a lot easier
+ WRITE(p, "#version 120\n");
+ // Silly differences
+ WRITE(p, "#define float2 vec2\n");
+ WRITE(p, "#define float3 vec3\n");
+ WRITE(p, "#define float4 vec4\n");
+
+ // cg to glsl function translation
+ WRITE(p, "#define frac(x) fract(x)\n");
+ WRITE(p, "#define saturate(x) clamp(x, 0.0f, 1.0f)\n");
+ WRITE(p, "#define lerp(x, y, z) mix(x, y, z)\n");
+ }
// Declare samplers
if(ApiType != API_D3D11)
@@ -538,7 +562,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
bool bfirst = true;
for (int i = 0; i < 8; ++i)
{
- WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i);
+ WRITE(p, "%s samp%d %s", bfirst?"":",", i, WriteRegister(ApiType, "s", i));
bfirst = false;
}
WRITE(p, ";\n");
@@ -555,67 +579,107 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}
WRITE(p, "\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);
+
+ WRITE(p, "uniform float4 "I_COLORS"[4] %s;\n", WriteRegister(ApiType, "c", C_COLORS));
+ WRITE(p, "uniform float4 "I_KCOLORS"[4] %s;\n", WriteRegister(ApiType, "c", C_KCOLORS));
+ WRITE(p, "uniform float4 "I_ALPHA"[1] %s;\n", WriteRegister(ApiType, "c", C_ALPHA));
+ WRITE(p, "uniform float4 "I_TEXDIMS"[8] %s;\n", WriteRegister(ApiType, "c", C_TEXDIMS));
+ WRITE(p, "uniform float4 "I_ZBIAS"[2] %s;\n", WriteRegister(ApiType, "c", C_ZBIAS));
+ WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] %s;\n", WriteRegister(ApiType, "c", C_INDTEXSCALE));
+ WRITE(p, "uniform float4 "I_INDTEXMTX"[6] %s;\n", WriteRegister(ApiType, "c", C_INDTEXMTX));
+ WRITE(p, "uniform float4 "I_FOG"[3] %s;\n", WriteRegister(ApiType, "c", 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);
+ WRITE(p, "uniform float4 "I_PLIGHTS"[40] %s;\n", WriteRegister(ApiType, "c", C_PLIGHTS));
+ WRITE(p, "uniform float4 "I_PMATERIALS"[4] %s;\n", WriteRegister(ApiType, "c", C_PMATERIALS));
}
- WRITE(p, "void main(\n");
- if(ApiType != API_D3D11)
- {
- WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
- dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
- DepthTextureEnable ? "\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",
- dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "",
- DepthTextureEnable ? "\n out float depth : SV_Depth," : "");
- }
+ if(ApiType != API_GLSL)
+ {
+ WRITE(p, "void main(\n");
+ if(ApiType != API_D3D11)
+ {
+ WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
+ dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
+ DepthTextureEnable ? "\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",
+ dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "",
+ DepthTextureEnable ? "\n out float depth : SV_Depth," : "");
+ }
- WRITE(p, " in float4 colors_0 : COLOR0,\n");
- WRITE(p, " in float4 colors_1 : COLOR1");
+ WRITE(p, " in float4 colors_0 : COLOR0,\n");
+ WRITE(p, " 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);
- if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
- WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1);
+ // 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);
+ if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
+ WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1);
+ }
+ else
+ {
+ // wpos 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, ",\n in float4 uv%d : TEXCOORD%d", i, i);
+ }
+ else
+ {
+ 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);
+ }
+ }
+ WRITE(p, " ) {\n");
}
else
{
- // wpos is in w of first 4 texcoords
- if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
+ // GLSL doesn't do main arguments
+ // Once we switch to GLSL 1.3 we will bind a lot of these.
+
+ WRITE(p, " float4 ocol0;\n");
+ if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
+ WRITE(p, " float4 ocol1;\n"); // Will be supported later
+ if(DepthTextureEnable)
+ WRITE(p, " float depth;\n"); // TODO: Passed to Vertex Shader right?
+ WRITE(p, " float4 rawpos = gl_FragCoord;\n");
+
+ WRITE(p, " float4 colors_0 = gl_Color;\n");
+ WRITE(p, " float4 colors_1 = gl_SecondaryColor;\n");
+
+ // compute window position if needed because binding semantic WPOS is not widely supported
+ if (numTexgen < 7)
{
- for (int i = 0; i < 8; ++i)
- WRITE(p, ",\n in float4 uv%d : TEXCOORD%d", i, i);
+ for (int i = 0; i < numTexgen; ++i)
+ WRITE(p, " float3 uv%d = gl_TexCoord[%d].xyz;\n", i, i);
+ WRITE(p, " float4 clipPos = gl_TexCoord[%d];\n", numTexgen);
+ if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
+ WRITE(p, " float4 Normal = gl_TexCoord[%d];\n", numTexgen + 1);
}
else
{
- 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);
+ // wpos 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 uv%d = gl_TexCoord[%d];\n", i, i);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
+ WRITE(p, " float%d uv%d = gl_TexCoord[%d]%s;\n", i < 4 ? 4 : 3 , i, i, i < 4 ? ".xyz" : "");
+ }
}
+ WRITE(p, "void main()\n{\n");
}
- WRITE(p, " ) {\n");
char* pmainstart = p;
int Pretest = AlphaPreTest();
@@ -624,8 +688,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if (!Pretest)
{
// alpha test will always fail, so restart the shader and just make it an empty function
- WRITE(p, "ocol0 = 0;\n");
+ WRITE(p, "ocol0 = float4(0);\n");
WRITE(p, "discard;\n");
+ if(ApiType == API_GLSL)
+ WRITE(p, "gl_FragData[0] = ocol0;\n");
if(ApiType != API_D3D11)
WRITE(p, "return;\n");
}
@@ -733,6 +799,15 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "depth = 1.f;\n");
if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "ocol1 = 0;\n");
+ if(ApiType == API_GLSL)
+ {
+ // Once we switch to GLSL 1.3 and bind variables, we won't need to do this
+ WRITE(p, "gl_FragData[0] = ocol0;\n");
+ if(DepthTextureEnable)
+ WRITE(p, "gl_FragDepth = depth;\n");
+ if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
+ ; // TODO: Will do this later
+ }
WRITE(p, "discard;\n");
if(ApiType != API_D3D11)
WRITE(p, "return;\n");
@@ -781,6 +856,13 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
// ...and the alpha from ocol0 will be written to the framebuffer.
WRITE(p, " ocol0.a = "I_ALPHA"[0].a;\n");
}
+
+ if(ApiType == API_GLSL)
+ {
+ if(DepthTextureEnable)
+ WRITE(p, "gl_FragDepth = depth;\n");
+ WRITE(p, "gl_FragData[0] = ocol0;\n");
+ }
}
WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C)
@@ -1242,4 +1324,4 @@ static void WriteFog(char *&p)
WRITE(p, " prev.rgb = lerp(prev.rgb,"I_FOG"[0].rgb,fog);\n");
-} \ No newline at end of file
+}
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h
index 31242a916e..589fc927bc 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.h
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h
@@ -47,6 +47,19 @@
#define PIXELSHADERUID_MAX_VALUES 70
#define PIXELSHADERUID_MAX_VALUES_SAFE 120
+// Annoying sure, can be removed once we get up to GLSL ~1.3
+const s_svar PSVar_Loc[] = { {I_COLORS, C_COLORS, 4 },
+ {I_KCOLORS, C_KCOLORS, 4 },
+ {I_ALPHA, C_ALPHA, 1 },
+ {I_TEXDIMS, C_TEXDIMS, 8 },
+ {I_ZBIAS , C_ZBIAS, 2 },
+ {I_INDTEXSCALE , C_INDTEXSCALE, 2 },
+ {I_INDTEXMTX, C_INDTEXMTX, 6 },
+ {I_FOG, C_FOG, 3 },
+ {I_PLIGHTS, C_PLIGHTS, 40 },
+ {I_PMATERIALS, C_PMATERIALS, 4 },
+ };
+
// DO NOT make anything in this class virtual.
template<bool safe>
class _PIXELSHADERUID
diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
index 5076f9f044..fcdc0e8976 100644
--- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
@@ -130,7 +130,7 @@ static char text[16384];
#define WRITE p+=sprintf
-char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type)
+char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE ApiType)
{
WRITE(p, "struct VS_OUTPUT {\n");
WRITE(p, " float4 pos : POSITION;\n");
@@ -161,7 +161,10 @@ char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type)
return p;
}
-const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
+extern const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num);
+
+
+const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
{
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
text[sizeof(text) - 1] = 0x7C; // canary
@@ -169,7 +172,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
_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);
+ bool is_d3d = (ApiType & API_D3D9 || ApiType == API_D3D11);
u32 lightMask = 0;
if (xfregs.numChan.numColorChans > 0)
lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask();
@@ -178,78 +181,109 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
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"
- );
-
- p = GenerateVSOutputStruct(p, 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);
-
- WRITE(p, "VS_OUTPUT main(\n");
- // inputs
- if (components & VB_HAS_NRM0)
- WRITE(p, " float3 rawnorm0 : NORMAL0,\n");
- if (components & VB_HAS_NRM1) {
- if (is_d3d)
- WRITE(p, " float3 rawnorm1 : NORMAL1,\n");
- else
- WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB);
- }
- if (components & VB_HAS_NRM2) {
- if (is_d3d)
- WRITE(p, " float3 rawnorm2 : NORMAL2,\n");
- else
- WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB);
+ if(ApiType == API_GLSL)
+ {
+ // A few required defines and ones that will make our lives a lot easier
+ WRITE(p, "#version 120\n");
+ // Silly differences
+ WRITE(p, "#define float2 vec2\n");
+ WRITE(p, "#define float3 vec3\n");
+ WRITE(p, "#define float4 vec4\n");
+
+ // cg to glsl function translation
+ WRITE(p, "#define frac(x) fract(x)\n");
+ WRITE(p, "#define saturate(x) clamp(x, 0.0f, 1.0f)\n");
+ WRITE(p, "#define lerp(x, y, z) mix(x, y, z)\n");
}
- if (components & VB_HAS_COL0)
- WRITE(p, " float4 color0 : COLOR0,\n");
- if (components & VB_HAS_COL1)
- WRITE(p, " float4 color1 : COLOR1,\n");
- for (int i = 0; i < 8; ++i) {
- u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
- if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
- WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i);
+ // uniforms
+ WRITE(p, "uniform float4 "I_TRANSFORMMATRICES"[64] %s;\n", WriteRegister(ApiType, "c", C_TRANSFORMMATRICES));
+ WRITE(p, "uniform float4 "I_TEXMATRICES"[24] %s;\n", WriteRegister(ApiType, "c", C_TEXMATRICES)); // also using tex matrices
+ WRITE(p, "uniform float4 "I_NORMALMATRICES"[32] %s;\n", WriteRegister(ApiType, "c", C_NORMALMATRICES));
+ WRITE(p, "uniform float4 "I_POSNORMALMATRIX"[6] %s;\n", WriteRegister(ApiType, "c", C_POSNORMALMATRIX));
+ WRITE(p, "uniform float4 "I_POSTTRANSFORMMATRICES"[64] %s;\n", WriteRegister(ApiType, "c", C_POSTTRANSFORMMATRICES));
+ WRITE(p, "uniform float4 "I_LIGHTS"[40] %s;\n", WriteRegister(ApiType, "c", C_LIGHTS));
+ WRITE(p, "uniform float4 "I_MATERIALS"[4] %s;\n", WriteRegister(ApiType, "c", C_MATERIALS));
+ WRITE(p, "uniform float4 "I_PROJECTION"[4] %s;\n", WriteRegister(ApiType, "c", C_PROJECTION));
+ WRITE(p, "uniform float4 "I_DEPTHPARAMS" %s;\n", WriteRegister(ApiType, "c", C_DEPTHPARAMS));
+
+ p = GenerateVSOutputStruct(p, components, ApiType);
+
+ if(ApiType == API_GLSL)
+ {
+ if (components & VB_HAS_NRM0)
+ WRITE(p, " float3 rawnorm0 = gl_Normal; // NORMAL0,\n");
+
+ if (components & VB_HAS_POSMTXIDX)
+ WRITE(p, "attribute float fposmtx; // ATTR%d,\n", SHADER_POSMTX_ATTRIB);
+ if (components & VB_HAS_NRM1)
+ WRITE(p, "attribute float3 rawnorm1; // ATTR%d,\n", SHADER_NORM1_ATTRIB);
+ if (components & VB_HAS_NRM2)
+ WRITE(p, "attribute float3 rawnorm2; // ATTR%d,\n", SHADER_NORM2_ATTRIB);
+
+ if (components & VB_HAS_COL0)
+ WRITE(p, " float4 color0 = gl_Color; // COLOR0,\n");
+ if (components & VB_HAS_COL1)
+ WRITE(p, " float4 color1 = gl_SecondaryColor; // COLOR1,\n");
+ for (int i = 0; i < 8; ++i) {
+ u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
+ if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
+ WRITE(p, " float%d tex%d = gl_MultiTexCoord%d.xy%s; // TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i, hastexmtx ? "z" : "", i);
+ }
+ WRITE(p, " float4 rawpos = gl_Vertex;\n") ;
+
+ WRITE(p, "void main()\n{\n");
}
- if (components & VB_HAS_POSMTXIDX) {
- if (is_d3d)
- {
- WRITE(p, " float4 blend_indices : BLENDINDICES,\n");
+ else
+ {
+
+ WRITE(p, "VS_OUTPUT main(\n");
+
+ // inputs
+ if (components & VB_HAS_NRM0)
+ WRITE(p, " float3 rawnorm0 : NORMAL0,\n");
+ if (components & VB_HAS_NRM1) {
+ if (is_d3d)
+ WRITE(p, " float3 rawnorm1 : NORMAL1,\n");
+ else
+ WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB);
}
- else
- WRITE(p, " float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB);
+ if (components & VB_HAS_NRM2) {
+ if (is_d3d)
+ WRITE(p, " float3 rawnorm2 : NORMAL2,\n");
+ else
+ WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB);
+ }
+ if (components & VB_HAS_COL0)
+ WRITE(p, " float4 color0 : COLOR0,\n");
+ if (components & VB_HAS_COL1)
+ WRITE(p, " float4 color1 : COLOR1,\n");
+ for (int i = 0; i < 8; ++i) {
+ u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
+ if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
+ WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i);
+ }
+ if (components & VB_HAS_POSMTXIDX) {
+ if (is_d3d)
+ {
+ WRITE(p, " float4 blend_indices : BLENDINDICES,\n");
+ }
+ else
+ WRITE(p, " float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB);
+ }
+ WRITE(p, " float4 rawpos : POSITION) {\n");
}
- WRITE(p, " float4 rawpos : POSITION) {\n");
WRITE(p, "VS_OUTPUT o;\n");
// transforms
if (components & VB_HAS_POSMTXIDX)
{
- if (api_type & API_D3D9)
+ if (ApiType & API_D3D9)
{
WRITE(p, "int4 indices = D3DCOLORtoUBYTE4(blend_indices);\n");
WRITE(p, "int posmtx = indices.x;\n");
}
- else if (api_type == API_D3D11)
+ else if (ApiType == API_D3D11)
{
WRITE(p, "int posmtx = blend_indices.x * 255.0f;\n");
}
@@ -493,7 +527,38 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
//seems to get rather complicated
}
- WRITE(p, "return o;\n}\n");
+ if(ApiType == API_GLSL)
+ {
+ // Bit ugly here
+ // Will look better when we bind uniforms in GLSL 1.3
+ // clipPos/w needs to be done in pixel shader, not here
+
+ if (xfregs.numTexGen.numTexGens < 7) {
+ for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
+ WRITE(p, " gl_TexCoord[%d].xyz = o.tex%d;\n", i, i);
+ WRITE(p, " gl_TexCoord[%d] = o.clipPos;\n", xfregs.numTexGen.numTexGens);
+ if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
+ WRITE(p, " gl_TexCoord[%d] = o.Normal;\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)
+ WRITE(p, " gl_TexCoord[%d] = o.tex%d;\n", i, i);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
+ WRITE(p, " gl_TexCoord[%d]%s = o.tex%d;\n", i, i < 4 ? ".xyzw" : ".xyz" , i);
+ }
+ }
+ WRITE(p, "gl_FrontColor = o.colors_0;\n");
+ WRITE(p, "gl_FrontSecondaryColor = o.colors_1;\n");
+ WRITE(p, "gl_Position = o.pos;\n");
+ WRITE(p, "}\n");
+ }
+ else
+ WRITE(p, "return o;\n}\n");
if (text[sizeof(text) - 1] != 0x7C)
diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h
index 0c522286b1..0d4eeeb1c5 100644
--- a/Source/Core/VideoCommon/Src/VertexShaderGen.h
+++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h
@@ -47,7 +47,16 @@
#define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES + 32)
#define C_DEPTHPARAMS (C_POSTTRANSFORMMATRICES + 64)
#define C_VENVCONST_END (C_DEPTHPARAMS + 4)
-
+const s_svar VSVar_Loc[] = { {I_POSNORMALMATRIX, C_POSNORMALMATRIX, 6 },
+ {I_PROJECTION , C_PROJECTION, 4 },
+ {I_MATERIALS, C_MATERIALS, 4 },
+ {I_LIGHTS, C_LIGHTS, 40 },
+ {I_TEXMATRICES, C_TEXMATRICES, 24 },
+ {I_TRANSFORMMATRICES , C_TRANSFORMMATRICES, 64 },
+ {I_NORMALMATRICES , C_NORMALMATRICES, 32 },
+ {I_POSTTRANSFORMMATRICES, C_POSTTRANSFORMMATRICES, 64 },
+ {I_DEPTHPARAMS, C_DEPTHPARAMS, 4 },
+ };
template<bool safe>
class _VERTEXSHADERUID
{
diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h
index 9f6dd59cd3..f87cb7e9b1 100644
--- a/Source/Core/VideoCommon/Src/VideoCommon.h
+++ b/Source/Core/VideoCommon/Src/VideoCommon.h
@@ -152,5 +152,11 @@ inline unsigned int GetPow2(unsigned int val)
++ret;
return ret;
}
+struct s_svar
+{
+ const char *name;
+ const unsigned int reg;
+ const unsigned int size;
+};
#endif // _VIDEOCOMMON_H
diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp
index b6ba76f45e..57685dec09 100644
--- a/Source/Core/VideoCommon/Src/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp
@@ -151,6 +151,7 @@ void VideoConfig::GameIniLoad(const char *ini_file)
iniFile.GetIfExists("Video_Settings", "DisableFog", &bDisableFog);
iniFile.GetIfExists("Video_Settings", "EnableOpenCL", &bEnableOpenCL);
iniFile.GetIfExists("Video_Settings", "OMPDecoder", &bOMPDecoder);
+ iniFile.GetIfExists("Video_Settings", "UseGLSL", &bUseGLSL);
iniFile.GetIfExists("Video_Enhancements", "ForceFiltering", &bForceFiltering);
iniFile.GetIfExists("Video_Enhancements", "MaxAnisotropy", &iMaxAnisotropy); // NOTE - this is x in (1 << x)
@@ -183,6 +184,7 @@ void VideoConfig::VerifyValidity()
if (!backend_info.bSupports3DVision) b3DVision = false;
if (!backend_info.bSupportsFormatReinterpretation) bEFBEmulateFormatChanges = false;
if (!backend_info.bSupportsPixelLighting) bEnablePixelLighting = false;
+ if (!backend_info.bSupportsGLSL) bUseGLSL = false;
}
void VideoConfig::Save(const char *ini_file)
@@ -230,6 +232,7 @@ void VideoConfig::Save(const char *ini_file)
iniFile.Set("Settings", "DisableTexturing", bDisableTexturing);
iniFile.Set("Settings", "DstAlphaPass", bDstAlphaPass);
iniFile.Set("Settings", "DisableFog", bDisableFog);
+ iniFile.Set("Settings", "bUseGLSL", bUseGLSL);
iniFile.Set("Settings", "EnableOpenCL", bEnableOpenCL);
iniFile.Set("Settings", "OMPDecoder", bOMPDecoder);
@@ -296,6 +299,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini)
SET_IF_DIFFERS("Video_Settings", "DisableFog", bDisableFog);
SET_IF_DIFFERS("Video_Settings", "EnableOpenCL", bEnableOpenCL);
SET_IF_DIFFERS("Video_Settings", "OMPDecoder", bOMPDecoder);
+ SET_IF_DIFFERS("Video_Settings", "UseGLSL", bUseGLSL);
SET_IF_DIFFERS("Video_Enhancements", "ForceFiltering", bForceFiltering);
SET_IF_DIFFERS("Video_Enhancements", "MaxAnisotropy", iMaxAnisotropy); // NOTE - this is x in (1 << x)
diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h
index 3bd833cc73..63df7e0ded 100644
--- a/Source/Core/VideoCommon/Src/VideoConfig.h
+++ b/Source/Core/VideoCommon/Src/VideoConfig.h
@@ -106,6 +106,7 @@ struct VideoConfig
bool bDisableTexturing;
bool bDstAlphaPass;
bool bDisableFog;
+ bool bUseGLSL;
// Utility
bool bDumpTextures;
@@ -166,6 +167,7 @@ struct VideoConfig
bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL
bool bSupportsFormatReinterpretation;
bool bSupportsPixelLighting;
+ bool bSupportsGLSL;
} backend_info;
};