summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-shader.cpp513
-rw-r--r--source/slang/slang-compiler.cpp106
-rw-r--r--source/slang/slang-compiler.h116
-rw-r--r--source/slang/slang-lower-to-ir.cpp11
-rw-r--r--source/slang/slang-parameter-binding.cpp202
-rw-r--r--source/slang/slang.cpp265
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;