mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 08:39:51 +00:00
Always pass vec3 texcoord between vertex and fragment shader, to allow for some simplification.
This commit is contained in:
parent
586d2aacc1
commit
24cc3dbc70
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user