Always pass vec3 texcoord between vertex and fragment shader, to allow for some simplification.

This commit is contained in:
Henrik Rydgard 2017-01-30 15:52:40 +01:00
parent 586d2aacc1
commit 24cc3dbc70
9 changed files with 56 additions and 69 deletions

View File

@ -22,7 +22,7 @@ std::string VertexShaderDesc(const ShaderID &id) {
if (id.Bit(VS_BIT_ENABLE_FOG)) desc << "Fog ";
if (id.Bit(VS_BIT_NORM_REVERSE)) desc << "RevN ";
if (id.Bit(VS_BIT_DO_TEXTURE)) desc << "Tex ";
if (id.Bit(VS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj ";
if (id.Bit(VS_BIT_DO_TEXTURE_TRANSFORM)) desc << "TexProj ";
int uvgMode = id.Bits(VS_BIT_UVGEN_MODE, 2);
const char *uvgModes[4] = { "UV ", "UVMtx ", "UVEnv ", "UVUnk " };
int ls0 = id.Bits(VS_BIT_LS0, 2);
@ -83,7 +83,7 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform)
if (doTexture) {
id.SetBit(VS_BIT_DO_TEXTURE);
id.SetBit(VS_BIT_DO_TEXTURE_PROJ, doTextureProjection);
id.SetBit(VS_BIT_DO_TEXTURE_TRANSFORM, doTextureProjection);
}
if (useHWTransform) {

View File

@ -11,7 +11,7 @@ enum {
VS_BIT_ENABLE_FOG = 2,
VS_BIT_HAS_COLOR = 3,
VS_BIT_DO_TEXTURE = 4,
VS_BIT_DO_TEXTURE_PROJ = 6,
VS_BIT_DO_TEXTURE_TRANSFORM = 6,
VS_BIT_USE_HW_TRANSFORM = 8,
VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform
VS_BIT_NORM_REVERSE = 10,

View File

@ -112,10 +112,7 @@ bool GenerateFragmentShaderDX9(const ShaderID &id, char *buffer) {
WRITE(p, "struct PS_IN {\n");
if (doTexture) {
if (doTextureProjection)
WRITE(p, " float3 v_texcoord: TEXCOORD0;\n");
else
WRITE(p, " float2 v_texcoord: TEXCOORD0;\n");
WRITE(p, " float3 v_texcoord: TEXCOORD0;\n");
}
WRITE(p, " float4 v_color0: COLOR0;\n");
if (lmode) {

View File

@ -61,7 +61,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
bool lmode = id.Bit(VS_BIT_LMODE) && !isModeThrough; // TODO: Different expression than in shaderIDgen
bool doTexture = id.Bit(VS_BIT_DO_TEXTURE);
bool doTextureProjection = id.Bit(VS_BIT_DO_TEXTURE_PROJ);
bool doTextureTransform = id.Bit(VS_BIT_DO_TEXTURE_TRANSFORM);
GETexMapMode uvGenMode = static_cast<GETexMapMode>(id.Bits(VS_BIT_UVGEN_MODE, 2));
@ -122,7 +122,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
// When transforming by hardware, we need a great deal more uniforms...
WRITE(p, "float4x3 u_world : register(c%i);\n", CONST_VS_WORLD);
WRITE(p, "float4x3 u_view : register(c%i);\n", CONST_VS_VIEW);
if (doTextureProjection)
if (doTextureTransform)
WRITE(p, "float4x3 u_texmtx : register(c%i);\n", CONST_VS_TEXMTX);
if (enableBones) {
#ifdef USE_BONE_ARRAY
@ -176,6 +176,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
}
// And the "varyings".
bool texCoordInVec3 = false;
if (useHWTransform) {
WRITE(p, "struct VS_IN { \n");
if (enableBones) {
@ -197,8 +198,10 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
WRITE(p, "struct VS_IN {\n");
WRITE(p, " float4 position : POSITION;\n");
if (doTexture && hasTexcoord) {
if (doTextureProjection && !throughmode)
if (doTextureTransform && !throughmode) {
texCoordInVec3 = true;
WRITE(p, " float3 texcoord : TEXCOORD0;\n");
}
else
WRITE(p, " float2 texcoord : TEXCOORD0;\n");
}
@ -215,10 +218,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
WRITE(p, "struct VS_OUT {\n");
WRITE(p, " float4 gl_Position : POSITION;\n");
if (doTexture) {
if (doTextureProjection)
WRITE(p, " float3 v_texcoord: TEXCOORD0;\n");
else
WRITE(p, " float2 v_texcoord: TEXCOORD0;\n");
WRITE(p, " float3 v_texcoord : TEXCOORD0;\n");
}
WRITE(p, " float4 v_color0 : COLOR0;\n");
if (lmode)
@ -248,14 +248,10 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
if (doTextureProjection) {
if (throughmode) {
WRITE(p, " Out.v_texcoord = float3(In.texcoord.x, In.texcoord.y, 1.0);\n");
} else {
WRITE(p, " Out.v_texcoord = In.texcoord;\n");
}
if (texCoordInVec3) {
WRITE(p, " Out.v_texcoord = In.texcoord;\n");
} else {
WRITE(p, " Out.v_texcoord = In.texcoord.xy;\n");
WRITE(p, " Out.v_texcoord = float3(In.texcoord, 1.0);\n");
}
}
if (hasColor) {
@ -505,15 +501,15 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works.
if (scaleUV) {
if (hasTexcoord) {
WRITE(p, " Out.v_texcoord = In.texcoord * u_uvscaleoffset.xy;\n");
WRITE(p, " Out.v_texcoord = float3(In.texcoord.xy * u_uvscaleoffset.xy, 0.0);\n");
} else {
WRITE(p, " Out.v_texcoord = float2(0.0, 0.0);\n");
WRITE(p, " Out.v_texcoord = float3(0.0, 0.0, 0.0);\n");
}
} else {
if (hasTexcoord) {
WRITE(p, " Out.v_texcoord = In.texcoord * u_uvscaleoffset.xy + u_uvscaleoffset.zw;\n");
WRITE(p, " Out.v_texcoord = float3(In.texcoord.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
} else {
WRITE(p, " Out.v_texcoord = u_uvscaleoffset.zw;\n");
WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.zw, 0.0);\n");
}
}
break;
@ -553,7 +549,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " Out.v_texcoord.xy = u_uvscaleoffset.xy * float2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5;\n", ls0, ls1);
WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 0.0);\n", ls0, ls1);
break;
default:

View File

@ -227,10 +227,7 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
WRITE(p, "%s %s float v_fogdepth;\n", varying, highpFog ? "highp" : "mediump");
}
if (doTexture) {
if (doTextureProjection)
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
else
WRITE(p, "%s %s vec2 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
}
if (!g_Config.bFragmentTestCache) {
@ -329,7 +326,7 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
if (doTextureProjection) {
WRITE(p, " vec4 t = %sProj(tex, %s);\n", texture, texcoord);
} else {
WRITE(p, " vec4 t = %s(tex, %s);\n", texture, texcoord);
WRITE(p, " vec4 t = %s(tex, %s.xy);\n", texture, texcoord);
}
WRITE(p, " vec4 p = v_color0;\n");

View File

@ -43,6 +43,8 @@
#include "GPU/GLES/DrawEngineGLES.h"
#include "FramebufferManagerGLES.h"
#define SHADERLOG
Shader::Shader(const char *code, uint32_t glShaderType, bool useHWTransform)
: failed_(false), useHWTransform_(useHWTransform) {
PROFILE_THIS_SCOPE("shadercomp");

View File

@ -166,7 +166,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
bool lmode = id.Bit(VS_BIT_LMODE) && !isModeThrough; // TODO: Different expression than in shaderIDgen
bool doTexture = id.Bit(VS_BIT_DO_TEXTURE);
bool doTextureProjection = id.Bit(VS_BIT_DO_TEXTURE_PROJ);
bool doTextureProjection = id.Bit(VS_BIT_DO_TEXTURE_TRANSFORM);
GETexMapMode uvGenMode = static_cast<GETexMapMode>(id.Bits(VS_BIT_UVGEN_MODE, 2));
@ -225,11 +225,14 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
if (useHWTransform && hasNormal)
WRITE(p, "%s mediump vec3 normal;\n", attribute);
bool texcoordVec3In = false;
if (doTexture && hasTexcoord) {
if (!useHWTransform && doTextureProjection && !throughmode)
if (!useHWTransform && doTextureProjection && !throughmode) {
WRITE(p, "%s vec3 texcoord;\n", attribute);
else
texcoordVec3In = true;
} else {
WRITE(p, "%s vec2 texcoord;\n", attribute);
}
}
if (hasColor) {
WRITE(p, "%s lowp vec4 color0;\n", attribute);
@ -315,11 +318,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
}
if (doTexture) {
if (doTextureProjection) {
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
} else {
WRITE(p, "%s %s vec2 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
}
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
}
if (enableFog) {
@ -430,10 +429,10 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
if (throughmode && doTextureProjection) {
WRITE(p, " v_texcoord = vec3(texcoord, 1.0);\n");
} else {
if (texcoordVec3In) {
WRITE(p, " v_texcoord = texcoord;\n");
} else {
WRITE(p, " v_texcoord = vec3(texcoord, 1.0);\n");
}
}
if (hasColor) {
@ -803,20 +802,20 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
if (doBezier || doSpline)
// TODO: Need fix?
// Fix to avoid temporarily texture animation bug with hardware tessellation.
WRITE(p, " v_texcoord = tex * u_uvscaleoffset.xy + u_uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(tex * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
else
WRITE(p, " v_texcoord = texcoord * u_uvscaleoffset.xy;\n");
WRITE(p, " v_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy, 0.0);\n");
} else {
WRITE(p, " v_texcoord = vec2(0.0);\n");
WRITE(p, " v_texcoord = vec3(0.0);\n");
}
} else {
if (hasTexcoord) {
if (doBezier || doSpline)
WRITE(p, " v_texcoord = tex * u_uvscaleoffset.xy + u_uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(tex * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
else
WRITE(p, " v_texcoord = texcoord * u_uvscaleoffset.xy + u_uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
} else {
WRITE(p, " v_texcoord = u_uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.zw, 0.0);\n");
}
}
break;
@ -857,7 +856,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " v_texcoord = u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5;\n", ls0, ls1);
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5);\n", ls0, ls1);
break;
default:

View File

@ -98,10 +98,7 @@ bool GenerateVulkanGLSLFragmentShader(const ShaderID &id, char *buffer) {
WRITE(p, "layout (location = 3) in float v_fogdepth;\n");
}
if (doTexture) {
if (doTextureProjection)
WRITE(p, "layout (location = 0) in vec3 v_texcoord;\n");
else
WRITE(p, "layout (location = 0) in vec2 v_texcoord;\n");
WRITE(p, "layout (location = 0) in vec3 v_texcoord;\n");
}
if (enableAlphaTest && !alphaTestAgainstZero) {
@ -176,7 +173,7 @@ bool GenerateVulkanGLSLFragmentShader(const ShaderID &id, char *buffer) {
if (doTextureProjection) {
WRITE(p, " vec4 t = textureProj(tex, %s);\n", texcoord);
} else {
WRITE(p, " vec4 t = texture(tex, %s);\n", texcoord);
WRITE(p, " vec4 t = texture(tex, %s.xy);\n", texcoord);
}
WRITE(p, " vec4 p = v_color0;\n");

View File

@ -108,7 +108,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
bool lmode = id.Bit(VS_BIT_LMODE) && !isModeThrough; // TODO: Different expression than in shaderIDgen
bool doTexture = id.Bit(VS_BIT_DO_TEXTURE);
bool doTextureProjection = id.Bit(VS_BIT_DO_TEXTURE_PROJ);
bool doTextureTransform = id.Bit(VS_BIT_DO_TEXTURE_TRANSFORM);
GETexMapMode uvGenMode = static_cast<GETexMapMode>(id.Bits(VS_BIT_UVGEN_MODE, 2));
@ -171,9 +171,12 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
if (useHWTransform && hasNormal)
WRITE(p, "layout (location = %d) in vec3 normal;\n", PspAttributeLocation::NORMAL);
bool texcoordInVec3 = false;
if (doTexture && hasTexcoord) {
if (!useHWTransform && doTextureProjection && !throughmode)
if (!useHWTransform && doTextureTransform && !throughmode) {
WRITE(p, "layout (location = %d) in vec3 texcoord;\n", PspAttributeLocation::TEXCOORD);
texcoordInVec3 = true;
}
else
WRITE(p, "layout (location = %d) in vec2 texcoord;\n", PspAttributeLocation::TEXCOORD);
}
@ -189,11 +192,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
}
if (doTexture) {
if (doTextureProjection) {
WRITE(p, "layout (location = 0) out vec3 v_texcoord;\n");
} else {
WRITE(p, "layout (location = 0) out vec2 v_texcoord;\n");
}
WRITE(p, "layout (location = 0) out vec3 v_texcoord;\n");
}
if (enableFog) {
@ -218,10 +217,10 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
if (throughmode && doTextureProjection) {
WRITE(p, " v_texcoord = vec3(texcoord, 1.0);\n");
} else {
if (texcoordInVec3) {
WRITE(p, " v_texcoord = texcoord;\n");
} else {
WRITE(p, " v_texcoord = vec3(texcoord, 1.0);\n");
}
}
if (hasColor) {
@ -435,15 +434,15 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works.
if (scaleUV) {
if (hasTexcoord) {
WRITE(p, " v_texcoord = texcoord;\n");
WRITE(p, " v_texcoord = vec3(texcoord.xy, 0.0);\n");
} else {
WRITE(p, " v_texcoord = vec2(0.0);\n");
WRITE(p, " v_texcoord = vec3(0.0);\n");
}
} else {
if (hasTexcoord) {
WRITE(p, " v_texcoord = texcoord * base.uvscaleoffset.xy + base.uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(texcoord.xy * base.uvscaleoffset.xy + base.uvscaleoffset.zw, 0.0);\n");
} else {
WRITE(p, " v_texcoord = base.uvscaleoffset.zw;\n");
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.zw, 0.0);\n");
}
}
break;
@ -484,7 +483,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " v_texcoord = base.uvscaleoffset.xy * vec2(1.0 + dot(normalize(light.pos[%i]), worldnormal), 1.0 + dot(normalize(light.pos[%i]), worldnormal)) * 0.5;\n", ls0, ls1);
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + dot(normalize(light.pos[%i]), worldnormal), 1.0 + dot(normalize(light.pos[%i]), worldnormal)) * 0.5, 0.0);\n", ls0, ls1);
break;
default: