VideoCommon: Don't pass structs between shaders, use the interface blocks instead.
This commit is contained in:
parent
2c0bee5da9
commit
7eb353b3bd
|
@ -462,8 +462,7 @@ Renderer::Renderer()
|
|||
g_Config.backend_info.bSupportsEarlyZ = GLExtensions::Supports("GL_ARB_shader_image_load_store");
|
||||
g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
|
||||
g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
|
||||
g_Config.backend_info.bSupportsGeometryShaders = (GLExtensions::Version() >= 320) &&
|
||||
!DriverDetails::HasBug(DriverDetails::BUG_INTELBROKENSTRUCTS);
|
||||
g_Config.backend_info.bSupportsGeometryShaders = GLExtensions::Version() >= 320;
|
||||
|
||||
// Desktop OpenGL supports the binding layout if it supports 420pack
|
||||
// OpenGL ES 3.1 supports it implicitly without an extension
|
||||
|
|
|
@ -84,7 +84,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
uid_data->numTexGens = bpmem.genMode.numtexgens;
|
||||
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
|
||||
GenerateVSOutputStruct<T>(out, ApiType);
|
||||
out.Write("struct VS_OUTPUT {\n");
|
||||
GenerateVSOutputMembers<T>(out, ApiType);
|
||||
out.Write("};\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
{
|
||||
|
@ -92,11 +94,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
out.Write("#define InstanceID gl_InvocationID\n");
|
||||
|
||||
out.Write("in VertexData {\n");
|
||||
out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "in");
|
||||
GenerateVSOutputMembers<T>(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid in");
|
||||
out.Write("} vs[%d];\n", vertex_in);
|
||||
|
||||
out.Write("out VertexData {\n");
|
||||
out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "out");
|
||||
GenerateVSOutputMembers<T>(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid out");
|
||||
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
out.Write("\tflat int layer;\n");
|
||||
|
@ -133,8 +135,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
{
|
||||
if (ApiType == API_OPENGL)
|
||||
{
|
||||
out.Write("\tVS_OUTPUT start = vs[0].o;\n");
|
||||
out.Write("\tVS_OUTPUT end = vs[1].o;\n");
|
||||
out.Write("\tVS_OUTPUT start, end;\n");
|
||||
AssignVSOutputMembers(out, "start", "vs[0]");
|
||||
AssignVSOutputMembers(out, "end", "vs[1]");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -163,9 +166,14 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
else if (primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\tVS_OUTPUT center = vs[0].o;\n");
|
||||
{
|
||||
out.Write("\tVS_OUTPUT center;\n");
|
||||
AssignVSOutputMembers(out, "center", "vs[0]");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Write("\tVS_OUTPUT center = o[0];\n");
|
||||
}
|
||||
|
||||
// Offset from center to upper right vertex
|
||||
// Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1]
|
||||
|
@ -188,9 +196,14 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in);
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\tVS_OUTPUT f = vs[i].o;\n");
|
||||
{
|
||||
out.Write("\tVS_OUTPUT f;\n");
|
||||
AssignVSOutputMembers(out, "f", "vs[i]");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Write("\tVS_OUTPUT f = o[i];\n");
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
{
|
||||
|
@ -289,9 +302,14 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool
|
|||
out.Write("\tif (i == 0) first = %s;\n", vertex);
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
{
|
||||
out.Write("\tgl_Position = %s.pos;\n", vertex);
|
||||
|
||||
out.Write("\tps.o = %s;\n", vertex);
|
||||
AssignVSOutputMembers(out, "ps", vertex);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Write("\tps.o = %s;\n", vertex);
|
||||
}
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\tEmitVertex();\n");
|
||||
|
|
|
@ -264,7 +264,9 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
|||
}
|
||||
}
|
||||
|
||||
GenerateVSOutputStruct<T>(out, ApiType);
|
||||
out.Write("struct VS_OUTPUT {\n");
|
||||
GenerateVSOutputMembers<T>(out, ApiType);
|
||||
out.Write("};\n");
|
||||
|
||||
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
||||
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z);
|
||||
|
@ -320,7 +322,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
|||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
{
|
||||
out.Write("in VertexData {\n");
|
||||
out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "in");
|
||||
GenerateVSOutputMembers<T>(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid in");
|
||||
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
out.Write("\tflat int layer;\n");
|
||||
|
@ -348,23 +350,16 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
|||
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
{
|
||||
// compute window position if needed because binding semantic WPOS is not widely supported
|
||||
// Let's set up attributes
|
||||
for (unsigned int i = 0; i < numTexgen; ++i)
|
||||
{
|
||||
out.Write("\tfloat3 uv%d = o.tex%d;\n", i, i);
|
||||
}
|
||||
out.Write("\tfloat4 clipPos = o.clipPos;\n");
|
||||
if (g_ActiveConfig.bEnablePixelLighting)
|
||||
{
|
||||
out.Write("\tfloat4 Normal = o.Normal;\n");
|
||||
}
|
||||
out.Write("\tfloat3 uv%d = tex%d;\n", i, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// On Mali, global variables must be initialized as constants.
|
||||
// This is why we initialize these variables locally instead.
|
||||
out.Write("\tfloat4 colors_0 = colors_02;\n");
|
||||
out.Write("\tfloat4 colors_1 = colors_12;\n");
|
||||
}
|
||||
|
||||
// On Mali, global variables must be initialized as constants.
|
||||
// This is why we initialize these variables locally instead.
|
||||
out.Write("\tfloat4 colors_0 = %s;\n", g_ActiveConfig.backend_info.bSupportsGeometryShaders ? "o.colors_0" : "colors_02");
|
||||
out.Write("\tfloat4 colors_1 = %s;\n", g_ActiveConfig.backend_info.bSupportsGeometryShaders ? "o.colors_1" : "colors_12");
|
||||
|
||||
out.Write("\tfloat4 rawpos = gl_FragCoord;\n");
|
||||
}
|
||||
|
|
|
@ -221,9 +221,13 @@ private:
|
|||
};
|
||||
|
||||
template<class T>
|
||||
static void DefineOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1)
|
||||
static void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifier, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1)
|
||||
{
|
||||
object.Write(" %s %s", type, name);
|
||||
if (qualifier != nullptr)
|
||||
object.Write("\t%s %s %s", qualifier, type, name);
|
||||
else
|
||||
object.Write("\t%s %s", type, name);
|
||||
|
||||
if (var_index != -1)
|
||||
object.Write("%d", var_index);
|
||||
|
||||
|
@ -239,23 +243,35 @@ static void DefineOutputStructMember(T& object, API_TYPE api_type, const char* t
|
|||
}
|
||||
|
||||
template<class T>
|
||||
static inline void GenerateVSOutputStruct(T& object, API_TYPE api_type)
|
||||
static inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const char* qualifier = nullptr)
|
||||
{
|
||||
object.Write("struct VS_OUTPUT {\n");
|
||||
|
||||
DefineOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION");
|
||||
DefineOutputStructMember(object, api_type, "float4", "colors_", 0, "COLOR", 0);
|
||||
DefineOutputStructMember(object, api_type, "float4", "colors_", 1, "COLOR", 1);
|
||||
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)
|
||||
DefineOutputStructMember(object, api_type, "float3", "tex", i, "TEXCOORD", i);
|
||||
DefineOutputMember(object, api_type, qualifier, "float3", "tex", i, "TEXCOORD", i);
|
||||
|
||||
DefineOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens);
|
||||
DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens);
|
||||
|
||||
if (g_ActiveConfig.bEnablePixelLighting)
|
||||
DefineOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1);
|
||||
DefineOutputMember(object, api_type, qualifier, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1);
|
||||
}
|
||||
|
||||
object.Write("};\n");
|
||||
template<class T>
|
||||
static inline void AssignVSOutputMembers(T& object, const char* a, const char* b)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
object.Write("\t%s.Normal = %s.Normal;\n", a, b);
|
||||
}
|
||||
|
||||
// Constant variable names
|
||||
|
|
|
@ -42,7 +42,9 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
|||
out.Write(s_shader_uniforms);
|
||||
out.Write("};\n");
|
||||
|
||||
GenerateVSOutputStruct<T>(out, api_type);
|
||||
out.Write("struct VS_OUTPUT {\n");
|
||||
GenerateVSOutputMembers<T>(out, api_type);
|
||||
out.Write("};\n");
|
||||
|
||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||
uid_data->components = components;
|
||||
|
@ -74,9 +76,9 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
|||
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
{
|
||||
out.Write("out VertexData {\n"
|
||||
"\tcentroid %s VS_OUTPUT o;\n"
|
||||
"};\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "out");
|
||||
out.Write("out VertexData {\n");
|
||||
GenerateVSOutputMembers<T>(out, api_type, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid out");
|
||||
out.Write("} o;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue