glsl: Allow dynamic tracking of variable allocation
This commit is contained in:
parent
465903468e
commit
258106038e
3 changed files with 35 additions and 21 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,21 +156,27 @@ 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;
|
||||||
}
|
|
||||||
use_tracker.num_used = std::max(use_tracker.num_used, var + 1);
|
|
||||||
use_tracker.var_use[var] = true;
|
|
||||||
Id ret{};
|
|
||||||
ret.is_valid.Assign(1);
|
|
||||||
ret.type.Assign(type);
|
|
||||||
ret.index.Assign(static_cast<u32>(var));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
use_tracker.num_used = std::max(use_tracker.num_used, var + 1);
|
||||||
|
use_tracker.var_use[var] = true;
|
||||||
|
Id ret{};
|
||||||
|
ret.is_valid.Assign(1);
|
||||||
|
ret.type.Assign(type);
|
||||||
|
ret.index.Assign(static_cast<u32>(var));
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
throw NotImplementedException("Variable spilling");
|
// Allocate a new variable
|
||||||
|
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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue