mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Cleanup
Clean up GLSL language setup further
This commit is contained in:
parent
2917b0e9e6
commit
c45515866b
5 changed files with 70 additions and 105 deletions
|
@ -141,13 +141,15 @@ enum DoLightComputation {
|
|||
|
||||
struct GLSLShaderCompat {
|
||||
const char *versionString;
|
||||
const char *varying;
|
||||
const char *varying_fs;
|
||||
const char *varying_vs;
|
||||
const char *attribute;
|
||||
const char *fragColor0;
|
||||
const char *fragColor1;
|
||||
const char *texture;
|
||||
const char *texelFetch;
|
||||
const char *lastFragData;
|
||||
const char *framebufferFetchExtension;
|
||||
bool gles;
|
||||
bool glslES30;
|
||||
bool bitwiseOps;
|
||||
|
|
|
@ -423,29 +423,6 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
"a_w2.x", "a_w2.y", "a_w2.z", "a_w2.w",
|
||||
};
|
||||
|
||||
#if defined(USE_FOR_LOOP) && defined(USE_BONE_ARRAY)
|
||||
|
||||
// To loop through the weights, we unfortunately need to put them in a float array.
|
||||
// GLSL ES sucks - no way to directly initialize an array!
|
||||
switch (numBoneWeights) {
|
||||
case 1: WRITE(p, " float w[1]; w[0] = a_w1;\n"); break;
|
||||
case 2: WRITE(p, " float w[2]; w[0] = a_w1.x; w[1] = a_w1.y;\n"); break;
|
||||
case 3: WRITE(p, " float w[3]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z;\n"); break;
|
||||
case 4: WRITE(p, " float w[4]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w;\n"); break;
|
||||
case 5: WRITE(p, " float w[5]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2;\n"); break;
|
||||
case 6: WRITE(p, " float w[6]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y;\n"); break;
|
||||
case 7: WRITE(p, " float w[7]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y; w[6] = a_w2.z;\n"); break;
|
||||
case 8: WRITE(p, " float w[8]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y; w[6] = a_w2.z; w[7] = a_w2.w;\n"); break;
|
||||
}
|
||||
|
||||
WRITE(p, " mat4 skinMatrix = w[0] * u_bone[0];\n");
|
||||
if (numBoneWeights > 1) {
|
||||
WRITE(p, " for (int i = 1; i < %i; i++) {\n", numBoneWeights);
|
||||
WRITE(p, " skinMatrix += w[i] * u_bone[i];\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
#else
|
||||
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
|
||||
if (numBoneWeights == 1)
|
||||
WRITE(p, " float4x3 skinMatrix = mul(In.a_w1, u_bone[0])");
|
||||
|
@ -471,7 +448,6 @@ bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
WRITE(p, " + mul(In.%s, u_bone%i)", weightAttr, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WRITE(p, ";\n");
|
||||
|
||||
|
|
|
@ -37,13 +37,11 @@
|
|||
|
||||
// Missing: Z depth range
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uniformMask, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
*uniformMask = 0;
|
||||
// In GLSL ES 3.0, you use "in" variables instead of varying.
|
||||
|
||||
GLSLShaderCompat compat{};
|
||||
compat.varying = "varying";
|
||||
compat.varying_vs = "varying";
|
||||
compat.varying_fs = "varying";
|
||||
compat.fragColor0 = "gl_FragColor";
|
||||
compat.fragColor1 = "fragColor1";
|
||||
compat.texture = "texture2D";
|
||||
|
@ -51,10 +49,6 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
|||
compat.bitwiseOps = false;
|
||||
compat.lastFragData = nullptr;
|
||||
compat.gles = gl_extensions.IsGLES;
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
||||
ReplaceAlphaType stencilToAlpha = static_cast<ReplaceAlphaType>(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2));
|
||||
|
||||
if (compat.gles) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
|
@ -75,25 +69,20 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
|||
compat.fragColor1 = "gl_SecondaryFragColorEXT";
|
||||
}
|
||||
}
|
||||
|
||||
// PowerVR needs highp to do the fog in MHU correctly.
|
||||
// Others don't, and some can't handle highp in the fragment shader.
|
||||
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
|
||||
highpTexcoord = highpFog;
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
compat.versionString = "#version 330";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
compat.versionString = "#version 330";
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
compat.versionString = "#version 130";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
compat.versionString = "#version 130";
|
||||
} else {
|
||||
compat.versionString = "#version 110";
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
|
@ -104,32 +93,54 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
|||
}
|
||||
}
|
||||
|
||||
// Here the writing starts!
|
||||
WRITE(p, "%s\n", compat.versionString);
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "fragColor0";
|
||||
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
|
||||
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
|
||||
WRITE(p, "#extension GL_NV_shader_framebuffer_fetch : require\n");
|
||||
compat.framebufferFetchExtension = "#extension GL_NV_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_ARM_shader_framebuffer_fetch : require\n");
|
||||
compat.framebufferFetchExtension = "#extension GL_ARM_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragColorARM";
|
||||
}
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.varying_vs = "out";
|
||||
compat.varying_fs = "in";
|
||||
compat.attribute = "in";
|
||||
}
|
||||
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
if (compat.gles) {
|
||||
// PowerVR needs highp to do the fog in MHU correctly.
|
||||
// Others don't, and some can't handle highp in the fragment shader.
|
||||
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
|
||||
highpTexcoord = highpFog;
|
||||
}
|
||||
|
||||
ReplaceAlphaType stencilToAlpha = static_cast<ReplaceAlphaType>(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2));
|
||||
|
||||
char *p = buffer;
|
||||
|
||||
// Here the writing starts!
|
||||
WRITE(p, "%s\n", compat.versionString);
|
||||
|
||||
if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) {
|
||||
WRITE(p, "#extension GL_EXT_blend_func_extended : require\n");
|
||||
}
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
}
|
||||
if (compat.framebufferFetchExtension) {
|
||||
WRITE(p, "%s\n", compat.framebufferFetchExtension);
|
||||
}
|
||||
if (!compat.gles) {
|
||||
WRITE(p, "#define lowp\n");
|
||||
WRITE(p, "#define mediump\n");
|
||||
|
@ -140,10 +151,6 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
|||
|
||||
WRITE(p, "#define splat3(x) vec3(x)\n");
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.varying = "in";
|
||||
}
|
||||
|
||||
bool lmode = id.Bit(FS_BIT_LMODE);
|
||||
bool doTexture = id.Bit(FS_BIT_DO_TEXTURE);
|
||||
bool enableFog = id.Bit(FS_BIT_ENABLE_FOG);
|
||||
|
@ -238,16 +245,16 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
|||
WRITE(p, "uniform vec3 u_texenv;\n");
|
||||
}
|
||||
|
||||
WRITE(p, "%s %s vec4 v_color0;\n", shading, compat.varying);
|
||||
WRITE(p, "%s %s vec4 v_color0;\n", shading, compat.varying_fs);
|
||||
if (lmode)
|
||||
WRITE(p, "%s %s vec3 v_color1;\n", shading, compat.varying);
|
||||
WRITE(p, "%s %s vec3 v_color1;\n", shading, compat.varying_fs);
|
||||
if (enableFog) {
|
||||
*uniformMask |= DIRTY_FOGCOLOR;
|
||||
WRITE(p, "uniform vec3 u_fogcolor;\n");
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", compat.varying, highpFog ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", compat.varying_fs, highpFog ? "highp" : "mediump");
|
||||
}
|
||||
if (doTexture) {
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying, highpTexcoord ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying_fs, highpTexcoord ? "highp" : "mediump");
|
||||
}
|
||||
|
||||
if (!g_Config.bFragmentTestCache) {
|
||||
|
|
|
@ -88,21 +88,17 @@ static const char * const boneWeightInDecl[9] = {
|
|||
// is a bit of a rare configuration, although quite common on mobile.
|
||||
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
*attrMask = 0;
|
||||
*uniformMask = 0;
|
||||
// #define USE_FOR_LOOP
|
||||
|
||||
// In GLSL ES 3.0, you use "out" variables instead.
|
||||
GLSLShaderCompat compat{};
|
||||
compat.glslES30 = false;
|
||||
compat.varying = "varying";
|
||||
compat.varying_vs = "varying";
|
||||
compat.varying_fs = "varying";
|
||||
compat.attribute = "attribute";
|
||||
const char * const * boneWeightDecl = boneWeightAttrDecl;
|
||||
compat.texelFetch = nullptr;
|
||||
compat.gles = gl_extensions.IsGLES;
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
||||
if (compat.gles) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
|
@ -115,11 +111,6 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
|
||||
// PowerVR needs highp to do the fog in MHU correctly.
|
||||
// Others don't, and some can't handle highp in the fragment shader.
|
||||
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
|
||||
highpTexcoord = highpFog;
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
|
@ -140,6 +131,25 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
}
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.attribute = "in";
|
||||
compat.varying_vs = "out";
|
||||
compat.varying_fs = "in";
|
||||
}
|
||||
|
||||
char *p = buffer;
|
||||
// Here the writing starts!
|
||||
WRITE(p, "%s\n", compat.versionString);
|
||||
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
if (compat.gles) {
|
||||
// PowerVR needs highp to do the fog in MHU correctly.
|
||||
// Others don't, and some can't handle highp in the fragment shader.
|
||||
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
|
||||
highpTexcoord = highpFog;
|
||||
}
|
||||
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
}
|
||||
|
@ -154,12 +164,6 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
WRITE(p, "#define highp\n");
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.attribute = "in";
|
||||
compat.varying = "out";
|
||||
boneWeightDecl = boneWeightInDecl;
|
||||
}
|
||||
|
||||
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
|
||||
bool lmode = id.Bit(VS_BIT_LMODE);
|
||||
bool doTexture = id.Bit(VS_BIT_DO_TEXTURE);
|
||||
|
@ -211,6 +215,10 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
int boneWeightScale = id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2);
|
||||
if (enableBones) {
|
||||
numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3);
|
||||
const char * const * boneWeightDecl = boneWeightAttrDecl;
|
||||
if (!strcmp(compat.attribute, "in")) {
|
||||
boneWeightDecl = boneWeightInDecl;
|
||||
}
|
||||
WRITE(p, "%s", boneWeightDecl[numBoneWeights]);
|
||||
*attrMask |= 1 << ATTR_W1;
|
||||
if (numBoneWeights >= 5)
|
||||
|
@ -341,21 +349,21 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
*uniformMask |= DIRTY_CULLRANGE;
|
||||
}
|
||||
|
||||
WRITE(p, "%s%s lowp vec4 v_color0;\n", shading, compat.varying);
|
||||
WRITE(p, "%s%s lowp vec4 v_color0;\n", shading, compat.varying_vs);
|
||||
if (lmode) {
|
||||
WRITE(p, "%s%s lowp vec3 v_color1;\n", shading, compat.varying);
|
||||
WRITE(p, "%s%s lowp vec3 v_color1;\n", shading, compat.varying_vs);
|
||||
}
|
||||
|
||||
if (doTexture) {
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying, highpTexcoord ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying_vs, highpTexcoord ? "highp" : "mediump");
|
||||
}
|
||||
|
||||
if (enableFog) {
|
||||
// See the fragment shader generator
|
||||
if (highpFog) {
|
||||
WRITE(p, "%s highp float v_fogdepth;\n", compat.varying);
|
||||
WRITE(p, "%s highp float v_fogdepth;\n", compat.varying_vs);
|
||||
} else {
|
||||
WRITE(p, "%s mediump float v_fogdepth;\n", compat.varying);
|
||||
WRITE(p, "%s mediump float v_fogdepth;\n", compat.varying_vs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,30 +531,6 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
"w2.x", "w2.y", "w2.z", "w2.w",
|
||||
};
|
||||
|
||||
#if defined(USE_FOR_LOOP) && defined(USE_BONE_ARRAY)
|
||||
|
||||
// To loop through the weights, we unfortunately need to put them in a float array.
|
||||
// GLSL ES sucks - no way to directly initialize an array!
|
||||
switch (numBoneWeights) {
|
||||
case 1: WRITE(p, " float w[1]; w[0] = w1;\n"); break;
|
||||
case 2: WRITE(p, " float w[2]; w[0] = w1.x; w[1] = w1.y;\n"); break;
|
||||
case 3: WRITE(p, " float w[3]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z;\n"); break;
|
||||
case 4: WRITE(p, " float w[4]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w;\n"); break;
|
||||
case 5: WRITE(p, " float w[5]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2;\n"); break;
|
||||
case 6: WRITE(p, " float w[6]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y;\n"); break;
|
||||
case 7: WRITE(p, " float w[7]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y; w[6] = w2.z;\n"); break;
|
||||
case 8: WRITE(p, " float w[8]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y; w[6] = w2.z; w[7] = w2.w;\n"); break;
|
||||
}
|
||||
|
||||
WRITE(p, " mat4 skinMatrix = w[0] * u_bone[0];\n");
|
||||
if (numBoneWeights > 1) {
|
||||
WRITE(p, " for (int i = 1; i < %i; i++) {\n", numBoneWeights);
|
||||
WRITE(p, " skinMatrix += w[i] * u_bone[i];\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_BONE_ARRAY
|
||||
if (numBoneWeights == 1)
|
||||
WRITE(p, " mat4 skinMatrix = w1 * u_bone[0]");
|
||||
|
@ -573,8 +557,6 @@ bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrM
|
|||
if (numBoneWeights == 5 && i == 4) weightAttr = "w2";
|
||||
WRITE(p, " + %s * u_bone%i", weightAttr, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
WRITE(p, ";\n");
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
// #define USE_BONE_ARRAY
|
||||
|
||||
struct VShaderID;
|
||||
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString);
|
||||
|
|
Loading…
Add table
Reference in a new issue