opengl: Declare fragment outputs even if they are not used
Fixes Ori and the Blind Forest's menu on GLASM. For some reason (probably high level optimizations) it is not sanitized on SPIR-V for OpenGL. Vulkan is unaffected by this change.
This commit is contained in:
parent
a7e9756671
commit
916ca74324
|
@ -117,13 +117,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
|
||||||
index, index);
|
index, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t index = 0; index < info.stores_frag_color.size(); ++index) {
|
if (stage == Stage::Fragment) {
|
||||||
if (!info.stores_frag_color[index]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (index == 0) {
|
|
||||||
Add("OUTPUT frag_color0=result.color;");
|
Add("OUTPUT frag_color0=result.color;");
|
||||||
} else {
|
for (size_t index = 1; index < info.stores_frag_color.size(); ++index) {
|
||||||
Add("OUTPUT frag_color{}=result.color[{}];", index, index);
|
Add("OUTPUT frag_color{}=result.color[{}];", index, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,8 +298,7 @@ void SetupOptions(const IR::Program& program, const Profile& profile,
|
||||||
if (stage == Stage::Fragment && runtime_info.force_early_z != 0) {
|
if (stage == Stage::Fragment && runtime_info.force_early_z != 0) {
|
||||||
header += "OPTION NV_early_fragment_tests;";
|
header += "OPTION NV_early_fragment_tests;";
|
||||||
}
|
}
|
||||||
const auto non_zero_frag_colors{info.stores_frag_color | std::views::drop(1)};
|
if (stage == Stage::Fragment) {
|
||||||
if (std::ranges::find(non_zero_frag_colors, true) != non_zero_frag_colors.end()) {
|
|
||||||
header += "OPTION ARB_draw_buffers;";
|
header += "OPTION ARB_draw_buffers;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1320,7 +1320,7 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
|
||||||
break;
|
break;
|
||||||
case Stage::Fragment:
|
case Stage::Fragment:
|
||||||
for (u32 index = 0; index < 8; ++index) {
|
for (u32 index = 0; index < 8; ++index) {
|
||||||
if (!info.stores_frag_color[index]) {
|
if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
frag_color[index] = DefineOutput(*this, F32[4], std::nullopt);
|
frag_color[index] = DefineOutput(*this, F32[4], std::nullopt);
|
||||||
|
|
|
@ -84,7 +84,11 @@ struct Profile {
|
||||||
bool support_int64_atomics{};
|
bool support_int64_atomics{};
|
||||||
|
|
||||||
bool warp_size_potentially_larger_than_guest{};
|
bool warp_size_potentially_larger_than_guest{};
|
||||||
|
|
||||||
bool lower_left_origin_mode{};
|
bool lower_left_origin_mode{};
|
||||||
|
/// Fragment outputs have to be declared even if they are not written to avoid undefined values.
|
||||||
|
/// See Ori and the Blind Forest's main menu for reference.
|
||||||
|
bool need_declared_frag_colors{};
|
||||||
|
|
||||||
/// OpFClamp is broken and OpFMax + OpFMin should be used instead
|
/// OpFClamp is broken and OpFMax + OpFMin should be used instead
|
||||||
bool has_broken_spirv_clamp{};
|
bool has_broken_spirv_clamp{};
|
||||||
|
|
|
@ -276,7 +276,9 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
|
||||||
.support_int64_atomics = false,
|
.support_int64_atomics = false,
|
||||||
|
|
||||||
.warp_size_potentially_larger_than_guest = true,
|
.warp_size_potentially_larger_than_guest = true,
|
||||||
|
|
||||||
.lower_left_origin_mode = true,
|
.lower_left_origin_mode = true,
|
||||||
|
.need_declared_frag_colors = true,
|
||||||
|
|
||||||
.has_broken_spirv_clamp = true,
|
.has_broken_spirv_clamp = true,
|
||||||
.has_broken_unsigned_image_offsets = true,
|
.has_broken_unsigned_image_offsets = true,
|
||||||
|
|
|
@ -274,9 +274,16 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw
|
||||||
.support_typeless_image_loads = device.IsFormatlessImageLoadSupported(),
|
.support_typeless_image_loads = device.IsFormatlessImageLoadSupported(),
|
||||||
.support_demote_to_helper_invocation = true,
|
.support_demote_to_helper_invocation = true,
|
||||||
.support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
|
.support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
|
||||||
|
|
||||||
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
|
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
|
||||||
|
|
||||||
|
.lower_left_origin_mode = false,
|
||||||
|
.need_declared_frag_colors = false,
|
||||||
|
|
||||||
.has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR,
|
.has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR,
|
||||||
.has_broken_unsigned_image_offsets = false,
|
.has_broken_unsigned_image_offsets = false,
|
||||||
|
.has_broken_signed_operations = false,
|
||||||
|
.ignore_nan_fp_comparisons = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue