forked from eden-emu/eden
		
	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 ""; | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|     for (u32 i = 0; i < static_cast<u32>(GlslVarType::Void); ++i) { | ||||
|         const auto type{static_cast<GlslVarType>(i)}; | ||||
|         const auto& tracker{ctx.var_alloc.GetUseTracker(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
 | ||||
|         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); | ||||
|         } | ||||
|         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, | ||||
|                                   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); | ||||
|         GetUseTracker(type).uses_temp = true; | ||||
|         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) { | ||||
|  | @ -156,21 +156,27 @@ std::string VarAlloc::GetGlslType(IR::Type type) const { | |||
| 
 | ||||
| Id VarAlloc::Alloc(GlslVarType 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) { | ||||
|  |  | |||
|  | @ -57,11 +57,10 @@ static_assert(sizeof(Id) == sizeof(u32)); | |||
| 
 | ||||
| class VarAlloc { | ||||
| public: | ||||
|     static constexpr size_t NUM_VARS = 1023; | ||||
|     struct UseTracker { | ||||
|         size_t num_used{}; | ||||
|         std::bitset<NUM_VARS> var_use{}; | ||||
|         bool uses_temp{}; | ||||
|         size_t num_used{}; | ||||
|         std::vector<bool> var_use; | ||||
|     }; | ||||
| 
 | ||||
|     /// Used for explicit usages of variables, may revert to temporaries
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ameerj
						ameerj