summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/spirv
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp3
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h5
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp6
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp13
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp16
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
}
}
-EmitContext::EmitContext(IR::Program& program) : Sirit::Module(0x00010000) {
+EmitContext::EmitContext(const Profile& profile_, IR::Program& program)
+ : Sirit::Module(0x00010000), profile{profile_} {
AddCapability(spv::Capability::Shader);
DefineCommonTypes(program.info);
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 @@
#include "shader_recompiler/frontend/ir/program.h"
#include "shader_recompiler/shader_info.h"
+#include "shader_recompiler/profile.h"
namespace Shader::Backend::SPIRV {
@@ -30,11 +31,13 @@ private:
class EmitContext final : public Sirit::Module {
public:
- explicit EmitContext(IR::Program& program);
+ explicit EmitContext(const Profile& profile, IR::Program& program);
~EmitContext();
[[nodiscard]] Id Def(const IR::Value& value);
+ const Profile& profile;
+
Id void_id{};
Id U1{};
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
} else if (info.uses_fp16_denorms_flush) {
if (profile.support_fp16_denorm_flush) {
ctx.AddCapability(spv::Capability::DenormFlushToZero);
- ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U);
+ ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 16U);
} else {
// Same as fp32, no need to warn as most drivers will flush by default
}
- } else if (info.uses_fp32_denorms_preserve) {
+ } else if (info.uses_fp16_denorms_preserve) {
if (profile.support_fp16_denorm_preserve) {
ctx.AddCapability(spv::Capability::DenormPreserve);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U);
@@ -166,7 +166,7 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit
} // Anonymous namespace
std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program& program) {
- EmitContext ctx{program};
+ EmitContext ctx{profile, program};
const Id void_function{ctx.TypeFunction(ctx.void_id)};
// FIXME: Forward declare functions (needs sirit support)
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);
Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs);
Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs);
Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs);
-void EmitLogicalOr(EmitContext& ctx);
-void EmitLogicalAnd(EmitContext& ctx);
-void EmitLogicalXor(EmitContext& ctx);
-void EmitLogicalNot(EmitContext& ctx);
+Id EmitLogicalOr(EmitContext& ctx, Id a, Id b);
+Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b);
+Id EmitLogicalXor(EmitContext& ctx, Id a, Id b);
+Id EmitLogicalNot(EmitContext& ctx, Id value);
Id EmitConvertS16F16(EmitContext& ctx, Id value);
Id EmitConvertS16F32(EmitContext& ctx, Id value);
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) {
return op;
}
+Id Saturate(EmitContext& ctx, Id type, Id value, Id zero, Id one) {
+ if (ctx.profile.has_broken_spirv_clamp) {
+ return ctx.OpFMin(type, ctx.OpFMax(type, value, zero), one);
+ } else {
+ return ctx.OpFClamp(type, value, zero, one);
+ }
+}
} // Anonymous namespace
Id EmitFPAbs16(EmitContext& ctx, Id value) {
@@ -144,19 +151,19 @@ void EmitFPLog2(EmitContext&) {
Id EmitFPSaturate16(EmitContext& ctx, Id value) {
const Id zero{ctx.Constant(ctx.F16[1], u16{0})};
const Id one{ctx.Constant(ctx.F16[1], u16{0x3c00})};
- return ctx.OpFClamp(ctx.F32[1], value, zero, one);
+ return Saturate(ctx, ctx.F16[1], value, zero, one);
}
Id EmitFPSaturate32(EmitContext& ctx, Id value) {
const Id zero{ctx.Constant(ctx.F32[1], f32{0.0})};
const Id one{ctx.Constant(ctx.F32[1], f32{1.0})};
- return ctx.OpFClamp(ctx.F32[1], value, zero, one);
+ return Saturate(ctx, ctx.F32[1], value, zero, one);
}
Id EmitFPSaturate64(EmitContext& ctx, Id value) {
const Id zero{ctx.Constant(ctx.F64[1], f64{0.0})};
const Id one{ctx.Constant(ctx.F64[1], f64{1.0})};
- return ctx.OpFClamp(ctx.F64[1], value, zero, one);
+ return Saturate(ctx, ctx.F64[1], value, zero, one);
}
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 @@
namespace Shader::Backend::SPIRV {
-void EmitLogicalOr(EmitContext&) {
- throw NotImplementedException("SPIR-V Instruction");
+Id EmitLogicalOr(EmitContext& ctx, Id a, Id b) {
+ return ctx.OpLogicalOr(ctx.U1, a, b);
}
-void EmitLogicalAnd(EmitContext&) {
- throw NotImplementedException("SPIR-V Instruction");
+Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b) {
+ return ctx.OpLogicalAnd(ctx.U1, a, b);
}
-void EmitLogicalXor(EmitContext&) {
- throw NotImplementedException("SPIR-V Instruction");
+Id EmitLogicalXor(EmitContext& ctx, Id a, Id b) {
+ return ctx.OpLogicalNotEqual(ctx.U1, a, b);
}
-void EmitLogicalNot(EmitContext&) {
- throw NotImplementedException("SPIR-V Instruction");
+Id EmitLogicalNot(EmitContext& ctx, Id value) {
+ return ctx.OpLogicalNot(ctx.U1, value);
}
} // namespace Shader::Backend::SPIRV