diff options
| author | 2021-02-21 23:42:38 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 274897dfd59b4d08029ab7e93be4f84654abcdc8 (patch) | |
| tree | 083336a4d665476a87b888368878a311a7edab2a /src/shader_recompiler/backend | |
| parent | shader: Rename, implement FADD.SAT and P2R (imm) (diff) | |
| download | yuzu-274897dfd59b4d08029ab7e93be4f84654abcdc8.tar.gz yuzu-274897dfd59b4d08029ab7e93be4f84654abcdc8.tar.xz yuzu-274897dfd59b4d08029ab7e93be4f84654abcdc8.zip | |
spirv: Fixes and Intel specific workarounds
Diffstat (limited to 'src/shader_recompiler/backend')
6 files changed, 31 insertions, 20 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index ea1c8a3be..d2dbd56d4 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -25,7 +25,8 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie | |||
| 25 | } | 25 | } |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | EmitContext::EmitContext(IR::Program& program) : Sirit::Module(0x00010000) { | 28 | EmitContext::EmitContext(const Profile& profile_, IR::Program& program) |
| 29 | : Sirit::Module(0x00010000), profile{profile_} { | ||
| 29 | AddCapability(spv::Capability::Shader); | 30 | AddCapability(spv::Capability::Shader); |
| 30 | DefineCommonTypes(program.info); | 31 | DefineCommonTypes(program.info); |
| 31 | DefineCommonConstants(); | 32 | DefineCommonConstants(); |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 8de203da2..d20cf387e 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include "shader_recompiler/frontend/ir/program.h" | 12 | #include "shader_recompiler/frontend/ir/program.h" |
| 13 | #include "shader_recompiler/shader_info.h" | 13 | #include "shader_recompiler/shader_info.h" |
| 14 | #include "shader_recompiler/profile.h" | ||
| 14 | 15 | ||
| 15 | namespace Shader::Backend::SPIRV { | 16 | namespace Shader::Backend::SPIRV { |
| 16 | 17 | ||
| @@ -30,11 +31,13 @@ private: | |||
| 30 | 31 | ||
| 31 | class EmitContext final : public Sirit::Module { | 32 | class EmitContext final : public Sirit::Module { |
| 32 | public: | 33 | public: |
| 33 | explicit EmitContext(IR::Program& program); | 34 | explicit EmitContext(const Profile& profile, IR::Program& program); |
| 34 | ~EmitContext(); | 35 | ~EmitContext(); |
| 35 | 36 | ||
| 36 | [[nodiscard]] Id Def(const IR::Value& value); | 37 | [[nodiscard]] Id Def(const IR::Value& value); |
| 37 | 38 | ||
| 39 | const Profile& profile; | ||
| 40 | |||
| 38 | Id void_id{}; | 41 | Id void_id{}; |
| 39 | Id U1{}; | 42 | Id U1{}; |
| 40 | Id U16{}; | 43 | Id U16{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 2519e446a..f3aca90d0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -150,11 +150,11 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | |||
| 150 | } else if (info.uses_fp16_denorms_flush) { | 150 | } else if (info.uses_fp16_denorms_flush) { |
| 151 | if (profile.support_fp16_denorm_flush) { | 151 | if (profile.support_fp16_denorm_flush) { |
| 152 | ctx.AddCapability(spv::Capability::DenormFlushToZero); | 152 | ctx.AddCapability(spv::Capability::DenormFlushToZero); |
| 153 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U); | 153 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 16U); |
| 154 | } else { | 154 | } else { |
| 155 | // Same as fp32, no need to warn as most drivers will flush by default | 155 | // Same as fp32, no need to warn as most drivers will flush by default |
| 156 | } | 156 | } |
| 157 | } else if (info.uses_fp32_denorms_preserve) { | 157 | } else if (info.uses_fp16_denorms_preserve) { |
| 158 | if (profile.support_fp16_denorm_preserve) { | 158 | if (profile.support_fp16_denorm_preserve) { |
| 159 | ctx.AddCapability(spv::Capability::DenormPreserve); | 159 | ctx.AddCapability(spv::Capability::DenormPreserve); |
| 160 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U); | 160 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U); |
| @@ -166,7 +166,7 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | |||
| 166 | } // Anonymous namespace | 166 | } // Anonymous namespace |
| 167 | 167 | ||
| 168 | std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) { | 168 | std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) { |
| 169 | EmitContext ctx{program}; | 169 | EmitContext ctx{profile, program}; |
| 170 | const Id void_function{ctx.TypeFunction(ctx.void_id)}; | 170 | const Id void_function{ctx.TypeFunction(ctx.void_id)}; |
| 171 | // FIXME: Forward declare functions (needs sirit support) | 171 | // FIXME: Forward declare functions (needs sirit support) |
| 172 | Id func{}; | 172 | Id func{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 922e294a7..cec80c13e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -202,10 +202,10 @@ Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs); | |||
| 202 | Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs); | 202 | Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs); |
| 203 | Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); | 203 | Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); |
| 204 | Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); | 204 | Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); |
| 205 | void EmitLogicalOr(EmitContext& ctx); | 205 | Id EmitLogicalOr(EmitContext& ctx, Id a, Id b); |
| 206 | void EmitLogicalAnd(EmitContext& ctx); | 206 | Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b); |
| 207 | void EmitLogicalXor(EmitContext& ctx); | 207 | Id EmitLogicalXor(EmitContext& ctx, Id a, Id b); |
| 208 | void EmitLogicalNot(EmitContext& ctx); | 208 | Id EmitLogicalNot(EmitContext& ctx, Id value); |
| 209 | Id EmitConvertS16F16(EmitContext& ctx, Id value); | 209 | Id EmitConvertS16F16(EmitContext& ctx, Id value); |
| 210 | Id EmitConvertS16F32(EmitContext& ctx, Id value); | 210 | Id EmitConvertS16F32(EmitContext& ctx, Id value); |
| 211 | Id EmitConvertS16F64(EmitContext& ctx, Id value); | 211 | Id EmitConvertS16F64(EmitContext& ctx, Id value); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp index 47f87054b..5d0b74f9b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp | |||
| @@ -15,6 +15,13 @@ Id Decorate(EmitContext& ctx, IR::Inst* inst, Id op) { | |||
| 15 | return op; | 15 | return op; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | Id Saturate(EmitContext& ctx, Id type, Id value, Id zero, Id one) { | ||
| 19 | if (ctx.profile.has_broken_spirv_clamp) { | ||
| 20 | return ctx.OpFMin(type, ctx.OpFMax(type, value, zero), one); | ||
| 21 | } else { | ||
| 22 | return ctx.OpFClamp(type, value, zero, one); | ||
| 23 | } | ||
| 24 | } | ||
| 18 | } // Anonymous namespace | 25 | } // Anonymous namespace |
| 19 | 26 | ||
| 20 | Id EmitFPAbs16(EmitContext& ctx, Id value) { | 27 | Id EmitFPAbs16(EmitContext& ctx, Id value) { |
| @@ -144,19 +151,19 @@ void EmitFPLog2(EmitContext&) { | |||
| 144 | Id EmitFPSaturate16(EmitContext& ctx, Id value) { | 151 | Id EmitFPSaturate16(EmitContext& ctx, Id value) { |
| 145 | const Id zero{ctx.Constant(ctx.F16[1], u16{0})}; | 152 | const Id zero{ctx.Constant(ctx.F16[1], u16{0})}; |
| 146 | const Id one{ctx.Constant(ctx.F16[1], u16{0x3c00})}; | 153 | const Id one{ctx.Constant(ctx.F16[1], u16{0x3c00})}; |
| 147 | return ctx.OpFClamp(ctx.F32[1], value, zero, one); | 154 | return Saturate(ctx, ctx.F16[1], value, zero, one); |
| 148 | } | 155 | } |
| 149 | 156 | ||
| 150 | Id EmitFPSaturate32(EmitContext& ctx, Id value) { | 157 | Id EmitFPSaturate32(EmitContext& ctx, Id value) { |
| 151 | const Id zero{ctx.Constant(ctx.F32[1], f32{0.0})}; | 158 | const Id zero{ctx.Constant(ctx.F32[1], f32{0.0})}; |
| 152 | const Id one{ctx.Constant(ctx.F32[1], f32{1.0})}; | 159 | const Id one{ctx.Constant(ctx.F32[1], f32{1.0})}; |
| 153 | return ctx.OpFClamp(ctx.F32[1], value, zero, one); | 160 | return Saturate(ctx, ctx.F32[1], value, zero, one); |
| 154 | } | 161 | } |
| 155 | 162 | ||
| 156 | Id EmitFPSaturate64(EmitContext& ctx, Id value) { | 163 | Id EmitFPSaturate64(EmitContext& ctx, Id value) { |
| 157 | const Id zero{ctx.Constant(ctx.F64[1], f64{0.0})}; | 164 | const Id zero{ctx.Constant(ctx.F64[1], f64{0.0})}; |
| 158 | const Id one{ctx.Constant(ctx.F64[1], f64{1.0})}; | 165 | const Id one{ctx.Constant(ctx.F64[1], f64{1.0})}; |
| 159 | return ctx.OpFClamp(ctx.F64[1], value, zero, one); | 166 | return Saturate(ctx, ctx.F64[1], value, zero, one); |
| 160 | } | 167 | } |
| 161 | 168 | ||
| 162 | Id EmitFPRoundEven16(EmitContext& ctx, Id value) { | 169 | Id EmitFPRoundEven16(EmitContext& ctx, Id value) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp index c5a07252f..bb434def2 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp | |||
| @@ -6,20 +6,20 @@ | |||
| 6 | 6 | ||
| 7 | namespace Shader::Backend::SPIRV { | 7 | namespace Shader::Backend::SPIRV { |
| 8 | 8 | ||
| 9 | void EmitLogicalOr(EmitContext&) { | 9 | Id EmitLogicalOr(EmitContext& ctx, Id a, Id b) { |
| 10 | throw NotImplementedException("SPIR-V Instruction"); | 10 | return ctx.OpLogicalOr(ctx.U1, a, b); |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | void EmitLogicalAnd(EmitContext&) { | 13 | Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b) { |
| 14 | throw NotImplementedException("SPIR-V Instruction"); | 14 | return ctx.OpLogicalAnd(ctx.U1, a, b); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | void EmitLogicalXor(EmitContext&) { | 17 | Id EmitLogicalXor(EmitContext& ctx, Id a, Id b) { |
| 18 | throw NotImplementedException("SPIR-V Instruction"); | 18 | return ctx.OpLogicalNotEqual(ctx.U1, a, b); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | void EmitLogicalNot(EmitContext&) { | 21 | Id EmitLogicalNot(EmitContext& ctx, Id value) { |
| 22 | throw NotImplementedException("SPIR-V Instruction"); | 22 | return ctx.OpLogicalNot(ctx.U1, value); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | } // namespace Shader::Backend::SPIRV | 25 | } // namespace Shader::Backend::SPIRV |