diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 02744c2889..2179307afd 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -20,6 +20,12 @@ static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_ template static void EndPrimitive(T& out, API_TYPE ApiType); +template +static void EmitVertex(T& out, geometry_shader_uid_data* uid_data, const char* vertex, + API_TYPE ApiType, bool first_vertex = false); +template +static void EndPrimitive(T& out, geometry_shader_uid_data* uid_data, API_TYPE ApiType); + template static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) { @@ -40,6 +46,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) if (g_ActiveConfig.bWireFrame) vertex_out++; + uid_data->msaa = g_ActiveConfig.iMultisamples > 1; + uid_data->ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA; uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) { @@ -77,7 +85,7 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, ""); + GenerateVSOutputMembers(out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting, ""); out.Write("};\n"); if (ApiType == API_OPENGL) @@ -86,11 +94,15 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) out.Write("#define InstanceID gl_InvocationID\n"); out.Write("in VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, GetInterpolationQualifier(true, true)); + GenerateVSOutputMembers( + out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting, + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, true, true)); out.Write("} vs[%d];\n", vertex_in); out.Write("out VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, GetInterpolationQualifier(true, false)); + GenerateVSOutputMembers( + out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting, + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, false, true)); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tflat int layer;\n"); @@ -135,8 +147,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) if (ApiType == API_OPENGL) { out.Write("\tVS_OUTPUT start, end;\n"); - AssignVSOutputMembers(out, "start", "vs[0]"); - AssignVSOutputMembers(out, "end", "vs[1]"); + AssignVSOutputMembers(out, "start", "vs[0]", uid_data->numTexGens, uid_data->pixel_lighting); + AssignVSOutputMembers(out, "end", "vs[1]", uid_data->numTexGens, uid_data->pixel_lighting); } else { @@ -166,11 +178,11 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) if (ApiType == API_OPENGL) { out.Write("\tVS_OUTPUT center;\n"); - AssignVSOutputMembers(out, "center", "vs[0]"); + AssignVSOutputMembers(out, "center", "vs[0]", uid_data->numTexGens, uid_data->pixel_lighting); } else { - out.Write("\tVS_OUTPUT center = o[0];\n"); + out.Write("\tVS_OUTPUT center = o[0];\n", uid_data->numTexGens, uid_data->pixel_lighting); } // Offset from center to upper right vertex @@ -197,7 +209,7 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) if (ApiType == API_OPENGL) { out.Write("\tVS_OUTPUT f;\n"); - AssignVSOutputMembers(out, "f", "vs[i]"); + AssignVSOutputMembers(out, "f", "vs[i]", uid_data->numTexGens, uid_data->pixel_lighting); } else { @@ -239,8 +251,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) } out.Write("\t}\n"); - EmitVertex(out, "l", ApiType, true); - EmitVertex(out, "r", ApiType); + EmitVertex(out, uid_data, "l", ApiType, true); + EmitVertex(out, uid_data, "r", ApiType); } else if (primitive_type == PRIMITIVE_POINTS) { @@ -268,19 +280,19 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) } out.Write("\t}\n"); - EmitVertex(out, "ll", ApiType, true); - EmitVertex(out, "lr", ApiType); - EmitVertex(out, "ul", ApiType); - EmitVertex(out, "ur", ApiType); + EmitVertex(out, uid_data, "ll", ApiType, true); + EmitVertex(out, uid_data, "lr", ApiType); + EmitVertex(out, uid_data, "ul", ApiType); + EmitVertex(out, uid_data, "ur", ApiType); } else { - EmitVertex(out, "f", ApiType, true); + EmitVertex(out, uid_data, "f", ApiType, true); } out.Write("\t}\n"); - EndPrimitive(out, ApiType); + EndPrimitive(out, uid_data, ApiType); if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); @@ -291,7 +303,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType) } template -static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex) +static void EmitVertex(T& out, geometry_shader_uid_data* uid_data, const char* vertex, + API_TYPE ApiType, bool first_vertex) { if (g_ActiveConfig.bWireFrame && first_vertex) out.Write("\tif (i == 0) first = %s;\n", vertex); @@ -299,7 +312,7 @@ static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_ if (ApiType == API_OPENGL) { out.Write("\tgl_Position = %s.pos;\n", vertex); - AssignVSOutputMembers(out, "ps", vertex); + AssignVSOutputMembers(out, "ps", vertex, uid_data->numTexGens, uid_data->pixel_lighting); } else { @@ -312,10 +325,10 @@ static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_ out.Write("\toutput.Append(ps);\n"); } template -static void EndPrimitive(T& out, API_TYPE ApiType) +static void EndPrimitive(T& out, geometry_shader_uid_data* uid_data, API_TYPE ApiType) { if (g_ActiveConfig.bWireFrame) - EmitVertex(out, "first", ApiType); + EmitVertex(out, uid_data, "first", ApiType); if (ApiType == API_OPENGL) out.Write("\tEndPrimitive();\n"); diff --git a/Source/Core/VideoCommon/GeometryShaderGen.h b/Source/Core/VideoCommon/GeometryShaderGen.h index 961ab770c6..fcf4f9c8db 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.h +++ b/Source/Core/VideoCommon/GeometryShaderGen.h @@ -23,6 +23,8 @@ struct geometry_shader_uid_data u32 pixel_lighting : 1; u32 primitive_type : 2; u32 wireframe : 1; + u32 msaa : 1; + u32 ssaa : 1; }; #pragma pack() diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 431ebeab4e..2d1df801db 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -281,7 +281,8 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) } out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, ApiType, ""); + GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, + uid_data->per_pixel_lighting, ""); out.Write("};\n"); { @@ -374,7 +375,9 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { out.Write("in VertexData {\n"); - GenerateVSOutputMembers(out, ApiType, GetInterpolationQualifier(true, true)); + GenerateVSOutputMembers( + out, ApiType, uid_data->genMode_numtexgens, uid_data->per_pixel_lighting, + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, true, true)); if (uid_data->stereo) out.Write("\tflat int layer;\n"); @@ -383,19 +386,25 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) } else { - out.Write("%s in float4 colors_0;\n", GetInterpolationQualifier()); - out.Write("%s in float4 colors_1;\n", GetInterpolationQualifier()); + out.Write("%s in float4 colors_0;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); + out.Write("%s in float4 colors_1;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) { - out.Write("%s in float3 uv%d;\n", GetInterpolationQualifier(), i); + out.Write("%s in float3 uv%d;\n", GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), + i); } - out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier()); + out.Write("%s in float4 clipPos;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); if (uid_data->per_pixel_lighting) { - out.Write("%s in float3 Normal;\n", GetInterpolationQualifier()); - out.Write("%s in float3 WorldPos;\n", GetInterpolationQualifier()); + out.Write("%s in float3 Normal;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); + out.Write("%s in float3 WorldPos;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); } } @@ -417,19 +426,25 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) "", uid_data->per_pixel_depth ? "\n out float depth : SV_Depth," : ""); - out.Write(" in %s float4 colors_0 : COLOR0,\n", GetInterpolationQualifier()); - out.Write(" in %s float4 colors_1 : COLOR1\n", GetInterpolationQualifier()); + out.Write(" in %s float4 colors_0 : COLOR0,\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); + out.Write(" in %s float4 colors_1 : COLOR1\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); // compute window position if needed because binding semantic WPOS is not widely supported for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i) - out.Write(",\n in %s float3 uv%d : TEXCOORD%d", GetInterpolationQualifier(), i, i); - out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(), + out.Write(",\n in %s float3 uv%d : TEXCOORD%d", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), i, i); + out.Write(",\n in %s float4 clipPos : TEXCOORD%d", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), uid_data->genMode_numtexgens); if (uid_data->per_pixel_lighting) { - out.Write(",\n in %s float3 Normal : TEXCOORD%d", GetInterpolationQualifier(), + out.Write(",\n in %s float3 Normal : TEXCOORD%d", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), uid_data->genMode_numtexgens + 1); - out.Write(",\n in %s float3 WorldPos : TEXCOORD%d", GetInterpolationQualifier(), + out.Write(",\n in %s float3 WorldPos : TEXCOORD%d", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), uid_data->genMode_numtexgens + 2); } if (uid_data->stereo) diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 2668c8ea7d..dbd6ce8823 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -245,40 +245,41 @@ inline void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifi } template -inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const char* qualifier) +inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, u32 texgens, + bool per_pixel_lighting, const char* qualifier) { DefineOutputMember(object, api_type, qualifier, "float4", "pos", -1, "POSITION"); DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 0, "COLOR", 0); DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 1, "COLOR", 1); - for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) + 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", - xfmem.numTexGen.numTexGens); + DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", texgens); - if (g_ActiveConfig.bEnablePixelLighting) + if (per_pixel_lighting) { DefineOutputMember(object, api_type, qualifier, "float3", "Normal", -1, "TEXCOORD", - xfmem.numTexGen.numTexGens + 1); + texgens + 1); DefineOutputMember(object, api_type, qualifier, "float3", "WorldPos", -1, "TEXCOORD", - xfmem.numTexGen.numTexGens + 2); + texgens + 2); } } template -inline void AssignVSOutputMembers(T& object, const char* a, const char* b) +inline void AssignVSOutputMembers(T& object, const char* a, const char* b, u32 texgens, + bool per_pixel_lighting) { object.Write("\t%s.pos = %s.pos;\n", a, b); object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b); object.Write("\t%s.colors_1 = %s.colors_1;\n", a, b); - for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) + 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 (g_ActiveConfig.bEnablePixelLighting) + if (per_pixel_lighting) { object.Write("\t%s.Normal = %s.Normal;\n", a, b); object.Write("\t%s.WorldPos = %s.WorldPos;\n", a, b); @@ -293,23 +294,24 @@ inline void AssignVSOutputMembers(T& object, const char* a, const char* b) // As a workaround, we interpolate at the centroid of the coveraged pixel, which // is always inside the primitive. // Without MSAA, this flag is defined to have no effect. -inline const char* GetInterpolationQualifier(bool in_glsl_interface_block = false, bool in = false) +inline const char* GetInterpolationQualifier(bool msaa, bool ssaa, + bool in_glsl_interface_block = false, bool in = false) { - if (g_ActiveConfig.iMultisamples <= 1) + if (!msaa) return ""; // Without GL_ARB_shading_language_420pack support, the interpolation qualifier must be // "centroid in" and not "centroid", even within an interface block. if (in_glsl_interface_block && !g_ActiveConfig.backend_info.bSupportsBindingLayout) { - if (!g_ActiveConfig.bSSAA) + if (!ssaa) return in ? "centroid in" : "centroid out"; else return in ? "sample in" : "sample out"; } else { - if (!g_ActiveConfig.bSSAA) + if (!ssaa) return "centroid"; else return "sample"; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 464ce00a30..f417988a21 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -39,13 +39,15 @@ static T GenerateVertexShader(API_TYPE api_type) out.Write(s_shader_uniforms); out.Write("};\n"); - out.Write("struct VS_OUTPUT {\n"); - GenerateVSOutputMembers(out, api_type, ""); - out.Write("};\n"); - uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->components = VertexLoaderManager::g_current_components; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; + uid_data->msaa = g_ActiveConfig.iMultisamples > 1; + uid_data->ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA; + + out.Write("struct VS_OUTPUT {\n"); + GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, uid_data->pixel_lighting, ""); + out.Write("};\n"); if (api_type == API_OPENGL) { @@ -75,7 +77,9 @@ static T GenerateVertexShader(API_TYPE api_type) if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { out.Write("out VertexData {\n"); - GenerateVSOutputMembers(out, api_type, GetInterpolationQualifier(true, false)); + GenerateVSOutputMembers( + out, api_type, uid_data->numTexGens, uid_data->pixel_lighting, + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, false, true)); out.Write("} vs;\n"); } else @@ -85,17 +89,23 @@ static T GenerateVertexShader(API_TYPE api_type) { if (i < uid_data->numTexGens) { - out.Write("%s out float3 uv%u;\n", GetInterpolationQualifier(), i); + out.Write("%s out float3 uv%u;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa), i); } } - out.Write("%s out float4 clipPos;\n", GetInterpolationQualifier()); + out.Write("%s out float4 clipPos;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); if (uid_data->pixel_lighting) { - out.Write("%s out float3 Normal;\n", GetInterpolationQualifier()); - out.Write("%s out float3 WorldPos;\n", GetInterpolationQualifier()); + out.Write("%s out float3 Normal;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); + out.Write("%s out float3 WorldPos;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); } - out.Write("%s out float4 colors_0;\n", GetInterpolationQualifier()); - out.Write("%s out float4 colors_1;\n", GetInterpolationQualifier()); + out.Write("%s out float4 colors_0;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); + out.Write("%s out float4 colors_1;\n", + GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa)); } out.Write("void main()\n{\n"); @@ -387,7 +397,7 @@ static T GenerateVertexShader(API_TYPE api_type) { if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { - AssignVSOutputMembers(out, "vs", "o"); + AssignVSOutputMembers(out, "vs", "o", uid_data->numTexGens, uid_data->pixel_lighting); } else { diff --git a/Source/Core/VideoCommon/VertexShaderGen.h b/Source/Core/VideoCommon/VertexShaderGen.h index 959226ea15..16931ec26d 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.h +++ b/Source/Core/VideoCommon/VertexShaderGen.h @@ -37,10 +37,13 @@ struct vertex_shader_uid_data u32 numColorChans : 2; u32 dualTexTrans_enabled : 1; u32 pixel_lighting : 1; - u32 pad : 1; + u32 msaa : 1; + u32 ssaa : 1; u32 texMtxInfo_n_projection : 16; // Stored separately to guarantee that the texMtxInfo struct is // 8 bits wide + u32 pad : 15; + struct { u32 inputform : 2;