Просмотр исходного кода

glsl: Allow dynamic tracking of variable allocation

ameerj 5 лет назад
Родитель
Сommit
258106038e

+ 13 - 4
src/shader_recompiler/backend/glsl/emit_glsl.cpp

@@ -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{
-            (type == GlslVarType::PrecF32 || type == GlslVarType::PrecF64) ? "precise " : ""};
+        const auto precise{IsPreciseType(type) ? "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);
         }
         }

+ 20 - 14
src/shader_recompiler/backend/glsl/var_alloc.cpp

@@ -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) {
-        for (size_t var = 1; var < NUM_VARS; ++var) {
-            if (use_tracker.var_use[var]) {
-                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;
+    const auto num_vars{use_tracker.var_use.size()};
+    for (size_t var = 0; var < num_vars; ++var) {
+        if (use_tracker.var_use[var]) {
+            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;
     }
     }
-    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) {

+ 2 - 3
src/shader_recompiler/backend/glsl/var_alloc.h

@@ -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