mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
Multithreadded Shadergen: Second Pass over geometery Shadergen
This commit is contained in:
@ -20,34 +20,40 @@ static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_
|
||||
template <class T>
|
||||
static void EndPrimitive(T& out, API_TYPE ApiType);
|
||||
|
||||
template <class T>
|
||||
static void EmitVertex(T& out, geometry_shader_uid_data* uid_data, const char* vertex,
|
||||
API_TYPE ApiType, bool first_vertex = false);
|
||||
template <class T>
|
||||
static void EndPrimitive(T& out, geometry_shader_uid_data* uid_data, API_TYPE ApiType);
|
||||
|
||||
template <class T>
|
||||
static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
GeometryShaderUid GetGeometryShaderUid(u32 primitive_type)
|
||||
{
|
||||
T out;
|
||||
// Non-uid template parameters will write to the dummy data (=> gets optimized out)
|
||||
geometry_shader_uid_data dummy_data;
|
||||
geometry_shader_uid_data* uid_data = out.template GetUidData<geometry_shader_uid_data>();
|
||||
if (uid_data == nullptr)
|
||||
uid_data = &dummy_data;
|
||||
memset(uid_data, 0, sizeof(*uid_data));
|
||||
ShaderUid<geometry_shader_uid_data> out;
|
||||
geometry_shader_uid_data* uid_data = out.GetUidData<geometry_shader_uid_data>();
|
||||
memset(uid_data, 0, sizeof(geometry_shader_uid_data));
|
||||
|
||||
uid_data->primitive_type = primitive_type;
|
||||
const unsigned int vertex_in = primitive_type + 1;
|
||||
unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4;
|
||||
|
||||
uid_data->wireframe = g_ActiveConfig.bWireFrame;
|
||||
if (uid_data->wireframe)
|
||||
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;
|
||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
const char* vertex, API_TYPE ApiType, bool first_vertex = false);
|
||||
static void EndPrimitive(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
API_TYPE ApiType);
|
||||
|
||||
ShaderCode GenerateGeometryShaderCode(u32 primitive_type, API_TYPE ApiType,
|
||||
const geometry_shader_uid_data* uid_data)
|
||||
{
|
||||
ShaderCode out;
|
||||
// Non-uid template parameters will write to the dummy data (=> gets optimized out)
|
||||
|
||||
const unsigned int vertex_in = primitive_type + 1;
|
||||
unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4;
|
||||
|
||||
if (uid_data->wireframe)
|
||||
vertex_out++;
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
{
|
||||
// Insert layout parameters
|
||||
@ -80,11 +86,10 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
"\tint4 " I_TEXOFFSET ";\n"
|
||||
"};\n");
|
||||
|
||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
|
||||
out.Write("struct VS_OUTPUT {\n");
|
||||
GenerateVSOutputMembers<T>(out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting, "");
|
||||
GenerateVSOutputMembers<ShaderCode>(out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting,
|
||||
"");
|
||||
out.Write("};\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
@ -93,13 +98,13 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
out.Write("#define InstanceID gl_InvocationID\n");
|
||||
|
||||
out.Write("in VertexData {\n");
|
||||
GenerateVSOutputMembers<T>(
|
||||
GenerateVSOutputMembers<ShaderCode>(
|
||||
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<T>(
|
||||
GenerateVSOutputMembers<ShaderCode>(
|
||||
out, ApiType, uid_data->numTexGens, uid_data->pixel_lighting,
|
||||
GetInterpolationQualifier(uid_data->msaa, uid_data->ssaa, false, true));
|
||||
|
||||
@ -248,8 +253,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
}
|
||||
out.Write("\t}\n");
|
||||
|
||||
EmitVertex<T>(out, uid_data, "l", ApiType, true);
|
||||
EmitVertex<T>(out, uid_data, "r", ApiType);
|
||||
EmitVertex(out, uid_data, "l", ApiType, true);
|
||||
EmitVertex(out, uid_data, "r", ApiType);
|
||||
}
|
||||
else if (primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
@ -277,19 +282,19 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
}
|
||||
out.Write("\t}\n");
|
||||
|
||||
EmitVertex<T>(out, uid_data, "ll", ApiType, true);
|
||||
EmitVertex<T>(out, uid_data, "lr", ApiType);
|
||||
EmitVertex<T>(out, uid_data, "ul", ApiType);
|
||||
EmitVertex<T>(out, uid_data, "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<T>(out, uid_data, "f", ApiType, true);
|
||||
EmitVertex(out, uid_data, "f", ApiType, true);
|
||||
}
|
||||
|
||||
out.Write("\t}\n");
|
||||
|
||||
EndPrimitive<T>(out, uid_data, ApiType);
|
||||
EndPrimitive(out, uid_data, ApiType);
|
||||
|
||||
if (uid_data->stereo && !g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
out.Write("\t}\n");
|
||||
@ -299,9 +304,8 @@ static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void EmitVertex(T& out, geometry_shader_uid_data* uid_data, const char* vertex,
|
||||
API_TYPE ApiType, bool first_vertex)
|
||||
static void EmitVertex(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
const char* vertex, API_TYPE ApiType, bool first_vertex)
|
||||
{
|
||||
if (uid_data->wireframe && first_vertex)
|
||||
out.Write("\tif (i == 0) first = %s;\n", vertex);
|
||||
@ -321,24 +325,15 @@ static void EmitVertex(T& out, geometry_shader_uid_data* uid_data, const char* v
|
||||
else
|
||||
out.Write("\toutput.Append(ps);\n");
|
||||
}
|
||||
template <class T>
|
||||
static void EndPrimitive(T& out, geometry_shader_uid_data* uid_data, API_TYPE ApiType)
|
||||
|
||||
static void EndPrimitive(ShaderCode& out, const geometry_shader_uid_data* uid_data,
|
||||
API_TYPE ApiType)
|
||||
{
|
||||
if (uid_data->wireframe)
|
||||
EmitVertex<T>(out, uid_data, "first", ApiType);
|
||||
EmitVertex(out, uid_data, "first", ApiType);
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\tEndPrimitive();\n");
|
||||
else
|
||||
out.Write("\toutput.RestartStrip();\n");
|
||||
}
|
||||
|
||||
GeometryShaderUid GetGeometryShaderUid(u32 primitive_type, API_TYPE ApiType)
|
||||
{
|
||||
return GenerateGeometryShader<GeometryShaderUid>(primitive_type, ApiType);
|
||||
}
|
||||
|
||||
ShaderCode GenerateGeometryShaderCode(u32 primitive_type, API_TYPE ApiType)
|
||||
{
|
||||
return GenerateGeometryShader<ShaderCode>(primitive_type, ApiType);
|
||||
}
|
||||
|
Reference in New Issue
Block a user