summaryrefslogtreecommitdiff
path: root/tools/gfx
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-05-25 10:24:38 -0700
committerGitHub <noreply@github.com>2021-05-25 10:24:38 -0700
commitba24264275c640e0ac3732f0f5720e1f5816cded (patch)
tree9413b919498c700afe89d498ff3434eea9cf3c89 /tools/gfx
parentfbf00dd54d787c6e22b0f1785a64dfb2fb1e300a (diff)
Allow overriding specialization args via `IShaderObject`. (#1854)
* Allow overriding specialization args via `IShaderObject`. * Fixes. Co-authored-by: T. Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'tools/gfx')
-rw-r--r--tools/gfx/debug-layer.cpp30
-rw-r--r--tools/gfx/debug-layer.h7
-rw-r--r--tools/gfx/renderer-shared.h53
3 files changed, 86 insertions, 4 deletions
diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp
index 56ae4fdab..3fa2eee9d 100644
--- a/tools/gfx/debug-layer.cpp
+++ b/tools/gfx/debug-layer.cpp
@@ -385,6 +385,8 @@ Result DebugDevice::createShaderObject(
auto result =
baseObject->createShaderObject(type, containerType, outObject->baseObject.writeRef());
outObject->m_typeName = typeName;
+ outObject->m_device = this;
+ outObject->m_slangType = type;
if (SLANG_FAILED(result))
return result;
returnComPtr(outShaderObject, outObject);
@@ -952,10 +954,38 @@ Result DebugShaderObject::setCombinedTextureSampler(
offset, viewImpl->baseObject.get(), samplerImpl->baseObject.get());
}
+Result DebugShaderObject::setSpecializationArgs(
+ const slang::SpecializationArg* args,
+ uint32_t count)
+{
+ ComPtr<slang::ISession> session;
+ m_device->getSlangSession(session.writeRef());
+ auto expectedCount = (uint32_t)session->getTypeLayout(m_slangType)
+ ->getSize(SLANG_PARAMETER_CATEGORY_EXISTENTIAL_TYPE_PARAM);
+ if (expectedCount != count)
+ {
+ GFX_DIAGNOSE_ERROR_FORMAT(
+ "specialization argument count for shader object type %s mismatch: expecting %d but %d "
+ "provided.",
+ m_typeName.getBuffer(),
+ expectedCount,
+ count);
+ };
+ return baseObject->setSpecializationArgs(args, count);
+}
+
DebugObjectBase::DebugObjectBase()
{
static uint64_t uidCounter = 0;
uid = ++uidCounter;
}
+Result DebugRootShaderObject::setSpecializationArgs(
+ const slang::SpecializationArg* args,
+ uint32_t count)
+{
+ GFX_DIAGNOSE_ERROR("`setSpecializationArgs` should not be called directly on root objects.");
+ return baseObject->setSpecializationArgs(args, count);
+}
+
} // namespace gfx
diff --git a/tools/gfx/debug-layer.h b/tools/gfx/debug-layer.h
index a4e201e4f..f9ecc7dfe 100644
--- a/tools/gfx/debug-layer.h
+++ b/tools/gfx/debug-layer.h
@@ -167,6 +167,9 @@ public:
ShaderOffset const& offset,
IResourceView* textureView,
ISamplerState* sampler) override;
+ virtual SLANG_NO_THROW Result SLANG_MCALL setSpecializationArgs(
+ const slang::SpecializationArg* args,
+ uint32_t count) override;
public:
struct ShaderOffsetKey
@@ -188,6 +191,8 @@ public:
}
};
Slang::String m_typeName;
+ slang::TypeReflection* m_slangType = nullptr;
+ DebugDevice* m_device;
Slang::List<Slang::RefPtr<DebugShaderObject>> m_entryPoints;
Slang::Dictionary<ShaderOffsetKey, Slang::RefPtr<DebugShaderObject>> m_objects;
Slang::Dictionary<ShaderOffsetKey, Slang::RefPtr<DebugResourceView>> m_resources;
@@ -199,6 +204,8 @@ class DebugRootShaderObject : public DebugShaderObject
public:
virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ setSpecializationArgs(const slang::SpecializationArg* args, uint32_t count) override;
};
class DebugCommandBuffer;
diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h
index ba0327cf4..83799ac25 100644
--- a/tools/gfx/renderer-shared.h
+++ b/tools/gfx/renderer-shared.h
@@ -296,6 +296,11 @@ struct ExtendedShaderObjectTypeList
}
};
+struct ExtendedShaderObjectTypeListObject
+ : public ExtendedShaderObjectTypeList
+ , public Slang::RefObject
+{};
+
class ShaderObjectLayoutBase : public Slang::RefObject
{
protected:
@@ -471,6 +476,7 @@ protected:
// Specialization args for a StructuredBuffer object.
ExtendedShaderObjectTypeList m_structuredBufferSpecializationArgs;
+ Slang::RefPtr<ExtendedShaderObjectTypeListObject> m_userProvidedSpecializationArgs;
public:
TShaderObjectLayoutImpl* getLayout()
@@ -687,10 +693,51 @@ public:
return SLANG_OK;
}
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ setSpecializationArgs(const slang::SpecializationArg* args, uint32_t count) override
+ {
+ if (!m_userProvidedSpecializationArgs)
+ {
+ m_userProvidedSpecializationArgs = new ExtendedShaderObjectTypeListObject();
+ }
+ else
+ {
+ m_userProvidedSpecializationArgs->clear();
+ }
+ auto device = getRenderer();
+ for (uint32_t i = 0; i < count; i++)
+ {
+ gfx::ExtendedShaderObjectType extendedType;
+ switch (args[i].kind)
+ {
+ case slang::SpecializationArg::Kind::Type:
+ extendedType.slangType = args[i].type;
+ extendedType.componentID = device->shaderCache.getComponentId(args[i].type);
+ break;
+ default:
+ SLANG_ASSERT(false && "Unexpected specialization argument kind.");
+ return SLANG_FAIL;
+ }
+ m_userProvidedSpecializationArgs->add(extendedType);
+ }
+ return SLANG_OK;
+ }
+
// Appends all types that are used to specialize the element type of this shader object in
// `args` list.
virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override
{
+ if (m_userProvidedSpecializationArgs)
+ {
+ args.addRange(*m_userProvidedSpecializationArgs);
+ return SLANG_OK;
+ }
+ if (m_layout->getContainerType() != ShaderObjectContainerType::None)
+ {
+ args.addRange(m_structuredBufferSpecializationArgs);
+ return SLANG_OK;
+ }
+
auto device = getRenderer();
auto& subObjectRanges = getLayout()->getSubObjectRanges();
// The following logic is built on the assumption that all fields that involve
@@ -740,6 +787,8 @@ public:
}
case slang::BindingType::ParameterBlock:
case slang::BindingType::ConstantBuffer:
+ case slang::BindingType::RawBuffer:
+ case slang::BindingType::MutableRawBuffer:
// Currently we only handle the case where the field's type is
// `ParameterBlock<SomeStruct>` or `ConstantBuffer<SomeStruct>`, where
// `SomeStruct` is a struct type (not directly an interface type). In this case,
@@ -751,10 +800,6 @@ public:
// `ExistentialValue` case here, but currently we lack a mechanism to
// distinguish the two scenarios.
break;
- case slang::BindingType::RawBuffer:
- case slang::BindingType::MutableRawBuffer:
- typeArgs.addRange(subObject->m_structuredBufferSpecializationArgs);
- break;
}
auto addedTypeArgCountForCurrentRange = args.getCount() - oldArgsCount;