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