diff options
Diffstat (limited to 'source/slang/slang-parameter-binding.cpp')
| -rw-r--r-- | source/slang/slang-parameter-binding.cpp | 675 |
1 files changed, 352 insertions, 323 deletions
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 605e50d41..3c4c23a42 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -2205,386 +2205,413 @@ static RefPtr<TypeLayout> processEntryPointVaryingParameter( varLayout->flags |= VarLayoutFlag::HasSemantic; } - // Scalar and vector types are treated as outputs directly - if (auto basicType = as<BasicExpressionType>(type)) + // We use a lambda here to process the parameter based on `type`. + // We need to be able to recurse on the lambda if need to translate/resolve + // `type` to something else, in that case we simply call the lambda recursively. + auto processParamOfType = [&](auto&& processParamOfTypeFunc, Type* type) -> RefPtr<TypeLayout> { - return processSimpleEntryPointParameter(context, basicType, state, varLayout); - } - else if (auto vectorType = as<VectorExpressionType>(type)) - { - return processSimpleEntryPointParameter(context, vectorType, state, varLayout); - } - // A matrix is processed as if it was an array of rows - else if (auto matrixType = as<MatrixExpressionType>(type)) - { - auto foldedRowCountVal = - context->getTargetProgram()->getProgram()->tryFoldIntVal(matrixType->getRowCount()); - IntegerLiteralValue rowCount = 0; - if (!foldedRowCountVal) + // Scalar and vector types are treated as outputs directly + if (auto basicType = as<BasicExpressionType>(type)) { - rowCount = getIntVal(foldedRowCountVal); + return processSimpleEntryPointParameter(context, basicType, state, varLayout); } - return processSimpleEntryPointParameter( - context, - matrixType, - state, - varLayout, - (int)rowCount); - } - else if (auto arrayType = as<ArrayExpressionType>(type)) - { - // Note: Bad Things will happen if we have an array input - // without a semantic already being enforced. - UInt elementCount = 0; - - if (!arrayType->isUnsized()) + else if (auto vectorType = as<VectorExpressionType>(type)) { - auto intVal = context->getTargetProgram()->getProgram()->tryFoldIntVal( - arrayType->getElementCount()); - if (intVal) - elementCount = (UInt)getIntVal(intVal); + return processSimpleEntryPointParameter(context, vectorType, state, varLayout); } - - // We use the first element to derive the layout for the element type - auto elementTypeLayout = processEntryPointVaryingParameter( - context, - arrayType->getElementType(), - state, - varLayout); - - // We still walk over subsequent elements to make sure they consume resources - // as needed - for (UInt ii = 1; ii < elementCount; ++ii) + // A matrix is processed as if it was an array of rows + else if (auto matrixType = as<MatrixExpressionType>(type)) { - processEntryPointVaryingParameter(context, arrayType->getElementType(), state, nullptr); + auto foldedRowCountVal = + context->getTargetProgram()->getProgram()->tryFoldIntVal(matrixType->getRowCount()); + IntegerLiteralValue rowCount = 0; + if (!foldedRowCountVal) + { + rowCount = getIntVal(foldedRowCountVal); + } + return processSimpleEntryPointParameter( + context, + matrixType, + state, + varLayout, + (int)rowCount); } - - RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); - arrayTypeLayout->elementTypeLayout = elementTypeLayout; - arrayTypeLayout->type = arrayType; - - for (auto rr : elementTypeLayout->resourceInfos) + else if (auto arrayType = as<ArrayExpressionType>(type)) { - arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count * elementCount; - } - - return arrayTypeLayout; - } - else if (auto meshOutputType = as<MeshOutputType>(type)) - { - // TODO: Ellie, revisit - // Note: Bad Things will happen if we have an array input - // without a semantic already being enforced. + // Note: Bad Things will happen if we have an array input + // without a semantic already being enforced. + UInt elementCount = 0; - // We use the first element to derive the layout for the element type - auto elementTypeLayout = processEntryPointVaryingParameter( - context, - meshOutputType->getElementType(), - state, - varLayout); + if (!arrayType->isUnsized()) + { + auto intVal = context->getTargetProgram()->getProgram()->tryFoldIntVal( + arrayType->getElementCount()); + if (intVal) + elementCount = (UInt)getIntVal(intVal); + } - RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); - arrayTypeLayout->elementTypeLayout = elementTypeLayout; - arrayTypeLayout->type = arrayType; + // We use the first element to derive the layout for the element type + auto elementTypeLayout = processEntryPointVaryingParameter( + context, + arrayType->getElementType(), + state, + varLayout); - // TODO: Ellie, this is probably not the right place to handle this - // On GLSL the indices type is built in and as such doesn't consume - // resources. - if (!isKhronosTarget(context->getTargetRequest()) || !as<IndicesType>(type)) - { - for (auto rr : elementTypeLayout->resourceInfos) + // We still walk over subsequent elements to make sure they consume resources + // as needed + for (UInt ii = 1; ii < elementCount; ++ii) { - // TODO: Ellie, explain why only one slot is consumed here - arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count; + processEntryPointVaryingParameter( + context, + arrayType->getElementType(), + state, + nullptr); } - } - return arrayTypeLayout; - } - else if (auto patchType = as<HLSLPatchType>(type)) - { - // Similar to the MeshOutput case, a `InputPatch` or `OutputPatch` type is just like an - // array. - // - auto elementTypeLayout = processEntryPointVaryingParameter( - context, - patchType->getElementType(), - state, - varLayout); + RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); + arrayTypeLayout->elementTypeLayout = elementTypeLayout; + arrayTypeLayout->type = arrayType; - RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); - arrayTypeLayout->elementTypeLayout = elementTypeLayout; - arrayTypeLayout->type = arrayType; + for (auto rr : elementTypeLayout->resourceInfos) + { + arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count * elementCount; + } - for (auto rr : elementTypeLayout->resourceInfos) - { - arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count; + return arrayTypeLayout; } - - return arrayTypeLayout; - } - // Ignore a bunch of types that don't make sense here... - else if (const auto subpassType = as<SubpassInputType>(type)) - { - return nullptr; - } - else if (const auto textureType = as<TextureType>(type)) - { - return nullptr; - } - else if (const auto samplerStateType = as<SamplerStateType>(type)) - { - return nullptr; - } - else if (const auto constantBufferType = as<ConstantBufferType>(type)) - { - return nullptr; - } - else if (auto ptrType = as<PtrType>(type)) - { - SLANG_ASSERT(ptrType->astNodeType == ASTNodeType::PtrType); - - auto typeLayout = processSimpleEntryPointParameter(context, ptrType, state, varLayout); - RefPtr<PointerTypeLayout> ptrTypeLayout = typeLayout.as<PointerTypeLayout>(); - - // Work out the layout for the value/target type - auto valueTypeLayout = - processEntryPointVaryingParameter(context, ptrType->getValueType(), state, varLayout); - ptrTypeLayout->valueTypeLayout = valueTypeLayout; - return ptrTypeLayout; - } - else if (auto optionalType = as<OptionalType>(type)) - { - Array<Type*, 2> types = - makeArray(optionalType->getValueType(), context->getASTBuilder()->getBoolType()); - auto tupleType = context->getASTBuilder()->getTupleType(types.getView()); - return processEntryPointVaryingParameter(context, tupleType, state, varLayout); - } - else if (auto tupleType = as<TupleType>(type)) - { - RefPtr<StructTypeLayout> structLayout = new StructTypeLayout(); - structLayout->type = type; - for (Index i = 0; i < tupleType->getMemberCount(); i++) + else if (auto meshOutputType = as<MeshOutputType>(type)) { - auto fieldType = tupleType->getMember(i); - RefPtr<VarLayout> fieldVarLayout = new VarLayout(); - - // We don't really have a "field" decl, so just use the tuple-typed decl - // itself as the varDecl of the elements. - auto fieldDecl = (VarDeclBase*)varLayout->varDecl.getDecl(); - fieldVarLayout->varDecl = fieldDecl; + // TODO: Ellie, revisit + // Note: Bad Things will happen if we have an array input + // without a semantic already being enforced. - structLayout->fields.add(fieldVarLayout); - - auto fieldTypeLayout = processEntryPointVaryingParameterDecl( + // We use the first element to derive the layout for the element type + auto elementTypeLayout = processEntryPointVaryingParameter( context, - fieldDecl, - fieldType, + meshOutputType->getElementType(), state, - fieldVarLayout); + varLayout); + + RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); + arrayTypeLayout->elementTypeLayout = elementTypeLayout; + arrayTypeLayout->type = arrayType; - if (!fieldTypeLayout) + // TODO: Ellie, this is probably not the right place to handle this + // On GLSL the indices type is built in and as such doesn't consume + // resources. + if (!isKhronosTarget(context->getTargetRequest()) || !as<IndicesType>(type)) { - getSink(context)->diagnose( - varLayout->varDecl, - Diagnostics::notValidVaryingParameter, - fieldType); - continue; + for (auto rr : elementTypeLayout->resourceInfos) + { + // TODO: Ellie, explain why only one slot is consumed here + arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count; + } } - fieldVarLayout->typeLayout = fieldTypeLayout; - // Assign offsets in var layout for each resource kind of the type. - for (auto fieldTypeResInfo : fieldTypeLayout->resourceInfos) + return arrayTypeLayout; + } + else if (auto patchType = as<HLSLPatchType>(type)) + { + // Similar to the MeshOutput case, a `InputPatch` or `OutputPatch` type is just like an + // array. + // + auto elementTypeLayout = processEntryPointVaryingParameter( + context, + patchType->getElementType(), + state, + varLayout); + + RefPtr<ArrayTypeLayout> arrayTypeLayout = new ArrayTypeLayout(); + arrayTypeLayout->elementTypeLayout = elementTypeLayout; + arrayTypeLayout->type = arrayType; + + for (auto rr : elementTypeLayout->resourceInfos) { - auto kind = fieldTypeResInfo.kind; - auto structTypeResInfo = structLayout->findOrAddResourceInfo(kind); - auto fieldResInfo = fieldVarLayout->findOrAddResourceInfo(kind); - fieldResInfo->index = structTypeResInfo->count.getFiniteValue(); - structTypeResInfo->count += fieldTypeResInfo.count; + arrayTypeLayout->findOrAddResourceInfo(rr.kind)->count = rr.count; } - } - return structLayout; - } - // Catch declaration-reference types late in the sequence, since - // otherwise they will include all of the above cases... - else if (auto declRefType = as<DeclRefType>(type)) - { - // If we are trying to get the layout of some extern type, do our best - // to look it up in other loaded modules and generate the type layout - // based on that. - declRefType = context->layoutContext.lookupExternDeclRefType(declRefType); - auto declRef = declRefType->getDeclRef(); + return arrayTypeLayout; + } + // Ignore a bunch of types that don't make sense here... + else if (const auto subpassType = as<SubpassInputType>(type)) + { + return nullptr; + } + else if (const auto textureType = as<TextureType>(type)) + { + return nullptr; + } + else if (const auto samplerStateType = as<SamplerStateType>(type)) + { + return nullptr; + } + else if (const auto constantBufferType = as<ConstantBufferType>(type)) + { + return nullptr; + } + else if (auto ptrType = as<PtrType>(type)) + { + SLANG_ASSERT(ptrType->astNodeType == ASTNodeType::PtrType); + auto typeLayout = processSimpleEntryPointParameter(context, ptrType, state, varLayout); + RefPtr<PointerTypeLayout> ptrTypeLayout = typeLayout.as<PointerTypeLayout>(); - if (auto structDeclRef = declRef.as<StructDecl>()) + // Work out the layout for the value/target type + auto valueTypeLayout = processEntryPointVaryingParameter( + context, + ptrType->getValueType(), + state, + varLayout); + ptrTypeLayout->valueTypeLayout = valueTypeLayout; + return ptrTypeLayout; + } + else if (auto optionalType = as<OptionalType>(type)) + { + Array<Type*, 2> types = + makeArray(optionalType->getValueType(), context->getASTBuilder()->getBoolType()); + auto tupleType = context->getASTBuilder()->getTupleType(types.getView()); + return processEntryPointVaryingParameter(context, tupleType, state, varLayout); + } + else if (auto tupleType = as<TupleType>(type)) { RefPtr<StructTypeLayout> structLayout = new StructTypeLayout(); - structLayout->type = declRefType; - - // We will recursively walk the fields of a `struct` type - // to compute layouts for those fields. - // - // Along the way, we may find fields with explicit layout - // annotations, along with fields that have no explicit - // layout. We will consider it an error to have a mix of - // the two. - // - // TODO: We could support a mix of implicit and explicit - // layout by performing layout on fields in two passes, - // much like is done for the global scope. This would - // complicate layout significantly for little practical - // benefit, so it is very much a "nice to have" rather - // than a "must have" feature. - // - Decl* firstExplicit = nullptr; - Decl* firstImplicit = nullptr; - for (auto field : - getFields(context->getASTBuilder(), structDeclRef, MemberFilterStyle::Instance)) + structLayout->type = type; + for (Index i = 0; i < tupleType->getMemberCount(); i++) { + auto fieldType = tupleType->getMember(i); RefPtr<VarLayout> fieldVarLayout = new VarLayout(); - fieldVarLayout->varDecl = field; + + // We don't really have a "field" decl, so just use the tuple-typed decl + // itself as the varDecl of the elements. + auto fieldDecl = (VarDeclBase*)varLayout->varDecl.getDecl(); + fieldVarLayout->varDecl = fieldDecl; structLayout->fields.add(fieldVarLayout); - structLayout->mapVarToLayout.add(field.getDecl(), fieldVarLayout); auto fieldTypeLayout = processEntryPointVaryingParameterDecl( context, - field.getDecl(), - getType(context->getASTBuilder(), field), + fieldDecl, + fieldType, state, fieldVarLayout); if (!fieldTypeLayout) { - getSink(context)->diagnose(field, Diagnostics::notValidVaryingParameter, field); + getSink(context)->diagnose( + varLayout->varDecl, + Diagnostics::notValidVaryingParameter, + fieldType); continue; } fieldVarLayout->typeLayout = fieldTypeLayout; - // The field needs to have offset information stored - // in `fieldVarLayout` for every kind of resource - // consumed by `fieldTypeLayout`. - // + // Assign offsets in var layout for each resource kind of the type. for (auto fieldTypeResInfo : fieldTypeLayout->resourceInfos) { - // If the field is a Conditional<T, false> type, then it could have 0 size. - // We should skip this field if it has no use of layout units. - if (fieldTypeResInfo.count == 0) - continue; - auto kind = fieldTypeResInfo.kind; - auto structTypeResInfo = structLayout->findOrAddResourceInfo(kind); + auto fieldResInfo = fieldVarLayout->findOrAddResourceInfo(kind); + fieldResInfo->index = structTypeResInfo->count.getFiniteValue(); + structTypeResInfo->count += fieldTypeResInfo.count; + } + } + return structLayout; + } + // Catch declaration-reference types late in the sequence, since + // otherwise they will include all of the above cases... + else if (auto declRefType = as<DeclRefType>(type)) + { + // If we are trying to get the layout of some extern type, do our best + // to look it up in other loaded modules and generate the type layout + // based on that. + auto lookedUpType = context->layoutContext.lookupExternDeclRefType(declRefType); + + // If the link-time type resolved to something concrete, process the param as if it is + // of the concrete type by recursively calling this lambda. + if (type != lookedUpType) + return processParamOfTypeFunc(_Move(processParamOfTypeFunc), lookedUpType); + + auto declRef = declRefType->getDeclRef(); + + if (auto structDeclRef = declRef.as<StructDecl>()) + { + RefPtr<StructTypeLayout> structLayout = new StructTypeLayout(); + structLayout->type = declRefType; + + // We will recursively walk the fields of a `struct` type + // to compute layouts for those fields. + // + // Along the way, we may find fields with explicit layout + // annotations, along with fields that have no explicit + // layout. We will consider it an error to have a mix of + // the two. + // + // TODO: We could support a mix of implicit and explicit + // layout by performing layout on fields in two passes, + // much like is done for the global scope. This would + // complicate layout significantly for little practical + // benefit, so it is very much a "nice to have" rather + // than a "must have" feature. + // + Decl* firstExplicit = nullptr; + Decl* firstImplicit = nullptr; + for (auto field : getFields( + context->getASTBuilder(), + structDeclRef, + MemberFilterStyle::Instance)) + { + RefPtr<VarLayout> fieldVarLayout = new VarLayout(); + fieldVarLayout->varDecl = field; + + structLayout->fields.add(fieldVarLayout); + structLayout->mapVarToLayout.add(field.getDecl(), fieldVarLayout); + + auto fieldTypeLayout = processEntryPointVaryingParameterDecl( + context, + field.getDecl(), + getType(context->getASTBuilder(), field), + state, + fieldVarLayout); - auto fieldResInfo = fieldVarLayout->FindResourceInfo(kind); - if (!fieldResInfo) + if (!fieldTypeLayout) { - if (!firstImplicit) - firstImplicit = field.getDecl(); - - // In the implicit-layout case, we assign the field - // the next available offset after the fields that - // have preceded it. - // - fieldResInfo = fieldVarLayout->findOrAddResourceInfo(kind); - fieldResInfo->index = structTypeResInfo->count.getFiniteValue(); - structTypeResInfo->count += fieldTypeResInfo.count; + getSink(context)->diagnose( + field, + Diagnostics::notValidVaryingParameter, + field); + continue; } - else + fieldVarLayout->typeLayout = fieldTypeLayout; + + // The field needs to have offset information stored + // in `fieldVarLayout` for every kind of resource + // consumed by `fieldTypeLayout`. + // + for (auto fieldTypeResInfo : fieldTypeLayout->resourceInfos) { - if (!firstExplicit) - firstExplicit = field.getDecl(); - - // In the explicit case, the field already has offset - // information, and we just need to update the computed - // size of the `struct` type to account for the field. - // - auto fieldEndOffset = fieldResInfo->index + fieldTypeResInfo.count; - structTypeResInfo->count = - maximum(structTypeResInfo->count, fieldEndOffset); + // If the field is a Conditional<T, false> type, then it could have 0 size. + // We should skip this field if it has no use of layout units. + if (fieldTypeResInfo.count == 0) + continue; + + auto kind = fieldTypeResInfo.kind; + + auto structTypeResInfo = structLayout->findOrAddResourceInfo(kind); + + auto fieldResInfo = fieldVarLayout->FindResourceInfo(kind); + if (!fieldResInfo) + { + if (!firstImplicit) + firstImplicit = field.getDecl(); + + // In the implicit-layout case, we assign the field + // the next available offset after the fields that + // have preceded it. + // + fieldResInfo = fieldVarLayout->findOrAddResourceInfo(kind); + fieldResInfo->index = structTypeResInfo->count.getFiniteValue(); + structTypeResInfo->count += fieldTypeResInfo.count; + } + else + { + if (!firstExplicit) + firstExplicit = field.getDecl(); + + // In the explicit case, the field already has offset + // information, and we just need to update the computed + // size of the `struct` type to account for the field. + // + auto fieldEndOffset = fieldResInfo->index + fieldTypeResInfo.count; + structTypeResInfo->count = + maximum(structTypeResInfo->count, fieldEndOffset); + } } } + if (firstImplicit && firstExplicit) + { + getSink(context)->diagnose( + firstImplicit, + Diagnostics::mixingImplicitAndExplicitBindingForVaryingParams, + firstImplicit->getName(), + firstExplicit->getName()); + } + + return structLayout; } - if (firstImplicit && firstExplicit) + else if (auto globalGenericParamDecl = declRef.as<GlobalGenericParamDecl>()) { - getSink(context)->diagnose( - firstImplicit, - Diagnostics::mixingImplicitAndExplicitBindingForVaryingParams, - firstImplicit->getName(), - firstExplicit->getName()); - } - - return structLayout; - } - else if (auto globalGenericParamDecl = declRef.as<GlobalGenericParamDecl>()) - { - auto& layoutContext = context->layoutContext; + auto& layoutContext = context->layoutContext; - if (auto concreteType = findGlobalGenericSpecializationArg( - layoutContext, - globalGenericParamDecl.getDecl())) + if (auto concreteType = findGlobalGenericSpecializationArg( + layoutContext, + globalGenericParamDecl.getDecl())) + { + // If we know what concrete type has been used to specialize + // the global generic type parameter, then we should use + // the concrete type instead. + // + // Note: it should be illegal for the user to use a generic + // type parameter in a varying parameter list without giving + // it an explicit user-defined semantic. Otherwise, it would be possible + // that the concrete type that gets plugged in is a user-defined + // `struct` that uses some `SV_` semantics in its definition, + // so that any static information about what system values + // the entry point uses would be incorrect. + // + return processEntryPointVaryingParameter( + context, + concreteType, + state, + varLayout); + } + else + { + // If we don't know a concrete type, then we aren't generating final + // code, so the reflection information should show the generic + // type parameter. + // + // We don't make any attempt to assign varying parameter resources + // to the generic type, since we can't know how many "slots" + // of varying input/output it would consume. + // + return createTypeLayoutForGlobalGenericTypeParam( + layoutContext, + type, + globalGenericParamDecl.getDecl()); + } + } + else if (auto enumDeclRef = declRef.as<EnumDecl>()) { - // If we know what concrete type has been used to specialize - // the global generic type parameter, then we should use - // the concrete type instead. + // We handle an enumeration type as its tag type for varying parameters. + // This allows enums to be used in vertex output/input similar to their + // underlying integer types. // - // Note: it should be illegal for the user to use a generic - // type parameter in a varying parameter list without giving - // it an explicit user-defined semantic. Otherwise, it would be possible - // that the concrete type that gets plugged in is a user-defined - // `struct` that uses some `SV_` semantics in its definition, - // so that any static information about what system values - // the entry point uses would be incorrect. - // - return processEntryPointVaryingParameter(context, concreteType, state, varLayout); + auto tagType = enumDeclRef.getDecl()->tagType; + SLANG_ASSERT(tagType); + return processEntryPointVaryingParameter(context, tagType, state, varLayout); + } + else if (auto associatedTypeParam = declRef.as<AssocTypeDecl>()) + { + RefPtr<TypeLayout> assocTypeLayout = new TypeLayout(); + assocTypeLayout->type = type; + return assocTypeLayout; } else { - // If we don't know a concrete type, then we aren't generating final - // code, so the reflection information should show the generic - // type parameter. - // - // We don't make any attempt to assign varying parameter resources - // to the generic type, since we can't know how many "slots" - // of varying input/output it would consume. - // - return createTypeLayoutForGlobalGenericTypeParam( - layoutContext, - type, - globalGenericParamDecl.getDecl()); + SLANG_UNEXPECTED("unhandled type kind"); } } - else if (auto enumDeclRef = declRef.as<EnumDecl>()) - { - // We handle an enumeration type as its tag type for varying parameters. - // This allows enums to be used in vertex output/input similar to their - // underlying integer types. - // - auto tagType = enumDeclRef.getDecl()->tagType; - SLANG_ASSERT(tagType); - return processEntryPointVaryingParameter(context, tagType, state, varLayout); - } - else if (auto associatedTypeParam = declRef.as<AssocTypeDecl>()) - { - RefPtr<TypeLayout> assocTypeLayout = new TypeLayout(); - assocTypeLayout->type = type; - return assocTypeLayout; - } - else + + // If we ran into an error in checking the user's code, then skip this parameter + else if (const auto errorType = as<ErrorType>(type)) { - SLANG_UNEXPECTED("unhandled type kind"); + return nullptr; } - } - // If we ran into an error in checking the user's code, then skip this parameter - else if (const auto errorType = as<ErrorType>(type)) - { - return nullptr; - } - - SLANG_UNEXPECTED("unhandled type kind"); - UNREACHABLE_RETURN(nullptr); + SLANG_UNEXPECTED("unhandled type kind"); + UNREACHABLE_RETURN(nullptr); + }; + return processParamOfType(_Move(processParamOfType), type); } /// Compute the type layout for a parameter declared directly on an entry point. @@ -2606,8 +2633,8 @@ static RefPtr<TypeLayout> computeEntryPointParameterTypeLayout( LayoutRulesImpl* layoutRules = nullptr; if (isKhronosTarget(context->getTargetRequest())) { - // For Vulkan, entry point uniform parameters are laid out using push constant buffer - // rules (defaults to std430). + // For Vulkan, entry point uniform parameters are laid out using push constant + // buffer rules (defaults to std430). layoutRules = context->getRulesFamily()->getShaderStorageBufferRules( context->getTargetProgram()->getOptionSet()); } @@ -3559,15 +3586,16 @@ static void collectParameters(ParameterBindingContext* inContext, ComponentType* /// Emit a diagnostic about a uniform/ordinary parameter at global scope. void diagnoseGlobalUniform(SharedParameterBindingContext* sharedContext, VarDeclBase* varDecl) { - // Don't emit the implicit global shader parameter warning if the variable is explicitly marked - // as uniform + // Don't emit the implicit global shader parameter warning if the variable is explicitly + // marked as uniform if (!varDecl->hasModifier<HLSLUniformModifier>()) { getSink(sharedContext) ->diagnose(varDecl, Diagnostics::globalUniformNotExpected, varDecl->getName()); } - // Always check and warn about binding attributes being ignored, regardless of uniform modifier + // Always check and warn about binding attributes being ignored, regardless of uniform + // modifier if (varDecl->findModifier<GLSLBindingAttribute>()) { sharedContext->m_sink->diagnose( @@ -3635,7 +3663,8 @@ struct ParameterBindingVisitorCounters Index globalParamCounter = 0; }; -/// Recursive routine to "complete" all binding for parameters and entry points in `componentType`. +/// Recursive routine to "complete" all binding for parameters and entry points in +/// `componentType`. /// /// This includes allocation of as-yet-unused register/binding ranges to parameters (which /// will then affect the ranges of registers/bindings that are available to subsequent @@ -3973,8 +4002,8 @@ static bool _calcNeedsDefaultSpace(SharedParameterBindingContext& sharedContext) continue; case LayoutResourceKind::Uniform: { - // If it's uniform, but we have globals binding defined, we don't need a default - // space for it as it will go in the global binding specified + // If it's uniform, but we have globals binding defined, we don't need a + // default space for it as it will go in the global binding specified if (auto hlslToVulkanOptions = sharedContext.getTargetProgram()->getHLSLToVulkanLayoutOptions()) { @@ -4070,8 +4099,8 @@ static void _maybeApplyHLSLToVulkanShifts( return; } - // If the user specified -fvk-b-shift for the default space but not -fvk-bind-global, we want to - // apply the shift to the global constant buffer. + // If the user specified -fvk-b-shift for the default space but not -fvk-bind-global, we + // want to apply the shift to the global constant buffer. if (!vulkanOptions->hasGlobalsBinding()) { auto globalCBufferShift = vulkanOptions->getShift( @@ -4117,10 +4146,10 @@ static void _maybeApplyHLSLToVulkanShifts( // In essence we need to look for HLSL kinds which have inferance. // We assume all map to Descriptor, and look for descriptor overlaps - // We know there can't be a clash of HLSL layout kinds previously, otherwise that - // would have already produced an a warning. We also know the only change is either - // *all* of a set is shifted or none. That means post a shift there still can't be - // clash between HLSL types. + // We know there can't be a clash of HLSL layout kinds previously, otherwise + // that would have already produced an a warning. We also know the only change + // is either *all* of a set is shifted or none. That means post a shift there + // still can't be clash between HLSL types. // So clashes can only be between HLSL types and other bindings (regardless) |
