spirv: Fixes and Intel specific workarounds
This commit is contained in:
parent
704c6f353f
commit
274897dfd5
11 changed files with 44 additions and 32 deletions
|
@ -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();
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue