Merge pull request #10090 from Pokechu22/d3d-isnan-replacement
Use custom isnan implementation to avoid HLSL optimizer issues
This commit is contained in:
commit
5538e90ebf
|
@ -87,6 +87,24 @@ std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteIsNanHeader(ShaderCode& out, APIType api_type)
|
||||||
|
{
|
||||||
|
if (api_type == APIType::D3D)
|
||||||
|
{
|
||||||
|
out.Write("bool dolphin_isnan(float f) {{\n"
|
||||||
|
" // Workaround for the HLSL compiler deciding that isnan can never be true and\n"
|
||||||
|
" // optimising away the call, even though the value can actually be NaN\n"
|
||||||
|
" // Just look for the bit pattern that indicates NaN instead\n"
|
||||||
|
" return (asint(f) & 0x7FFFFFFF) > 0x7F800000;\n"
|
||||||
|
"}}\n\n");
|
||||||
|
// If isfinite is needed, (asint(f) & 0x7F800000) != 0x7F800000 can be used
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.Write("#define dolphin_isnan(f) isnan(f)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void DefineOutputMember(ShaderCode& object, APIType api_type, std::string_view qualifier,
|
static void DefineOutputMember(ShaderCode& object, APIType api_type, std::string_view qualifier,
|
||||||
std::string_view type, std::string_view name, int var_index,
|
std::string_view type, std::string_view name, int var_index,
|
||||||
std::string_view semantic = {}, int semantic_index = -1)
|
std::string_view semantic = {}, int semantic_index = -1)
|
||||||
|
|
|
@ -176,6 +176,8 @@ union ShaderHostConfig
|
||||||
std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool include_gameid,
|
std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool include_gameid,
|
||||||
bool include_host_config, bool include_api = true);
|
bool include_host_config, bool include_api = true);
|
||||||
|
|
||||||
|
void WriteIsNanHeader(ShaderCode& out, APIType api_type);
|
||||||
|
|
||||||
void GenerateVSOutputMembers(ShaderCode& object, APIType api_type, u32 texgens,
|
void GenerateVSOutputMembers(ShaderCode& object, APIType api_type, u32 texgens,
|
||||||
const ShaderHostConfig& host_config, std::string_view qualifier);
|
const ShaderHostConfig& host_config, std::string_view qualifier);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ ShaderCode GenVertexShader(APIType api_type, const ShaderHostConfig& host_config
|
||||||
out.Write("}};\n\n");
|
out.Write("}};\n\n");
|
||||||
|
|
||||||
WriteUberShaderCommonHeader(out, api_type, host_config);
|
WriteUberShaderCommonHeader(out, api_type, host_config);
|
||||||
|
WriteIsNanHeader(out, api_type);
|
||||||
WriteLightingFunction(out);
|
WriteLightingFunction(out);
|
||||||
|
|
||||||
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
||||||
|
@ -438,9 +439,9 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
|
||||||
// Convert NaNs to 1 - needed to fix eyelids in Shadow the Hedgehog during cutscenes
|
// Convert NaNs to 1 - needed to fix eyelids in Shadow the Hedgehog during cutscenes
|
||||||
// See https://bugs.dolphin-emu.org/issues/11458
|
// See https://bugs.dolphin-emu.org/issues/11458
|
||||||
out.Write(" // Convert NaN to 1\n");
|
out.Write(" // Convert NaN to 1\n");
|
||||||
out.Write(" if (isnan(coord.x)) coord.x = 1.0;\n");
|
out.Write(" if (dolphin_isnan(coord.x)) coord.x = 1.0;\n");
|
||||||
out.Write(" if (isnan(coord.y)) coord.y = 1.0;\n");
|
out.Write(" if (dolphin_isnan(coord.y)) coord.y = 1.0;\n");
|
||||||
out.Write(" if (isnan(coord.z)) coord.z = 1.0;\n");
|
out.Write(" if (dolphin_isnan(coord.z)) coord.z = 1.0;\n");
|
||||||
|
|
||||||
out.Write(" // first transformation\n");
|
out.Write(" // first transformation\n");
|
||||||
out.Write(" uint texgentype = {};\n", BitfieldExtract<&TexMtxInfo::texgentype>("texMtxInfo"));
|
out.Write(" uint texgentype = {};\n", BitfieldExtract<&TexMtxInfo::texgentype>("texMtxInfo"));
|
||||||
|
|
|
@ -96,7 +96,9 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
|
|
||||||
out.Write("struct VS_OUTPUT {{\n");
|
out.Write("struct VS_OUTPUT {{\n");
|
||||||
GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, "");
|
GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, "");
|
||||||
out.Write("}};\n");
|
out.Write("}};\n\n");
|
||||||
|
|
||||||
|
WriteIsNanHeader(out, api_type);
|
||||||
|
|
||||||
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
|
@ -335,9 +337,9 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||||
// Convert NaNs to 1 - needed to fix eyelids in Shadow the Hedgehog during cutscenes
|
// Convert NaNs to 1 - needed to fix eyelids in Shadow the Hedgehog during cutscenes
|
||||||
// See https://bugs.dolphin-emu.org/issues/11458
|
// See https://bugs.dolphin-emu.org/issues/11458
|
||||||
out.Write("// Convert NaN to 1\n");
|
out.Write("// Convert NaN to 1\n");
|
||||||
out.Write("if (isnan(coord.x)) coord.x = 1.0;\n");
|
out.Write("if (dolphin_isnan(coord.x)) coord.x = 1.0;\n");
|
||||||
out.Write("if (isnan(coord.y)) coord.y = 1.0;\n");
|
out.Write("if (dolphin_isnan(coord.y)) coord.y = 1.0;\n");
|
||||||
out.Write("if (isnan(coord.z)) coord.z = 1.0;\n");
|
out.Write("if (dolphin_isnan(coord.z)) coord.z = 1.0;\n");
|
||||||
|
|
||||||
// first transformation
|
// first transformation
|
||||||
switch (texinfo.texgentype)
|
switch (texinfo.texgentype)
|
||||||
|
|
Loading…
Reference in New Issue