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.cpp132
1 files changed, 107 insertions, 25 deletions
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index c933c5bb5..5cf8d2350 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -696,12 +696,60 @@ struct GLSLSpecializationConstantLayoutRulesImpl : DefaultLayoutRulesImpl
GLSLSpecializationConstantLayoutRulesImpl kGLSLSpecializationConstantLayoutRulesImpl;
-//
+// Given a ShaderParamKind returns the equivalent LayoutResourceKind/ParameterCategory/SlangParameterCategory
+static LayoutResourceKind _getHLSLLayoutResourceKind(ShaderParameterKind kind)
+{
+ switch (kind)
+ {
+ case ShaderParameterKind::ConstantBuffer:
+ return LayoutResourceKind::ConstantBuffer;
+
+ case ShaderParameterKind::TextureUniformBuffer:
+ case ShaderParameterKind::StructuredBuffer:
+ case ShaderParameterKind::RawBuffer:
+ case ShaderParameterKind::Buffer:
+ case ShaderParameterKind::Texture:
+ return LayoutResourceKind::ShaderResource;
+
+ case ShaderParameterKind::MutableStructuredBuffer:
+ case ShaderParameterKind::MutableRawBuffer:
+ case ShaderParameterKind::MutableBuffer:
+ case ShaderParameterKind::MutableTexture:
+ return LayoutResourceKind::UnorderedAccess;
+
+ case ShaderParameterKind::SamplerState:
+ return LayoutResourceKind::SamplerState;
+ default:
+ return LayoutResourceKind::None;
+ }
+}
struct GLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl
{
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) override
{
+ if (options.hlslToVulkanKindFlags)
+ {
+ // Is this an HLSL kind that might be shifted
+
+ // Get as hlslLayoutKind
+ const auto hlslLayoutKind = _getHLSLLayoutResourceKind(kind);
+
+ // Get as hlslToVulkanKind
+ const auto hlslToVulkanKind = HLSLToVulkanLayoutOptions::getKind(hlslLayoutKind);
+
+ if (hlslToVulkanKind != HLSLToVulkanLayoutOptions::Kind::Invalid)
+ {
+ // Is this kind enabled for shift?
+ if (options.hlslToVulkanKindFlags & HLSLToVulkanLayoutOptions::getKindFlag(hlslToVulkanKind))
+ {
+ // We are going to consume a HLSL layout kind
+ // Later we will do shifting as necessary
+ return SimpleLayoutInfo(hlslLayoutKind, 1);
+ }
+ }
+ }
+
// In Vulkan GLSL, pretty much every object is just a descriptor-table slot.
// We can refine this method once we support a case where this isn't true.
return SimpleLayoutInfo(LayoutResourceKind::DescriptorTableSlot, 1);
@@ -711,7 +759,7 @@ GLSLObjectLayoutRulesImpl kGLSLObjectLayoutRulesImpl;
struct GLSLPushConstantBufferObjectLayoutRulesImpl : GLSLObjectLayoutRulesImpl
{
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override
{
// Special-case the layout for a constant-buffer, because we don't
// want it to allocate a descriptor-table slot
@@ -722,7 +770,7 @@ GLSLPushConstantBufferObjectLayoutRulesImpl kGLSLPushConstantBufferObjectLayoutR
struct GLSLShaderRecordConstantBufferObjectLayoutRulesImpl : GLSLObjectLayoutRulesImpl
{
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override
{
// Special-case the layout for a constant-buffer, because we don't
// want it to allocate a descriptor-table slot
@@ -733,7 +781,7 @@ GLSLShaderRecordConstantBufferObjectLayoutRulesImpl kGLSLShaderRecordConstantBuf
struct HLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl
{
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override
{
switch( kind )
{
@@ -910,7 +958,7 @@ CUDALayoutRulesFamilyImpl kCUDALayoutRulesFamilyImpl;
struct CPUObjectLayoutRulesImpl : ObjectLayoutRulesImpl
{
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override
{
switch (kind)
{
@@ -962,7 +1010,7 @@ struct CUDAObjectLayoutRulesImpl : CPUObjectLayoutRulesImpl
// of opaque handle (as opposed to a pointer) such as CUsurfObject, CUtexObject
typedef unsigned long long ObjectHandle;
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind) override
+ virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options & /* options */) override
{
switch (kind)
{
@@ -1501,6 +1549,11 @@ TypeLayoutContext getInitialLayoutContextForTarget(TargetRequest* targetReq, Pro
context.rules = nullptr;
context.matrixLayoutMode = targetReq->getDefaultMatrixLayoutMode();
+ if (auto hlslToVulkanLayoutOptions = targetReq->getHLSLToVulkanLayoutOptions())
+ {
+ context.objectLayoutOptions.hlslToVulkanKindFlags = hlslToVulkanLayoutOptions->getKindShiftEnabledFlags();
+ }
+
if( rulesFamily )
{
context.rules = rulesFamily->getConstantBufferRules(targetReq);
@@ -1586,21 +1639,22 @@ static TypeLayoutResult createSimpleTypeLayout(
return TypeLayoutResult(typeLayout, info);
}
-static SimpleLayoutInfo getParameterGroupLayoutInfo(
- ParameterGroupType* type,
- LayoutRulesImpl* rules)
+static SimpleLayoutInfo _getParameterGroupLayoutInfo(
+ TypeLayoutContext const& context,
+ ParameterGroupType* type,
+ LayoutRulesImpl* rules)
{
if( as<ConstantBufferType>(type) )
{
- return rules->GetObjectLayout(ShaderParameterKind::ConstantBuffer);
+ return rules->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context.objectLayoutOptions);
}
else if( as<TextureBufferType>(type) )
{
- return rules->GetObjectLayout(ShaderParameterKind::TextureUniformBuffer);
+ return rules->GetObjectLayout(ShaderParameterKind::TextureUniformBuffer, context.objectLayoutOptions);
}
else if( as<GLSLShaderStorageBufferType>(type) )
{
- return rules->GetObjectLayout(ShaderParameterKind::ShaderStorageBuffer);
+ return rules->GetObjectLayout(ShaderParameterKind::ShaderStorageBuffer, context.objectLayoutOptions);
}
else if (as<ParameterBlockType>(type))
{
@@ -2270,7 +2324,7 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout(
// allocate a constant buffer regiser/binding into
// the overall layout, to account for it.
//
- auto cbUsage = parameterGroupRules->GetObjectLayout(ShaderParameterKind::ConstantBuffer);
+ auto cbUsage = parameterGroupRules->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context.objectLayoutOptions);
containerTypeLayout->addResourceUsage(cbUsage.kind, cbUsage.size);
}
@@ -2730,7 +2784,7 @@ createStructuredBufferTypeLayout(
RefPtr<TypeLayout> elementTypeLayout)
{
auto rules = context.rules;
- auto info = rules->GetObjectLayout(kind);
+ auto info = rules->GetObjectLayout(kind, context.objectLayoutOptions);
auto typeLayout = new StructuredBufferTypeLayout();
@@ -3378,6 +3432,26 @@ RefPtr<TypeLayout> createTypeLayoutForGlobalGenericTypeParam(
return _createTypeLayoutForGlobalGenericTypeParam(context, type, globalGenericParamDecl).layout;
}
+static bool _isDescriptorSlotLike(
+ TypeLayoutContext const& context,
+ LayoutResourceKind kind)
+{
+ if (kind == LayoutResourceKind::DescriptorTableSlot)
+ {
+ return true;
+ }
+
+ if (context.objectLayoutOptions.hlslToVulkanKindFlags)
+ {
+ const auto hlslToVulkanKind = HLSLToVulkanLayoutOptions::getKind(kind);
+ // If it maps to a kind and it is enabled it is 'in effect' a Descriptor slot
+ return hlslToVulkanKind != HLSLToVulkanLayoutOptions::Kind::Invalid &&
+ (context.objectLayoutOptions.hlslToVulkanKindFlags & HLSLToVulkanLayoutOptions::getKindFlag(hlslToVulkanKind));
+ }
+
+ return false;
+}
+
static TypeLayoutResult createArrayLikeTypeLayout(
TypeLayoutContext const& context,
Type* type,
@@ -3472,6 +3546,13 @@ static TypeLayoutResult createArrayLikeTypeLayout(
LayoutSize arrayResourceCount = 0;
+ // We copy because if the element is *actually* DescriptorSlot like,
+ // we'll change the type.
+ // NOTE! That as it stands this will change the resource type from an HLSL type
+ // to Descriptor slot. This scenario happens when we have HLSLToVulkanLayoutOptions
+ // enabled, we layout with some HLSL types.
+ auto elementResourceKind = elementResourceInfo.kind;
+
// In almost all cases, the resources consumed by an array
// will be its element count times the resources consumed
// by its element type.
@@ -3480,14 +3561,15 @@ static TypeLayoutResult createArrayLikeTypeLayout(
// compiling to GLSL for Vulkan, where an entire array
// only consumes a single descriptor-table slot.
//
- if (elementResourceInfo.kind == LayoutResourceKind::DescriptorTableSlot)
+ if (_isDescriptorSlotLike(context, elementResourceKind))
{
arrayResourceCount = elementResourceInfo.count;
+ elementResourceKind = LayoutResourceKind::DescriptorTableSlot;
}
// The second exception to this is arrays of an existential type
// where the entire array should be specialized to a single concrete type.
//
- else if (elementResourceInfo.kind == LayoutResourceKind::ExistentialTypeParam)
+ else if (elementResourceKind == LayoutResourceKind::ExistentialTypeParam)
{
arrayResourceCount = elementResourceInfo.count;
}
@@ -3505,7 +3587,7 @@ static TypeLayoutResult createArrayLikeTypeLayout(
else if(
elementCount.isInfinite()
&& adjustedElementTypeLayout != elementTypeLayout
- && doesResourceRequireAdjustmentForArrayOfStructs(elementResourceInfo.kind) )
+ && doesResourceRequireAdjustmentForArrayOfStructs(elementResourceKind) )
{
// We want to ignore resource types consumed by the element type
// that need adjustement if the array size is infinite, since
@@ -3611,7 +3693,7 @@ static TypeLayoutResult _createTypeLayout(
// different from a `Texture2D<U>` in terms of how it
// should be handled as a member of a container.
//
- auto info = getParameterGroupLayoutInfo(parameterGroupType, rules);
+ auto info = _getParameterGroupLayoutInfo(context, parameterGroupType, rules);
// The more interesting case, though, is when the user
// is requesting us to actually create a `TypeLayout`,
@@ -3633,7 +3715,7 @@ static TypeLayoutResult _createTypeLayout(
else if (const auto samplerStateType = as<SamplerStateType>(type))
{
return createSimpleTypeLayout(
- rules->GetObjectLayout(ShaderParameterKind::SamplerState),
+ rules->GetObjectLayout(ShaderParameterKind::SamplerState, context.objectLayoutOptions),
type,
rules);
}
@@ -3654,7 +3736,7 @@ static TypeLayoutResult _createTypeLayout(
}
return createSimpleTypeLayout(
- rules->GetObjectLayout(kind),
+ rules->GetObjectLayout(kind, context.objectLayoutOptions),
type,
rules);
}
@@ -3675,7 +3757,7 @@ static TypeLayoutResult _createTypeLayout(
}
return createSimpleTypeLayout(
- rules->GetObjectLayout(kind),
+ rules->GetObjectLayout(kind, context.objectLayoutOptions),
type,
rules);
}
@@ -3696,7 +3778,7 @@ static TypeLayoutResult _createTypeLayout(
}
return createSimpleTypeLayout(
- rules->GetObjectLayout(kind),
+ rules->GetObjectLayout(kind, context.objectLayoutOptions),
type,
rules);
}
@@ -3704,7 +3786,7 @@ static TypeLayoutResult _createTypeLayout(
// TODO: need a better way to handle this stuff...
#define CASE(TYPE, KIND) \
else if(auto type_##TYPE = as<TYPE>(type)) do { \
- auto info = rules->GetObjectLayout(ShaderParameterKind::KIND); \
+ auto info = rules->GetObjectLayout(ShaderParameterKind::KIND, context.objectLayoutOptions); \
auto typeLayout = createStructuredBufferTypeLayout( \
context, \
ShaderParameterKind::KIND, \
@@ -3726,7 +3808,7 @@ static TypeLayoutResult _createTypeLayout(
#define CASE(TYPE, KIND) \
else if(as<TYPE>(type)) do { \
return createSimpleTypeLayout( \
- rules->GetObjectLayout(ShaderParameterKind::KIND), \
+ rules->GetObjectLayout(ShaderParameterKind::KIND, context.objectLayoutOptions), \
type, rules); \
} while(0)