glsl: Allow dynamic tracking of variable allocation

This commit is contained in:
ameerj 2021-06-07 18:04:01 -04:00
parent 465903468e
commit 258106038e
3 changed files with 35 additions and 21 deletions

View File

@ -172,19 +172,28 @@ std::string GlslVersionSpecifier(const EmitContext& ctx) {
return ""; return "";
} }
bool IsPreciseType(GlslVarType type) {
switch (type) {
case GlslVarType::PrecF32:
case GlslVarType::PrecF64:
return true;
default:
return false;
}
}
void DefineVariables(const EmitContext& ctx, std::string& header) { void DefineVariables(const EmitContext& ctx, std::string& header) {
for (u32 i = 0; i < static_cast<u32>(GlslVarType::Void); ++i) { for (u32 i = 0; i < static_cast<u32>(GlslVarType::Void); ++i) {
const auto type{static_cast<GlslVarType>(i)}; const auto type{static_cast<GlslVarType>(i)};
const auto& tracker{ctx.var_alloc.GetUseTracker(type)}; const auto& tracker{ctx.var_alloc.GetUseTracker(type)};
const auto type_name{ctx.var_alloc.GetGlslType(type)}; const auto type_name{ctx.var_alloc.GetGlslType(type)};
const auto precise{ const auto precise{IsPreciseType(type) ? "precise " : ""};
(type == GlslVarType::PrecF32 || type == GlslVarType::PrecF64) ? "precise " : ""};
// Temps/return types that are never used are stored at index 0 // Temps/return types that are never used are stored at index 0
if (tracker.uses_temp) { if (tracker.uses_temp) {
header += fmt::format("{}{} {}={}(0);", precise, type_name, header += fmt::format("{}{} t{}={}(0);", precise, type_name,
ctx.var_alloc.Representation(0, type), type_name); ctx.var_alloc.Representation(0, type), type_name);
} }
for (u32 index = 1; index <= tracker.num_used; ++index) { for (u32 index = 0; index < tracker.num_used; ++index) {
header += fmt::format("{}{} {}={}(0);", precise, type_name, header += fmt::format("{}{} {}={}(0);", precise, type_name,
ctx.var_alloc.Representation(index, type), type_name); ctx.var_alloc.Representation(index, type), type_name);
} }

View File

@ -116,8 +116,8 @@ std::string VarAlloc::Define(IR::Inst& inst, GlslVarType type) {
id.type.Assign(type); id.type.Assign(type);
GetUseTracker(type).uses_temp = true; GetUseTracker(type).uses_temp = true;
inst.SetDefinition<Id>(id); inst.SetDefinition<Id>(id);
return "t" + Representation(inst.Definition<Id>());
} }
return Representation(inst.Definition<Id>());
} }
std::string VarAlloc::Define(IR::Inst& inst, IR::Type type) { std::string VarAlloc::Define(IR::Inst& inst, IR::Type type) {
@ -156,8 +156,8 @@ std::string VarAlloc::GetGlslType(IR::Type type) const {
Id VarAlloc::Alloc(GlslVarType type) { Id VarAlloc::Alloc(GlslVarType type) {
auto& use_tracker{GetUseTracker(type)}; auto& use_tracker{GetUseTracker(type)};
if (use_tracker.num_used < NUM_VARS) { const auto num_vars{use_tracker.var_use.size()};
for (size_t var = 1; var < NUM_VARS; ++var) { for (size_t var = 0; var < num_vars; ++var) {
if (use_tracker.var_use[var]) { if (use_tracker.var_use[var]) {
continue; continue;
} }
@ -169,8 +169,14 @@ Id VarAlloc::Alloc(GlslVarType type) {
ret.index.Assign(static_cast<u32>(var)); ret.index.Assign(static_cast<u32>(var));
return ret; return ret;
} }
} // Allocate a new variable
throw NotImplementedException("Variable spilling"); use_tracker.var_use.push_back(true);
Id ret{};
ret.is_valid.Assign(1);
ret.type.Assign(type);
ret.index.Assign(static_cast<u32>(use_tracker.num_used));
++use_tracker.num_used;
return ret;
} }
void VarAlloc::Free(Id id) { void VarAlloc::Free(Id id) {

View File

@ -57,11 +57,10 @@ static_assert(sizeof(Id) == sizeof(u32));
class VarAlloc { class VarAlloc {
public: public:
static constexpr size_t NUM_VARS = 1023;
struct UseTracker { struct UseTracker {
size_t num_used{};
std::bitset<NUM_VARS> var_use{};
bool uses_temp{}; bool uses_temp{};
size_t num_used{};
std::vector<bool> var_use;
}; };
/// Used for explicit usages of variables, may revert to temporaries /// Used for explicit usages of variables, may revert to temporaries