summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2021-04-01 16:15:09 -0700
committerGitHub <noreply@github.com>2021-04-01 16:15:09 -0700
commit0ec8e5b016e56ad491a418ab72a5be28dd83f3b4 (patch)
treee7934e78346cd63a4d944e68dc90fcafebc40d42 /source
parent9475b11045089c9bc9773b16f7eb84f843db70c4 (diff)
Refactor D3D12 renderer root signature creation (#1779)
This change originated as an attempt to re-enable a test case, but it has ended up disabling more tests (for good reasons) than it re-enables. The main change here is a significant overhaul of the way that the D3D12 render path extracts information from the Slang reflection API to produce a root signature. There were also some supporting fixes in the reflection information to make sure it returns what the D3D12 back-end needed. The big picture here is that the D3D12 path now uses the descriptor ranges stored in the reflection data more or less directly. It still needs to use register/space offset information queried via the "old" reflection API, but it only does so at the top level now, for the program and entry points themselves. All other layout information is derived directly from what Slang provides. Smaller changes: * The "flat" reflection API was expanded to include `getBindingRangeDescriptorRangeCount()` which was clearly missing. * The "flat" reflection results for a constant buffer or parameter block that didn't contain any uniform data and was mapped to a plain constant buffer needed to be fixed up. That logic is still way to subtle to be trusted. * Several additional tests were disabled that relied on static specialization, global/entry-point generi type parameters, structured buffers of interfaces or other features we don't officially support with shader objects right now. All of the affected tests were somehow passing by sheer luck and because they often passed in specialization arguments via explicit `TEST_INPUT` lines. * The `inteface-shader-param` test is re-enabled now that we can properly describe its input with the new `set` mode on `TEST_INPUT` * `ShaderCursor::getElement()` can now be used on structure types (in addition to arrays) to support by-index access to fields * The `TEST_INPUT` system was expanded to support both by-name and by-index setting of structure fields for aggregates * The `TEST_INPUT` system was expanded to allow an `out` prefix to mark parts of an expression as outputs on a `set` lines * The `TEST_INPUT` system was expanded so that anything that would be allowed on a `TEST_INPUT` line by itself (like `ubuffer(...)`) can now be used as a sub-expression on a `set` line Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-reflection-api.cpp38
-rw-r--r--source/slang/slang.cpp4
2 files changed, 36 insertions, 6 deletions
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index 2031b4a0f..6f022cc90 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -1326,6 +1326,7 @@ namespace Slang
Index bindingRangeIndex = m_extendedInfo->m_bindingRanges.getCount();
SlangBindingType bindingType = SLANG_BINDING_TYPE_CONSTANT_BUFFER;
Index spaceOffset = -1;
+ bool usesIndirectAllocation = false;
LayoutResourceKind kind = LayoutResourceKind::None;
// TODO: It is unclear if this should be looking at the resource
@@ -1333,12 +1334,25 @@ namespace Slang
//
for(auto& resInfo : parameterGroupTypeLayout->resourceInfos)
{
+ if( spaceOffset == -1 )
+ {
+ spaceOffset = _calcSpaceOffset(path, kind);
+ }
+
kind = resInfo.kind;
switch(kind)
{
default:
continue;
+ case LayoutResourceKind::ConstantBuffer:
+ case LayoutResourceKind::PushConstantBuffer:
+ case LayoutResourceKind::DescriptorTableSlot:
+ break;
+
+ // Certain cases indicate a parameter block that
+ // actually involves indirection.
+ //
// Note: the only case where a parameter group should
// reflect as consuming `Uniform` storage is on CPU/CUDA,
// where that will be the only resource it contains.
@@ -1346,18 +1360,19 @@ namespace Slang
// TODO: If we ever support targets that don't have
// constant buffers at all, this logic would be questionable.
//
- case LayoutResourceKind::ConstantBuffer:
- case LayoutResourceKind::PushConstantBuffer:
case LayoutResourceKind::RegisterSpace:
- case LayoutResourceKind::DescriptorTableSlot:
case LayoutResourceKind::Uniform:
+ usesIndirectAllocation = true;
break;
}
bindingType = _calcBindingType(typeLayout, kind);
- spaceOffset = _calcSpaceOffset(path, kind);
break;
}
+ if(spaceOffset == -1)
+ {
+ spaceOffset = 0;
+ }
TypeLayout::ExtendedInfo::BindingRangeInfo bindingRange;
bindingRange.leafTypeLayout = typeLayout;
@@ -1419,7 +1434,7 @@ namespace Slang
// because the physical storage for `C.a` is provided by the
// memory allocation for `C` itself.
- if( spaceOffset != -1 )
+ if( !usesIndirectAllocation )
{
// The logic here assumes that when a parameter group consumes
// resources that must "leak" into the outer scope (including
@@ -1848,6 +1863,19 @@ SLANG_API SlangInt spReflectionTypeLayout_getBindingRangeFirstDescriptorRangeInd
return bindingRange.firstDescriptorRangeIndex;
}
+SLANG_API SlangInt spReflectionTypeLayout_getBindingRangeDescriptorRangeCount(SlangReflectionTypeLayout* inTypeLayout, SlangInt index)
+{
+ auto typeLayout = convert(inTypeLayout);
+ if(!typeLayout) return 0;
+
+ auto extTypeLayout = Slang::getExtendedTypeLayout(typeLayout);
+ if(index < 0) return 0;
+ if(index >= extTypeLayout->m_bindingRanges.getCount()) return 0;
+ auto& bindingRange = extTypeLayout->m_bindingRanges[index];
+
+ return bindingRange.descriptorRangeCount;
+}
+
SLANG_API SlangInt spReflectionTypeLayout_getDescriptorSetCount(SlangReflectionTypeLayout* inTypeLayout)
{
auto typeLayout = convert(inTypeLayout);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 8c6bf403e..c48701575 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -2832,7 +2832,9 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::specialize(
auto specializationParamCount = getSpecializationParamCount();
if( specializationArgCount != specializationParamCount )
{
- // TODO: diagnose
+ sink.diagnose(SourceLoc(), Diagnostics::mismatchSpecializationArguments,
+ specializationParamCount,
+ specializationArgCount);
sink.getBlobIfNeeded(outDiagnostics);
return SLANG_FAIL;
}