summaryrefslogtreecommitdiff
path: root/source/slang/slang-type-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-type-layout.cpp')
-rw-r--r--source/slang/slang-type-layout.cpp230
1 files changed, 205 insertions, 25 deletions
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index f76b29a51..3b14b74c2 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -346,6 +346,38 @@ struct HLSLConstantBufferLayoutRulesImpl : DefaultLayoutRulesImpl
}
};
+struct CPULayoutRulesImpl : DefaultLayoutRulesImpl
+{
+ typedef DefaultLayoutRulesImpl Super;
+
+ SimpleLayoutInfo GetScalarLayout(BaseType baseType) override
+ {
+ switch (baseType)
+ {
+ case BaseType::Bool:
+ {
+ // TODO(JS): Much like ptr this is a problem - in knowing how to return this value. In the past it's been a word
+ // on some compilers for example.
+ // On checking though current compilers (clang, g++, visual studio) it is a single byte
+ return SimpleLayoutInfo( LayoutResourceKind::Uniform, 1, 1 );
+ }
+
+ default: return Super::GetScalarLayout(baseType);
+ }
+ }
+
+ UniformLayoutInfo BeginStructLayout() override
+ {
+ return Super::BeginStructLayout();
+ }
+
+ void EndStructLayout(UniformLayoutInfo* ioStructInfo) override
+ {
+ // Conform to C/C++ size is adjusted to the largest alignment
+ ioStructInfo->size = RoundToAlignment(ioStructInfo->size, ioStructInfo->alignment);
+ }
+};
+
struct HLSLStructuredBufferLayoutRulesImpl : DefaultLayoutRulesImpl
{
// HLSL structured buffers drop the restrictions added for constant buffers,
@@ -558,6 +590,8 @@ struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
LayoutRulesImpl* getHitAttributesParameterRules() override;
LayoutRulesImpl* getShaderRecordConstantBufferRules() override;
+
+ LayoutRulesImpl* getStructuredBufferRules() override;
};
struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
@@ -576,11 +610,86 @@ struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
LayoutRulesImpl* getHitAttributesParameterRules() override;
LayoutRulesImpl* getShaderRecordConstantBufferRules() override;
+
+ LayoutRulesImpl* getStructuredBufferRules() override;
+};
+
+struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
+{
+ virtual LayoutRulesImpl* getConstantBufferRules() override;
+ virtual LayoutRulesImpl* getPushConstantBufferRules() override;
+ virtual LayoutRulesImpl* getTextureBufferRules() override;
+ virtual LayoutRulesImpl* getVaryingInputRules() override;
+ virtual LayoutRulesImpl* getVaryingOutputRules() override;
+ virtual LayoutRulesImpl* getSpecializationConstantRules() override;
+ virtual LayoutRulesImpl* getShaderStorageBufferRules() override;
+ virtual LayoutRulesImpl* getParameterBlockRules() override;
+
+ LayoutRulesImpl* getRayPayloadParameterRules() override;
+ LayoutRulesImpl* getCallablePayloadParameterRules() override;
+ LayoutRulesImpl* getHitAttributesParameterRules() override;
+
+ LayoutRulesImpl* getShaderRecordConstantBufferRules() override;
+ LayoutRulesImpl* getStructuredBufferRules() override;
};
GLSLLayoutRulesFamilyImpl kGLSLLayoutRulesFamilyImpl;
HLSLLayoutRulesFamilyImpl kHLSLLayoutRulesFamilyImpl;
+CPULayoutRulesFamilyImpl kCPULayoutRulesFamilyImpl;
+// CPU case
+
+struct CPUObjectLayoutRulesImpl : ObjectLayoutRulesImpl
+{
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind) override
+ {
+ switch (kind)
+ {
+ case ShaderParameterKind::ConstantBuffer:
+ // It's a pointer to the actual uniform data
+ return SimpleLayoutInfo(LayoutResourceKind::Uniform, sizeof(void*), sizeof(void*));
+
+ case ShaderParameterKind::MutableTexture:
+ case ShaderParameterKind::TextureUniformBuffer:
+ case ShaderParameterKind::Texture:
+ // It's a pointer to a texture interface
+ return SimpleLayoutInfo(LayoutResourceKind::Uniform, sizeof(void*), sizeof(void*));
+
+ case ShaderParameterKind::StructuredBuffer:
+ case ShaderParameterKind::MutableStructuredBuffer:
+ // It's a ptr and a size of the amount of elements
+ return SimpleLayoutInfo(LayoutResourceKind::Uniform, sizeof(void*) * 2, sizeof(void*));
+
+ case ShaderParameterKind::RawBuffer:
+ case ShaderParameterKind::Buffer:
+ case ShaderParameterKind::MutableRawBuffer:
+ case ShaderParameterKind::MutableBuffer:
+ // It's a pointer and a size in bytes
+ return SimpleLayoutInfo(LayoutResourceKind::Uniform, sizeof(void*) * 2, sizeof(void*));
+
+ case ShaderParameterKind::SamplerState:
+ // It's a pointer
+ return SimpleLayoutInfo(LayoutResourceKind::Uniform, sizeof(void*), sizeof(void*));
+
+ case ShaderParameterKind::TextureSampler:
+ case ShaderParameterKind::MutableTextureSampler:
+ case ShaderParameterKind::InputRenderTarget:
+ // TODO: how to handle these?
+ default:
+ SLANG_UNEXPECTED("unhandled shader parameter kind");
+ UNREACHABLE_RETURN(SimpleLayoutInfo());
+ }
+ }
+};
+
+
+
+static CPUObjectLayoutRulesImpl kCPUObjectLayoutRulesImpl;
+static CPULayoutRulesImpl kCPULayoutRulesImpl;
+
+LayoutRulesImpl kCPULayoutRulesImpl_ = {
+ &kCPULayoutRulesFamilyImpl, &kCPULayoutRulesImpl, &kCPUObjectLayoutRulesImpl,
+};
// GLSL cases
@@ -624,6 +733,11 @@ LayoutRulesImpl kGLSLHitAttributesParameterLayoutRulesImpl_ = {
&kGLSLLayoutRulesFamilyImpl, &kGLSLHitAttributesParameterLayoutRulesImpl, &kGLSLObjectLayoutRulesImpl,
};
+LayoutRulesImpl kGLSLStructuredBufferLayoutRulesImpl_ = {
+ &kGLSLLayoutRulesFamilyImpl, &kStd430LayoutRulesImpl, &kGLSLObjectLayoutRulesImpl,
+};
+
+
// HLSL cases
LayoutRulesImpl kHLSLConstantBufferLayoutRulesImpl_ = {
@@ -654,7 +768,7 @@ LayoutRulesImpl kHLSLHitAttributesParameterLayoutRulesImpl_ = {
&kHLSLLayoutRulesFamilyImpl, &kHLSLHitAttributesParameterLayoutRulesImpl, &kHLSLObjectLayoutRulesImpl,
};
-//
+// GLSL Family
LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules()
{
@@ -717,7 +831,12 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getHitAttributesParameterRules()
return &kGLSLHitAttributesParameterLayoutRulesImpl_;
}
-//
+LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getStructuredBufferRules()
+{
+ return &kGLSLStructuredBufferLayoutRulesImpl_;
+}
+
+// HLSL Family
LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules()
{
@@ -741,6 +860,11 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getShaderRecordConstantBufferRules()
return &kHLSLConstantBufferLayoutRulesImpl_;
}
+LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getStructuredBufferRules()
+{
+ return &kHLSLStructuredBufferLayoutRulesImpl_;
+}
+
LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getTextureBufferRules()
{
return nullptr;
@@ -781,21 +905,65 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getHitAttributesParameterRules()
return &kHLSLHitAttributesParameterLayoutRulesImpl_;
}
+// CPU Family
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules()
+{
+ return &kCPULayoutRulesImpl_;
+}
-//
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getPushConstantBufferRules()
+{
+ return &kCPULayoutRulesImpl_;
+}
-LayoutRulesImpl* GetLayoutRulesImpl(LayoutRule rule)
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getTextureBufferRules()
{
- switch (rule)
- {
- case LayoutRule::Std140: return &kStd140LayoutRulesImpl_;
- case LayoutRule::Std430: return &kStd430LayoutRulesImpl_;
- case LayoutRule::HLSLConstantBuffer: return &kHLSLConstantBufferLayoutRulesImpl_;
- case LayoutRule::HLSLStructuredBuffer: return &kHLSLStructuredBufferLayoutRulesImpl_;
- default:
- return nullptr;
- }
+ return nullptr;
+}
+
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getVaryingInputRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getVaryingOutputRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getSpecializationConstantRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getShaderStorageBufferRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getParameterBlockRules()
+{
+ // Not clear - just use similar to CPU
+ return &kCPULayoutRulesImpl_;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getRayPayloadParameterRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getCallablePayloadParameterRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getHitAttributesParameterRules()
+{
+ return nullptr;
+}
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getShaderRecordConstantBufferRules()
+{
+ // Just following HLSLs lead for the moment
+ return &kCPULayoutRulesImpl_;
+}
+
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getStructuredBufferRules()
+{
+ return &kCPULayoutRulesImpl_;
}
LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targetReq)
@@ -820,13 +988,15 @@ LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targe
case CodeGenTarget::CPPSource:
case CodeGenTarget::CSource:
{
+ // For now lets use some fairly simple CPU binding rules
+
// We just need to decide here what style of layout is appropriate, in terms of memory
// and binding. That in terms of the actual binding that will be injected into functions
// in the form of a BindContext. For now we'll go with HLSL layout -
// that we may want to rethink that with the use of arrays and binding VK style binding might be
// more appropriate in some ways.
- return &kHLSLLayoutRulesFamilyImpl;
+ return &kCPULayoutRulesFamilyImpl;
}
default:
@@ -1253,7 +1423,10 @@ static bool _usesOrdinaryData(RefPtr<TypeLayout> typeLayout)
/// to the resource usage of a container like a `ConstantBuffer<X>` or
/// `ParameterBlock<X>`.
///
+ /// TODO: letUnformBleedThrough is (hopefully temporary) a hack that was added to enable CPU targets to
+ /// produce workable layout. CPU targets have all bindings/variables laid out as uniforms
static void _addUnmaskedResourceUsage(
+ bool letUniformBleedThrough,
TypeLayout* dstTypeLayout,
TypeLayout* srcTypeLayout,
bool haveFullRegisterSpaceOrSet)
@@ -1264,6 +1437,10 @@ static void _addUnmaskedResourceUsage(
{
case LayoutResourceKind::Uniform:
// Ordinary/uniform resource usage will always be masked.
+ if (letUniformBleedThrough)
+ {
+ dstTypeLayout->addResourceUsage(resInfo);
+ }
break;
case LayoutResourceKind::RegisterSpace:
@@ -1453,6 +1630,13 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout(
for( auto elementTypeResInfo : rawElementTypeLayout->resourceInfos )
{
auto kind = elementTypeResInfo.kind;
+
+ // TODO: Added to make layout work correctly for CPU target
+ if(kind == LayoutResourceKind::Uniform)
+ {
+ continue;
+ }
+
auto elementVarResInfo = elementVarLayout->findOrAddResourceInfo(kind);
// If the container part of things is using the same resource kind
@@ -1518,7 +1702,7 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout(
// buffer. Its resource usage will only bleed through if we
// didn't allocate a full `space` or `set`.
//
- _addUnmaskedResourceUsage(typeLayout, containerTypeLayout, wantSpaceOrSet);
+ _addUnmaskedResourceUsage(true, typeLayout, containerTypeLayout, wantSpaceOrSet);
// next we turn to the element type, where the cases are slightly
// more involved (technically we could use this same logic for
@@ -1526,7 +1710,7 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout(
// just special-case the container).
//
- _addUnmaskedResourceUsage(typeLayout, rawElementTypeLayout, wantSpaceOrSet);
+ _addUnmaskedResourceUsage(false, typeLayout, rawElementTypeLayout, wantSpaceOrSet);
// At this point we have handled all the complexities that
// arise for a parameter group that doesn't include interface-type
@@ -1684,8 +1868,8 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout(
// up the hierarchy.
//
RefPtr<TypeLayout> unmaskedPendingDataTypeLayout = new TypeLayout();
- _addUnmaskedResourceUsage(unmaskedPendingDataTypeLayout, pendingContainerTypeLayout, wantSpaceOrSet);
- _addUnmaskedResourceUsage(unmaskedPendingDataTypeLayout, pendingElementTypeLayout, wantSpaceOrSet);
+ _addUnmaskedResourceUsage(true, unmaskedPendingDataTypeLayout, pendingContainerTypeLayout, wantSpaceOrSet);
+ _addUnmaskedResourceUsage(false, unmaskedPendingDataTypeLayout, pendingElementTypeLayout, wantSpaceOrSet);
// TODO: we should probably optimize for the case where there is no unmasked
// usage that needs to be reported out, since it should be a common case.
@@ -1836,9 +2020,7 @@ createStructuredBufferTypeLayout(
typeLayout->elementTypeLayout = elementTypeLayout;
typeLayout->uniformAlignment = info.alignment;
- SLANG_RELEASE_ASSERT(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
- SLANG_RELEASE_ASSERT(typeLayout->uniformAlignment == 1);
-
+
if( info.size != 0 )
{
typeLayout->addResourceUsage(info.kind, info.size);
@@ -1859,10 +2041,8 @@ createStructuredBufferTypeLayout(
RefPtr<Type> structuredBufferType,
RefPtr<Type> elementType)
{
- // TODO(tfoley): we should be looking up the appropriate rules
- // via the `LayoutRulesFamily` in use here...
- auto structuredBufferLayoutRules = GetLayoutRulesImpl(
- LayoutRule::HLSLStructuredBuffer);
+ // look up the appropriate rules via the `LayoutRulesFamily`
+ auto structuredBufferLayoutRules = context.getRulesFamily()->getStructuredBufferRules();
// Create and save type layout for the buffer contents.
auto elementTypeLayout = createTypeLayout(