MCPcopy Create free account
hub / github.com/carbonengine/trinity / AutoAssignRegistersForNode

Function AutoAssignRegistersForNode

shadercompiler/EffectCompilerMetal.cpp:1754–2189  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1752}
1753
1754bool AutoAssignRegistersForNode( ParserState& state, ASTNode* functionHeader, const FileLocation& messageLocation )
1755{
1756 /*
1757
1758 This function assigns "registers" i.e. Metal input attributes [[buffer(###)]] or [[texture(###)]] to the shader arguments.
1759 Metal partitions the set off all inputs into "buffers" and "textures", which is somewhat different from DirectX that partitions
1760 the inputs into "constant buffers", SRVs and UAVs. Since Trinity uses DirectX partitioning for inputs we need to adapt Metal
1761 to that. This puts some extra limitations on the allocation of registers. For metal we use a single set or "registers" (up to
1762 31 registers - the limit for min supported macOS): all SRV/UAV buffers and textures go into this set of "registers". Constant
1763 buffers are in a separate set. We map these to sets to "buffers" and "textures" for Metal.
1764
1765 Firstly, we reserve 4 first slots in [[buffer(###)]] metal set for IA buffers
1766 Secondly, we reserve space in [[buffer(###)]] metal set for all constant buffers as they have an explicit register binding. We map
1767 them with an offset of 4, so for example the Globals constant buffer (cb0) would be mapped to [[buffer(4)]].
1768 Then we allocate any unused [[buffer(###)]] indices for SRV/UAV buffer inputs. For example, if [[buffer(5)]] is not assigned, the
1769 next SRV/UAV buffer gets assigned to that slot and also recieves SRV register #5 as if it was declared register(t5) in HLSL.
1770 Lastly we allocate SRV/UAV texture registers, making sure we don't put them into the same SRV "register" as a previously allocated
1771 SRV/UAV buffer.
1772
1773 */
1774
1775 auto GetAssignedSymbolNames = []( const std::vector<Symbol*>& symbols ) {
1776 std::string result;
1777 for( auto symbol : symbols )
1778 {
1779 if( !result.empty() )
1780 {
1781 result += ", ";
1782 }
1783 result += ToString( symbol->name );
1784 }
1785 return result;
1786 };
1787
1788 auto RecordRegister = [&state]( int index, std::vector<Symbol*>& registers, ASTNode* node ) {
1789 Symbol* symbol = node->GetSymbol();
1790
1791 if( index < 0 || index >= int( registers.size() ) )
1792 {
1793 state.ShowMessage(
1794 node->GetLocation(),
1795 EC_CUSTOM_ERROR,
1796 "Couldn't allocate a register for %s. Reason: Invalid register index.",
1797 ToString( symbol->name ).c_str() );
1798 return false;
1799 }
1800
1801 if( !registers[index] )
1802 {
1803 registers[index] = symbol;
1804 return true;
1805 }
1806 else
1807 {
1808 state.ShowMessage(
1809 node->GetLocation(),
1810 EC_CUSTOM_ERROR,
1811 "Couldn't allocate a register for %s. Reason: register %d already assigned to %s.",

Callers 2

AutoAssignRegistersFunction · 0.85
GetGlobalInputDataFunction · 0.85

Calls 10

GetCBufferIndexFunction · 0.85
emptyMethod · 0.80
GetSymbolMethod · 0.80
sizeMethod · 0.80
ShowMessageMethod · 0.80
GetChildrenCountMethod · 0.80
IsStructMethod · 0.80
ToStringFunction · 0.70
GetChildMethod · 0.45
GetTypeMethod · 0.45

Tested by

no test coverage detected