glsl: Implement precise fp variable allocation
This commit is contained in:
parent
14bfb4719a
commit
e10366974e
|
@ -118,6 +118,16 @@ public:
|
|||
Add<GlslVarType::F32x4>(format_str, inst, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void AddPrecF32(const char* format_str, IR::Inst& inst, Args&&... args) {
|
||||
Add<GlslVarType::PrecF32>(format_str, inst, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void AddPrecF64(const char* format_str, IR::Inst& inst, Args&&... args) {
|
||||
Add<GlslVarType::PrecF64>(format_str, inst, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void Add(const char* format_str, Args&&... args) {
|
||||
code += fmt::format(format_str, std::forward<Args>(args)...);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "shader_recompiler/backend/glsl/emit_context.h"
|
||||
#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
|
||||
#include "shader_recompiler/frontend/ir/modifiers.h"
|
||||
#include "shader_recompiler/frontend/ir/value.h"
|
||||
|
||||
namespace Shader::Backend::GLSL {
|
||||
|
@ -20,6 +21,10 @@ void Compare(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, std::string
|
|||
}
|
||||
ctx.code += ";";
|
||||
}
|
||||
|
||||
bool Precise(IR::Inst& inst) {
|
||||
return {inst.Flags<IR::FpControl>().no_contraction};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
|
||||
|
@ -41,11 +46,19 @@ void EmitFPAdd16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
|
|||
}
|
||||
|
||||
void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF32("{}=float({})+float({});", inst, a, b);
|
||||
} else {
|
||||
ctx.AddF32("{}=float({})+float({});", inst, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF64("{}=double({})+double({});", inst, a, b);
|
||||
} else {
|
||||
ctx.AddF64("{}=double({})+double({});", inst, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
|
||||
|
@ -56,12 +69,20 @@ void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
|
|||
|
||||
void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b,
|
||||
std::string_view c) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF32("{}=fma({},{},{});", inst, a, b, c);
|
||||
} else {
|
||||
ctx.AddF32("{}=fma({},{},{});", inst, a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b,
|
||||
std::string_view c) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF64("{}=fma({},{},{});", inst, a, b, c);
|
||||
} else {
|
||||
ctx.AddF64("{}=fma({},{},{});", inst, a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPMax32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
|
||||
|
@ -86,11 +107,19 @@ void EmitFPMul16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
|
|||
}
|
||||
|
||||
void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF32("{}={}*{};", inst, a, b);
|
||||
} else {
|
||||
ctx.AddF32("{}={}*{};", inst, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
|
||||
if (Precise(inst)) {
|
||||
ctx.AddPrecF64("{}={}*{};", inst, a, b);
|
||||
} else {
|
||||
ctx.AddF64("{}={}*{};", inst, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFPNeg16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
|
||||
|
|
|
@ -43,6 +43,10 @@ std::string TypePrefix(GlslVarType type) {
|
|||
return "u4_";
|
||||
case GlslVarType::F32x4:
|
||||
return "f4_";
|
||||
case GlslVarType::PrecF32:
|
||||
return "pf_";
|
||||
case GlslVarType::PrecF64:
|
||||
return "pd_";
|
||||
case GlslVarType::Void:
|
||||
return "";
|
||||
default:
|
||||
|
@ -225,6 +229,10 @@ std::string VarAlloc::GetGlslType(GlslVarType type) const {
|
|||
return "uvec4 ";
|
||||
case GlslVarType::F32x4:
|
||||
return "vec4 ";
|
||||
case GlslVarType::PrecF32:
|
||||
return "precise float ";
|
||||
case GlslVarType::PrecF64:
|
||||
return "precise double ";
|
||||
case GlslVarType::Void:
|
||||
return "";
|
||||
default:
|
||||
|
@ -262,6 +270,10 @@ VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) {
|
|||
return var_u32x4;
|
||||
case GlslVarType::F32x4:
|
||||
return var_f32x4;
|
||||
case GlslVarType::PrecF32:
|
||||
return var_precf32;
|
||||
case GlslVarType::PrecF64:
|
||||
return var_precf64;
|
||||
default:
|
||||
throw NotImplementedException("Type {}", type);
|
||||
}
|
||||
|
@ -297,6 +309,10 @@ const VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) const {
|
|||
return var_u32x4;
|
||||
case GlslVarType::F32x4:
|
||||
return var_f32x4;
|
||||
case GlslVarType::PrecF32:
|
||||
return var_precf32;
|
||||
case GlslVarType::PrecF64:
|
||||
return var_precf64;
|
||||
default:
|
||||
throw NotImplementedException("Type {}", type);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ enum class GlslVarType : u32 {
|
|||
F32x3,
|
||||
U32x4,
|
||||
F32x4,
|
||||
PrecF32,
|
||||
PrecF64,
|
||||
Void,
|
||||
};
|
||||
|
||||
|
@ -40,8 +42,8 @@ struct Id {
|
|||
union {
|
||||
u32 raw;
|
||||
BitField<0, 1, u32> is_valid;
|
||||
BitField<1, 4, GlslVarType> type;
|
||||
BitField<5, 27, u32> index;
|
||||
BitField<1, 5, GlslVarType> type;
|
||||
BitField<6, 26, u32> index;
|
||||
};
|
||||
|
||||
bool operator==(Id rhs) const noexcept {
|
||||
|
@ -101,6 +103,8 @@ private:
|
|||
UseTracker var_u64{};
|
||||
UseTracker var_s64{};
|
||||
UseTracker var_f64{};
|
||||
UseTracker var_precf32{};
|
||||
UseTracker var_precf64{};
|
||||
};
|
||||
|
||||
} // namespace Shader::Backend::GLSL
|
||||
|
|
Reference in New Issue