Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShaderGen: Fix broken rendering on Adreno Vulkan drivers #7729

Merged
merged 2 commits into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions Source/Core/VideoCommon/GeometryShaderGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -96,7 +93,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
"};\n");

out.Write("struct VS_OUTPUT {\n");
GenerateVSOutputMembers<ShaderCode>(out, ApiType, uid_data->numTexGens, pixel_lighting, "");
GenerateVSOutputMembers<ShaderCode>(out, ApiType, uid_data->numTexGens, host_config, "");
out.Write("};\n");

if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
Expand All @@ -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<ShaderCode>(out, ApiType, uid_data->numTexGens, pixel_lighting,
GenerateVSOutputMembers<ShaderCode>(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<ShaderCode>(out, ApiType, uid_data->numTexGens, pixel_lighting,
GenerateVSOutputMembers<ShaderCode>(out, ApiType, uid_data->numTexGens, host_config,
GetInterpolationQualifier(msaa, ssaa, true, false));

if (stereo)
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand All @@ -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
{
Expand All @@ -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");
Expand Down
48 changes: 30 additions & 18 deletions Source/Core/VideoCommon/PixelShaderGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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");
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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));
}
}

Expand Down Expand Up @@ -646,17 +652,23 @@ 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),
uid_data->genMode_numtexgens + 1);
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");
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/PixelShaderGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ typedef ShaderUid<pixel_shader_uid_data> 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();
28 changes: 18 additions & 10 deletions Source/Core/VideoCommon/ShaderGenCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ inline void DefineOutputMember(T& object, APIType api_type, const char* qualifie

template <class T>
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);
Expand All @@ -223,23 +223,27 @@ 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);
DefineOutputMember(object, api_type, qualifier, "float3", "WorldPos", -1, "TEXCOORD",
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 <class T>
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);
Expand All @@ -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
Expand Down
Loading