summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-type-layout.cpp110
-rw-r--r--source/slang/slang-type-layout.h18
2 files changed, 108 insertions, 20 deletions
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index dbdfaf79c..fd0b126e8 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -687,6 +687,7 @@ struct HLSLRayTracingLayoutRulesImpl : DefaultVaryingLayoutRulesImpl
{}
};
+DefaultLayoutRulesImpl kDefaultLayoutRulesImpl;
Std140LayoutRulesImpl kStd140LayoutRulesImpl;
Std430LayoutRulesImpl kStd430LayoutRulesImpl;
HLSLConstantBufferLayoutRulesImpl kHLSLConstantBufferLayoutRulesImpl;
@@ -710,6 +711,7 @@ HLSLRayTracingLayoutRulesImpl kHLSLHitAttributesParameterLayoutRulesImpl(LayoutR
struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
+ virtual LayoutRulesImpl* getAnyValueRules() override;
virtual LayoutRulesImpl* getConstantBufferRules() override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules() override;
@@ -730,6 +732,7 @@ struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
+ virtual LayoutRulesImpl* getAnyValueRules() override;
virtual LayoutRulesImpl* getConstantBufferRules() override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules() override;
@@ -750,6 +753,7 @@ struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
+ virtual LayoutRulesImpl* getAnyValueRules() override;
virtual LayoutRulesImpl* getConstantBufferRules() override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules() override;
@@ -769,6 +773,7 @@ struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct CUDALayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
+ virtual LayoutRulesImpl* getAnyValueRules() override;
virtual LayoutRulesImpl* getConstantBufferRules() override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules() override;
@@ -903,6 +908,12 @@ LayoutRulesImpl kCPULayoutRulesImpl_ = {
&kCPULayoutRulesFamilyImpl, &kCPULayoutRulesImpl, &kCPUObjectLayoutRulesImpl,
};
+LayoutRulesImpl kCPUAnyValueLayoutRulesImpl_ = {
+ &kCPULayoutRulesFamilyImpl,
+ &kDefaultLayoutRulesImpl,
+ &kCPUObjectLayoutRulesImpl,
+};
+
// CUDA
static CUDAObjectLayoutRulesImpl kCUDAObjectLayoutRulesImpl;
@@ -912,6 +923,11 @@ LayoutRulesImpl kCUDALayoutRulesImpl_ = {
&kCUDALayoutRulesFamilyImpl, &kCUDALayoutRulesImpl, &kCUDAObjectLayoutRulesImpl,
};
+LayoutRulesImpl kCUDAAnyValueLayoutRulesImpl_ = {
+ &kCUDALayoutRulesFamilyImpl,
+ &kDefaultLayoutRulesImpl,
+ &kCUDAObjectLayoutRulesImpl,
+};
// GLSL cases
@@ -923,6 +939,12 @@ LayoutRulesImpl kStd430LayoutRulesImpl_ = {
&kGLSLLayoutRulesFamilyImpl, &kStd430LayoutRulesImpl, &kGLSLObjectLayoutRulesImpl,
};
+LayoutRulesImpl kGLSLAnyValueLayoutRulesImpl_ = {
+ &kGLSLLayoutRulesFamilyImpl,
+ &kDefaultLayoutRulesImpl,
+ &kGLSLPushConstantBufferObjectLayoutRulesImpl_,
+};
+
LayoutRulesImpl kGLSLPushConstantLayoutRulesImpl_ = {
&kGLSLLayoutRulesFamilyImpl, &kStd430LayoutRulesImpl, &kGLSLPushConstantBufferObjectLayoutRulesImpl_,
};
@@ -962,6 +984,12 @@ LayoutRulesImpl kGLSLStructuredBufferLayoutRulesImpl_ = {
// HLSL cases
+LayoutRulesImpl kHLSLAnyValueLayoutRulesImpl_ = {
+ &kHLSLLayoutRulesFamilyImpl,
+ &kDefaultLayoutRulesImpl,
+ &kHLSLObjectLayoutRulesImpl,
+};
+
LayoutRulesImpl kHLSLConstantBufferLayoutRulesImpl_ = {
&kHLSLLayoutRulesFamilyImpl, &kHLSLConstantBufferLayoutRulesImpl, &kHLSLObjectLayoutRulesImpl,
};
@@ -992,6 +1020,11 @@ LayoutRulesImpl kHLSLHitAttributesParameterLayoutRulesImpl_ = {
// GLSL Family
+LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getAnyValueRules()
+{
+ return &kGLSLAnyValueLayoutRulesImpl_;
+}
+
LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules()
{
return &kStd140LayoutRulesImpl_;
@@ -1060,6 +1093,11 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getStructuredBufferRules()
// HLSL Family
+LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getAnyValueRules()
+{
+ return &kHLSLAnyValueLayoutRulesImpl_;
+}
+
LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules()
{
return &kHLSLConstantBufferLayoutRulesImpl_;
@@ -1129,6 +1167,11 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getHitAttributesParameterRules()
// CPU Family
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getAnyValueRules()
+{
+ return &kCPUAnyValueLayoutRulesImpl_;
+}
+
LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules()
{
return &kCPULayoutRulesImpl_;
@@ -1190,6 +1233,11 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getStructuredBufferRules()
// CUDA Family
+LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getAnyValueRules()
+{
+ return &kCUDAAnyValueLayoutRulesImpl_;
+}
+
LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getConstantBufferRules()
{
return &kCUDALayoutRulesImpl_;
@@ -3613,21 +3661,18 @@ static TypeLayoutResult _createTypeLayout(
typeLayout->type = type;
typeLayout->rules = rules;
- if (isCPUTarget(context.targetReq) || isCUDATarget(context.targetReq))
+ LayoutSize fixedExistentialValueSize = 0;
+ bool useFixedSizedExistentialValue =
+ isCPUTarget(context.targetReq) || isCUDATarget(context.targetReq);
+ if (useFixedSizedExistentialValue)
{
- LayoutSize fixedSize = 16;
+ fixedExistentialValueSize = 16;
if (auto anyValueAttr =
interfaceDeclRef.getDecl()->findModifier<AnyValueSizeAttribute>())
{
- fixedSize += anyValueAttr->size;
+ fixedExistentialValueSize = anyValueAttr->size;
}
- else
- {
- // The interface type does not have an `[anyValueSize]` attribute,
- // assume a default of 8 bytes.
- fixedSize += 8;
- }
- typeLayout->addResourceUsage(LayoutResourceKind::Uniform, fixedSize);
+ typeLayout->addResourceUsage(LayoutResourceKind::Uniform, fixedExistentialValueSize + 16);
}
typeLayout->addResourceUsage(LayoutResourceKind::ExistentialTypeParam, 1);
typeLayout->addResourceUsage(LayoutResourceKind::ExistentialObjectParam, 1);
@@ -3635,21 +3680,46 @@ static TypeLayoutResult _createTypeLayout(
// If there are any concrete types available, the first one will be
// the value that should be plugged into the slot we just introduced.
//
- if( context.specializationArgCount )
+ if (context.specializationArgCount)
{
auto& specializationArg = context.specializationArgs[0];
Type* concreteType = as<Type>(specializationArg.val);
SLANG_ASSERT(concreteType);
- RefPtr<TypeLayout> concreteTypeLayout = createTypeLayout(context, concreteType);
-
- // Layout for this specialized interface type then results
- // in a type layout that tracks both the resource usage of the
- // interface type itself (just the type + value slots introduced
- // above), plus a "pending data" type that represents the value
- // conceptually pointed to by the interface-type field/variable at runtime.
- //
- typeLayout->pendingDataTypeLayout = concreteTypeLayout;
+ // Always use AnyValueRules regardless of the enclosing environment's layout rule
+ // for existential values.
+ auto anyValueRules = context.getRulesFamily()->getAnyValueRules();
+
+ // TODO: for traditional GPU targets (HLSL/GLSL) we don't force
+ // anyValueRule for now, since it requires additional work to load
+ // the existential value. We should remove this special case logic
+ // and always use anyValueRule once we implement the correct loading
+ // code gen logic for these targets.
+ if (!(isCPUTarget(context.targetReq) || isCUDATarget(context.targetReq)))
+ anyValueRules = context.rules;
+
+ RefPtr<TypeLayout> concreteTypeLayout =
+ createTypeLayout(context.with(anyValueRules), concreteType);
+ auto uniformLayoutInfo =
+ concreteTypeLayout->FindResourceInfo(LayoutResourceKind::Uniform);
+ if (!useFixedSizedExistentialValue ||
+ (uniformLayoutInfo && uniformLayoutInfo->count > fixedExistentialValueSize))
+ {
+ // TODO: for targets that supports pointers, oversized existential values
+ // should be placed in an overflow region and only a pointer is needed in
+ // the place of the fixed sized uniform slot.
+ // We only need the "pending layout" mechanism for targets that does not
+ // support pointers.
+
+ // For legacy targets without pointer support, the layout for this
+ // specialized interface type then results in a type layout that tracks
+ // both the resource usage of the interface type itself (just the
+ // type + value slots introduced above), plus a "pending data" type that
+ // represents the value conceptually pointed to by the interface-type
+ // field/variable at runtime.
+ //
+ typeLayout->pendingDataTypeLayout = concreteTypeLayout;
+ }
}
return TypeLayoutResult(typeLayout, SimpleLayoutInfo());
diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h
index 6298219f0..fc24f46bc 100644
--- a/source/slang/slang-type-layout.h
+++ b/source/slang/slang-type-layout.h
@@ -73,6 +73,23 @@ struct LayoutSize
return raw != that.raw;
}
+ bool operator>(LayoutSize that) const
+ {
+ if (that.isFinite())
+ {
+ if (this->isFinite())
+ return this->raw > that.raw;
+ return true;
+
+ }
+ else
+ {
+ if (that.isInfinite())
+ return false;
+ return true;
+ }
+ }
+
void operator+=(LayoutSize right)
{
if( isInfinite() ) {}
@@ -892,6 +909,7 @@ struct LayoutRulesImpl
struct LayoutRulesFamilyImpl
{
+ virtual LayoutRulesImpl* getAnyValueRules() = 0;
virtual LayoutRulesImpl* getConstantBufferRules() = 0;
virtual LayoutRulesImpl* getPushConstantBufferRules() = 0;
virtual LayoutRulesImpl* getTextureBufferRules() = 0;