diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-06 09:52:53 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-06 09:52:53 -0700 |
| commit | 21a14cb4e0d578bc4f8a460016269a1199cac0da (patch) | |
| tree | 88a04619ceaaa37b87199dd82334cc9d102c156d /source/slang/parameter-binding.cpp | |
| parent | f313df379dd9e0d4395f072ffb87016a6f20d5a1 (diff) | |
| parent | f145e09a6dcbcf326f782b3e6a76dbf291c792cf (diff) | |
Merge pull request #53 from tfoleyNV/cross-compilation
Initial work on cross-compilation
Diffstat (limited to 'source/slang/parameter-binding.cpp')
| -rw-r--r-- | source/slang/parameter-binding.cpp | 220 |
1 files changed, 145 insertions, 75 deletions
diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index 2a0c64892..8d008618f 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -767,86 +767,87 @@ SimpleSemanticInfo decomposeSimpleSemantic( return info; } -enum class EntryPointParameterDirection +enum EntryPointParameterDirection { - Input, - Output, + kEntryPointParameterDirection_Input = 0x1, + kEntryPointParameterDirection_Output = 0x2, }; +typedef unsigned int EntryPointParameterDirectionMask; struct EntryPointParameterState { - String* optSemanticName; - int* ioSemanticIndex; - EntryPointParameterDirection direction; - int semanticSlotCount; + String* optSemanticName; + int* ioSemanticIndex; + EntryPointParameterDirectionMask directionMask; + int semanticSlotCount; }; -static void processSimpleEntryPointInput( +static RefPtr<TypeLayout> processSimpleEntryPointParameter( ParameterBindingContext* context, RefPtr<ExpressionType> type, - EntryPointParameterState const& state) + EntryPointParameterState const& inState, + int semanticSlotCount = 1) { - auto optSemanticName = state.optSemanticName; - auto semanticIndex = *state.ioSemanticIndex; - auto semanticSlotCount = state.semanticSlotCount; -} + EntryPointParameterState state = inState; + state.semanticSlotCount = semanticSlotCount; -static void processSimpleEntryPointOutput( - ParameterBindingContext* context, - RefPtr<ExpressionType> type, - EntryPointParameterState const& state) -{ auto optSemanticName = state.optSemanticName; auto semanticIndex = *state.ioSemanticIndex; - auto semanticSlotCount = state.semanticSlotCount; - - if(!optSemanticName) - return; - auto semanticName = *optSemanticName; + String semanticName = optSemanticName ? *optSemanticName : ""; + String sn = semanticName.ToLower(); - // Note: I'm just doing something expedient here and detecting `SV_Target` - // outputs and claiming the appropriate register range right away. - // - // TODO: we should really be building up some representation of all of this, - // once we've gone to the trouble of looking it all up... - if( semanticName.ToLower() == "sv_target" ) + RefPtr<TypeLayout> typeLayout = new TypeLayout(); + if (sn.StartsWith("sv_")) { - context->shared->usedResourceRanges[int(LayoutResourceKind::UnorderedAccess)].Add(semanticIndex, semanticIndex + semanticSlotCount); - } -} + // System-value semantic. -static void processSimpleEntryPointParameter( - ParameterBindingContext* context, - RefPtr<ExpressionType> type, - EntryPointParameterState const& inState, - int semanticSlotCount = 1) -{ - EntryPointParameterState state = inState; - state.semanticSlotCount = semanticSlotCount; + if (state.directionMask & kEntryPointParameterDirection_Output) + { + // Note: I'm just doing something expedient here and detecting `SV_Target` + // outputs and claiming the appropriate register range right away. + // + // TODO: we should really be building up some representation of all of this, + // once we've gone to the trouble of looking it all up... + if( sn == "sv_target" ) + { + context->shared->usedResourceRanges[int(LayoutResourceKind::UnorderedAccess)].Add(semanticIndex, semanticIndex + semanticSlotCount); + } + } - switch( state.direction ) + // TODO: add some kind of usage information for system input/output + } + else { - case EntryPointParameterDirection::Input: - processSimpleEntryPointInput(context, type, state); - break; + // user-defined semantic - case EntryPointParameterDirection::Output: - processSimpleEntryPointOutput(context, type, state); - break; + if (state.directionMask & kEntryPointParameterDirection_Input) + { + auto rules = context->layoutRules->getVaryingInputRules(); + SimpleLayoutInfo layout = GetLayout(type, rules); + typeLayout->addResourceUsage(layout.kind, layout.size); + } - SLANG_EXHAUSTIVE_SWITCH() + if (state.directionMask & kEntryPointParameterDirection_Output) + { + auto rules = context->layoutRules->getVaryingOutputRules(); + SimpleLayoutInfo layout = GetLayout(type, rules); + typeLayout->addResourceUsage(layout.kind, layout.size); + } } *state.ioSemanticIndex += state.semanticSlotCount; + typeLayout->type = type; + + return typeLayout; } -static void processEntryPointParameter( +static RefPtr<TypeLayout> processEntryPointParameter( ParameterBindingContext* context, RefPtr<ExpressionType> type, EntryPointParameterState const& state); -static void processEntryPointParameterWithPossibleSemantic( +static RefPtr<TypeLayout> processEntryPointParameterWithPossibleSemantic( ParameterBindingContext* context, Decl* declForSemantic, RefPtr<ExpressionType> type, @@ -873,11 +874,11 @@ static void processEntryPointParameterWithPossibleSemantic( // *or* we couldn't find an explicit semantic to apply on the given // declaration, so we will just recursive with whatever we have at // the moment. - processEntryPointParameter(context, type, state); + return processEntryPointParameter(context, type, state); } -static void processEntryPointParameter( +static RefPtr<TypeLayout> processEntryPointParameter( ParameterBindingContext* context, RefPtr<ExpressionType> type, EntryPointParameterState const& state) @@ -885,31 +886,50 @@ static void processEntryPointParameter( // Scalar and vector types are treated as outputs directly if(auto basicType = type->As<BasicExpressionType>()) { - processSimpleEntryPointParameter(context, basicType, state); + return processSimpleEntryPointParameter(context, basicType, state); } else if(auto basicType = type->As<VectorExpressionType>()) { - processSimpleEntryPointParameter(context, basicType, state); + return processSimpleEntryPointParameter(context, basicType, state); } // A matrix is processed as if it was an array of rows else if( auto matrixType = type->As<MatrixExpressionType>() ) { auto rowCount = GetIntVal(matrixType->getRowCount()); - processSimpleEntryPointParameter(context, basicType, state, (int) rowCount); + return processSimpleEntryPointParameter(context, basicType, state, (int) rowCount); } else if( auto arrayType = type->As<ArrayExpressionType>() ) { + // Note: Bad Things will happen if we have an array input + // without a semantic already being enforced. + auto elementCount = GetIntVal(arrayType->ArrayLength); - for( int ii = 0; ii < elementCount; ++ii ) + // We use the first element to derive the layout for the element type + auto elementTypeLayout = processEntryPointParameter(context, arrayType->BaseType, state); + + // We still walk over subsequent elements to make sure they consume resources + // as needed + for( int ii = 1; ii < elementCount; ++ii ) { processEntryPointParameter(context, arrayType->BaseType, state); } + + RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); + arrayTypeLayout->elementTypeLayout = elementTypeLayout; + arrayTypeLayout->type = arrayType; + + for (auto rr : elementTypeLayout->resourceInfos) + { + arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count * elementCount; + } + + return arrayTypeLayout; } // Ignore a bunch of types that don't make sense here... - else if(auto textureType = type->As<TextureType>()) {} - else if(auto samplerStateType = type->As<SamplerStateType>()) {} - else if(auto constantBufferType = type->As<ConstantBufferType>()) {} + else if (auto textureType = type->As<TextureType>()) { return nullptr; } + else if(auto samplerStateType = type->As<SamplerStateType>()) { return nullptr; } + else if(auto constantBufferType = type->As<ConstantBufferType>()) { return nullptr; } // Catch declaration-reference types late in the sequence, since // otherwise they will include all of the above cases... else if( auto declRefType = type->As<DeclRefType>() ) @@ -918,15 +938,36 @@ static void processEntryPointParameter( if (auto structDeclRef = declRef.As<StructSyntaxNode>()) { + RefPtr<StructTypeLayout> structLayout = new StructTypeLayout(); + structLayout->type = type; + // Need to recursively walk the fields of the structure now... for( auto field : GetFields(structDeclRef) ) { - processEntryPointParameterWithPossibleSemantic( + auto fieldTypeLayout = processEntryPointParameterWithPossibleSemantic( context, field.getDecl(), GetType(field), state); + + RefPtr<VarLayout> fieldVarLayout = new VarLayout(); + fieldVarLayout->varDecl = field; + fieldVarLayout->typeLayout = fieldTypeLayout; + + for (auto rr : fieldTypeLayout->resourceInfos) + { + assert(rr.count != 0); + + auto structRes = structLayout->findOrAddResourceInfo(rr.kind); + fieldVarLayout->findOrAddResourceInfo(rr.kind)->index = structRes->count; + structRes->count += rr.count; + } + + structLayout->fields.Add(fieldVarLayout); + structLayout->mapVarToLayout.Add(field.getDecl(), fieldVarLayout); } + + return structLayout; } else { @@ -937,6 +978,9 @@ static void processEntryPointParameter( { assert(!"unimplemented"); } + + assert(!"unexpected"); + return nullptr; } static void collectEntryPointParameters( @@ -998,42 +1042,68 @@ static void collectEntryPointParameters( // We have an entry-point parameter, and need to figure out what to do with it. + // TODO: need to handle `uniform`-qualified parameters here + if (paramDecl->HasModifier<UniformModifier>()) + continue; + + state.directionMask = 0; + // If it appears to be an input, process it as such. if( paramDecl->HasModifier<InModifier>() || paramDecl->HasModifier<InOutModifier>() || !paramDecl->HasModifier<OutModifier>() ) { - state.direction = EntryPointParameterDirection::Input; - - processEntryPointParameterWithPossibleSemantic( - context, - paramDecl.Ptr(), - paramDecl->Type.type, - state); + state.directionMask |= kEntryPointParameterDirection_Input; } // If it appears to be an output, process it as such. if(paramDecl->HasModifier<OutModifier>() || paramDecl->HasModifier<InOutModifier>()) { - state.direction = EntryPointParameterDirection::Output; + state.directionMask |= kEntryPointParameterDirection_Output; + } + + auto paramTypeLayout = processEntryPointParameterWithPossibleSemantic( + context, + paramDecl.Ptr(), + paramDecl->Type.type, + state); - processEntryPointParameterWithPossibleSemantic( - context, - paramDecl.Ptr(), - paramDecl->Type.type, - state); + RefPtr<VarLayout> paramVarLayout = new VarLayout(); + paramVarLayout->varDecl = makeDeclRef(paramDecl.Ptr()); + paramVarLayout->typeLayout = paramTypeLayout; + + for (auto rr : paramTypeLayout->resourceInfos) + { + auto entryPointRes = entryPointLayout->findOrAddResourceInfo(rr.kind); + paramVarLayout->findOrAddResourceInfo(rr.kind)->index = entryPointRes->count; + entryPointRes->count += rr.count; } + + entryPointLayout->fields.Add(paramVarLayout); + entryPointLayout->mapVarToLayout.Add(paramDecl, paramVarLayout); } // If we can find an output type for the entry point, then process it as // an output parameter. if( auto resultType = entryPointFuncDecl->ReturnType.type ) { - state.direction = EntryPointParameterDirection::Output; + state.directionMask = kEntryPointParameterDirection_Output; - processEntryPointParameterWithPossibleSemantic( + auto resultTypeLayout = processEntryPointParameterWithPossibleSemantic( context, entryPointFuncDecl, resultType, state); + + RefPtr<VarLayout> resultLayout = new VarLayout(); + resultLayout->typeLayout = resultTypeLayout; + + for (auto rr : resultTypeLayout->resourceInfos) + { + auto entryPointRes = entryPointLayout->findOrAddResourceInfo(rr.kind); + resultLayout->findOrAddResourceInfo(rr.kind)->index = entryPointRes->count; + entryPointRes->count += rr.count; + } + + entryPointLayout->resultLayout = resultLayout; } } |
