diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-shader.cpp | 513 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 106 | ||||
| -rw-r--r-- | source/slang/slang-compiler.h | 116 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-parameter-binding.cpp | 202 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 265 |
6 files changed, 260 insertions, 953 deletions
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp index c229e8f96..611f6be58 100644 --- a/source/slang/slang-check-shader.cpp +++ b/source/slang/slang-check-shader.cpp @@ -569,408 +569,15 @@ namespace Slang return entryPoint; } - /// Get the name a variable will use for reflection purposes -Name* getReflectionName(VarDeclBase* varDecl) -{ - if (auto reflectionNameModifier = varDecl->FindModifier<ParameterGroupReflectionName>()) - return reflectionNameModifier->nameAndLoc.name; - - return varDecl->getName(); -} - -// Information tracked when doing a structural -// match of types. -struct StructuralTypeMatchStack -{ - DeclRef<VarDeclBase> leftDecl; - DeclRef<VarDeclBase> rightDecl; - StructuralTypeMatchStack* parent; -}; - -static void diagnoseParameterTypeMismatch( - DiagnosticSink* sink, - StructuralTypeMatchStack* inStack) -{ - SLANG_ASSERT(inStack); - - // The bottom-most entry in the stack should represent - // the shader parameters that kicked things off - auto stack = inStack; - while(stack->parent) - stack = stack->parent; - - sink->diagnose(stack->leftDecl, Diagnostics::shaderParameterDeclarationsDontMatch, getReflectionName(stack->leftDecl)); - sink->diagnose(stack->rightDecl, Diagnostics::seeOtherDeclarationOf, getReflectionName(stack->rightDecl)); -} - -// Two types that were expected to match did not. -// Inform the user with a suitable message. -static void diagnoseTypeMismatch( - DiagnosticSink* sink, - StructuralTypeMatchStack* inStack) -{ - auto stack = inStack; - SLANG_ASSERT(stack); - diagnoseParameterTypeMismatch(sink, stack); - - auto leftType = GetType(stack->leftDecl); - auto rightType = GetType(stack->rightDecl); - - if( stack->parent ) - { - sink->diagnose(stack->leftDecl, Diagnostics::fieldTypeMisMatch, getReflectionName(stack->leftDecl), leftType, rightType); - sink->diagnose(stack->rightDecl, Diagnostics::seeOtherDeclarationOf, getReflectionName(stack->rightDecl)); - - stack = stack->parent; - if( stack ) - { - while( stack->parent ) - { - sink->diagnose(stack->leftDecl, Diagnostics::usedInDeclarationOf, getReflectionName(stack->leftDecl)); - stack = stack->parent; - } - } - } - else - { - sink->diagnose(stack->leftDecl, Diagnostics::shaderParameterTypeMismatch, leftType, rightType); - } -} - -// Two types that were expected to match did not. -// Inform the user with a suitable message. -static void diagnoseTypeFieldsMismatch( - DiagnosticSink* sink, - DeclRef<Decl> const& left, - DeclRef<Decl> const& right, - StructuralTypeMatchStack* stack) -{ - diagnoseParameterTypeMismatch(sink, stack); - - sink->diagnose(left, Diagnostics::fieldDeclarationsDontMatch, left.GetName()); - sink->diagnose(right, Diagnostics::seeOtherDeclarationOf, right.GetName()); - - if( stack ) - { - while( stack->parent ) - { - sink->diagnose(stack->leftDecl, Diagnostics::usedInDeclarationOf, getReflectionName(stack->leftDecl)); - stack = stack->parent; - } - } -} - -static void collectFields( - DeclRef<AggTypeDecl> declRef, - List<DeclRef<VarDecl>>& outFields) -{ - for( auto fieldDeclRef : getMembersOfType<VarDecl>(declRef) ) - { - if(fieldDeclRef.getDecl()->HasModifier<HLSLStaticModifier>()) - continue; - - outFields.add(fieldDeclRef); - } -} - -static bool validateTypesMatch( - DiagnosticSink* sink, - Type* left, - Type* right, - StructuralTypeMatchStack* stack); - -static bool validateIntValuesMatch( - DiagnosticSink* sink, - IntVal* left, - IntVal* right, - StructuralTypeMatchStack* stack) -{ - if(left->EqualsVal(right)) - return true; - - // TODO: are there other cases we need to handle here? - - diagnoseTypeMismatch(sink, stack); - return false; -} - - -static bool validateValuesMatch( - DiagnosticSink* sink, - Val* left, - Val* right, - StructuralTypeMatchStack* stack) -{ - if( auto leftType = dynamicCast<Type>(left) ) - { - if( auto rightType = dynamicCast<Type>(right) ) - { - return validateTypesMatch(sink, leftType, rightType, stack); - } - } - - if( auto leftInt = dynamicCast<IntVal>(left) ) - { - if( auto rightInt = dynamicCast<IntVal>(right) ) - { - return validateIntValuesMatch(sink, leftInt, rightInt, stack); - } - } - - if( auto leftWitness = dynamicCast<SubtypeWitness>(left) ) - { - if( auto rightWitness = dynamicCast<SubtypeWitness>(right) ) - { - return true; - } - } - - diagnoseTypeMismatch(sink, stack); - return false; -} - -static bool validateGenericSubstitutionsMatch( - DiagnosticSink* sink, - GenericSubstitution* left, - GenericSubstitution* right, - StructuralTypeMatchStack* stack) -{ - if( !left ) - { - if( !right ) - { - return true; - } - - diagnoseTypeMismatch(sink, stack); - return false; - } - - - - Index argCount = left->args.getCount(); - if( argCount != right->args.getCount() ) - { - diagnoseTypeMismatch(sink, stack); - return false; - } - - for( Index aa = 0; aa < argCount; ++aa ) - { - auto leftArg = left->args[aa]; - auto rightArg = right->args[aa]; - - if(!validateValuesMatch(sink, leftArg, rightArg, stack)) - return false; - } - - return true; -} - -static bool validateThisTypeSubstitutionsMatch( - DiagnosticSink* /*sink*/, - ThisTypeSubstitution* /*left*/, - ThisTypeSubstitution* /*right*/, - StructuralTypeMatchStack* /*stack*/) -{ - // TODO: actual checking. - return true; -} - -static bool validateSpecializationsMatch( - DiagnosticSink* sink, - SubstitutionSet left, - SubstitutionSet right, - StructuralTypeMatchStack* stack) -{ - auto ll = left.substitutions; - auto rr = right.substitutions; - for(;;) - { - // Skip any global generic substitutions. - if(auto leftGlobalGeneric = as<GlobalGenericParamSubstitution>(ll)) - { - ll = leftGlobalGeneric->outer; - continue; - } - if(auto rightGlobalGeneric = as<GlobalGenericParamSubstitution>(rr)) - { - rr = rightGlobalGeneric->outer; - continue; - } - - // If either ran out, then we expect both to have run out. - if(!ll || !rr) - return !ll && !rr; - - auto leftSubst = ll; - auto rightSubst = rr; - - ll = ll->outer; - rr = rr->outer; - - if(auto leftGeneric = as<GenericSubstitution>(leftSubst)) - { - if(auto rightGeneric = as<GenericSubstitution>(rightSubst)) - { - if(validateGenericSubstitutionsMatch(sink, leftGeneric, rightGeneric, stack)) - { - continue; - } - } - } - else if(auto leftThisType = as<ThisTypeSubstitution>(leftSubst)) - { - if(auto rightThisType = as<ThisTypeSubstitution>(rightSubst)) - { - if(validateThisTypeSubstitutionsMatch(sink, leftThisType, rightThisType, stack)) - { - continue; - } - } - } - - return false; - } - - return true; -} - -// Determine if two types "match" for the purposes of `cbuffer` layout rules. -// -static bool validateTypesMatch( - DiagnosticSink* sink, - Type* left, - Type* right, - StructuralTypeMatchStack* stack) -{ - if(left->Equals(right)) - return true; - - // It is possible that the types don't match exactly, but - // they *do* match structurally. - - // Note: the following code will lead to infinite recursion if there - // are ever recursive types. We'd need a more refined system to - // cache the matches we've already found. - - if( auto leftDeclRefType = as<DeclRefType>(left) ) - { - if( auto rightDeclRefType = as<DeclRefType>(right) ) - { - // Are they references to matching decl refs? - auto leftDeclRef = leftDeclRefType->declRef; - auto rightDeclRef = rightDeclRefType->declRef; - - // Do the reference the same declaration? Or declarations - // with the same name? - // - // TODO: we should only consider the same-name case if the - // declarations come from translation units being compiled - // (and not an imported module). - if( leftDeclRef.getDecl() == rightDeclRef.getDecl() - || leftDeclRef.GetName() == rightDeclRef.GetName() ) - { - // Check that any generic arguments match - if( !validateSpecializationsMatch( - sink, - leftDeclRef.substitutions, - rightDeclRef.substitutions, - stack) ) - { - return false; - } - - // Check that any declared fields match too. - if( auto leftStructDeclRef = leftDeclRef.as<AggTypeDecl>() ) - { - if( auto rightStructDeclRef = rightDeclRef.as<AggTypeDecl>() ) - { - List<DeclRef<VarDecl>> leftFields; - List<DeclRef<VarDecl>> rightFields; - - collectFields(leftStructDeclRef, leftFields); - collectFields(rightStructDeclRef, rightFields); - - Index leftFieldCount = leftFields.getCount(); - Index rightFieldCount = rightFields.getCount(); - - if( leftFieldCount != rightFieldCount ) - { - diagnoseTypeFieldsMismatch(sink, leftDeclRef, rightDeclRef, stack); - return false; - } - - for( Index ii = 0; ii < leftFieldCount; ++ii ) - { - auto leftField = leftFields[ii]; - auto rightField = rightFields[ii]; - - if( leftField.GetName() != rightField.GetName() ) - { - diagnoseTypeFieldsMismatch(sink, leftDeclRef, rightDeclRef, stack); - return false; - } - - auto leftFieldType = GetType(leftField); - auto rightFieldType = GetType(rightField); - - StructuralTypeMatchStack subStack; - subStack.parent = stack; - subStack.leftDecl = leftField; - subStack.rightDecl = rightField; - - if(!validateTypesMatch(sink, leftFieldType,rightFieldType, &subStack)) - return false; - } - } - } - - // Everything seemed to match recursively. - return true; - } - } - } - - // If we are looking at `T[N]` and `U[M]` we want to check that - // `T` is structurally equivalent to `U` and `N` is the same as `M`. - else if( auto leftArrayType = as<ArrayExpressionType>(left) ) + /// Get the name a variable will use for reflection purposes + Name* getReflectionName(VarDeclBase* varDecl) { - if( auto rightArrayType = as<ArrayExpressionType>(right) ) - { - if(!validateTypesMatch(sink, leftArrayType->baseType, rightArrayType->baseType, stack) ) - return false; - - if(!validateValuesMatch(sink, leftArrayType->ArrayLength, rightArrayType->ArrayLength, stack)) - return false; + if (auto reflectionNameModifier = varDecl->FindModifier<ParameterGroupReflectionName>()) + return reflectionNameModifier->nameAndLoc.name; - return true; - } + return varDecl->getName(); } - diagnoseTypeMismatch(sink, stack); - return false; -} - -// This function is supposed to determine if two global shader -// parameter declarations represent the same logical parameter -// (so that they should get the exact same binding(s) allocated). -// -static bool doesParameterMatch( - DiagnosticSink* sink, - DeclRef<VarDeclBase> varDeclRef, - DeclRef<VarDeclBase> existingVarDeclRef) -{ - StructuralTypeMatchStack stack; - stack.parent = nullptr; - stack.leftDecl = varDeclRef; - stack.rightDecl = existingVarDeclRef; - - validateTypesMatch(sink, GetType(varDeclRef), GetType(existingVarDeclRef), &stack); - - return true; -} - void Module::_collectShaderParams() { auto moduleDecl = m_moduleDecl; @@ -1003,7 +610,7 @@ static bool doesParameterMatch( // At this point we know we have a global shader parameter. - GlobalShaderParamInfo shaderParamInfo; + ShaderParamInfo shaderParamInfo; shaderParamInfo.paramDeclRef = makeDeclRef(globalVar.Ptr()); // We need to consider what specialization parameters @@ -1072,102 +679,6 @@ static bool doesParameterMatch( } - /// Enumerate the parameters of a `LegacyProgram`. - void LegacyProgram::_collectShaderParams(DiagnosticSink* sink) - { - // We need to collect all of the global shader parameters - // referenced by the compile request, and for each we - // need to do a few things: - // - // * We need to determine if the parameter is a duplicate/redeclaration - // of the "same" parameter in another translation unit, and collapse - // those into one logical shader parameter if so. - // - // * We need to determine what existential type slots are introduced - // by the parameter, and associate that information with the parameter. - // - // To deal with the first issue, we will maintain a map from a parameter - // name to the index of an existing parameter with that name. - // - // TODO: Eventually we should deprecate support for the - // deduplication feature of `LegaqcyProgram`, at which point - // this entire type and all its complications can be eliminated - // from the code (that includes a lot of support in the "parameter - // binding" step for shader parameters with multiple declarations). - // Until that point this type will have a fair amount of duplication - // with stuff in `Module` and `CompositeComponentType`. - - // We use a dictionary to keep track of any shader parameter - // we've alrady collected with a given name. - // - Dictionary<Name*, Int> mapNameToParamIndex; - - for( auto translationUnit : m_translationUnits ) - { - auto module = translationUnit->getModule(); - auto moduleDecl = module->getModuleDecl(); - for( auto globalVar : moduleDecl->getMembersOfType<VarDecl>() ) - { - // We do not want to consider global variable declarations - // that don't represents shader parameters. This includes - // things like `static` globals and `groupshared` variables. - // - if(!isGlobalShaderParameter(globalVar)) - continue; - - // This declaration may represent the same logical parameter - // as a declaration that came from a different translation unit. - // If that is the case, we want to re-use the same `ShaderParamInfo` - // across both parameters. - // - // TODO: This logic currently detects *any* global-scope parameters - // with matching names, but it should eventually be narrowly - // scoped so that it only applies to parameters from unnamed modules - // (that is, modules that represent directly-compiled shader files - // and not `import`ed code). - // - // First we look for an existing entry matching the name - // of this parameter: - // - auto paramName = getReflectionName(globalVar); - Int existingParamIndex = -1; - if( mapNameToParamIndex.TryGetValue(paramName, existingParamIndex) ) - { - // If the parameters have the same name, but don't "match" according to some reasonable rules, - // then we will treat them as distinct global parameters. - // - // Note: all of the mismatch cases currently report errors, so that - // compilation will fail on a mismatch. - // - auto& existingParam = m_shaderParams[existingParamIndex]; - if( doesParameterMatch(sink, makeDeclRef(globalVar.Ptr()), existingParam.paramDeclRef) ) - { - // If we hit this case, then we had a match, and we should - // consider the new variable to be a redclaration of - // the existing one. - - existingParam.additionalParamDeclRefs.add( - makeDeclRef(globalVar.Ptr())); - continue; - } - } - - Int newParamIndex = Int(m_shaderParams.getCount()); - mapNameToParamIndex.Add(paramName, newParamIndex); - - GlobalShaderParamInfo shaderParamInfo; - shaderParamInfo.paramDeclRef = makeDeclRef(globalVar.Ptr()); - - _collectExistentialSpecializationParamsForShaderParam( - shaderParamInfo, - m_specializationParams, - makeDeclRef(globalVar.Ptr())); - - m_shaderParams.add(shaderParamInfo); - } - } - } - /// Create a new component type based on `inComponentType`, but with all its requiremetns filled. RefPtr<ComponentType> fillRequirements( ComponentType* inComponentType) @@ -1234,7 +745,6 @@ static bool doesParameterMatch( // compiler behavior (at least for now). // auto linkage = compileRequest->getLinkage(); - auto sink = compileRequest->getSink(); RefPtr<ComponentType> globalComponentType; if(compileRequest->translationUnits.getCount() == 1) @@ -1248,10 +758,15 @@ static bool doesParameterMatch( } else { - globalComponentType = new LegacyProgram( + List<RefPtr<ComponentType>> translationUnitComponentTypes; + for( auto tu : compileRequest->translationUnits ) + { + translationUnitComponentTypes.add(tu->getModule()); + } + + globalComponentType = CompositeComponentType::create( linkage, - compileRequest->translationUnits, - sink); + translationUnitComponentTypes); } return fillRequirements(globalComponentType); diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index cc60f18f4..6cb3603b9 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -939,6 +939,93 @@ namespace Slang return UnownedStringSlice(); } + /// Read a file in the context of handling a preprocessor directive + static SlangResult readFile( + Linkage* linkage, + String const& path, + ISlangBlob** outBlob) + { + // The actual file loading will be handled by the file system + // associated with the parent linkage. + // + auto fileSystemExt = linkage->getFileSystemExt(); + SLANG_RETURN_ON_FAIL(fileSystemExt->loadFile(path.getBuffer(), outBlob)); + + return SLANG_OK; + } + + struct FxcIncludeHandler : ID3DInclude + { + Linkage* linkage; + DiagnosticSink* sink; + IncludeHandler* includeHandler; + PathInfo rootPathInfo; + + STDMETHOD(Open)(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override + { + SLANG_UNUSED(IncludeType); + SLANG_UNUSED(pParentData); + + String path(pFileName); + + SourceLoc loc; + + PathInfo includedFromPathInfo = rootPathInfo; + + if (!includeHandler) + { + return SLANG_E_NOT_IMPLEMENTED; + } + + // Find the path relative to the foundPath + PathInfo filePathInfo; + if (SLANG_FAILED(includeHandler->findFile(path, includedFromPathInfo.foundPath, filePathInfo))) + { + return SLANG_E_CANNOT_OPEN; + } + + // We must have a uniqueIdentity to be compare + if (!filePathInfo.hasUniqueIdentity()) + { + return SLANG_E_ABORT; + } + + // Simplify the path + filePathInfo.foundPath = includeHandler->simplifyPath(filePathInfo.foundPath); + + // See if this an already loaded source file + auto sourceManager = linkage->getSourceManager(); + SourceFile* sourceFile = sourceManager->findSourceFileRecursively(filePathInfo.uniqueIdentity); + + // If not create a new one, and add to the list of known source files + if (!sourceFile) + { + ComPtr<ISlangBlob> foundSourceBlob; + if (SLANG_FAILED(readFile(linkage, filePathInfo.foundPath, foundSourceBlob.writeRef()))) + { + return SLANG_E_CANNOT_OPEN; + } + + sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob); + sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile); + } + + // This is a new parse (even if it's a pre-existing source file), so create a new SourceUnit + SourceView* sourceView = sourceManager->createSourceView(sourceFile, &filePathInfo); + + *ppData = sourceView->getContent().begin(); + *pBytes = (UINT) sourceView->getContentSize(); + + return S_OK; + } + + STDMETHOD(Close)(LPCVOID pData) override + { + SLANG_UNUSED(pData); + return S_OK; + } + }; + SlangResult emitDXBytecodeForEntryPoint( BackEndCompileRequest* compileRequest, EntryPoint* entryPoint, @@ -963,6 +1050,8 @@ namespace Slang auto profile = getEffectiveProfile(entryPoint, targetReq); + auto linkage = compileRequest->getLinkage(); + // If we have been invoked in a pass-through mode, then we need to make sure // that the downstream compiler sees whatever options were passed to Slang // via the command line or API. @@ -971,6 +1060,14 @@ namespace Slang // List<D3D_SHADER_MACRO> dxMacrosStorage; D3D_SHADER_MACRO const* dxMacros = nullptr; + + IncludeHandlerImpl includeHandler; + includeHandler.linkage = linkage; + includeHandler.searchDirectories = &linkage->searchDirectories; + + FxcIncludeHandler fxcIncludeHandlerStorage; + FxcIncludeHandler* fxcIncludeHandler = nullptr; + if(auto translationUnit = findPassThroughTranslationUnit(endToEndReq, entryPointIndex)) { for( auto& define : translationUnit->compileRequest->preprocessorDefinitions ) @@ -991,6 +1088,12 @@ namespace Slang dxMacrosStorage.add(nullTerminator); dxMacros = dxMacrosStorage.getBuffer(); + + fxcIncludeHandler = &fxcIncludeHandlerStorage; + fxcIncludeHandler->linkage = linkage; + fxcIncludeHandler->sink = compileRequest->getSink(); + fxcIncludeHandler->includeHandler = &includeHandler; + fxcIncludeHandler->rootPathInfo = translationUnit->m_sourceFiles[0]->getPathInfo(); } DWORD flags = 0; @@ -1018,7 +1121,6 @@ namespace Slang flags |= D3DCOMPILE_ENABLE_STRICTNESS; flags |= D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES; - auto linkage = compileRequest->getLinkage(); switch( linkage->optimizationLevel ) { default: @@ -1049,7 +1151,7 @@ namespace Slang hlslCode.getLength(), sourcePath.getBuffer(), dxMacros, - nullptr, + fxcIncludeHandler, getText(entryPoint->getName()).begin(), GetHLSLProfileName(profile).getBuffer(), flags, diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 17da14c14..9950764e4 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -10,6 +10,7 @@ #include "slang-diagnostics.h" #include "slang-name.h" +#include "slang-preprocessor.h" #include "slang-profile.h" #include "slang-syntax.h" @@ -159,20 +160,6 @@ namespace Slang Int specializationParamCount = 0; }; - /// Extended information specific to global shader parameters - struct GlobalShaderParamInfo : ShaderParamInfo - { - // TODO: This type should be eliminated if/when we remove - // support for compilation with multiple translation units - // that all declare the "same" shader parameter (e.g., a - // `cbuffer`) and expect those duplicate declarations - // to get the same parameter binding/layout. - - // Additional global-scope declarations that are conceptually - // declaring the "same" parameter as the `paramDeclRef`. - List<DeclRef<VarDeclBase>> additionalParamDeclRefs; - }; - /// A request for the front-end to find and validate an entry-point function struct FrontEndEntryPointRequest : RefObject { @@ -321,7 +308,7 @@ namespace Slang virtual Index getShaderParamCount() = 0; /// Get one of the global shader parametesr linked into this component type. - virtual GlobalShaderParamInfo getShaderParam(Index index) = 0; + virtual ShaderParamInfo getShaderParam(Index index) = 0; /// Get the number of (unspecialized) specialization parameters for the component type. virtual Index getSpecializationParamCount() = 0; @@ -351,8 +338,7 @@ namespace Slang /// to the provided `sink`. /// /// TODO: This function shouldn't be on the base class, since - /// it only really makes sense on `Module` and (as a compatibility - /// feature) on `LegacyProgram`. + /// it only really makes sense on `Module`. /// Type* getTypeFromString( String const& typeStr, @@ -508,7 +494,7 @@ namespace Slang String getEntryPointMangledName(Index index) SLANG_OVERRIDE; Index getShaderParamCount() SLANG_OVERRIDE; - GlobalShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE; + ShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE; Index getSpecializationParamCount() SLANG_OVERRIDE; SpecializationParam const& getSpecializationParam(Index index) SLANG_OVERRIDE; @@ -555,7 +541,7 @@ namespace Slang // List<EntryPoint*> m_entryPoints; List<String> m_entryPointMangledNames; - List<GlobalShaderParamInfo> m_shaderParams; + List<ShaderParamInfo> m_shaderParams; List<SpecializationParam> m_specializationParams; List<ComponentType*> m_requirements; @@ -595,7 +581,7 @@ namespace Slang String getEntryPointMangledName(Index index) SLANG_OVERRIDE; Index getShaderParamCount() SLANG_OVERRIDE { return m_base->getShaderParamCount(); } - GlobalShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { return m_base->getShaderParam(index); } + ShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { return m_base->getShaderParam(index); } Index getSpecializationParamCount() SLANG_OVERRIDE { return 0; } SpecializationParam const& getSpecializationParam(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); static SpecializationParam dummy; return dummy; } @@ -726,7 +712,7 @@ namespace Slang String getEntryPointMangledName(Index index) SLANG_OVERRIDE; Index getShaderParamCount() SLANG_OVERRIDE { return 0; } - GlobalShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); return GlobalShaderParamInfo(); } + ShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); return ShaderParamInfo(); } class EntryPointSpecializationInfo : public SpecializationInfo { @@ -890,7 +876,7 @@ namespace Slang String getEntryPointMangledName(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); return String(); } Index getShaderParamCount() SLANG_OVERRIDE { return m_shaderParams.getCount(); } - GlobalShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { return m_shaderParams[index]; } + ShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { return m_shaderParams[index]; } Index getSpecializationParamCount() SLANG_OVERRIDE { return m_specializationParams.getCount(); } SpecializationParam const& getSpecializationParam(Index index) SLANG_OVERRIDE { return m_specializationParams[index]; } @@ -940,7 +926,7 @@ namespace Slang // The IR for the module RefPtr<IRModule> m_irModule = nullptr; - List<GlobalShaderParamInfo> m_shaderParams; + List<ShaderParamInfo> m_shaderParams; SpecializationParams m_specializationParams; List<Module*> m_requirements; @@ -1479,64 +1465,6 @@ namespace Slang List<RefPtr<ComponentType>> m_unspecializedEntryPoints; }; - /// A "legacy" program composes multiple translation units from a single compile request, - /// and takes care to treat global declarations of the same name from different translation - /// units as representing the "same" parameter. - /// - /// TODO: This type only exists to support a single requirement: that multiple translation - /// units can be compiled in one pass and be guaranteed that the "same" parameter declared - /// in different translation units (hence different modules) will get the same layout. - /// This feature should be deprecated and removed as soon as possible, since the complexity - /// it creates in the codebase is not justified by its limited utility. - /// - class LegacyProgram : public ComponentType - { - public: - LegacyProgram( - Linkage* linkage, - List<RefPtr<TranslationUnitRequest>> const& translationUnits, - DiagnosticSink* sink); - - Index getTranslationUnitCount() { return m_translationUnits.getCount(); } - RefPtr<TranslationUnitRequest> getTranslationUnit(Index index) { return m_translationUnits[index]; } - - Index getEntryPointCount() SLANG_OVERRIDE { return 0; } - RefPtr<EntryPoint> getEntryPoint(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); return nullptr; } - String getEntryPointMangledName(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); return String(); } - - Index getShaderParamCount() SLANG_OVERRIDE { return m_shaderParams.getCount(); } - GlobalShaderParamInfo getShaderParam(Index index) SLANG_OVERRIDE { return m_shaderParams[index]; } - - Index getSpecializationParamCount() SLANG_OVERRIDE { return m_specializationParams.getCount(); } - SpecializationParam const& getSpecializationParam(Index index) SLANG_OVERRIDE { return m_specializationParams[index]; } - - Index getRequirementCount() SLANG_OVERRIDE; - RefPtr<ComponentType> getRequirement(Index index) SLANG_OVERRIDE; - - List<Module*> const& getModuleDependencies() SLANG_OVERRIDE { return m_moduleDependencies.getModuleList(); } - List<String> const& getFilePathDependencies() SLANG_OVERRIDE { return m_fileDependencies.getFilePathList(); } - - protected: - void acceptVisitor(ComponentTypeVisitor* visitor, SpecializationInfo* specializationInfo) SLANG_OVERRIDE; - - RefPtr<SpecializationInfo> _validateSpecializationArgsImpl( - SpecializationArg const* args, - Index argCount, - DiagnosticSink* sink) SLANG_OVERRIDE; - - private: - void _collectShaderParams(DiagnosticSink* sink); - - List<RefPtr<TranslationUnitRequest>> m_translationUnits; - - List<EntryPoint*> m_entryPoints; - List<GlobalShaderParamInfo> m_shaderParams; - List<ComponentType*> m_requirements; - SpecializationParams m_specializationParams; - ModuleDependencyList m_moduleDependencies; - FilePathDependencyList m_fileDependencies; - }; - /// A visitor for use with `ComponentType`s, allowing dispatch over the concrete subclasses. class ComponentTypeVisitor { @@ -1552,23 +1480,14 @@ namespace Slang virtual void visitModule(Module* module, Module::ModuleSpecializationInfo* specializationInfo) = 0; virtual void visitComposite(CompositeComponentType* composite, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) = 0; virtual void visitSpecialized(SpecializedComponentType* specialized) = 0; - virtual void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) = 0; protected: // These helpers can be used to recurse into the logical children of a // component type, and are useful for the common case where a visitor // only cares about a few leaf cases. // - // Note that for a `LegacyProgram` the "children" in this case are the - // `Module`s of the translation units that make up the legacy program. - // In some cases this is what is desired, but in others it is incorrect - // to treat a legacy program as a composition of modules, and instead - // it should be treated directly as a leaf case. Clients should make - // an informed decision based on an understanding of what `LegacyProgram` is used for. - // void visitChildren(CompositeComponentType* composite, CompositeComponentType::CompositeSpecializationInfo* specializationInfo); void visitChildren(SpecializedComponentType* specialized); - void visitChildren(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo); }; /// A `TargetProgram` represents a `ComponentType` specialized for a particular `TargetRequest` @@ -2079,6 +1998,23 @@ namespace Slang PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)]; }; +struct IncludeHandlerImpl : IncludeHandler +{ + Linkage* linkage; + SearchDirectoryList* searchDirectories; + + ISlangFileSystemExt* _getFileSystemExt(); + + SlangResult _findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& pathInfoOut); + + virtual SlangResult findFile( + String const& pathToInclude, + String const& pathIncludedFrom, + PathInfo& pathInfoOut) override; + + virtual String simplifyPath(const String& path) override; +}; + // // The following functions are utilties to convert between diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 2ea4f3d32..b3c45b704 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -6941,17 +6941,6 @@ struct SpecializedComponentTypeIRGenContext : ComponentTypeVisitor { visitChildren(specialized); } - - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - // TODO: This case should be akin to the `Module` case, - // and deal with global-scope specialization parameters - // directly. - // - SLANG_UNUSED(legacy); - SLANG_UNUSED(specializationInfo); - SLANG_UNIMPLEMENTED_X("legacy program case"); - } }; RefPtr<IRModule> generateIRForSpecializedComponentType( diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 9e11152c4..5cd4156c3 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -306,13 +306,13 @@ struct UsedRangeSet : RefObject // Information on a single parameter struct ParameterInfo : RefObject { - // Layout info for the concrete variables that will make up this parameter - List<RefPtr<VarLayout>> varLayouts; + // Layout info for the variable that represents this parameter + RefPtr<VarLayout> varLayout; ParameterBindingInfo bindingInfo[kLayoutResourceKindCount]; // The translation unit this parameter is specific to, if any - TranslationUnitRequest* translationUnit = nullptr; +// TranslationUnitRequest* translationUnit = nullptr; ParameterInfo() { @@ -696,9 +696,9 @@ static RefPtr<VarLayout> _createVarLayout( // Collect a single declaration into our set of parameters static void collectGlobalScopeParameter( - ParameterBindingContext* context, - GlobalShaderParamInfo const& shaderParamInfo, - SubstitutionSet globalGenericSubst) + ParameterBindingContext* context, + ShaderParamInfo const& shaderParamInfo, + SubstitutionSet globalGenericSubst) { auto varDeclRef = shaderParamInfo.paramDeclRef; @@ -722,7 +722,7 @@ static void collectGlobalScopeParameter( // Now create a variable layout that we can use RefPtr<VarLayout> varLayout = _createVarLayout(typeLayout, varDeclRef); - // The logic in `check.cpp` that created the `GlobalShaderParamInfo` + // The logic in `check.cpp` that created the `ShaderParamInfo` // will have identified any cases where there might be multiple // global variables that logically represent the same shader parameter. // @@ -734,30 +734,10 @@ static void collectGlobalScopeParameter( ParameterInfo* parameterInfo = new ParameterInfo(); context->shared->parameters.add(parameterInfo); - // Add the first variable declaration to the list of declarations for the parameter - parameterInfo->varLayouts.add(varLayout); - - // Add any additional variables to the list of declarations - for( auto additionalVarDeclRef : shaderParamInfo.additionalParamDeclRefs ) - { - // TODO: We should either eliminate the design choice where different - // declarations of the "same" shade parameter get merged across - // translation units (it is effectively just a compatiblity feature), - // or we should clean things up earlier in the chain so that we can - // re-use a single `VarLayout` across all of the different declarations. - // - // TODO: It would also make sense in these cases to ensure that - // such global shader parameters get the same mangled name across - // all translation units, so that they can automatically be collapsed - // during linking. - - RefPtr<VarLayout> additionalVarLayout = new VarLayout(); - additionalVarLayout->typeLayout = typeLayout; - additionalVarLayout->varDecl = additionalVarDeclRef; - additionalVarLayout->pendingVarLayout = varLayout->pendingVarLayout; - - parameterInfo->varLayouts.add(additionalVarLayout); - } + // Add the created var layout to the parameter information structure, + // so that we can update it as we proceed with parameter binding. + // + parameterInfo->varLayout = varLayout; } static RefPtr<UsedRangeSet> findUsedRangeSetForSpace( @@ -831,12 +811,6 @@ static void addExplicitParameterBinding( || bindingInfo.space != semanticInfo.space ) { getSink(context)->diagnose(varDecl, Diagnostics::conflictingExplicitBindingsForParameter, getReflectionName(varDecl)); - - auto firstVarDecl = parameterInfo->varLayouts[0]->varDecl.getDecl(); - if( firstVarDecl != varDecl ) - { - getSink(context)->diagnose(firstVarDecl, Diagnostics::seeOtherDeclarationOf, getReflectionName(firstVarDecl)); - } } // TODO(tfoley): `register` semantics can technically be @@ -859,13 +833,13 @@ static void addExplicitParameterBinding( markSpaceUsed(context, semanticInfo.space); } auto overlappedVarLayout = usedRangeSet->usedResourceRanges[(int)semanticInfo.kind].Add( - parameterInfo->varLayouts[0], + parameterInfo->varLayout, semanticInfo.index, semanticInfo.index + count); if (overlappedVarLayout) { - auto paramA = parameterInfo->varLayouts[0]->varDecl.getDecl(); + auto paramA = parameterInfo->varLayout->varDecl.getDecl(); auto paramB = overlappedVarLayout->varDecl.getDecl(); auto& diagnosticInfo = Diagnostics::parameterBindingsOverlap; @@ -1052,19 +1026,24 @@ void generateParameterBindings( ParameterBindingContext* context, RefPtr<ParameterInfo> parameterInfo) { - // There must be at least one declaration for the parameter. - SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.getCount() != 0); + // There must have been a declaration for the parameter. + SLANG_RELEASE_ASSERT(parameterInfo->varLayout); - // Iterate over all declarations looking for explicit binding information. - for( auto& varLayout : parameterInfo->varLayouts ) - { - // Handle HLSL `register` and `packoffset` modifiers - addExplicitParameterBindings_HLSL(context, parameterInfo, varLayout); + // We will look for explicit binding information on the declaration. + auto varLayout = parameterInfo->varLayout; + // Handle HLSL `register` and `packoffset` modifiers + addExplicitParameterBindings_HLSL(context, parameterInfo, varLayout); - // Handle GLSL `layout` modifiers - addExplicitParameterBindings_GLSL(context, parameterInfo, varLayout); - } + + // Handle GLSL `layout` modifiers and `[vk::...]` attributes. + // + // TODO: We should deprecate the support for `layout` and then rename + // these `_HLSL` and `_GLSL` functions to be more explicit and clear + // about the fact that they are specific to the *target* and not to + // the *source language* (as they were at one point). + // + addExplicitParameterBindings_GLSL(context, parameterInfo, varLayout); } // Generate the binding information for a shader parameter. @@ -1292,17 +1271,12 @@ static void completeBindingsForParameter( ParameterBindingContext* context, RefPtr<ParameterInfo> parameterInfo) { - // We will use the first declaration of the parameter as - // a stand-in for all the declarations, so it is important - // that earlier code has validated that the declarations - // "match". - - SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.getCount() != 0); - auto firstVarLayout = parameterInfo->varLayouts.getFirst(); + auto varLayout = parameterInfo->varLayout; + SLANG_RELEASE_ASSERT(varLayout); completeBindingsForParameterImpl( context, - firstVarLayout, + varLayout, parameterInfo->bindingInfo, parameterInfo); @@ -1310,10 +1284,7 @@ static void completeBindingsForParameter( // all the relevant resource kinds, so we can apply these to the // declarations: - for(auto& varLayout : parameterInfo->varLayouts) - { - applyBindingInfoToParameter(varLayout, parameterInfo->bindingInfo); - } + applyBindingInfoToParameter(varLayout, parameterInfo->bindingInfo); } static void completeBindingsForParameter( @@ -1925,11 +1896,10 @@ struct ScopeLayoutBuilder } void _addParameter( - RefPtr<VarLayout> firstVarLayout, - ParameterInfo* parameterInfo) + RefPtr<VarLayout> varLayout) { // Does the parameter have any uniform data? - auto layoutInfo = firstVarLayout->typeLayout->FindResourceInfo(LayoutResourceKind::Uniform); + auto layoutInfo = varLayout->typeLayout->FindResourceInfo(LayoutResourceKind::Uniform); LayoutSize uniformSize = layoutInfo ? layoutInfo->count : 0; if( uniformSize != 0 ) { @@ -1937,44 +1907,24 @@ struct ScopeLayoutBuilder UniformLayoutInfo fieldInfo( uniformSize, - firstVarLayout->typeLayout->uniformAlignment); + varLayout->typeLayout->uniformAlignment); LayoutSize uniformOffset = m_rules->AddStructField( &m_structLayoutInfo, fieldInfo); - if( parameterInfo ) - { - for( auto& varLayout : parameterInfo->varLayouts ) - { - varLayout->findOrAddResourceInfo(LayoutResourceKind::Uniform)->index = uniformOffset.getFiniteValue(); - } - } - else - { - firstVarLayout->findOrAddResourceInfo(LayoutResourceKind::Uniform)->index = uniformOffset.getFiniteValue(); - } + varLayout->findOrAddResourceInfo(LayoutResourceKind::Uniform)->index = uniformOffset.getFiniteValue(); } - m_structLayout->fields.add(firstVarLayout); + m_structLayout->fields.add(varLayout); - if( parameterInfo ) - { - for( auto& varLayout : parameterInfo->varLayouts ) - { - m_structLayout->mapVarToLayout.Add(varLayout->varDecl.getDecl(), varLayout); - } - } - else - { - m_structLayout->mapVarToLayout.Add(firstVarLayout->varDecl.getDecl(), firstVarLayout); - } + m_structLayout->mapVarToLayout.Add(varLayout->varDecl.getDecl(), varLayout); } void addParameter( RefPtr<VarLayout> varLayout) { - _addParameter(varLayout, nullptr); + _addParameter(varLayout); // Any "pending" items on a field type become "pending" items // on the overall `struct` type layout. @@ -1997,17 +1947,17 @@ struct ScopeLayoutBuilder void addParameter( ParameterInfo* parameterInfo) { - SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.getCount() != 0); - auto firstVarLayout = parameterInfo->varLayouts.getFirst(); + auto varLayout = parameterInfo->varLayout; + SLANG_RELEASE_ASSERT(varLayout); - _addParameter(firstVarLayout, parameterInfo); + _addParameter(varLayout); // Global parameters will have their non-orindary/uniform // pending data handled by the main parameter binding // logic, but we still need to construct a layout // that includes any pending data. // - if(auto fieldPendingVarLayout = firstVarLayout->pendingVarLayout) + if(auto fieldPendingVarLayout = varLayout->pendingVarLayout) { auto fieldPendingTypeLayout = fieldPendingVarLayout->typeLayout; @@ -2404,13 +2354,6 @@ struct CollectGlobalGenericArgumentsVisitor : ComponentTypeVisitor { specialized->getBaseComponentType()->acceptVisitor(this, specialized->getSpecializationInfo()); } - - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - // TODO: Need to do something in this case... - SLANG_UNUSED(legacy); - SLANG_UNUSED(specializationInfo); - } }; /// Collect an ordered list of all the specialization arguments given for global generic specialization parameters in `program`. @@ -2563,34 +2506,6 @@ struct CollectParametersVisitor : ComponentTypeVisitor } } - - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - // A legacy program is also a leaf case, and we - // can enumerate its parameters directly. - // - // Note: there is a mismatch here where we really - // ought to be tracking specialization arguments - // for a `LegacyProgram` akin to how they are - // tracked for a `Module`, but right now we try - // to do it like a `CompositeComponentType`. - // As a result we are just ignoring specialization - // information here, which will lead to incorrect - // results if somebody every uses specialization - // together with the "legacy" program case. - // - // TODO: eliminate this problem by getting rid of - // `LegacyProgram`, rather than spend time trying - // to make this corner case actually work. - // - SLANG_UNUSED(specializationInfo); - - auto paramCount = legacy->getShaderParamCount(); - for(Index pp = 0; pp < paramCount; ++pp) - { - collectGlobalScopeParameter(m_context, legacy->getShaderParam(pp), SubstitutionSet()); - } - } }; /// Recursively collect the global shader parameters and entry points in `program`. @@ -2751,13 +2666,6 @@ struct CompleteBindingsVisitor : ComponentTypeVisitor visitLeafParams(module); } - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - SLANG_UNUSED(specializationInfo); - // A legacy program is a leaf case: we just want to visit each parameter. - visitLeafParams(legacy); - } - void visitLeafParams(ComponentType* componentType) { auto paramCount = componentType->getShaderParamCount(); @@ -2881,12 +2789,6 @@ struct FlushPendingDataVisitor : ComponentTypeVisitor visitLeafParams(module); } - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - SLANG_UNUSED(specializationInfo); - visitLeafParams(legacy); - } - void visitLeafParams(ComponentType* componentType) { // In the "leaf" case we just allocate space for any @@ -2897,9 +2799,9 @@ struct FlushPendingDataVisitor : ComponentTypeVisitor { auto globalParamIndex = m_counters->globalParamCounter++; auto globalParamInfo = m_context->shared->parameters[globalParamIndex]; - auto firstVarLayout = globalParamInfo->varLayouts[0]; + auto varLayout = globalParamInfo->varLayout; - _allocateBindingsForPendingData(m_context, firstVarLayout->pendingVarLayout); + _allocateBindingsForPendingData(m_context, varLayout->pendingVarLayout); } } @@ -3072,14 +2974,14 @@ RefPtr<ProgramLayout> generateParameterBindings( { for( auto& parameterInfo : sharedContext.parameters ) { - SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.getCount() != 0); - auto firstVarLayout = parameterInfo->varLayouts.getFirst(); + auto varLayout = parameterInfo->varLayout; + SLANG_RELEASE_ASSERT(varLayout); // Does the field have any uniform data? - if( firstVarLayout->typeLayout->FindResourceInfo(LayoutResourceKind::Uniform) ) + if( varLayout->typeLayout->FindResourceInfo(LayoutResourceKind::Uniform) ) { needDefaultConstantBuffer = true; - diagnoseGlobalUniform(&sharedContext, firstVarLayout->varDecl); + diagnoseGlobalUniform(&sharedContext, varLayout->varDecl); } } } @@ -3102,12 +3004,12 @@ RefPtr<ProgramLayout> generateParameterBindings( // for (auto& parameterInfo : sharedContext.parameters) { - SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.getCount() != 0); - auto firstVarLayout = parameterInfo->varLayouts.getFirst(); + auto varLayout = parameterInfo->varLayout; + SLANG_RELEASE_ASSERT(varLayout); // For each parameter, we will look at each resource it consumes. // - for (auto resInfo : firstVarLayout->typeLayout->resourceInfos) + for (auto resInfo : varLayout->typeLayout->resourceInfos) { // We don't care about whole register spaces/sets, since // we don't need to allocate a default space/set for a parameter diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 28e0a358d..339ace54f 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -297,112 +297,92 @@ CPPCompiler* Session::getDefaultCPPCompiler(SourceLanguage sourceLanguage) return getCPPCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)]); } -struct IncludeHandlerImpl : IncludeHandler +ISlangFileSystemExt* IncludeHandlerImpl::_getFileSystemExt() { - Linkage* linkage; - SearchDirectoryList* searchDirectories; + return linkage->getFileSystemExt(); +} + +SlangResult IncludeHandlerImpl::_findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& pathInfoOut) +{ + ISlangFileSystemExt* fileSystemExt = _getFileSystemExt(); - ISlangFileSystemExt* _getFileSystemExt() + // Get relative path + ComPtr<ISlangBlob> combinedPathBlob; + SLANG_RETURN_ON_FAIL(fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef())); + String combinedPath(StringUtil::getString(combinedPathBlob)); + if (combinedPath.getLength() <= 0) { - return linkage->getFileSystemExt(); + return SLANG_FAIL; } - - SlangResult _findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& pathInfoOut) + + SlangPathType pathType; + SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(combinedPath.begin(), &pathType)); + if (pathType != SLANG_PATH_TYPE_FILE) { - ISlangFileSystemExt* fileSystemExt = _getFileSystemExt(); + return SLANG_E_NOT_FOUND; + } - // Get relative path - ComPtr<ISlangBlob> combinedPathBlob; - SLANG_RETURN_ON_FAIL(fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef())); - String combinedPath(StringUtil::getString(combinedPathBlob)); - if (combinedPath.getLength() <= 0) - { - return SLANG_FAIL; - } - - SlangPathType pathType; - SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(combinedPath.begin(), &pathType)); - if (pathType != SLANG_PATH_TYPE_FILE) - { - return SLANG_E_NOT_FOUND; - } + // Get the uniqueIdentity + ComPtr<ISlangBlob> uniqueIdentityBlob; + SLANG_RETURN_ON_FAIL(fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef())); + + // If the rel path exists -> a uniqueIdentity MUST exists too + String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob)); + if (uniqueIdentity.getLength() <= 0) + { + // Unique identity can't be empty + return SLANG_FAIL; + } + + pathInfoOut.type = PathInfo::Type::Normal; + pathInfoOut.foundPath = combinedPath; + pathInfoOut.uniqueIdentity = uniqueIdentity; + return SLANG_OK; +} - // Get the uniqueIdentity - ComPtr<ISlangBlob> uniqueIdentityBlob; - SLANG_RETURN_ON_FAIL(fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef())); +SlangResult IncludeHandlerImpl::findFile( + String const& pathToInclude, + String const& pathIncludedFrom, + PathInfo& pathInfoOut) +{ + pathInfoOut.type = PathInfo::Type::Unknown; - // If the rel path exists -> a uniqueIdentity MUST exists too - String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob)); - if (uniqueIdentity.getLength() <= 0) - { - // Unique identity can't be empty - return SLANG_FAIL; + // Try just relative to current path + { + SlangResult res = _findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, pathInfoOut); + // It either succeeded or wasn't found, anything else is a failure passed back + if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND) + { + return res; } - - pathInfoOut.type = PathInfo::Type::Normal; - pathInfoOut.foundPath = combinedPath; - pathInfoOut.uniqueIdentity = uniqueIdentity; - return SLANG_OK; } - virtual SlangResult findFile( - String const& pathToInclude, - String const& pathIncludedFrom, - PathInfo& pathInfoOut) override + // Search all the searchDirectories + for(auto sd = searchDirectories; sd; sd = sd->parent) { - pathInfoOut.type = PathInfo::Type::Unknown; - - // Try just relative to current path + for(auto& dir : sd->searchDirectories) { - SlangResult res = _findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, pathInfoOut); - // It either succeeded or wasn't found, anything else is a failure passed back + SlangResult res = _findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, pathInfoOut); if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND) { return res; } } - - // Search all the searchDirectories - for(auto sd = searchDirectories; sd; sd = sd->parent) - { - for(auto& dir : sd->searchDirectories) - { - SlangResult res = _findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, pathInfoOut); - if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND) - { - return res; - } - } - } - - return SLANG_E_NOT_FOUND; } -#if 0 - virtual SlangResult readFile(const String& path, - ISlangBlob** blobOut) override - { - ISlangFileSystem* fileSystemExt = _getFileSystemExt(); - SLANG_RETURN_ON_FAIL(fileSystemExt->loadFile(path.begin(), blobOut)); - - request->mDependencyFilePaths.Add(path); - - return SLANG_OK; - } -#endif + return SLANG_E_NOT_FOUND; +} - virtual String simplifyPath(const String& path) override +String IncludeHandlerImpl::simplifyPath(const String& path) +{ + ISlangFileSystemExt* fileSystemExt = _getFileSystemExt(); + ComPtr<ISlangBlob> simplifiedPath; + if (SLANG_FAILED(fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef()))) { - ISlangFileSystemExt* fileSystemExt = _getFileSystemExt(); - ComPtr<ISlangBlob> simplifiedPath; - if (SLANG_FAILED(fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef()))) - { - return path; - } - return StringUtil::getString(simplifiedPath); + return path; } - -}; + return StringUtil::getString(simplifiedPath); +} // @@ -2039,11 +2019,6 @@ struct EnumerateModulesVisitor : ComponentTypeVisitor { visitChildren(specialized); } - - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - visitChildren(legacy, specializationInfo); - } }; @@ -2082,11 +2057,6 @@ struct EnumerateIRModulesVisitor : ComponentTypeVisitor m_callback(specialized->getIRModule(), m_userData); } - - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { - visitChildren(legacy, specializationInfo); - } }; void ComponentType::enumerateIRModules(EnumerateIRModulesCallback callback, void* userData) @@ -2211,7 +2181,7 @@ Index CompositeComponentType::getShaderParamCount() return m_shaderParams.getCount(); } -GlobalShaderParamInfo CompositeComponentType::getShaderParam(Index index) +ShaderParamInfo CompositeComponentType::getShaderParam(Index index) { return m_shaderParams[index]; } @@ -2357,8 +2327,6 @@ SpecializedComponentType::SpecializedComponentType( { visitChildren(composite, specializationInfo); } void visitSpecialized(SpecializedComponentType* specialized) SLANG_OVERRIDE { visitChildren(specialized); } - void visitLegacy(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) SLANG_OVERRIDE - { visitChildren(legacy, specializationInfo); } }; // With the visitor defined, we apply it to ourself to compute @@ -2395,96 +2363,6 @@ String SpecializedComponentType::getEntryPointMangledName(Index index) return m_entryPointMangledNames[index]; } -// -// LegacyProgram -// - -LegacyProgram::LegacyProgram( - Linkage* linkage, - List<RefPtr<TranslationUnitRequest>> const& translationUnits, - DiagnosticSink* sink) - : ComponentType(linkage) - , m_translationUnits(translationUnits) -{ - HashSet<ComponentType*> requirementsSet; - - for(auto translationUnit : translationUnits ) - { - ComponentType* child = translationUnit->getModule(); - - auto childEntryPointCount = child->getEntryPointCount(); - for(Index cc = 0; cc < childEntryPointCount; ++cc) - { - m_entryPoints.add(child->getEntryPoint(cc)); - } - - for(auto module : child->getModuleDependencies()) - { - m_moduleDependencies.addDependency(module); - } - for(auto filePath : child->getFilePathDependencies()) - { - m_fileDependencies.addDependency(filePath); - } - - auto childRequirementCount = child->getRequirementCount(); - for(Index rr = 0; rr < childRequirementCount; ++rr) - { - auto childRequirement = child->getRequirement(rr); - if(!requirementsSet.Contains(childRequirement)) - { - requirementsSet.Add(childRequirement); - m_requirements.add(childRequirement); - } - } - } - - _collectShaderParams(sink); -} - -void LegacyProgram::acceptVisitor(ComponentTypeVisitor* visitor, SpecializationInfo* specializationInfo) -{ - visitor->visitLegacy(this, as<CompositeComponentType::CompositeSpecializationInfo>(specializationInfo)); -} - -RefPtr<ComponentType::SpecializationInfo> LegacyProgram::_validateSpecializationArgsImpl( - SpecializationArg const* args, - Index argCount, - DiagnosticSink* sink) -{ - SLANG_UNUSED(argCount); - - RefPtr<CompositeComponentType::CompositeSpecializationInfo> info = new CompositeComponentType::CompositeSpecializationInfo(); - - Index offset = 0; - for(auto translationUnit : m_translationUnits) - { - ComponentType* child = translationUnit->getModule(); - auto childParamCount = child->getSpecializationParamCount(); - SLANG_ASSERT(offset + childParamCount <= argCount); - - auto childInfo = child->_validateSpecializationArgs( - args + offset, - childParamCount, - sink); - - info->childInfos.add(childInfo); - - offset += childParamCount; - } - return info; -} - -Index LegacyProgram::getRequirementCount() -{ - return m_requirements.getCount(); -} - -RefPtr<ComponentType> LegacyProgram::getRequirement(Index index) -{ - return m_requirements[index]; -} - void ComponentTypeVisitor::visitChildren(CompositeComponentType* composite, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) { auto childCount = composite->getChildComponentCount(); @@ -2504,21 +2382,6 @@ void ComponentTypeVisitor::visitChildren(SpecializedComponentType* specialized) specialized->getBaseComponentType()->acceptVisitor(this, specialized->getSpecializationInfo()); } -void ComponentTypeVisitor::visitChildren(LegacyProgram* legacy, CompositeComponentType::CompositeSpecializationInfo* specializationInfo) -{ - auto childCount = legacy->getTranslationUnitCount(); - for(Index ii = 0; ii < childCount; ++ii) - { - auto translationUnit = legacy->getTranslationUnit(ii); - ComponentType* child = translationUnit->getModule(); - auto childSpecializationInfo = specializationInfo - ? specializationInfo->childInfos[ii] - : nullptr; - - child->acceptVisitor(this, childSpecializationInfo); - } -} - TargetProgram* ComponentType::getTargetProgram(TargetRequest* target) { RefPtr<TargetProgram> targetProgram; |
