Creates a new shader functions with all the inputs/outputs layed out for Metal: - all [[stage_in]] inputs are put into a new flat struct - all outputs are put into a new struct - uniform arguments are moved to local variables inside the shader - all the other arguments from the original entry point are passed as is Returns new entry point function definition (added to AST root)
| 2702 | // - all the other arguments from the original entry point are passed as is |
| 2703 | // Returns new entry point function definition (added to AST root) |
| 2704 | ASTNode* PatchShader( PatchShaderType shaderType, ASTNode* callNode, ParserState& state ) |
| 2705 | { |
| 2706 | ZoneScoped; |
| 2707 | |
| 2708 | Symbol* entryPointSymbol = callNode->GetSymbol(); |
| 2709 | if( !entryPointSymbol || !entryPointSymbol->definition ) |
| 2710 | { |
| 2711 | return nullptr; |
| 2712 | } |
| 2713 | |
| 2714 | ASTNode* functionHeader = entryPointSymbol->definition->GetChildOrNull( 0 ); |
| 2715 | if( !functionHeader ) |
| 2716 | { |
| 2717 | return nullptr; |
| 2718 | } |
| 2719 | |
| 2720 | ScannerToken shaderName = ScannerToken::ID( GetEntryPointName( shaderType, callNode ) ); |
| 2721 | |
| 2722 | state.GetCurrentLocation().fileName = shaderName.stringValue; |
| 2723 | state.GetCurrentLocation().lineNumber = 1; |
| 2724 | |
| 2725 | ASTNode* inputsStruct = NewStruct( state, state.AllocateNameWithPrefix( "StageInData" ) ); |
| 2726 | ASTNode* outputsStruct = NewStruct( state, state.AllocateNameWithPrefix( "StageOutData" ) ); |
| 2727 | |
| 2728 | auto header = state.NewNode( NT_FUNCTION_HEADER, shaderName ); |
| 2729 | auto shaderSymbol = state.GetSymbolTable().AddSymbol( shaderName.stringValue, ALLOW_OVERRIDES ); |
| 2730 | shaderSymbol->isFunction = true; |
| 2731 | header->SetSymbol( shaderSymbol ); |
| 2732 | |
| 2733 | state.GetSymbolTable().EnterScope(); |
| 2734 | |
| 2735 | auto shaderBody = state.NewNode( NT_BLOCK ); |
| 2736 | |
| 2737 | std::vector<Symbol*> params; |
| 2738 | |
| 2739 | size_t uniformArgIndex = 0; |
| 2740 | |
| 2741 | for( size_t i = 0; i < functionHeader->GetChildrenCount(); ++i ) |
| 2742 | { |
| 2743 | // Create local variable declarations for original shader function arguments |
| 2744 | |
| 2745 | ASTNode* sourceArg = functionHeader->GetChild( i ); |
| 2746 | Symbol* sourceSymbol = sourceArg->GetSymbol(); |
| 2747 | ASTNode* bracketList = sourceArg->GetChildOrNull( 0 ); |
| 2748 | |
| 2749 | if( sourceSymbol->addressSpace != AddressSpace::Threadgroup && |
| 2750 | !IsUniformInputArgument( sourceArg ) && |
| 2751 | ( ( !sourceArg->GetType().IsStruct() && !sourceArg->GetType().IsScalarOrVector() ) || |
| 2752 | sourceSymbol->addressSpace != AddressSpace::None || |
| 2753 | HasSystemRegister( sourceSymbol ) ) ) |
| 2754 | { |
| 2755 | params.push_back( nullptr ); |
| 2756 | continue; |
| 2757 | } |
| 2758 | |
| 2759 | auto isUniform = IsUniformInputArgument( sourceArg ); |
| 2760 | if( shaderType >= PatchShaderType::RAY_GEN && !isUniform ) |
| 2761 | { |
no test coverage detected