diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/backend/glasm/emit_context.cpp | 10 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glasm/emit_glasm.cpp | 3 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/profile.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 7 |
6 files changed, 18 insertions, 10 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp index e18526816..08918a5c2 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/emit_context.cpp | |||
| @@ -117,13 +117,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 117 | index, index); | 117 | index, index); |
| 118 | } | 118 | } |
| 119 | } | 119 | } |
| 120 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { | 120 | if (stage == Stage::Fragment) { |
| 121 | if (!info.stores_frag_color[index]) { | 121 | Add("OUTPUT frag_color0=result.color;"); |
| 122 | continue; | 122 | for (size_t index = 1; index < info.stores_frag_color.size(); ++index) { |
| 123 | } | ||
| 124 | if (index == 0) { | ||
| 125 | Add("OUTPUT frag_color0=result.color;"); | ||
| 126 | } else { | ||
| 127 | Add("OUTPUT frag_color{}=result.color[{}];", index, index); | 123 | Add("OUTPUT frag_color{}=result.color[{}];", index, index); |
| 128 | } | 124 | } |
| 129 | } | 125 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index e23208d2c..70ca6f621 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -298,8 +298,7 @@ void SetupOptions(const IR::Program& program, const Profile& profile, | |||
| 298 | if (stage == Stage::Fragment && runtime_info.force_early_z != 0) { | 298 | if (stage == Stage::Fragment && runtime_info.force_early_z != 0) { |
| 299 | header += "OPTION NV_early_fragment_tests;"; | 299 | header += "OPTION NV_early_fragment_tests;"; |
| 300 | } | 300 | } |
| 301 | const auto non_zero_frag_colors{info.stores_frag_color | std::views::drop(1)}; | 301 | if (stage == Stage::Fragment) { |
| 302 | if (std::ranges::find(non_zero_frag_colors, true) != non_zero_frag_colors.end()) { | ||
| 303 | header += "OPTION ARB_draw_buffers;"; | 302 | header += "OPTION ARB_draw_buffers;"; |
| 304 | } | 303 | } |
| 305 | } | 304 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 3e8899f53..7c618125e 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -1320,7 +1320,7 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||
| 1320 | break; | 1320 | break; |
| 1321 | case Stage::Fragment: | 1321 | case Stage::Fragment: |
| 1322 | for (u32 index = 0; index < 8; ++index) { | 1322 | for (u32 index = 0; index < 8; ++index) { |
| 1323 | if (!info.stores_frag_color[index]) { | 1323 | if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { |
| 1324 | continue; | 1324 | continue; |
| 1325 | } | 1325 | } |
| 1326 | frag_color[index] = DefineOutput(*this, F32[4], std::nullopt); | 1326 | frag_color[index] = DefineOutput(*this, F32[4], std::nullopt); |
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index f8913bf14..f059e3b26 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h | |||
| @@ -84,7 +84,11 @@ struct Profile { | |||
| 84 | bool support_int64_atomics{}; | 84 | bool support_int64_atomics{}; |
| 85 | 85 | ||
| 86 | bool warp_size_potentially_larger_than_guest{}; | 86 | bool warp_size_potentially_larger_than_guest{}; |
| 87 | |||
| 87 | bool lower_left_origin_mode{}; | 88 | bool lower_left_origin_mode{}; |
| 89 | /// Fragment outputs have to be declared even if they are not written to avoid undefined values. | ||
| 90 | /// See Ori and the Blind Forest's main menu for reference. | ||
| 91 | bool need_declared_frag_colors{}; | ||
| 88 | 92 | ||
| 89 | /// OpFClamp is broken and OpFMax + OpFMin should be used instead | 93 | /// OpFClamp is broken and OpFMax + OpFMin should be used instead |
| 90 | bool has_broken_spirv_clamp{}; | 94 | bool has_broken_spirv_clamp{}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 7d2ec4efa..6ea7c0ee8 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -276,7 +276,9 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | |||
| 276 | .support_int64_atomics = false, | 276 | .support_int64_atomics = false, |
| 277 | 277 | ||
| 278 | .warp_size_potentially_larger_than_guest = true, | 278 | .warp_size_potentially_larger_than_guest = true, |
| 279 | |||
| 279 | .lower_left_origin_mode = true, | 280 | .lower_left_origin_mode = true, |
| 281 | .need_declared_frag_colors = true, | ||
| 280 | 282 | ||
| 281 | .has_broken_spirv_clamp = true, | 283 | .has_broken_spirv_clamp = true, |
| 282 | .has_broken_unsigned_image_offsets = true, | 284 | .has_broken_unsigned_image_offsets = true, |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index b6998e37c..cec51cc77 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -274,9 +274,16 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw | |||
| 274 | .support_typeless_image_loads = device.IsFormatlessImageLoadSupported(), | 274 | .support_typeless_image_loads = device.IsFormatlessImageLoadSupported(), |
| 275 | .support_demote_to_helper_invocation = true, | 275 | .support_demote_to_helper_invocation = true, |
| 276 | .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), | 276 | .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), |
| 277 | |||
| 277 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | 278 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), |
| 279 | |||
| 280 | .lower_left_origin_mode = false, | ||
| 281 | .need_declared_frag_colors = false, | ||
| 282 | |||
| 278 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | 283 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, |
| 279 | .has_broken_unsigned_image_offsets = false, | 284 | .has_broken_unsigned_image_offsets = false, |
| 285 | .has_broken_signed_operations = false, | ||
| 286 | .ignore_nan_fp_comparisons = false, | ||
| 280 | }; | 287 | }; |
| 281 | } | 288 | } |
| 282 | 289 | ||