Merge pull request #7729 from stenzek/adreno-sillyness
ShaderGen: Fix broken rendering on Adreno Vulkan drivers
This commit is contained in:
commit
224b23b979
|
@ -39,11 +39,9 @@ GeometryShaderUid GetGeometryShaderUid(PrimitiveType primitive_type)
|
||||||
|
|
||||||
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||||
const geometry_shader_uid_data* uid_data, const char* vertex,
|
const geometry_shader_uid_data* uid_data, const char* vertex,
|
||||||
APIType ApiType, bool wireframe, bool pixel_lighting,
|
APIType ApiType, bool wireframe, bool first_vertex = false);
|
||||||
bool first_vertex = false);
|
|
||||||
static void EndPrimitive(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,
|
const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe);
|
||||||
bool pixel_lighting);
|
|
||||||
|
|
||||||
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
const geometry_shader_uid_data* uid_data)
|
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)
|
// Non-uid template parameters will write to the dummy data (=> gets optimized out)
|
||||||
|
|
||||||
const bool wireframe = host_config.wireframe;
|
const bool wireframe = host_config.wireframe;
|
||||||
const bool pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
|
||||||
const bool msaa = host_config.msaa;
|
const bool msaa = host_config.msaa;
|
||||||
const bool ssaa = host_config.ssaa;
|
const bool ssaa = host_config.ssaa;
|
||||||
const bool stereo = host_config.stereo;
|
const bool stereo = host_config.stereo;
|
||||||
|
@ -96,7 +93,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
"};\n");
|
"};\n");
|
||||||
|
|
||||||
out.Write("struct VS_OUTPUT {\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");
|
out.Write("};\n");
|
||||||
|
|
||||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
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("#define InstanceID gl_InvocationID\n");
|
||||||
|
|
||||||
out.Write("VARYING_LOCATION(0) in VertexData {\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));
|
GetInterpolationQualifier(msaa, ssaa, true, true));
|
||||||
out.Write("} vs[%d];\n", vertex_in);
|
out.Write("} vs[%d];\n", vertex_in);
|
||||||
|
|
||||||
out.Write("VARYING_LOCATION(0) out VertexData {\n");
|
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));
|
GetInterpolationQualifier(msaa, ssaa, true, false));
|
||||||
|
|
||||||
if (stereo)
|
if (stereo)
|
||||||
|
@ -152,8 +149,8 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
out.Write("\tVS_OUTPUT start, end;\n");
|
out.Write("\tVS_OUTPUT start, end;\n");
|
||||||
AssignVSOutputMembers(out, "start", "vs[0]", uid_data->numTexGens, pixel_lighting);
|
AssignVSOutputMembers(out, "start", "vs[0]", uid_data->numTexGens, host_config);
|
||||||
AssignVSOutputMembers(out, "end", "vs[1]", uid_data->numTexGens, pixel_lighting);
|
AssignVSOutputMembers(out, "end", "vs[1]", uid_data->numTexGens, host_config);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -183,7 +180,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
out.Write("\tVS_OUTPUT center;\n");
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -214,7 +211,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
out.Write("\tVS_OUTPUT f;\n");
|
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 &&
|
if (host_config.backend_depth_clamp &&
|
||||||
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLIP_DISTANCE))
|
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLIP_DISTANCE))
|
||||||
|
@ -266,8 +263,8 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
}
|
}
|
||||||
out.Write("\t}\n");
|
out.Write("\t}\n");
|
||||||
|
|
||||||
EmitVertex(out, host_config, uid_data, "l", ApiType, wireframe, pixel_lighting, true);
|
EmitVertex(out, host_config, uid_data, "l", ApiType, wireframe, true);
|
||||||
EmitVertex(out, host_config, uid_data, "r", ApiType, wireframe, pixel_lighting);
|
EmitVertex(out, host_config, uid_data, "r", ApiType, wireframe);
|
||||||
}
|
}
|
||||||
else if (primitive_type == PrimitiveType::Points)
|
else if (primitive_type == PrimitiveType::Points)
|
||||||
{
|
{
|
||||||
|
@ -295,19 +292,19 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
}
|
}
|
||||||
out.Write("\t}\n");
|
out.Write("\t}\n");
|
||||||
|
|
||||||
EmitVertex(out, host_config, uid_data, "ll", ApiType, wireframe, pixel_lighting, true);
|
EmitVertex(out, host_config, uid_data, "ll", ApiType, wireframe, true);
|
||||||
EmitVertex(out, host_config, uid_data, "lr", ApiType, wireframe, pixel_lighting);
|
EmitVertex(out, host_config, uid_data, "lr", ApiType, wireframe);
|
||||||
EmitVertex(out, host_config, uid_data, "ul", ApiType, wireframe, pixel_lighting);
|
EmitVertex(out, host_config, uid_data, "ul", ApiType, wireframe);
|
||||||
EmitVertex(out, host_config, uid_data, "ur", ApiType, wireframe, pixel_lighting);
|
EmitVertex(out, host_config, uid_data, "ur", ApiType, wireframe);
|
||||||
}
|
}
|
||||||
else
|
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");
|
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)
|
if (stereo && !host_config.backend_gs_instancing)
|
||||||
out.Write("\t}\n");
|
out.Write("\t}\n");
|
||||||
|
@ -319,7 +316,7 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& h
|
||||||
|
|
||||||
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||||
const geometry_shader_uid_data* uid_data, const char* vertex,
|
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)
|
if (wireframe && first_vertex)
|
||||||
out.Write("\tif (i == 0) first = %s;\n", 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[0] = %s.clipDist0;\n", vertex);
|
||||||
out.Write("\tgl_ClipDistance[1] = %s.clipDist1;\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)
|
else if (ApiType == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
||||||
out.Write("\tgl_Position = %s.pos;\n", vertex);
|
out.Write("\tgl_Position = %s.pos;\n", vertex);
|
||||||
out.Write("\tgl_Position.y = -gl_Position.y;\n");
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -353,11 +350,10 @@ static void EmitVertex(ShaderCode& out, const ShaderHostConfig& host_config,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EndPrimitive(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,
|
const geometry_shader_uid_data* uid_data, APIType ApiType, bool wireframe)
|
||||||
bool pixel_lighting)
|
|
||||||
{
|
{
|
||||||
if (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)
|
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
|
||||||
out.Write("\tEndPrimitive();\n");
|
out.Write("\tEndPrimitive();\n");
|
||||||
|
|
|
@ -351,7 +351,7 @@ void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host
|
||||||
}
|
}
|
||||||
|
|
||||||
void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
|
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
|
// dot product for integer vectors
|
||||||
out.Write("int idot(int3 x, int3 y)\n"
|
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_tevorder(i) (bpmem_pack2[(i)].x)\n"
|
||||||
"#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\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);
|
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");
|
out.Write("struct VS_OUTPUT {\n");
|
||||||
GenerateVSOutputMembers(out, ApiType, num_texgens, per_pixel_lighting, "");
|
GenerateVSOutputMembers(out, ApiType, num_texgens, host_config, "");
|
||||||
out.Write("};\n");
|
out.Write("};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
|
||||||
uid_data->genMode_numindstages);
|
uid_data->genMode_numindstages);
|
||||||
|
|
||||||
// Stuff that is shared between ubershaders and pixelgen.
|
// 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);
|
uid_data->bounding_box);
|
||||||
|
|
||||||
if (uid_data->forced_early_z && g_ActiveConfig.backend_info.bSupportsEarlyZ)
|
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)
|
if (uid_data->per_pixel_depth)
|
||||||
out.Write("#define depth gl_FragDepth\n");
|
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)
|
||||||
if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan)
|
|
||||||
{
|
{
|
||||||
out.Write("VARYING_LOCATION(0) in VertexData {\n");
|
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));
|
GetInterpolationQualifier(msaa, ssaa, true, true));
|
||||||
|
|
||||||
if (stereo)
|
if (stereo)
|
||||||
|
@ -601,19 +600,26 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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)
|
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)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write("%s in float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa));
|
out.Write("VARYING_LOCATION(%u) %s in float3 Normal;\n", counter++,
|
||||||
out.Write("%s in float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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)
|
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,
|
out.Write(",\n in %s float3 tex%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i,
|
||||||
i);
|
i);
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
|
{
|
||||||
out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa),
|
out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa),
|
||||||
uid_data->genMode_numtexgens);
|
uid_data->genMode_numtexgens);
|
||||||
|
}
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write(",\n in %s float3 Normal : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa),
|
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),
|
out.Write(",\n in %s float3 WorldPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa),
|
||||||
uid_data->genMode_numtexgens + 2);
|
uid_data->genMode_numtexgens + 2);
|
||||||
}
|
}
|
||||||
|
if (host_config.backend_geometry_shaders)
|
||||||
|
{
|
||||||
out.Write(",\n in float clipDist0 : SV_ClipDistance0\n");
|
out.Write(",\n in float clipDist0 : SV_ClipDistance0\n");
|
||||||
out.Write(",\n in float clipDist1 : SV_ClipDistance1\n");
|
out.Write(",\n in float clipDist1 : SV_ClipDistance1\n");
|
||||||
|
}
|
||||||
if (stereo)
|
if (stereo)
|
||||||
out.Write(",\n in uint layer : SV_RenderTargetArrayIndex\n");
|
out.Write(",\n in uint layer : SV_RenderTargetArrayIndex\n");
|
||||||
out.Write(" ) {\n");
|
out.Write(" ) {\n");
|
||||||
|
|
|
@ -167,7 +167,7 @@ typedef ShaderUid<pixel_shader_uid_data> PixelShaderUid;
|
||||||
ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
const pixel_shader_uid_data* uid_data);
|
const pixel_shader_uid_data* uid_data);
|
||||||
void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
|
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,
|
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
PixelShaderUid* uid);
|
PixelShaderUid* uid);
|
||||||
PixelShaderUid GetPixelShaderUid();
|
PixelShaderUid GetPixelShaderUid();
|
||||||
|
|
|
@ -214,7 +214,7 @@ inline void DefineOutputMember(T& object, APIType api_type, const char* qualifie
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void GenerateVSOutputMembers(T& object, APIType api_type, u32 texgens,
|
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", "pos", -1, "POSITION");
|
||||||
DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 0, "COLOR", 0);
|
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)
|
for (unsigned int i = 0; i < texgens; ++i)
|
||||||
DefineOutputMember(object, api_type, qualifier, "float3", "tex", i, "TEXCOORD", i);
|
DefineOutputMember(object, api_type, qualifier, "float3", "tex", i, "TEXCOORD", i);
|
||||||
|
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", texgens);
|
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",
|
DefineOutputMember(object, api_type, qualifier, "float3", "Normal", -1, "TEXCOORD",
|
||||||
texgens + 1);
|
texgens + 1);
|
||||||
|
@ -233,13 +234,16 @@ inline void GenerateVSOutputMembers(T& object, APIType api_type, u32 texgens,
|
||||||
texgens + 2);
|
texgens + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host_config.backend_geometry_shaders)
|
||||||
|
{
|
||||||
DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 0, "SV_ClipDistance", 0);
|
DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 0, "SV_ClipDistance", 0);
|
||||||
DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 1, "SV_ClipDistance", 1);
|
DefineOutputMember(object, api_type, qualifier, "float", "clipDist", 1, "SV_ClipDistance", 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void AssignVSOutputMembers(T& object, const char* a, const char* b, u32 texgens,
|
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.pos = %s.pos;\n", a, b);
|
||||||
object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b);
|
object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b);
|
||||||
|
@ -248,17 +252,21 @@ inline void AssignVSOutputMembers(T& object, const char* a, const char* b, u32 t
|
||||||
for (unsigned int i = 0; i < texgens; ++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.tex%d = %s.tex%d;\n", a, i, b, i);
|
||||||
|
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
object.Write("\t%s.clipPos = %s.clipPos;\n", a, b);
|
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.Normal = %s.Normal;\n", a, b);
|
||||||
object.Write("\t%s.WorldPos = %s.WorldPos;\n", a, b);
|
object.Write("\t%s.WorldPos = %s.WorldPos;\n", a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host_config.backend_geometry_shaders)
|
||||||
|
{
|
||||||
object.Write("\t%s.clipDist0 = %s.clipDist0;\n", a, b);
|
object.Write("\t%s.clipDist0 = %s.clipDist0;\n", a, b);
|
||||||
object.Write("\t%s.clipDist1 = %s.clipDist1;\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
|
// We use the flag "centroid" to fix some MSAA rendering bugs. With MSAA, the
|
||||||
// pixel shader will be executed for each pixel which has at least one passed sample.
|
// pixel shader will be executed for each pixel which has at least one passed sample.
|
||||||
|
|
|
@ -59,7 +59,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
|
|
||||||
out.Write("// Pixel UberShader for %u texgens%s%s\n", numTexgen,
|
out.Write("// Pixel UberShader for %u texgens%s%s\n", numTexgen,
|
||||||
early_depth ? ", early-depth" : "", per_pixel_depth ? ", per-pixel depth" : "");
|
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);
|
WriteUberShaderCommonHeader(out, ApiType, host_config);
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
WriteLightingFunction(out);
|
WriteLightingFunction(out);
|
||||||
|
@ -103,10 +103,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
if (per_pixel_depth)
|
if (per_pixel_depth)
|
||||||
out.Write("#define depth gl_FragDepth\n");
|
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");
|
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));
|
GetInterpolationQualifier(msaa, ssaa, true, true));
|
||||||
|
|
||||||
if (stereo)
|
if (stereo)
|
||||||
|
@ -116,17 +116,26 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
}
|
}
|
||||||
else
|
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
|
// Let's set up attributes
|
||||||
for (u32 i = 0; i < numTexgen; ++i)
|
u32 counter = 0;
|
||||||
out.Write("%s in float3 tex%d;\n", GetInterpolationQualifier(msaa, ssaa), i);
|
out.Write("VARYING_LOCATION(%u) %s in float4 colors_0;\n", counter++,
|
||||||
out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write("%s in float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa));
|
out.Write("VARYING_LOCATION(%u) %s in float3 Normal;\n", counter++,
|
||||||
out.Write("%s in float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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)
|
for (u32 i = 0; i < numTexgen; ++i)
|
||||||
out.Write(",\n in %s float3 tex%u : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), i,
|
out.Write(",\n in %s float3 tex%u : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa), i,
|
||||||
i);
|
i);
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
|
{
|
||||||
out.Write("\n,\n in %s float4 clipPos : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa),
|
out.Write("\n,\n in %s float4 clipPos : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa),
|
||||||
numTexgen);
|
numTexgen);
|
||||||
|
}
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write(",\n in %s float3 Normal : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa),
|
out.Write(",\n in %s float3 Normal : TEXCOORD%u", GetInterpolationQualifier(msaa, ssaa),
|
||||||
|
|
|
@ -45,7 +45,7 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
out.Write("};\n");
|
out.Write("};\n");
|
||||||
|
|
||||||
out.Write("struct VS_OUTPUT {\n");
|
out.Write("struct VS_OUTPUT {\n");
|
||||||
GenerateVSOutputMembers(out, ApiType, numTexgen, per_pixel_lighting, "");
|
GenerateVSOutputMembers(out, ApiType, numTexgen, host_config, "");
|
||||||
out.Write("};\n\n");
|
out.Write("};\n\n");
|
||||||
|
|
||||||
WriteUberShaderCommonHeader(out, ApiType, host_config);
|
WriteUberShaderCommonHeader(out, ApiType, host_config);
|
||||||
|
@ -63,28 +63,38 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
out.Write("ATTRIBUTE_LOCATION(%d) in float3 rawtex%d;\n", SHADER_TEXTURE0_ATTRIB + i, 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)
|
||||||
if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan)
|
|
||||||
{
|
{
|
||||||
out.Write("VARYING_LOCATION(0) out VertexData {\n");
|
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));
|
GetInterpolationQualifier(msaa, ssaa, true, false));
|
||||||
out.Write("} vs;\n");
|
out.Write("} vs;\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Let's set up attributes
|
// 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)
|
for (u32 i = 0; i < numTexgen; ++i)
|
||||||
out.Write("%s out float3 tex%u;\n", GetInterpolationQualifier(msaa, ssaa), i);
|
{
|
||||||
|
out.Write("VARYING_LOCATION(%u) %s out float3 tex%u;\n", counter++,
|
||||||
out.Write("%s out float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write("%s out float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa));
|
out.Write("VARYING_LOCATION(%u) %s out float3 Normal;\n", counter++,
|
||||||
out.Write("%s out float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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");
|
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(" o.colors_1 = float4(1.0, 1.0, 1.0, 1.0);\n");
|
||||||
out.Write("}\n");
|
out.Write("}\n");
|
||||||
|
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
|
{
|
||||||
// clipPos/w needs to be done in pixel shader, not here
|
// clipPos/w needs to be done in pixel shader, not here
|
||||||
out.Write("o.clipPos = o.pos;\n");
|
out.Write("o.clipPos = o.pos;\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (per_pixel_lighting)
|
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
|
// 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.
|
// 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("float clipDepth = o.pos.z * (1.0 - 1e-7);\n");
|
||||||
out.Write("o.clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w
|
out.Write("float clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w
|
||||||
out.Write("o.clipDist1 = -clipDepth;\n"); // Far: z > 0
|
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
|
// 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 (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
|
else
|
||||||
{
|
{
|
||||||
|
@ -277,6 +295,7 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
// are not supported, however that will require at least OpenGL 3.2 support.
|
// are not supported, however that will require at least OpenGL 3.2 support.
|
||||||
for (u32 i = 0; i < numTexgen; ++i)
|
for (u32 i = 0; i < numTexgen; ++i)
|
||||||
out.Write("tex%d.xyz = o.tex%d;\n", i, i);
|
out.Write("tex%d.xyz = o.tex%d;\n", i, i);
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
out.Write("clipPos = o.clipPos;\n");
|
out.Write("clipPos = o.clipPos;\n");
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
|
@ -289,8 +308,8 @@ ShaderCode GenVertexShader(APIType ApiType, const ShaderHostConfig& host_config,
|
||||||
|
|
||||||
if (host_config.backend_depth_clamp)
|
if (host_config.backend_depth_clamp)
|
||||||
{
|
{
|
||||||
out.Write("gl_ClipDistance[0] = o.clipDist0;\n");
|
out.Write("gl_ClipDistance[0] = clipDist0;\n");
|
||||||
out.Write("gl_ClipDistance[1] = o.clipDist1;\n");
|
out.Write("gl_ClipDistance[1] = clipDist1;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
||||||
|
@ -477,4 +496,4 @@ void EnumerateVertexShaderUids(const std::function<void(const VertexShaderUid&)>
|
||||||
callback(uid);
|
callback(uid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace UberShader
|
||||||
|
|
|
@ -98,7 +98,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
out.Write("};\n");
|
out.Write("};\n");
|
||||||
|
|
||||||
out.Write("struct VS_OUTPUT {\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");
|
out.Write("};\n");
|
||||||
|
|
||||||
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
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)
|
||||||
if (host_config.backend_geometry_shaders || api_type == APIType::Vulkan)
|
|
||||||
{
|
{
|
||||||
out.Write("VARYING_LOCATION(0) out VertexData {\n");
|
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));
|
GetInterpolationQualifier(msaa, ssaa, true, false));
|
||||||
out.Write("} vs;\n");
|
out.Write("} vs;\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Let's set up attributes
|
// 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("VARYING_LOCATION(%u) %s out float3 tex%u;\n", counter++,
|
||||||
{
|
GetInterpolationQualifier(msaa, ssaa), i);
|
||||||
out.Write("%s out float3 tex%u;\n", GetInterpolationQualifier(msaa, ssaa), i);
|
|
||||||
}
|
}
|
||||||
}
|
if (!host_config.fast_depth_calc)
|
||||||
out.Write("%s out float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
out.Write("VARYING_LOCATION(%u) %s out float4 clipPos;\n", counter++,
|
||||||
|
GetInterpolationQualifier(msaa, ssaa));
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
out.Write("%s out float3 Normal;\n", GetInterpolationQualifier(msaa, ssaa));
|
out.Write("VARYING_LOCATION(%u) %s out float3 Normal;\n", counter++,
|
||||||
out.Write("%s out float3 WorldPos;\n", GetInterpolationQualifier(msaa, ssaa));
|
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");
|
out.Write("void main()\n{\n");
|
||||||
|
@ -398,6 +402,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
}
|
}
|
||||||
|
|
||||||
// clipPos/w needs to be done in pixel shader, not here
|
// clipPos/w needs to be done in pixel shader, not here
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
out.Write("o.clipPos = o.pos;\n");
|
out.Write("o.clipPos = o.pos;\n");
|
||||||
|
|
||||||
if (per_pixel_lighting)
|
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
|
// 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.
|
// 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("float clipDepth = o.pos.z * (1.0 - 1e-7);\n");
|
||||||
out.Write("o.clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w
|
out.Write("float clipDist0 = clipDepth + o.pos.w;\n"); // Near: z < -w
|
||||||
out.Write("o.clipDist1 = -clipDepth;\n"); // Far: z > 0
|
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
|
// 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 (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
|
else
|
||||||
{
|
{
|
||||||
|
@ -495,6 +505,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
// are not supported, however that will require at least OpenGL 3.2 support.
|
// are not supported, however that will require at least OpenGL 3.2 support.
|
||||||
for (unsigned int i = 0; i < uid_data->numTexGens; ++i)
|
for (unsigned int i = 0; i < uid_data->numTexGens; ++i)
|
||||||
out.Write("tex%d.xyz = o.tex%d;\n", i, i);
|
out.Write("tex%d.xyz = o.tex%d;\n", i, i);
|
||||||
|
if (!host_config.fast_depth_calc)
|
||||||
out.Write("clipPos = o.clipPos;\n");
|
out.Write("clipPos = o.clipPos;\n");
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
{
|
{
|
||||||
|
@ -507,8 +518,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
|
|
||||||
if (host_config.backend_depth_clamp)
|
if (host_config.backend_depth_clamp)
|
||||||
{
|
{
|
||||||
out.Write("gl_ClipDistance[0] = o.clipDist0;\n");
|
out.Write("gl_ClipDistance[0] = clipDist0;\n");
|
||||||
out.Write("gl_ClipDistance[1] = o.clipDist1;\n");
|
out.Write("gl_ClipDistance[1] = clipDist1;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
// Vulkan NDC space has Y pointing down (right-handed NDC space).
|
||||||
|
|
Loading…
Reference in New Issue