diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index f5b7b1b35e..e6fa3d3913 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -39,11 +39,9 @@ GeometryShaderUid GetGeometryShaderUid(PrimitiveType primitive_type) static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config, const geometry_shader_uid_data* uid_data, const char* vertex, - APIType ApiType, bool wireframe, bool pixel_lighting, - bool first_vertex = false); + APIType ApiType, bool wireframe, bool first_vertex = false); static void EndPrimitive(ShaderCode& out, const ShaderHostConfig& host_config, - const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe, - bool pixel_lighting); + const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe); ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config, const geometry_shader_uid_data* uid_data) @@ -52,7 +50,6 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h // Non-uid template parameters will write to the dummy data (=> gets optimized out) const bool wireframe = host_config.wireframe; - const bool pixel_lighting = g_ActiveConfig.bEnablePixelLighting; const bool msaa = host_config.msaa; const bool ssaa = host_config.ssaa; const bool stereo = host_config.stereo; @@ -96,7 +93,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h "};\n"); out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, pixel_lighting, ""); + GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, host_config, ""); out.Write("};\n"); if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) @@ -105,12 +102,12 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h out.Write("#define InstanceID gl_InvocationID\n"); out.Write("VARYING_LOCATION(0) in VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, pixel_lighting, + GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, host_config, GetInterpolationQualifier(msaa, ssaa, true, true)); out.Write("} vs[%d];\n", vertex_in); out.Write("VARYING_LOCATION(0) out VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, pixel_lighting, + GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, host_config, GetInterpolationQualifier(msaa, ssaa, true, false)); if (stereo) @@ -152,8 +149,8 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("\tVS_OUTPUT start, end;\n"); - AssignVSOutputMembers(out, "start", "vs[0]", uid_data->numTexGens, pixel_lighting); - AssignVSOutputMembers(out, "end", "vs[1]", uid_data->numTexGens, pixel_lighting); + AssignVSOutputMembers(out, "start", "vs[0]", uid_data->numTexGens, host_config); + AssignVSOutputMembers(out, "end", "vs[1]", uid_data->numTexGens, host_config); } else { @@ -183,7 +180,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("\tVS_OUTPUT center;\n"); - AssignVSOutputMembers(out, "center", "vs[0]", uid_data->numTexGens, pixel_lighting); + AssignVSOutputMembers(out, "center", "vs[0]", uid_data->numTexGens, host_config); } else { @@ -214,7 +211,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("\tVS_OUTPUT f;\n"); - AssignVSOutputMembers(out, "f", "vs[i]", uid_data->numTexGens, pixel_lighting); + AssignVSOutputMembers(out, "f", "vs[i]", uid_data->numTexGens, host_config); if (host_config.backend_depth_clamp && DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLIP_DISTANCE)) @@ -266,8 +263,8 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h } out.Write("\t}\n"); - EmitVertex(out, host_config, uid_data, "l", ApiType, wireframe, pixel_lighting, true); - EmitVertex(out, host_config, uid_data, "r", ApiType, wireframe, pixel_lighting); + EmitVertex(out, host_config, uid_data, "l", ApiType, wireframe, true); + EmitVertex(out, host_config, uid_data, "r", ApiType, wireframe); } else if (primitive_type == PrimitiveType::Points) { @@ -295,19 +292,19 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h } out.Write("\t}\n"); - EmitVertex(out, host_config, uid_data, "ll", ApiType, wireframe, pixel_lighting, true); - EmitVertex(out, host_config, uid_data, "lr", ApiType, wireframe, pixel_lighting); - EmitVertex(out, host_config, uid_data, "ul", ApiType, wireframe, pixel_lighting); - EmitVertex(out, host_config, uid_data, "ur", ApiType, wireframe, pixel_lighting); + EmitVertex(out, host_config, uid_data, "ll", ApiType, wireframe, true); + EmitVertex(out, host_config, uid_data, "lr", ApiType, wireframe); + EmitVertex(out, host_config, uid_data, "ul", ApiType, wireframe); + EmitVertex(out, host_config, uid_data, "ur", ApiType, wireframe); } else { - EmitVertex(out, host_config, uid_data, "f", ApiType, wireframe, pixel_lighting, true); + EmitVertex(out, host_config, uid_data, "f", ApiType, wireframe, true); } out.Write("\t}\n"); - EndPrimitive(out, host_config, uid_data, ApiType, wireframe, pixel_lighting); + EndPrimitive(out, host_config, uid_data, ApiType, wireframe); if (stereo && !host_config.backend_gs_instancing) out.Write("\t}\n"); @@ -319,7 +316,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config, const geometry_shader_uid_data* uid_data, const char* vertex, - APIType ApiType, bool wireframe, bool pixel_lighting, bool first_vertex) + APIType ApiType, bool wireframe, bool first_vertex) { if (wireframe && first_vertex) out.Write("\tif (i == 0) first = %s;\n", vertex); @@ -332,14 +329,14 @@ static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config, out.Write("\tgl_ClipDistance[0] = %s.clipDist0;\n", vertex); out.Write("\tgl_ClipDistance[1] = %s.clipDist1;\n", vertex); } - AssignVSOutputMembers(out, "ps", vertex, uid_data->numTexGens, pixel_lighting); + AssignVSOutputMembers(out, "ps", vertex, uid_data->numTexGens, host_config); } else if (ApiType == APIType::Vulkan) { // Vulkan NDC space has Y pointing down (right-handed NDC space). out.Write("\tgl_Position = %s.pos;\n", vertex); out.Write("\tgl_Position.y = -gl_Position.y;\n"); - AssignVSOutputMembers(out, "ps", vertex, uid_data->numTexGens, pixel_lighting); + AssignVSOutputMembers(out, "ps", vertex, uid_data->numTexGens, host_config); } else { @@ -353,11 +350,10 @@ static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config, } static void EndPrimitive(ShaderCode& out, const ShaderHostConfig& host_config, - const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe, - bool pixel_lighting) + const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe) { if (wireframe) - EmitVertex(out, host_config, uid_data, "first", ApiType, wireframe, pixel_lighting); + EmitVertex(out, host_config, uid_data, "first", ApiType, wireframe); if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) out.Write("\tEndPrimitive();\n"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 936dd8e937..9fbbb2cda4 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -351,7 +351,7 @@ void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host } void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens, - bool per_pixel_lighting, bool bounding_box) + const ShaderHostConfig& host_config, bool bounding_box) { // dot product for integer vectors out.Write("int idot(int3 x, int3 y)\n" @@ -430,7 +430,7 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texg "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n" "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n"); - if (per_pixel_lighting) + if (host_config.per_pixel_lighting) { out.Write("%s", s_lighting_struct); @@ -458,7 +458,7 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texg } out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, num_texgens, per_pixel_lighting, ""); + GenerateVSOutputMembers(out, ApiType, num_texgens, host_config, ""); out.Write("};\n"); } @@ -491,7 +491,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host uid_data->genMode_numindstages); // Stuff that is shared between ubershaders and pixelgen. - WritePixelShaderCommonHeader(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, + WritePixelShaderCommonHeader(out, ApiType, uid_data->genMode_numtexgens, host_config, uid_data->bounding_box); if (uid_data->forced_early_z && g_ActiveConfig.backend_info.bSupportsEarlyZ) @@ -587,11 +587,10 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host if (uid_data->per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); - // We need to always use output blocks for Vulkan, but geometry shaders are also optional. - if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { out.Write("VARYING_LOCATION(0) in VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, + GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, host_config, GetInterpolationQualifier(msaa, ssaa, true, true)); if (stereo) @@ -601,19 +600,26 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host } else { - out.Write("%s in float4 colors_0;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s in float4 colors_1;\n", GetInterpolationQualifier(msaa, ssaa)); - // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes + u32 counter = 0; + out.Write("VARYING_LOCATION(%u) %s in float4 colors_0;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float4 colors_1;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) { - out.Write("%s in float3 tex%d;\n", GetInterpolationQualifier(msaa, ssaa), i); + out.Write("VARYING_LOCATION(%u) %s in float3 tex%d;\n", counter++, + GetInterpolationQualifier(msaa, ssaa), i); } - out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa)); + if (!host_config.fast_depth_calc) + out.Write("VARYING_LOCATION(%u) %s in float4 clipPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); if (per_pixel_lighting) { - out.Write("%s in float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s in float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float3 Normal;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float3 WorldPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); } } @@ -646,8 +652,11 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) out.Write(",\n in %s float3 tex%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i, i); - out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), - uid_data->genMode_numtexgens); + if (!host_config.fast_depth_calc) + { + out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), + uid_data->genMode_numtexgens); + } if (per_pixel_lighting) { out.Write(",\n in %s float3 Normal : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), @@ -655,8 +664,11 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host out.Write(",\n in %s float3 WorldPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), uid_data->genMode_numtexgens + 2); } - out.Write(",\n in float clipDist0 : SV_ClipDistance0\n"); - out.Write(",\n in float clipDist1 : SV_ClipDistance1\n"); + if (host_config.backend_geometry_shaders) + { + out.Write(",\n in float clipDist0 : SV_ClipDistance0\n"); + out.Write(",\n in float clipDist1 : SV_ClipDistance1\n"); + } if (stereo) out.Write(",\n in uint layer : SV_RenderTargetArrayIndex\n"); out.Write(" ) {\n"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index da5137b8cb..91c19300ba 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -167,7 +167,7 @@ typedef ShaderUid PixelShaderUid; ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config, const pixel_shader_uid_data* uid_data); void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens, - bool per_pixel_lighting, bool bounding_box); + const ShaderHostConfig& host_config, bool bounding_box); void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config, PixelShaderUid* uid); PixelShaderUid GetPixelShaderUid(); diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 85534b164b..83416d06d4 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -214,7 +214,7 @@ inline void DefineOutputMember(T& object, APIType api_type, const char* qualifie template inline void GenerateVSOutputMembers(T& object, APIType api_type, u32 texgens, - bool per_pixel_lighting, const char* qualifier) + const ShaderHostConfig& host_config, const char* qualifier) { DefineOutputMember(object, api_type, qualifier, "float4", "pos", -1, "POSITION"); DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 0, "COLOR", 0); @@ -223,9 +223,10 @@ inline void GenerateVSOutputMembers(T& object, APIType api_type, u32 texgens, for (unsigned int i = 0; i < texgens; ++i) DefineOutputMember(object, api_type, qualifier, "float3", "tex", i, "TEXCOORD", i); - DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", texgens); + if (!host_config.fast_depth_calc) + DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", texgens); - if (per_pixel_lighting) + if (host_config.per_pixel_lighting) { DefineOutputMember(object, api_type, qualifier, "float3", "Normal", -1, "TEXCOORD", texgens + 1); @@ -233,13 +234,16 @@ inline void GenerateVSOutputMembers(T& object, APIType api_type, u32 texgens, texgens + 2); } - DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 0, "SV_ClipDistance", 0); - DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 1, "SV_ClipDistance", 1); + if (host_config.backend_geometry_shaders) + { + DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 0, "SV_ClipDistance", 0); + DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 1, "SV_ClipDistance", 1); + } } template inline void AssignVSOutputMembers(T& object, const char* a, const char* b, u32 texgens, - bool per_pixel_lighting) + const ShaderHostConfig& host_config) { object.Write("\t%s.pos = %s.pos;\n", a, b); object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b); @@ -248,16 +252,20 @@ inline void AssignVSOutputMembers(T& object, const char* a, const char* b, u32 t for (unsigned int i = 0; i < texgens; ++i) object.Write("\t%s.tex%d = %s.tex%d;\n", a, i, b, i); - object.Write("\t%s.clipPos = %s.clipPos;\n", a, b); + if (!host_config.fast_depth_calc) + object.Write("\t%s.clipPos = %s.clipPos;\n", a, b); - if (per_pixel_lighting) + if (host_config.per_pixel_lighting) { object.Write("\t%s.Normal = %s.Normal;\n", a, b); object.Write("\t%s.WorldPos = %s.WorldPos;\n", a, b); } - object.Write("\t%s.clipDist0 = %s.clipDist0;\n", a, b); - object.Write("\t%s.clipDist1 = %s.clipDist1;\n", a, b); + if (host_config.backend_geometry_shaders) + { + object.Write("\t%s.clipDist0 = %s.clipDist0;\n", a, b); + object.Write("\t%s.clipDist1 = %s.clipDist1;\n", a, b); + } } // We use the flag "centroid" to fix some MSAA rendering bugs. With MSAA, the diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 4d66fac968..27e69808dc 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -59,7 +59,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config, out.Write("// Pixel UberShader for %u texgens%s%s\n", numTexgen, early_depth ? ", early-depth" : "", per_pixel_depth ? ", per-pixel depth" : ""); - WritePixelShaderCommonHeader(out, ApiType, numTexgen, per_pixel_lighting, bounding_box); + WritePixelShaderCommonHeader(out, ApiType, numTexgen, host_config, bounding_box); WriteUberShaderCommonHeader(out, ApiType, host_config); if (per_pixel_lighting) WriteLightingFunction(out); @@ -103,10 +103,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config, if (per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); - if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { out.Write("VARYING_LOCATION(0) in VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, numTexgen, per_pixel_lighting, + GenerateVSOutputMembers(out, ApiType, numTexgen, host_config, GetInterpolationQualifier(msaa, ssaa, true, true)); if (stereo) @@ -116,17 +116,26 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config, } else { - out.Write("%s in float4 colors_0;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s in float4 colors_1;\n", GetInterpolationQualifier(msaa, ssaa)); - // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes - for (u32 i = 0; i < numTexgen; ++i) - out.Write("%s in float3 tex%d;\n", GetInterpolationQualifier(msaa, ssaa), i); - out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa)); + u32 counter = 0; + out.Write("VARYING_LOCATION(%u) %s in float4 colors_0;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float4 colors_1;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + for (unsigned int i = 0; i < numTexgen; ++i) + { + out.Write("VARYING_LOCATION(%u) %s in float3 tex%d;\n", counter++, + GetInterpolationQualifier(msaa, ssaa), i); + } + if (!host_config.fast_depth_calc) + out.Write("VARYING_LOCATION(%u) %s in float4 clipPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); if (per_pixel_lighting) { - out.Write("%s in float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s in float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float3 Normal;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s in float3 WorldPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); } } } @@ -709,8 +718,11 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config, for (u32 i = 0; i < numTexgen; ++i) out.Write(",\n in %s float3 tex%u : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), i, i); - out.Write("\n,\n in %s float4 clipPos : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), - numTexgen); + if (!host_config.fast_depth_calc) + { + out.Write("\n,\n in %s float4 clipPos : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), + numTexgen); + } if (per_pixel_lighting) { out.Write(",\n in %s float3 Normal : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), diff --git a/Source/Core/VideoCommon/UberShaderVertex.cpp b/Source/Core/VideoCommon/UberShaderVertex.cpp index bf24f6afda..4032e0df40 100644 --- a/Source/Core/VideoCommon/UberShaderVertex.cpp +++ b/Source/Core/VideoCommon/UberShaderVertex.cpp @@ -45,7 +45,7 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, out.Write("};\n"); out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, numTexgen, per_pixel_lighting, ""); + GenerateVSOutputMembers(out, ApiType, numTexgen, host_config, ""); out.Write("};\n\n"); WriteUberShaderCommonHeader(out, ApiType, host_config); @@ -63,28 +63,38 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, for (int i = 0; i < 8; ++i) out.Write("ATTRIBUTE_LOCATION(%d) in float3 rawtex%d;\n", SHADER_TEXTURE0_ATTRIB + i, i); - // We need to always use output blocks for Vulkan, but geometry shaders are also optional. - if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { out.Write("VARYING_LOCATION(0) out VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, numTexgen, per_pixel_lighting, + GenerateVSOutputMembers(out, ApiType, numTexgen, host_config, GetInterpolationQualifier(msaa, ssaa, true, false)); out.Write("} vs;\n"); } else { // Let's set up attributes + u32 counter = 0; + out.Write("VARYING_LOCATION(%u) %s out float4 colors_0;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float4 colors_1;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); for (u32 i = 0; i < numTexgen; ++i) - out.Write("%s out float3 tex%u;\n", GetInterpolationQualifier(msaa, ssaa), i); - - out.Write("%s out float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa)); + { + out.Write("VARYING_LOCATION(%u) %s out float3 tex%u;\n", counter++, + GetInterpolationQualifier(msaa, ssaa), i); + } + if (!host_config.fast_depth_calc) + { + out.Write("VARYING_LOCATION(%u) %s out float4 clipPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + } if (per_pixel_lighting) { - out.Write("%s out float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s out float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float3 Normal;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float3 WorldPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); } - out.Write("%s out float4 colors_0;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s out float4 colors_1;\n", GetInterpolationQualifier(msaa, ssaa)); } out.Write("void main()\n{\n"); @@ -184,8 +194,11 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, out.Write(" o.colors_1 = float4(1.0, 1.0, 1.0, 1.0);\n"); out.Write("}\n"); - // clipPos/w needs to be done in pixel shader, not here - out.Write("o.clipPos = o.pos;\n"); + if (!host_config.fast_depth_calc) + { + // clipPos/w needs to be done in pixel shader, not here + out.Write("o.clipPos = o.pos;\n"); + } if (per_pixel_lighting) { @@ -207,8 +220,13 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, // We adjust our depth value for clipping purposes to match the perspective projection in the // software backend, which is a hack to fix Sonic Adventure and Unleashed games. out.Write("float clipDepth = o.pos.z * (1.0 - 1e-7);\n"); - out.Write("o.clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w - out.Write("o.clipDist1 = -clipDepth;\n"); // Far: z > 0 + out.Write("float clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w + out.Write("float clipDist1 = -clipDepth;\n"); // Far: z > 0 + if (host_config.backend_geometry_shaders) + { + out.Write("o.clipDist0 = clipDist0;\n"); + out.Write("o.clipDist1 = clipDist1;\n"); + } } // Write the true depth value. If the game uses depth textures, then the pixel shader will @@ -267,9 +285,9 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { - if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { - AssignVSOutputMembers(out, "vs", "o", numTexgen, per_pixel_lighting); + AssignVSOutputMembers(out, "vs", "o", numTexgen, host_config); } else { @@ -277,7 +295,8 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, // are not supported, however that will require at least OpenGL 3.2 support. for (u32 i = 0; i < numTexgen; ++i) out.Write("tex%d.xyz = o.tex%d;\n", i, i); - out.Write("clipPos = o.clipPos;\n"); + if (!host_config.fast_depth_calc) + out.Write("clipPos = o.clipPos;\n"); if (per_pixel_lighting) { out.Write("Normal = o.Normal;\n"); @@ -289,8 +308,8 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config, if (host_config.backend_depth_clamp) { - out.Write("gl_ClipDistance[0] = o.clipDist0;\n"); - out.Write("gl_ClipDistance[1] = o.clipDist1;\n"); + out.Write("gl_ClipDistance[0] = clipDist0;\n"); + out.Write("gl_ClipDistance[1] = clipDist1;\n"); } // Vulkan NDC space has Y pointing down (right-handed NDC space). @@ -477,4 +496,4 @@ void EnumerateVertexShaderUids(const std::function callback(uid); } } -} +} // namespace UberShader diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index ccec60731c..678df11a0e 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -98,7 +98,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho out.Write("};\n"); out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, per_pixel_lighting, ""); + GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, ""); out.Write("};\n"); if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) @@ -128,32 +128,36 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho } } - // We need to always use output blocks for Vulkan, but geometry shaders are also optional. - if (host_config.backend_geometry_shaders || api_type == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { out.Write("VARYING_LOCATION(0) out VertexData {\n"); - GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, per_pixel_lighting, + GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, GetInterpolationQualifier(msaa, ssaa, true, false)); out.Write("} vs;\n"); } else { // Let's set up attributes - for (u32 i = 0; i < 8; ++i) + u32 counter = 0; + out.Write("VARYING_LOCATION(%u) %s out float4 colors_0;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float4 colors_1;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + for (u32 i = 0; i < uid_data->numTexGens; ++i) { - if (i < uid_data->numTexGens) - { - out.Write("%s out float3 tex%u;\n", GetInterpolationQualifier(msaa, ssaa), i); - } + out.Write("VARYING_LOCATION(%u) %s out float3 tex%u;\n", counter++, + GetInterpolationQualifier(msaa, ssaa), i); } - out.Write("%s out float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa)); + if (!host_config.fast_depth_calc) + out.Write("VARYING_LOCATION(%u) %s out float4 clipPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); if (per_pixel_lighting) { - out.Write("%s out float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s out float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float3 Normal;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); + out.Write("VARYING_LOCATION(%u) %s out float3 WorldPos;\n", counter++, + GetInterpolationQualifier(msaa, ssaa)); } - out.Write("%s out float4 colors_0;\n", GetInterpolationQualifier(msaa, ssaa)); - out.Write("%s out float4 colors_1;\n", GetInterpolationQualifier(msaa, ssaa)); } out.Write("void main()\n{\n"); @@ -398,7 +402,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho } // clipPos/w needs to be done in pixel shader, not here - out.Write("o.clipPos = o.pos;\n"); + if (!host_config.fast_depth_calc) + out.Write("o.clipPos = o.pos;\n"); if (per_pixel_lighting) { @@ -422,8 +427,13 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho // We adjust our depth value for clipping purposes to match the perspective projection in the // software backend, which is a hack to fix Sonic Adventure and Unleashed games. out.Write("float clipDepth = o.pos.z * (1.0 - 1e-7);\n"); - out.Write("o.clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w - out.Write("o.clipDist1 = -clipDepth;\n"); // Far: z > 0 + out.Write("float clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w + out.Write("float clipDist1 = -clipDepth;\n"); // Far: z > 0 + if (host_config.backend_geometry_shaders) + { + out.Write("o.clipDist0 = clipDist0;\n"); + out.Write("o.clipDist1 = clipDist1;\n"); + } } // Write the true depth value. If the game uses depth textures, then the pixel shader will @@ -485,9 +495,9 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) { - if (host_config.backend_geometry_shaders || api_type == APIType::Vulkan) + if (host_config.backend_geometry_shaders) { - AssignVSOutputMembers(out, "vs", "o", uid_data->numTexGens, per_pixel_lighting); + AssignVSOutputMembers(out, "vs", "o", uid_data->numTexGens, host_config); } else { @@ -495,7 +505,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho // are not supported, however that will require at least OpenGL 3.2 support. for (unsigned int i = 0; i < uid_data->numTexGens; ++i) out.Write("tex%d.xyz = o.tex%d;\n", i, i); - out.Write("clipPos = o.clipPos;\n"); + if (!host_config.fast_depth_calc) + out.Write("clipPos = o.clipPos;\n"); if (per_pixel_lighting) { out.Write("Normal = o.Normal;\n"); @@ -507,8 +518,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho if (host_config.backend_depth_clamp) { - out.Write("gl_ClipDistance[0] = o.clipDist0;\n"); - out.Write("gl_ClipDistance[1] = o.clipDist1;\n"); + out.Write("gl_ClipDistance[0] = clipDist0;\n"); + out.Write("gl_ClipDistance[1] = clipDist1;\n"); } // Vulkan NDC space has Y pointing down (right-handed NDC space).