glsl: Allow dynamic tracking of variable allocation
This commit is contained in:
		| @@ -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,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) { | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user