summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-16 17:11:54 -0700
committerGitHub <noreply@github.com>2022-08-16 17:11:54 -0700
commit42f49937ffa69c82e333e886952eed027e12340e (patch)
tree08e3e9821dd40e23476060215d589e29092adb53
parente68fab2bda5d979f8d991fc41122bb9aa71849a6 (diff)
Add gfx interface definition in Slang. (#2364)
* Add gfx interface definition in Slang. - add gfx interface definitons in Slang. - fix slang compiler to correctly type-check `out` interface argument. - modify gfx interface to be fully COM compatible - add convenient ShaderProgram creation methods to gfx. * Fix compile errors and warnings. * Update project files * Fix cuda. * Properly implement queryInterface in command encoder impls. Co-authored-by: Yong He <yhe@nvidia.com>
-rw-r--r--build/visual-studio/gfx/gfx.vcxproj4
-rw-r--r--build/visual-studio/gfx/gfx.vcxproj.filters8
-rw-r--r--examples/ray-tracing/main.cpp4
-rw-r--r--prelude/slang-cpp-host-prelude.h2
-rw-r--r--slang-com-ptr.h2
-rw-r--r--slang-gfx.h45
-rw-r--r--slang.h9
-rw-r--r--source/slang/core.meta.slang77
-rw-r--r--source/slang/slang-ast-type.h7
-rw-r--r--source/slang/slang-check-decl.cpp30
-rw-r--r--source/slang/slang-check-overload.cpp9
-rwxr-xr-xsource/slang/slang-compiler.h15
-rw-r--r--source/slang/slang-diagnostic-defs.h3
-rw-r--r--source/slang/slang-lower-to-ir.cpp20
-rw-r--r--tests/bugs/interface-lvalue.slang36
-rw-r--r--tests/bugs/interface-lvalue.slang.expected6
-rw-r--r--tools/gfx-unit-test/gfx-test-util.cpp2
-rw-r--r--tools/gfx-unit-test/instanced-draw-tests.cpp4
-rw-r--r--tools/gfx/command-encoder-com-forward.h260
-rw-r--r--tools/gfx/cuda/cuda-command-encoder.h25
-rw-r--r--tools/gfx/d3d12/d3d12-command-encoder.h40
-rw-r--r--tools/gfx/debug-layer/debug-command-encoder.h48
-rw-r--r--tools/gfx/debug-layer/debug-device.cpp18
-rw-r--r--tools/gfx/debug-layer/debug-device.h2
-rw-r--r--tools/gfx/debug-layer/debug-shader-program.cpp4
-rw-r--r--tools/gfx/debug-layer/debug-shader-program.h4
-rw-r--r--tools/gfx/gfx.slang1958
-rw-r--r--tools/gfx/immediate-renderer-base.cpp37
-rw-r--r--tools/gfx/renderer-shared.cpp62
-rw-r--r--tools/gfx/renderer-shared.h11
-rw-r--r--tools/gfx/slang.slang451
-rw-r--r--tools/gfx/vulkan/vk-command-encoder.h50
-rw-r--r--tools/render-test/render-test-main.cpp4
33 files changed, 3098 insertions, 159 deletions
diff --git a/build/visual-studio/gfx/gfx.vcxproj b/build/visual-studio/gfx/gfx.vcxproj
index e08630f11..e5ff57b1e 100644
--- a/build/visual-studio/gfx/gfx.vcxproj
+++ b/build/visual-studio/gfx/gfx.vcxproj
@@ -539,6 +539,10 @@
<ClCompile Include="..\..\..\tools\gfx\vulkan\vk-util.cpp" />
</ItemGroup>
<ItemGroup>
+ <None Include="..\..\..\tools\gfx\gfx.slang" />
+ <None Include="..\..\..\tools\gfx\slang.slang" />
+ </ItemGroup>
+ <ItemGroup>
<ProjectReference Include="..\core\core.vcxproj">
<Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
</ProjectReference>
diff --git a/build/visual-studio/gfx/gfx.vcxproj.filters b/build/visual-studio/gfx/gfx.vcxproj.filters
index b0fde63c7..1a7ed3d03 100644
--- a/build/visual-studio/gfx/gfx.vcxproj.filters
+++ b/build/visual-studio/gfx/gfx.vcxproj.filters
@@ -720,4 +720,12 @@
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\tools\gfx\gfx.slang">
+ <Filter>Source Files</Filter>
+ </None>
+ <None Include="..\..\..\tools\gfx\slang.slang">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/examples/ray-tracing/main.cpp b/examples/ray-tracing/main.cpp
index 82ad01c95..a12da707d 100644
--- a/examples/ray-tracing/main.cpp
+++ b/examples/ray-tracing/main.cpp
@@ -404,13 +404,13 @@ Slang::Result initialize()
IBufferResource::Desc asBufferDesc;
asBufferDesc.type = IResource::Type::Buffer;
asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = compactedSize;
+ asBufferDesc.sizeInBytes = (Size)compactedSize;
gBLASBuffer = gDevice->createBufferResource(asBufferDesc);
IAccelerationStructure::CreateDesc createDesc;
createDesc.buffer = gBLASBuffer;
createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
createDesc.offset = 0;
- createDesc.size = compactedSize;
+ createDesc.size = (Size)compactedSize;
gDevice->createAccelerationStructure(createDesc, gBLAS.writeRef());
commandBuffer = gTransientHeaps[0]->createCommandBuffer();
diff --git a/prelude/slang-cpp-host-prelude.h b/prelude/slang-cpp-host-prelude.h
index 37f28f8d6..3aec0dd07 100644
--- a/prelude/slang-cpp-host-prelude.h
+++ b/prelude/slang-cpp-host-prelude.h
@@ -5,6 +5,8 @@
#include <cmath>
#include <cstring>
+#define SLANG_COM_PTR_ENABLE_REF_OPERATOR 1
+
#include "../source/slang-rt/slang-rt.h"
#include "../slang-com-ptr.h"
#include "slang-cpp-types.h"
diff --git a/slang-com-ptr.h b/slang-com-ptr.h
index ced36d178..00cc9dbb1 100644
--- a/slang-com-ptr.h
+++ b/slang-com-ptr.h
@@ -111,7 +111,9 @@ public:
protected:
/// Gets the address of the dumb pointer.
// Disabled: use writeRef and readRef to get a reference based on usage.
+#ifndef SLANG_COM_PTR_ENABLE_REF_OPERATOR
SLANG_FORCE_INLINE T** operator&() = delete;
+#endif
T* m_ptr;
};
diff --git a/slang-gfx.h b/slang-gfx.h
index 962cd40a5..9d7ddaf71 100644
--- a/slang-gfx.h
+++ b/slang-gfx.h
@@ -130,6 +130,14 @@ const GfxCount kMaxRenderTargetCount = 8;
class ITransientResourceHeap;
+enum class ShaderModuleSourceType
+{
+ SlangSource, // a slang source string in memory.
+ SlangModuleBinary, // a slang module binary code in memory.
+ SlangSourceFile, // a slang source from file.
+ SlangModuleBinaryFile, // a slang module binary code from file.
+};
+
class IShaderProgram: public ISlangUnknown
{
public:
@@ -162,6 +170,22 @@ public:
// Each element must define only 1 Slang EntryPoint.
slang::IComponentType** slangEntryPoints = nullptr;
};
+
+ struct CreateDesc2
+ {
+ ShaderModuleSourceType sourceType;
+ void* sourceData;
+ Size sourceDataSize;
+
+ // Number of entry points to include in the shader program. 0 means include all entry points
+ // defined in the module.
+ GfxCount entryPointCount = 0;
+ // Names of entry points to include in the shader program. The size of the array must be
+ // `entryPointCount`.
+ const char** entryPointNames = nullptr;
+ };
+
+ virtual SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL findTypeByName(const char* name) = 0;
};
#define SLANG_UUID_IShaderProgram \
{ \
@@ -1516,8 +1540,9 @@ public:
{ 0xc2cc3784, 0x12da, 0x480a, { 0xa8, 0x74, 0x8b, 0x31, 0x96, 0x1c, 0xa4, 0x36 } }
-class ICommandEncoder
+class ICommandEncoder : public ISlangUnknown
{
+ SLANG_COM_INTERFACE( 0x77ea6383, 0xbe3d, 0x40aa, { 0x8b, 0x45, 0xfd, 0xf0, 0xd7, 0x5b, 0xfa, 0x34 });
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() = 0;
virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* queryPool, GfxIndex queryIndex) = 0;
@@ -1566,6 +1591,9 @@ struct ClearResourceViewFlags
class IResourceCommandEncoder : public ICommandEncoder
{
+ // {F99A00E9-ED50-4088-8A0E-3B26755031EA}
+ SLANG_COM_INTERFACE(0xf99a00e9, 0xed50, 0x4088, { 0x8a, 0xe, 0x3b, 0x26, 0x75, 0x50, 0x31, 0xea });
+
public:
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
IBufferResource* dst,
@@ -1646,6 +1674,8 @@ public:
class IRenderCommandEncoder : public IResourceCommandEncoder
{
+ // {7A8D56D0-53E6-4AD6-85F7-D14DC110FDCE}
+ SLANG_COM_INTERFACE(0x7a8d56d0, 0x53e6, 0x4ad6, { 0x85, 0xf7, 0xd1, 0x4d, 0xc1, 0x10, 0xfd, 0xce })
public:
// Sets the current pipeline state. This method returns a transient shader object for
// writing shader parameters. This shader object will not retain any resources or
@@ -1728,6 +1758,9 @@ public:
class IComputeCommandEncoder : public IResourceCommandEncoder
{
+ // {88AA9322-82F7-4FE6-A68A-29C7FE798737}
+ SLANG_COM_INTERFACE(0x88aa9322, 0x82f7, 0x4fe6, { 0xa6, 0x8a, 0x29, 0xc7, 0xfe, 0x79, 0x87, 0x37 })
+
public:
// Sets the current pipeline state. This method returns a transient shader object for
// writing shader parameters. This shader object will not retain any resources or
@@ -1765,6 +1798,7 @@ struct AccelerationStructureQueryDesc
class IRayTracingCommandEncoder : public IResourceCommandEncoder
{
+ SLANG_COM_INTERFACE(0x9a672b87, 0x5035, 0x45e3, { 0x96, 0x7c, 0x1f, 0x85, 0xcd, 0xb3, 0x63, 0x4f })
public:
virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure(
const IAccelerationStructure::BuildDesc& desc,
@@ -1799,10 +1833,6 @@ public:
GfxCount height,
GfxCount depth) = 0;
};
-#define SLANG_UUID_IRayTracingCommandEncoder \
- { \
- 0x9a672b87, 0x5035, 0x45e3, { 0x96, 0x7c, 0x1f, 0x85, 0xcd, 0xb3, 0x63, 0x4f } \
- }
class ICommandBuffer : public ISlangUnknown
{
@@ -2356,6 +2386,11 @@ public:
return program;
}
+ virtual SLANG_NO_THROW Result SLANG_MCALL createProgram2(
+ const IShaderProgram::CreateDesc2& createDesc,
+ IShaderProgram** outProgram,
+ ISlangBlob** outDiagnosticBlob = nullptr) = 0;
+
virtual SLANG_NO_THROW Result SLANG_MCALL createGraphicsPipelineState(
const GraphicsPipelineStateDesc& desc,
IPipelineState** outState) = 0;
diff --git a/slang.h b/slang.h
index 8d2b05e5a..9b6c71cf4 100644
--- a/slang.h
+++ b/slang.h
@@ -4449,6 +4449,15 @@ namespace slang
virtual SLANG_NO_THROW SlangResult SLANG_MCALL findEntryPointByName(
char const* name,
IEntryPoint** outEntryPoint) = 0;
+
+ /// Get number of entry points defined in the module. An entry point defined in a module
+ /// is by default not included in the linkage, so calls to `IComponentType::getEntryPointCount`
+ /// on an `IModule` instance will always return 0. However `IModule::getDefinedEntryPointCount`
+ /// will return the number of defined entry points.
+ virtual SLANG_NO_THROW SlangInt32 SLANG_MCALL getDefinedEntryPointCount() = 0;
+ /// Get the name of an entry point defined in the module.
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getDefinedEntryPoint(SlangInt32 index, IEntryPoint** outEntryPoint) = 0;
};
#define SLANG_UUID_IModule IModule::getTypeGuid()
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index d912fe8ce..42295eeca 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -428,6 +428,9 @@ extension bool
__implicit_conversion($(kConversionCost_PtrToBool))
__intrinsic_op($(kIROp_CastPtrToBool))
__init(Ptr<T> ptr);
+
+ static bool maxValue = true;
+ static bool minValue = false;
}
extension uint64_t
@@ -435,6 +438,9 @@ extension uint64_t
__generic<T>
__intrinsic_op($(kIROp_Construct))
__init(Ptr<T> ptr);
+
+ static uint64_t maxValue = 0xFFFFFFFFFFFFFFFFULL;
+ static uint64_t minValue = 0;
}
extension int64_t
@@ -442,6 +448,9 @@ extension int64_t
__generic<T>
__intrinsic_op($(kIROp_Construct))
__init(Ptr<T> ptr);
+
+ static int64_t maxValue = 0x7FFFFFFFFFFFFFFFLL;
+ static int64_t minValue = -0x8000000000000000LL;
}
__generic<T>
@@ -509,6 +518,28 @@ bool operator!=(__none_t noneVal, Optional<T> val)
return val.hasValue;
}
+__generic<T>
+__magic_type(NativeRefType)
+__intrinsic_type($(kIROp_NativePtrType))
+struct NativeRef
+{
+ __intrinsic_op($(kIROp_GetNativePtr))
+ __init(T val);
+};
+
+__generic<T>
+__intrinsic_op($(kIROp_ManagedPtrAttach))
+void __managed_ptr_attach(__ref T val, NativeRef<T> nativeVal);
+
+__generic<T>
+[__unsafeForceInlineEarly]
+T __attachToNativeRef(NativeRef<T> nativeVal)
+{
+ T result;
+ __managed_ptr_attach(result, nativeVal);
+ return result;
+}
+
__magic_type(StringType)
__intrinsic_type($(kIROp_StringType))
struct String
@@ -524,6 +555,52 @@ __intrinsic_type($(kIROp_DynamicType))
struct __Dynamic
{};
+extension float
+{
+ static float maxValue = 340282346638528859811704183484516925440.0f;
+}
+
+extension double
+{
+ static double maxValue = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0;
+}
+
+extension int
+{
+ static int maxValue = 2147483647;
+ static int minValue = -2147483648;
+}
+
+extension uint
+{
+ static uint maxValue = 4294967295;
+ static uint minValue = 0;
+}
+
+extension int8_t
+{
+ static int8_t maxValue = 127;
+ static int8_t minValue = -128;
+}
+
+extension uint16_t
+{
+ static uint16_t maxValue = 255;
+ static uint16_t minValue = 0;
+}
+
+extension int16_t
+{
+ static int16_t maxValue = 32767;
+ static int16_t minValue = -32768;
+}
+
+extension uint16_t
+{
+ static uint16_t maxValue = 65535;
+ static uint16_t minValue = 0;
+}
+
/// An `N` component vector with elements of type `T`.
__generic<T = float, let N : int = 4>
__magic_type(Vector)
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index 0ee0fce2c..458c24a23 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -583,6 +583,13 @@ class OptionalType : public BuiltinType
Type* getValueType();
};
+// A raw-pointer reference to an managed value.
+class NativeRefType : public BuiltinType
+{
+ SLANG_AST_CLASS(NativeRefType)
+ Type* getValueType();
+};
+
// A type alias of some kind (e.g., via `typedef`)
class NamedExpressionType : public Type
{
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 22567c889..f2a339643 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -3063,10 +3063,37 @@ namespace Slang
InheritanceDecl* inheritanceDecl,
ContainerDecl* parentDecl)
{
+ auto superType = inheritanceDecl->base.type;
+
if( auto declRefType = as<DeclRefType>(subType) )
{
auto declRef = declRefType->declRef;
+ if (auto superDeclRefType = as<DeclRefType>(superType))
+ {
+ auto superTypeDecl = superDeclRefType->declRef.getDecl();
+ if (superTypeDecl->findModifier<ComInterfaceAttribute>())
+ {
+ // A struct cannot implement a COM Interface.
+ if (auto classDecl = as<ClassDecl>(superTypeDecl))
+ {
+ // OK.
+ SLANG_UNUSED(classDecl);
+ }
+ else if (auto subInterfaceDecl = as<InterfaceDecl>(superTypeDecl))
+ {
+ if (!subInterfaceDecl->findModifier<ComInterfaceAttribute>())
+ {
+ getSink()->diagnose(inheritanceDecl, Diagnostics::interfaceInheritingComMustBeCom);
+ }
+ }
+ else if (auto structDecl = as<StructDecl>(superTypeDecl))
+ {
+ getSink()->diagnose(inheritanceDecl, Diagnostics::structCannotImplementComInterface);
+ }
+ }
+ }
+
// Don't check conformances for abstract types that
// are being used to express *required* conformances.
if (auto assocTypeDeclRef = declRef.as<AssocTypeDecl>())
@@ -3089,11 +3116,12 @@ namespace Slang
// code to work.
return true;
}
+
+
}
// Look at the type being inherited from, and validate
// appropriately.
- auto superType = inheritanceDecl->base.type;
DeclaredSubtypeWitness* subIsSuperWitness = m_astBuilder->create<DeclaredSubtypeWitness>();
subIsSuperWitness->declRef = makeDeclRef(inheritanceDecl);
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 879c49da0..36c93a2e2 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -1443,8 +1443,15 @@ namespace Slang
arg = maybeOpenRef(arg);
}
- for (auto& arg : expr->arguments)
+ auto funcType = as<FuncType>(funcExprType);
+ for (Index i = 0; i < expr->arguments.getCount(); i++)
{
+ auto& arg = expr->arguments[i];
+ if (funcType && i < (Index)funcType->getParamCount())
+ {
+ if (funcType->getParamDirection(i) == kParameterDirection_Out)
+ continue;
+ }
arg = maybeOpenExistential(arg);
}
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 97111f540..0dbaa9099 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1210,6 +1210,21 @@ namespace Slang
return SLANG_OK;
}
+ virtual SlangInt32 SLANG_MCALL getDefinedEntryPointCount() override
+ {
+ return (SlangInt32)m_entryPoints.getCount();
+ }
+
+ virtual SlangResult SLANG_MCALL getDefinedEntryPoint(SlangInt32 index, slang::IEntryPoint** outEntryPoint) override
+ {
+ if (index < 0 || index >= m_entryPoints.getCount())
+ return SLANG_E_INVALID_ARG;
+
+ ComPtr<slang::IEntryPoint> entryPoint(m_entryPoints[index].Ptr());
+ *outEntryPoint = entryPoint.detach();
+ return SLANG_OK;
+ }
+
//
/// Create a module (initially empty).
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 6acd27e40..0fa5d64a7 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -324,6 +324,9 @@ DIAGNOSTIC(31121, Error, anyValueSizeExceedsLimit, "'anyValueSize' cannot exceed
DIAGNOSTIC(31122, Error, associatedTypeNotAllowInComInterface, "associatedtype not allowed in a [COM] interface")
DIAGNOSTIC(31123, Error, invalidGUID, "'$0' is not a valid GUID")
+DIAGNOSTIC(31124, Error, structCannotImplementComInterface, "a struct type cannot implement a [COM] interface")
+DIAGNOSTIC(31124, Error, interfaceInheritingComMustBeCom, "an interface type that inherits from a [COM] interface must itself be a [COM] interface")
+
// Enums
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 81ea93f77..1f3da064a 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -8180,16 +8180,16 @@ bool canDeclLowerToAGeneric(Decl* decl)
static bool isInterfaceRequirement(Decl* decl)
{
- auto ancestor = decl->parentDecl;
- for(; ancestor; ancestor = ancestor->parentDecl )
- {
- if(as<InterfaceDecl>(ancestor))
- return true;
-
- if(as<ExtensionDecl>(ancestor))
- return false;
- }
- return false;
+ auto ancestor = decl->parentDecl;
+ for (; ancestor; ancestor = ancestor->parentDecl)
+ {
+ if (as<InterfaceDecl>(ancestor))
+ return true;
+
+ if (as<ExtensionDecl>(ancestor))
+ return false;
+ }
+ return false;
}
/// Add flattened "leaf" elements from `val` to the `ioArgs` list
diff --git a/tests/bugs/interface-lvalue.slang b/tests/bugs/interface-lvalue.slang
new file mode 100644
index 000000000..87cfa54ed
--- /dev/null
+++ b/tests/bugs/interface-lvalue.slang
@@ -0,0 +1,36 @@
+//TEST:EXECUTABLE:
+__target_intrinsic(cpp, "printf(\"%s\\n\", ($0).getBuffer())")
+void writeln(String text);
+
+[COM("BE18F5D2-4522-4AB0-A6EE-1D157FA2B083")]
+interface IFoo
+{
+ int method();
+};
+
+class Impl : IFoo
+{
+ __init() { }
+ int method()
+ {
+ return 0;
+ }
+}
+
+void createFoo(out IFoo val)
+{
+ Impl resuult = new Impl();
+ val = resuult;
+}
+
+public __extern_cpp int main()
+{
+ IFoo v;
+ createFoo(v);
+
+ if (v.method() == 0)
+ writeln("succ");
+ else
+ writeln("fail");
+ return 0;
+}
diff --git a/tests/bugs/interface-lvalue.slang.expected b/tests/bugs/interface-lvalue.slang.expected
new file mode 100644
index 000000000..981dcfc29
--- /dev/null
+++ b/tests/bugs/interface-lvalue.slang.expected
@@ -0,0 +1,6 @@
+result code = 0
+standard error = {
+}
+standard output = {
+succ
+}
diff --git a/tools/gfx-unit-test/gfx-test-util.cpp b/tools/gfx-unit-test/gfx-test-util.cpp
index e9f683524..9a6a7c4f6 100644
--- a/tools/gfx-unit-test/gfx-test-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-util.cpp
@@ -151,7 +151,7 @@ namespace gfx_test
void compareComputeResultFuzzy(const float* result, float* expectedResult, size_t expectedBufferSize)
{
- for (int i = 0; i < expectedBufferSize / sizeof(float); ++i)
+ for (size_t i = 0; i < expectedBufferSize / sizeof(float); ++i)
{
SLANG_CHECK(abs(result[i] - expectedResult[i]) <= 0.01);
}
diff --git a/tools/gfx-unit-test/instanced-draw-tests.cpp b/tools/gfx-unit-test/instanced-draw-tests.cpp
index 1e2fa1037..6491e8944 100644
--- a/tools/gfx-unit-test/instanced-draw-tests.cpp
+++ b/tools/gfx-unit-test/instanced-draw-tests.cpp
@@ -387,7 +387,7 @@ namespace gfx_test
encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
uint32_t maxDrawCount = 1;
- uint64_t argOffset = offsetof(IndirectArgData, args);
+ Offset argOffset = offsetof(IndirectArgData, args);
encoder->drawIndirect(maxDrawCount, indirectBuffer, argOffset);
encoder->endEncoding();
@@ -464,7 +464,7 @@ namespace gfx_test
encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
uint32_t maxDrawCount = 1;
- uint64_t argOffset = offsetof(IndexedIndirectArgData, args);
+ Offset argOffset = offsetof(IndexedIndirectArgData, args);
encoder->drawIndexedIndirect(maxDrawCount, indirectBuffer, argOffset);
encoder->endEncoding();
diff --git a/tools/gfx/command-encoder-com-forward.h b/tools/gfx/command-encoder-com-forward.h
index 50539cba1..9a26b0590 100644
--- a/tools/gfx/command-encoder-com-forward.h
+++ b/tools/gfx/command-encoder-com-forward.h
@@ -1,124 +1,142 @@
#pragma once
-#define SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderBase) \
- virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( \
- IBufferResource* dst, \
- Offset dstOffset, \
- IBufferResource* src, \
- Offset srcOffset, \
- Size size) override \
- { \
- ResourceCommandEncoderBase::copyBuffer(dst, dstOffset, src, srcOffset, size); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL copyTexture( \
- ITextureResource* dst, \
- ResourceState dstState, \
- SubresourceRange dstSubresource, \
- ITextureResource::Offset3D dstOffset, \
- ITextureResource* src, \
- ResourceState srcState, \
- SubresourceRange srcSubresource, \
- ITextureResource::Offset3D srcOffset, \
- ITextureResource::Extents extent) override \
- { \
- ResourceCommandEncoderBase::copyTexture( \
- dst, \
- dstState, \
- dstSubresource, \
- dstOffset, \
- src, \
- srcState, \
- srcSubresource, \
- srcOffset, \
- extent); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( \
- IBufferResource* dst, \
- Offset dstOffset, \
- Size dstSize, \
- Size dstRowStride, \
- ITextureResource* src, \
- ResourceState srcState, \
- SubresourceRange srcSubresource, \
- ITextureResource::Offset3D srcOffset, \
- ITextureResource::Extents extent) override \
- { \
- ResourceCommandEncoderBase::copyTextureToBuffer( \
- dst, dstOffset, dstSize, dstRowStride, src, srcState, srcSubresource, srcOffset, extent); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL uploadTextureData( \
- ITextureResource* dst, \
- SubresourceRange subResourceRange, \
- ITextureResource::Offset3D offset, \
- ITextureResource::Extents extent, \
- ITextureResource::SubresourceData* subResourceData, \
- GfxCount subResourceDataCount) override \
- { \
- ResourceCommandEncoderBase::uploadTextureData( \
- dst, subResourceRange, offset, extent, subResourceData, subResourceDataCount); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL uploadBufferData( \
- IBufferResource* dst, Offset offset, Size size, void* data) override \
- { \
- ResourceCommandEncoderBase::uploadBufferData(dst, offset, size, data); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier( \
- GfxCount count, ITextureResource* const* textures, ResourceState src, ResourceState dst) \
- override \
- { \
- ResourceCommandEncoderBase::textureBarrier(count, textures, src, dst); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier( \
- ITextureResource* texture, \
- SubresourceRange subresourceRange, \
- ResourceState src, \
- ResourceState dst) override \
- { \
- ResourceCommandEncoderBase::textureSubresourceBarrier( \
- texture, subresourceRange, src, dst); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier( \
- GfxCount count, IBufferResource* const* buffers, ResourceState src, ResourceState dst) \
- override \
- { \
- ResourceCommandEncoderBase::bufferBarrier(count, buffers, src, dst); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView( \
- IResourceView* view, ClearValue* clearValue, ClearResourceViewFlags::Enum flags) override \
- { \
- ResourceCommandEncoderBase::clearResourceView(view, clearValue, flags); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( \
- ITextureResource* source, \
- ResourceState sourceState, \
- SubresourceRange sourceRange, \
- ITextureResource* dest, \
- ResourceState destState, \
- SubresourceRange destRange) override \
- { \
- ResourceCommandEncoderBase::resolveResource( \
- source, sourceState, sourceRange, dest, destState, destRange); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL resolveQuery( \
- IQueryPool* queryPool, \
- GfxIndex index, \
- GfxCount count, \
- IBufferResource* buffer, \
- Offset offset) override \
- { \
- ResourceCommandEncoderBase::resolveQuery(queryPool, index, count, buffer, offset); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, GfxIndex index) \
- override \
- { \
- ResourceCommandEncoderBase::writeTimestamp(pool, index); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL beginDebugEvent(const char* name, float rgbColor[3]) \
- override \
- { \
- ResourceCommandEncoderBase::beginDebugEvent(name, rgbColor); \
- } \
- virtual SLANG_NO_THROW void SLANG_MCALL endDebugEvent() override \
- { \
- ResourceCommandEncoderBase::endDebugEvent(); \
+#define SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderBase) \
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface( \
+ SlangUUID const& uuid, void** outObject) override \
+ { \
+ return ResourceCommandEncoderBase::queryInterface(uuid, outObject); \
+ } \
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override \
+ { \
+ return ResourceCommandEncoderBase::addRef(); \
+ } \
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override \
+ { \
+ return ResourceCommandEncoderBase::release(); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( \
+ IBufferResource* dst, Offset dstOffset, IBufferResource* src, Offset srcOffset, Size size) \
+ override \
+ { \
+ ResourceCommandEncoderBase::copyBuffer(dst, dstOffset, src, srcOffset, size); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL copyTexture( \
+ ITextureResource* dst, \
+ ResourceState dstState, \
+ SubresourceRange dstSubresource, \
+ ITextureResource::Offset3D dstOffset, \
+ ITextureResource* src, \
+ ResourceState srcState, \
+ SubresourceRange srcSubresource, \
+ ITextureResource::Offset3D srcOffset, \
+ ITextureResource::Extents extent) override \
+ { \
+ ResourceCommandEncoderBase::copyTexture( \
+ dst, \
+ dstState, \
+ dstSubresource, \
+ dstOffset, \
+ src, \
+ srcState, \
+ srcSubresource, \
+ srcOffset, \
+ extent); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( \
+ IBufferResource* dst, \
+ Offset dstOffset, \
+ Size dstSize, \
+ Size dstRowStride, \
+ ITextureResource* src, \
+ ResourceState srcState, \
+ SubresourceRange srcSubresource, \
+ ITextureResource::Offset3D srcOffset, \
+ ITextureResource::Extents extent) override \
+ { \
+ ResourceCommandEncoderBase::copyTextureToBuffer( \
+ dst, \
+ dstOffset, \
+ dstSize, \
+ dstRowStride, \
+ src, \
+ srcState, \
+ srcSubresource, \
+ srcOffset, \
+ extent); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL uploadTextureData( \
+ ITextureResource* dst, \
+ SubresourceRange subResourceRange, \
+ ITextureResource::Offset3D offset, \
+ ITextureResource::Extents extent, \
+ ITextureResource::SubresourceData* subResourceData, \
+ GfxCount subResourceDataCount) override \
+ { \
+ ResourceCommandEncoderBase::uploadTextureData( \
+ dst, subResourceRange, offset, extent, subResourceData, subResourceDataCount); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL uploadBufferData( \
+ IBufferResource* dst, Offset offset, Size size, void* data) override \
+ { \
+ ResourceCommandEncoderBase::uploadBufferData(dst, offset, size, data); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier( \
+ GfxCount count, ITextureResource* const* textures, ResourceState src, ResourceState dst) \
+ override \
+ { \
+ ResourceCommandEncoderBase::textureBarrier(count, textures, src, dst); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier( \
+ ITextureResource* texture, \
+ SubresourceRange subresourceRange, \
+ ResourceState src, \
+ ResourceState dst) override \
+ { \
+ ResourceCommandEncoderBase::textureSubresourceBarrier( \
+ texture, subresourceRange, src, dst); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier( \
+ GfxCount count, IBufferResource* const* buffers, ResourceState src, ResourceState dst) \
+ override \
+ { \
+ ResourceCommandEncoderBase::bufferBarrier(count, buffers, src, dst); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView( \
+ IResourceView* view, ClearValue* clearValue, ClearResourceViewFlags::Enum flags) override \
+ { \
+ ResourceCommandEncoderBase::clearResourceView(view, clearValue, flags); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( \
+ ITextureResource* source, \
+ ResourceState sourceState, \
+ SubresourceRange sourceRange, \
+ ITextureResource* dest, \
+ ResourceState destState, \
+ SubresourceRange destRange) override \
+ { \
+ ResourceCommandEncoderBase::resolveResource( \
+ source, sourceState, sourceRange, dest, destState, destRange); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL resolveQuery( \
+ IQueryPool* queryPool, \
+ GfxIndex index, \
+ GfxCount count, \
+ IBufferResource* buffer, \
+ Offset offset) override \
+ { \
+ ResourceCommandEncoderBase::resolveQuery(queryPool, index, count, buffer, offset); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, GfxIndex index) \
+ override \
+ { \
+ ResourceCommandEncoderBase::writeTimestamp(pool, index); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL beginDebugEvent(const char* name, float rgbColor[3]) \
+ override \
+ { \
+ ResourceCommandEncoderBase::beginDebugEvent(name, rgbColor); \
+ } \
+ virtual SLANG_NO_THROW void SLANG_MCALL endDebugEvent() override \
+ { \
+ ResourceCommandEncoderBase::endDebugEvent(); \
}
diff --git a/tools/gfx/cuda/cuda-command-encoder.h b/tools/gfx/cuda/cuda-command-encoder.h
index 73660534a..9b7e94c8c 100644
--- a/tools/gfx/cuda/cuda-command-encoder.h
+++ b/tools/gfx/cuda/cuda-command-encoder.h
@@ -15,6 +15,25 @@ class ResourceCommandEncoderImpl : public IResourceCommandEncoder
public:
CommandWriter* m_writer;
+ virtual void* getInterface(SlangUUID const& uuid)
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ queryInterface(SlangUUID const& uuid, void** outObject) override
+ {
+ if (auto ptr = getInterface(uuid))
+ {
+ *outObject = ptr;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; }
+
void init(CommandBufferImpl* cmdBuffer);
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {}
@@ -111,6 +130,12 @@ class ComputeCommandEncoderImpl
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IComputeCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
public:
CommandWriter* m_writer;
CommandBufferImpl* m_commandBuffer;
diff --git a/tools/gfx/d3d12/d3d12-command-encoder.h b/tools/gfx/d3d12/d3d12-command-encoder.h
index bf2f7710b..5dd9909f8 100644
--- a/tools/gfx/d3d12/d3d12-command-encoder.h
+++ b/tools/gfx/d3d12/d3d12-command-encoder.h
@@ -52,6 +52,25 @@ class ResourceCommandEncoderImpl
, public PipelineCommandEncoder
{
public:
+ virtual void* getInterface(SlangUUID const& uuid)
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ queryInterface(SlangUUID const& uuid, void** outObject)
+ {
+ if (auto ptr = getInterface(uuid))
+ {
+ *outObject = ptr;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; }
+
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
IBufferResource* dst,
Offset dstOffset,
@@ -138,6 +157,13 @@ class ComputeCommandEncoderImpl
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IComputeCommandEncoder || uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
void init(
@@ -169,6 +195,13 @@ class RenderCommandEncoderImpl
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IRenderCommandEncoder || uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+
public:
RefPtr<RenderPassLayoutImpl> m_renderPass;
RefPtr<FramebufferImpl> m_framebuffer;
@@ -266,6 +299,13 @@ class RayTracingCommandEncoderImpl
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IRayTracingCommandEncoder || uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+
public:
virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure(
const IAccelerationStructure::BuildDesc& desc,
diff --git a/tools/gfx/debug-layer/debug-command-encoder.h b/tools/gfx/debug-layer/debug-command-encoder.h
index 8a0ffbfdb..b53a11074 100644
--- a/tools/gfx/debug-layer/debug-command-encoder.h
+++ b/tools/gfx/debug-layer/debug-command-encoder.h
@@ -15,7 +15,18 @@ public:
virtual DebugCommandBuffer* getCommandBuffer() = 0;
virtual bool getIsOpen() = 0;
virtual IResourceCommandEncoder* getBaseResourceEncoder() = 0;
-
+ virtual void* getInterface(SlangUUID const& uuid) = 0;
+ SlangResult queryInterface(SlangUUID const& uuid, void** outObject)
+ {
+ if (auto ptr = getInterface(uuid))
+ {
+ *outObject = ptr;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ uint32_t addRef() { return 1; }
+ uint32_t release() { return 1; }
public:
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
IBufferResource* dst,
@@ -97,6 +108,14 @@ public:
virtual DebugCommandBuffer* getCommandBuffer() override { return commandBuffer; }
virtual bool getIsOpen() override { return isOpen; }
virtual IResourceCommandEncoder* getBaseResourceEncoder() override { return baseObject; }
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IComputeCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
@@ -122,7 +141,14 @@ public:
virtual DebugCommandBuffer* getCommandBuffer() override { return commandBuffer; }
virtual bool getIsOpen() override { return isOpen; }
virtual IResourceCommandEncoder* getBaseResourceEncoder() override { return baseObject; }
-
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
@@ -144,7 +170,14 @@ public:
}
virtual bool getIsOpen() override { return isOpen; }
virtual IResourceCommandEncoder* getBaseResourceEncoder() override { return baseObject; }
-
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IRenderCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
virtual SLANG_NO_THROW Result SLANG_MCALL
@@ -212,7 +245,14 @@ public:
virtual DebugCommandBuffer* getCommandBuffer() override { return commandBuffer; }
virtual bool getIsOpen() override { return isOpen; }
virtual IResourceCommandEncoder* getBaseResourceEncoder() override { return baseObject; }
-
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IRayTracingCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure(
diff --git a/tools/gfx/debug-layer/debug-device.cpp b/tools/gfx/debug-layer/debug-device.cpp
index aae7f9cea..356c875d4 100644
--- a/tools/gfx/debug-layer/debug-device.cpp
+++ b/tools/gfx/debug-layer/debug-device.cpp
@@ -448,10 +448,26 @@ Result DebugDevice::createProgram(
{
SLANG_GFX_API_FUNC;
- RefPtr<DebugShaderProgram> outObject = new DebugShaderProgram(desc);
+ RefPtr<DebugShaderProgram> outObject = new DebugShaderProgram();
auto result = baseObject->createProgram(desc, outObject->baseObject.writeRef(), outDiagnostics);
if (SLANG_FAILED(result))
return result;
+ outObject->m_slangProgram = desc.slangGlobalScope;
+ returnComPtr(outProgram, outObject);
+ return result;
+}
+
+Result DebugDevice::createProgram2(
+ const IShaderProgram::CreateDesc2& desc, IShaderProgram** outProgram, ISlangBlob** outDiagnostics)
+{
+ SLANG_GFX_API_FUNC;
+ IShaderProgram::Desc desc1 = {};
+ RefPtr<DebugShaderProgram> outObject = new DebugShaderProgram();
+ auto result = baseObject->createProgram2(desc, outObject->baseObject.writeRef(), outDiagnostics);
+ if (SLANG_FAILED(result))
+ return result;
+ auto base = static_cast<ShaderProgramBase*>(outObject->baseObject.get());
+ outObject->m_slangProgram = base->desc.slangGlobalScope;
returnComPtr(outProgram, outObject);
return result;
}
diff --git a/tools/gfx/debug-layer/debug-device.h b/tools/gfx/debug-layer/debug-device.h
index 83a67428f..db07cdd1b 100644
--- a/tools/gfx/debug-layer/debug-device.h
+++ b/tools/gfx/debug-layer/debug-device.h
@@ -104,6 +104,8 @@ public:
createMutableRootShaderObject(IShaderProgram* program, IShaderObject** outObject) override;
virtual SLANG_NO_THROW Result SLANG_MCALL
createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram, ISlangBlob** outDiagnostics) override;
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ createProgram2(const IShaderProgram::CreateDesc2& desc, IShaderProgram** outProgram, ISlangBlob** outDiagnostics) override;
virtual SLANG_NO_THROW Result SLANG_MCALL createGraphicsPipelineState(
const GraphicsPipelineStateDesc& desc,
IPipelineState** outState) override;
diff --git a/tools/gfx/debug-layer/debug-shader-program.cpp b/tools/gfx/debug-layer/debug-shader-program.cpp
index 264087abd..745fc8691 100644
--- a/tools/gfx/debug-layer/debug-shader-program.cpp
+++ b/tools/gfx/debug-layer/debug-shader-program.cpp
@@ -8,9 +8,9 @@ using namespace Slang;
namespace debug
{
-DebugShaderProgram::DebugShaderProgram(const IShaderProgram::Desc& desc)
+slang::TypeReflection* DebugShaderProgram::findTypeByName(const char* name)
{
- m_slangProgram = desc.slangGlobalScope;
+ return baseObject->findTypeByName(name);
}
} // namespace debug
diff --git a/tools/gfx/debug-layer/debug-shader-program.h b/tools/gfx/debug-layer/debug-shader-program.h
index 050ee8e3c..0f154f2a3 100644
--- a/tools/gfx/debug-layer/debug-shader-program.h
+++ b/tools/gfx/debug-layer/debug-shader-program.h
@@ -16,9 +16,7 @@ public:
public:
IShaderProgram* getInterface(const Slang::Guid& guid);
-
- DebugShaderProgram(const IShaderProgram::Desc& desc);
-
+ virtual SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL findTypeByName(const char* name) override;
public:
Slang::ComPtr<slang::IComponentType> m_slangProgram;
};
diff --git a/tools/gfx/gfx.slang b/tools/gfx/gfx.slang
new file mode 100644
index 000000000..1561ac2a8
--- /dev/null
+++ b/tools/gfx/gfx.slang
@@ -0,0 +1,1958 @@
+import slang;
+
+namespace gfx
+{
+typedef slang.Result Result;
+
+typedef int64_t Int;
+typedef uint64_t UInt;
+typedef uint64_t DeviceAddress;
+typedef int GfxIndex;
+typedef int GfxCount;
+typedef uint64_t Size;
+typedef uint64_t Offset;
+
+const uint64_t kTimeoutInfinite = 0xFFFFFFFFFFFFFFFF;
+
+enum class StructType
+{
+ D3D12ExtendedDesc,
+};
+
+enum class StageType
+{
+ Unknown,
+ Vertex,
+ Hull,
+ Domain,
+ Geometry,
+ Fragment,
+ Compute,
+ RayGeneration,
+ Intersection,
+ AnyHit,
+ ClosestHit,
+ Miss,
+ Callable,
+ Amplification,
+ Mesh,
+ CountOf,
+};
+
+enum class DeviceType
+{
+ Unknown,
+ Default,
+ DirectX11,
+ DirectX12,
+ OpenGl,
+ Vulkan,
+ CPU,
+ CUDA,
+ CountOf,
+};
+
+enum class ProjectionStyle
+{
+ Unknown,
+ OpenGl,
+ DirectX,
+ Vulkan,
+ CountOf,
+};
+
+enum class BindingStyle
+{
+ Unknown,
+ DirectX,
+ OpenGl,
+ Vulkan,
+ CPU,
+ CUDA,
+ CountOf,
+};
+
+enum class AccessFlag
+{
+ None,
+ Read,
+ Write,
+};
+
+static const GfxCount kMaxRenderTargetCount = 8;
+
+// Defines how linking should be performed for a shader program.
+enum class LinkingStyle
+{
+ // Compose all entry-points in a single program, then compile all entry-points together with the same
+ // set of root shader arguments.
+ SingleProgram,
+
+ // Link and compile each entry-point individually, potentially with different specializations.
+ SeparateEntryPointCompilation
+};
+
+enum class ShaderModuleSourceType
+{
+ SlangSource, // a slang source string in memory.
+ SlangModuleBinary, // a slang module binary code in memory.
+ SlangSourceFile, // a slang source from file.
+ SlangModuleBinaryFile, // a slang module binary code from file.
+};
+
+struct ShaderProgramDesc2
+{
+ ShaderModuleSourceType sourceType;
+ void *sourceData;
+ Size sourceDataSize;
+
+ // Number of entry points to include in the shader program. 0 means include all entry points
+ // defined in the module.
+ GfxCount entryPointCount = 0;
+ // Names of entry points to include in the shader program. The size of the array must be
+ // `entryPointCount`.
+ NativeString* entryPointNames = nullptr;
+};
+
+[COM("9d32d0ad-915c-4ffd-91e2-508554a04a76")]
+interface IShaderProgram
+{
+ slang::TypeReflection* findTypeByName(NativeString name);
+};
+
+enum class Format
+{
+ // D3D formats omitted: 19-22, 44-47, 65-66, 68-70, 73, 76, 79, 82, 88-89, 92-94, 97, 100-114
+ // These formats are omitted due to lack of a corresponding Vulkan format. D24_UNORM_S8_UINT (DXGI_FORMAT 45)
+ // has a matching Vulkan format but is also omitted as it is only supported by Nvidia.
+ Unknown,
+
+ R32G32B32A32_TYPELESS,
+ R32G32B32_TYPELESS,
+ R32G32_TYPELESS,
+ R32_TYPELESS,
+
+ R16G16B16A16_TYPELESS,
+ R16G16_TYPELESS,
+ R16_TYPELESS,
+
+ R8G8B8A8_TYPELESS,
+ R8G8_TYPELESS,
+ R8_TYPELESS,
+ B8G8R8A8_TYPELESS,
+
+ R32G32B32A32_FLOAT,
+ R32G32B32_FLOAT,
+ R32G32_FLOAT,
+ R32_FLOAT,
+
+ R16G16B16A16_FLOAT,
+ R16G16_FLOAT,
+ R16_FLOAT,
+
+ R32G32B32A32_UINT,
+ R32G32B32_UINT,
+ R32G32_UINT,
+ R32_UINT,
+
+ R16G16B16A16_UINT,
+ R16G16_UINT,
+ R16_UINT,
+
+ R8G8B8A8_UINT,
+ R8G8_UINT,
+ R8_UINT,
+
+ R32G32B32A32_SINT,
+ R32G32B32_SINT,
+ R32G32_SINT,
+ R32_SINT,
+
+ R16G16B16A16_SINT,
+ R16G16_SINT,
+ R16_SINT,
+
+ R8G8B8A8_SINT,
+ R8G8_SINT,
+ R8_SINT,
+
+ R16G16B16A16_UNORM,
+ R16G16_UNORM,
+ R16_UNORM,
+
+ R8G8B8A8_UNORM,
+ R8G8B8A8_UNORM_SRGB,
+ R8G8_UNORM,
+ R8_UNORM,
+ B8G8R8A8_UNORM,
+ B8G8R8A8_UNORM_SRGB,
+ B8G8R8X8_UNORM,
+ B8G8R8X8_UNORM_SRGB,
+
+ R16G16B16A16_SNORM,
+ R16G16_SNORM,
+ R16_SNORM,
+
+ R8G8B8A8_SNORM,
+ R8G8_SNORM,
+ R8_SNORM,
+
+ D32_FLOAT,
+ D16_UNORM,
+
+ B4G4R4A4_UNORM,
+ B5G6R5_UNORM,
+ B5G5R5A1_UNORM,
+
+ R9G9B9E5_SHAREDEXP,
+ R10G10B10A2_TYPELESS,
+ R10G10B10A2_UNORM,
+ R10G10B10A2_UINT,
+ R11G11B10_FLOAT,
+
+ BC1_UNORM,
+ BC1_UNORM_SRGB,
+ BC2_UNORM,
+ BC2_UNORM_SRGB,
+ BC3_UNORM,
+ BC3_UNORM_SRGB,
+ BC4_UNORM,
+ BC4_SNORM,
+ BC5_UNORM,
+ BC5_SNORM,
+ BC6H_UF16,
+ BC6H_SF16,
+ BC7_UNORM,
+ BC7_UNORM_SRGB,
+
+ _Count,
+};
+
+struct FormatInfo
+{
+ GfxCount channelCount; ///< The amount of channels in the format. Only set if the channelType is set
+ uint8_t channelType; ///< One of SlangScalarType None if type isn't made up of elements of type. TODO: Change to uint32_t?
+
+ Size blockSizeInBytes; ///< The size of a block in bytes.
+ GfxCount pixelsPerBlock; ///< The number of pixels contained in a block.
+ GfxCount blockWidth; ///< The width of a block in pixels.
+ GfxCount blockHeight; ///< The height of a block in pixels.
+};
+
+enum class InputSlotClass
+{
+ PerVertex, PerInstance
+};
+
+struct InputElementDesc
+{
+ NativeString semanticName; ///< The name of the corresponding parameter in shader code.
+ GfxIndex semanticIndex; ///< The index of the corresponding parameter in shader code. Only needed if multiple parameters share a semantic name.
+ Format format; ///< The format of the data being fetched for this element.
+ Offset offset; ///< The offset in bytes of this element from the start of the corresponding chunk of vertex stream data.
+ GfxIndex bufferSlotIndex; ///< The index of the vertex stream to fetch this element's data from.
+};
+
+struct VertexStreamDesc
+{
+ Size stride; ///< The stride in bytes for this vertex stream.
+ InputSlotClass slotClass; ///< Whether the stream contains per-vertex or per-instance data.
+ GfxCount instanceDataStepRate; ///< How many instances to draw per chunk of data.
+};
+
+enum class PrimitiveType
+{
+ Point, Line, Triangle, Patch
+};
+
+enum class PrimitiveTopology
+{
+ TriangleList, TriangleStrip, PointList, LineList, LineStrip
+};
+
+enum class ResourceState
+{
+ Undefined,
+ General,
+ PreInitialized,
+ VertexBuffer,
+ IndexBuffer,
+ ConstantBuffer,
+ StreamOutput,
+ ShaderResource,
+ UnorderedAccess,
+ RenderTarget,
+ DepthRead,
+ DepthWrite,
+ Present,
+ IndirectArgument,
+ CopySource,
+ CopyDestination,
+ ResolveSource,
+ ResolveDestination,
+ AccelerationStructure,
+ AccelerationStructureBuildInput,
+ _Count
+};
+
+struct ResourceStateSet
+{
+ uint64_t m_bitFields;
+
+ [mutating]
+ void add(ResourceState state) { m_bitFields |= (1LL << (uint32_t)state); }
+
+ bool contains(ResourceState state) { return (m_bitFields & (1LL << (uint32_t)state)) != 0; }
+ __init() { m_bitFields = 0; }
+ __init(ResourceState state) { add(state); }
+};
+
+ResourceStateSet operator &(ResourceStateSet val, ResourceStateSet that)
+{
+ ResourceStateSet result;
+ result.m_bitFields = val.m_bitFields & that.m_bitFields;
+ return result;
+}
+
+/// Describes how memory for the resource should be allocated for CPU access.
+enum class MemoryType
+{
+ DeviceLocal,
+ Upload,
+ ReadBack,
+};
+
+enum class InteropHandleAPI
+{
+ Unknown,
+ D3D12, // A D3D12 object pointer.
+ Vulkan, // A general Vulkan object handle.
+ CUDA, // A general CUDA object handle.
+ Win32, // A general Win32 HANDLE.
+ FileDescriptor, // A file descriptor.
+ DeviceAddress, // A device address.
+ D3D12CpuDescriptorHandle, // A D3D12_CPU_DESCRIPTOR_HANDLE value.
+};
+
+struct InteropHandle
+{
+ InteropHandleAPI api = InteropHandleAPI::Unknown;
+ uint64_t handleValue;
+};
+
+// Declare opaque type
+struct InputLayoutDesc
+{
+ InputElementDesc *inputElements;
+ GfxCount inputElementCount;
+ VertexStreamDesc *vertexStreams;
+ GfxCount vertexStreamCount;
+};
+
+[COM("45223711-a84b-455c-befa-4937421e8e2e")]
+interface IInputLayout
+{
+};
+
+/// The type of resource.
+/// NOTE! The order needs to be such that all texture types are at or after Texture1D (otherwise isTexture won't work correctly)
+enum class ResourceType
+{
+ Unknown, ///< Unknown
+ Buffer, ///< A buffer (like a constant/index/vertex buffer)
+ Texture1D, ///< A 1d texture
+ Texture2D, ///< A 2d texture
+ Texture3D, ///< A 3d texture
+ TextureCube, ///< A cubemap consists of 6 Texture2D like faces
+ _Count,
+};
+
+/// Base class for Descs
+struct ResourceDescBase
+{
+ ResourceType type;
+ ResourceState defaultState;
+ ResourceStateSet allowedStates;
+ MemoryType memoryType;
+ InteropHandle existingHandle;
+ bool isShared;
+};
+
+[COM("a0e39f34-8398-4522-95c2-ebc0f984ef3f")]
+interface IResource
+{
+ ResourceType getType();
+ Result getNativeResourceHandle(out InteropHandle outHandle);
+ Result getSharedHandle(out InteropHandle outHandle);
+ Result setDebugName(NativeString name);
+ NativeString getDebugName();
+};
+
+struct MemoryRange
+{
+ // TODO: Change to Offset/Size?
+ uint64_t offset;
+ uint64_t size;
+};
+
+struct BufferResourceDesc : ResourceDescBase
+{
+ Size sizeInBytes = 0; ///< Total size in bytes
+ Size elementSize = 0; ///< Get the element stride. If > 0, this is a structured buffer
+ Format format = Format::Unknown;
+};
+
+[COM("1b274efe-5e37-492b-826e-7ee7e8f5a49b")]
+interface IBufferResource : IResource
+{
+ BufferResourceDesc *getDesc();
+ DeviceAddress getDeviceAddress();
+ Result map(MemoryRange* rangeToRead, void** outPointer);
+ Result unmap(MemoryRange* writtenRange);
+};
+
+struct DepthStencilClearValue
+{
+ float depth = 1.0f;
+ uint32_t stencil = 0;
+};
+
+struct ColorClearValue
+{
+ float4 values;
+
+ [mutating]
+ void setValue(uint4 uintVal)
+ {
+ values = reinterpret<float4, uint4>(uintVal);
+ }
+
+ [mutating]
+ void setValue(float4 floatVal)
+ {
+ values = floatVal;
+ }
+};
+
+struct ClearValue
+{
+ ColorClearValue color;
+ DepthStencilClearValue depthStencil;
+};
+
+struct BufferRange
+{
+ // TODO: Change to Index and Count?
+ uint64_t firstElement;
+ uint64_t elementCount;
+};
+
+enum class TextureAspect : uint32_t
+{
+ Default = 0,
+ Color = 0x00000001,
+ Depth = 0x00000002,
+ Stencil = 0x00000004,
+ MetaData = 0x00000008,
+ Plane0 = 0x00000010,
+ Plane1 = 0x00000020,
+ Plane2 = 0x00000040,
+
+ DepthStencil = 0x6,
+};
+
+struct SubresourceRange
+{
+ TextureAspect aspectMask;
+ GfxIndex mipLevel;
+ GfxCount mipLevelCount;
+ GfxIndex baseArrayLayer; // For Texture3D, this is WSlice.
+ GfxCount layerCount; // For cube maps, this is a multiple of 6.
+};
+
+static const Size kRemainingTextureSize = 0xFFFFFFFF;
+struct TextureResourceSampleDesc
+{
+ GfxCount numSamples; ///< Number of samples per pixel
+ int quality; ///< The quality measure for the samples
+};
+
+struct TextureResourceDesc : ResourceDescBase
+{
+ int3 size;
+
+ GfxCount arraySize = 0; ///< Array size
+
+ GfxCount numMipLevels = 0; ///< Number of mip levels - if 0 will create all mip levels
+ Format format; ///< The resources format
+ TextureResourceSampleDesc sampleDesc; ///< How the resource is sampled
+ ClearValue optimalClearValue;
+};
+
+/// Data for a single subresource of a texture.
+///
+/// Each subresource is a tensor with `1 <= rank <= 3`,
+/// where the rank is deterined by the base shape of the
+/// texture (Buffer, 1D, 2D, 3D, or Cube). For the common
+/// case of a 2D texture, `rank == 2` and each subresource
+/// is a 2D image.
+///
+/// Subresource tensors must be stored in a row-major layout,
+/// so that the X axis strides over texels, the Y axis strides
+/// over 1D rows of texels, and the Z axis strides over 2D
+/// "layers" of texels.
+///
+/// For a texture with multiple mip levels or array elements,
+/// each mip level and array element is stores as a distinct
+/// subresource. When indexing into an array of subresources,
+/// the index of a subresoruce for mip level `m` and array
+/// index `a` is `m + a*mipLevelCount`.
+///
+struct SubresourceData
+{
+ /// Pointer to texel data for the subresource tensor.
+ void *data;
+
+ /// Stride in bytes between rows of the subresource tensor.
+ ///
+ /// This is the number of bytes to add to a pointer to a texel
+ /// at (X,Y,Z) to get to a texel at (X,Y+1,Z).
+ ///
+ /// Devices may not support all possible values for `strideY`.
+ /// In particular, they may only support strictly positive strides.
+ ///
+ gfx::Size strideY;
+
+ /// Stride in bytes between layers of the subresource tensor.
+ ///
+ /// This is the number of bytes to add to a pointer to a texel
+ /// at (X,Y,Z) to get to a texel at (X,Y,Z+1).
+ ///
+ /// Devices may not support all possible values for `strideZ`.
+ /// In particular, they may only support strictly positive strides.
+ ///
+ gfx::Size strideZ;
+};
+
+[COM("cf88a31c-6187-46c5-a4b7-eb-58-c7-33-40-17")]
+interface ITextureResource : IResource
+{
+ TextureResourceDesc* getDesc();
+};
+
+enum class ComparisonFunc : uint8_t
+{
+ Never = 0x0,
+ Less = 0x1,
+ Equal = 0x2,
+ LessEqual = 0x3,
+ Greater = 0x4,
+ NotEqual = 0x5,
+ GreaterEqual = 0x6,
+ Always = 0x7,
+};
+
+enum class TextureFilteringMode
+{
+ Point,
+ Linear,
+};
+
+enum class TextureAddressingMode
+{
+ Wrap,
+ ClampToEdge,
+ ClampToBorder,
+ MirrorRepeat,
+ MirrorOnce,
+};
+
+enum class TextureReductionOp
+{
+ Average,
+ Comparison,
+ Minimum,
+ Maximum,
+};
+
+struct SamplerStateDesc
+{
+ TextureFilteringMode minFilter;
+ TextureFilteringMode magFilter;
+ TextureFilteringMode mipFilter;
+ TextureReductionOp reductionOp;
+ TextureAddressingMode addressU;
+ TextureAddressingMode addressV;
+ TextureAddressingMode addressW;
+ float mipLODBias;
+ uint32_t maxAnisotropy;
+ ComparisonFunc comparisonFunc;
+ float4 borderColor;
+ float minLOD;
+ float maxLOD;
+ __init()
+ {
+ minFilter = TextureFilteringMode::Linear;
+ magFilter = TextureFilteringMode::Linear;
+ mipFilter = TextureFilteringMode::Linear;
+ reductionOp = TextureReductionOp::Average;
+ addressU = TextureAddressingMode::Wrap;
+ addressV = TextureAddressingMode::Wrap;
+ addressW = TextureAddressingMode::Wrap;
+ mipLODBias = 0.0f;
+ maxAnisotropy = 1;
+ comparisonFunc = ComparisonFunc::Never;
+ borderColor = float4(1.0f, 1.0f, 1.0f, 1.0f);
+ minLOD = -float.maxValue;
+ maxLOD = float.maxValue;
+ }
+};
+
+[COM("8b8055df-9377-401d-91ff-3f-a3-bf-66-64-f4")]
+interface ISamplerState
+{
+ /// Returns a native API handle representing this sampler state object.
+ /// When using D3D12, this will be a D3D12_CPU_DESCRIPTOR_HANDLE.
+ /// When using Vulkan, this will be a VkSampler.
+ Result getNativeHandle(InteropHandle *outNativeHandle);
+};
+
+enum class ResourceViewType
+{
+ Unknown,
+
+ RenderTarget,
+ DepthStencil,
+ ShaderResource,
+ UnorderedAccess,
+ AccelerationStructure,
+
+ CountOf_,
+};
+
+struct RenderTargetDesc
+{
+ // The resource shape of this render target view.
+ ResourceType shape;
+};
+
+struct ResourceViewDesc
+{
+ ResourceViewType type;
+ Format format;
+
+ // Required fields for `RenderTarget` and `DepthStencil` views.
+ RenderTargetDesc renderTarget;
+ // Specifies the range of a texture resource for a ShaderRsource/UnorderedAccess/RenderTarget/DepthStencil view.
+ SubresourceRange subresourceRange;
+ // Specifies the range of a buffer resource for a ShaderResource/UnorderedAccess view.
+ BufferRange bufferRange;
+ // Specifies the element size in bytes of a structured buffer. Pass 0 for a raw buffer view.
+ Size bufferElementSize;
+};
+
+[COM("7b6c4926-0884-408c-ad8a-50-3a-8e-23-98-a4")]
+interface IResourceView
+{
+ ResourceViewDesc* getViewDesc();
+
+ /// Returns a native API handle representing this resource view object.
+ /// When using D3D12, this will be a D3D12_CPU_DESCRIPTOR_HANDLE or a buffer device address depending
+ /// on the type of the resource view.
+ /// When using Vulkan, this will be a VkImageView, VkBufferView, VkAccelerationStructure or a VkBuffer
+ /// depending on the type of the resource view.
+ Result getNativeHandle(InteropHandle *outNativeHandle);
+};
+
+enum class AccelerationStructureKind
+{
+ TopLevel,
+ BottomLevel
+};
+
+// The enum values are intentionally consistent with
+// D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS.
+enum AccelerationStructureBuildFlags
+{
+ None,
+ AllowUpdate = 1,
+ AllowCompaction = 2,
+ PreferFastTrace = 4,
+ PreferFastBuild = 8,
+ MinimizeMemory = 16,
+ PerformUpdate = 32
+};
+
+enum class GeometryType
+{
+ Triangles, ProcedurePrimitives
+};
+
+struct GeometryFlags
+{
+ // The enum values are intentionally consistent with
+ // D3D12_RAYTRACING_GEOMETRY_FLAGS.
+ enum Enum
+ {
+ None,
+ Opaque = 1,
+ NoDuplicateAnyHitInvocation = 2
+ };
+};
+
+struct TriangleDesc
+{
+ DeviceAddress transform3x4;
+ Format indexFormat;
+ Format vertexFormat;
+ GfxCount indexCount;
+ GfxCount vertexCount;
+ DeviceAddress indexData;
+ DeviceAddress vertexData;
+ Size vertexStride;
+};
+
+struct ProceduralAABB
+{
+ float minX;
+ float minY;
+ float minZ;
+ float maxX;
+ float maxY;
+ float maxZ;
+};
+
+struct ProceduralAABBDesc
+{
+ /// Number of AABBs.
+ GfxCount count;
+
+ /// Pointer to an array of `ProceduralAABB` values in device memory.
+ DeviceAddress data;
+
+ /// Stride in bytes of the AABB values array.
+ Size stride;
+};
+
+struct GeometryDesc
+{
+ GeometryType type;
+ GeometryFlags::Enum flags;
+ TriangleDesc triangles;
+ property ProceduralAABBDesc proceduralAABBs
+ {
+ get { return reinterpret<ProceduralAABBDesc, TriangleDesc>(triangles); }
+ set { triangles = reinterpret<TriangleDesc, ProceduralAABBDesc>(newValue); }
+ }
+};
+
+// The enum values are kept consistent with D3D12_RAYTRACING_INSTANCE_FLAGS
+// and VkGeometryInstanceFlagBitsKHR.
+enum GeometryInstanceFlags
+{
+ None = 0,
+ TriangleFacingCullDisable = 0x00000001,
+ TriangleFrontCounterClockwise = 0x00000002,
+ ForceOpaque = 0x00000004,
+ NoOpaque = 0x00000008
+};
+
+// TODO: Should any of these be changed?
+// The layout of this struct is intentionally consistent with D3D12_RAYTRACING_INSTANCE_DESC
+// and VkAccelerationStructureInstanceKHR.
+struct InstanceDesc
+{
+ float transform[3][4];
+ uint32_t instanceID24_mask8;
+ property uint32_t instanceID { get { return instanceID24_mask8 & 0xFFFFFF; } set { instanceID24_mask8 = (instanceID24_mask8 & 0xFF000000) | (newValue & 0xFFFFFF); } }
+ property uint32_t instanceMask { get { return instanceID24_mask8 >> 24; } set { instanceID24_mask8 = (newValue << 24) | (instanceID24_mask8 & 0x00FFFFFF); } }
+
+ uint32_t instanceContributionToHitGroupIndex24_flags8;
+ property uint32_t instanceContributionToHitGroupIndex
+ {
+ get { return instanceContributionToHitGroupIndex24_flags8 & 0xFFFFFF; }
+ set { instanceContributionToHitGroupIndex24_flags8 = (instanceContributionToHitGroupIndex24_flags8 & 0xFF000000) | (newValue & 0xFFFFFF); }
+ }
+ property GeometryInstanceFlags flags
+ {
+ get { return (GeometryInstanceFlags)(instanceContributionToHitGroupIndex24_flags8 >> 24); }
+ set { instanceContributionToHitGroupIndex24_flags8 = ((uint32_t)newValue << 24) | (instanceContributionToHitGroupIndex24_flags8 & 0x00FFFFFF); }
+ }
+ DeviceAddress accelerationStructure;
+};
+
+struct AccelerationStructurePrebuildInfo
+{
+ Size resultDataMaxSize;
+ Size scratchDataSize;
+ Size updateScratchDataSize;
+};
+
+struct AccelerationStructureBuildInputs
+{
+ AccelerationStructureKind kind;
+
+ AccelerationStructureBuildFlags flags;
+
+ GfxCount descCount;
+
+ /// Array of `InstanceDesc` values in device memory.
+ /// Used when `kind` is `TopLevel`.
+ DeviceAddress instanceDescs;
+
+ /// Array of `GeometryDesc` values.
+ /// Used when `kind` is `BottomLevel`.
+ GeometryDesc *geometryDescs;
+};
+
+struct AccelerationStructureCreateDesc
+{
+ AccelerationStructureKind kind;
+ IBufferResource *buffer;
+ Offset offset;
+ Size size;
+};
+
+struct AccelerationStructureBuildDesc
+{
+ AccelerationStructureBuildInputs inputs;
+ IAccelerationStructure *source;
+ IAccelerationStructure *dest;
+ DeviceAddress scratchData;
+};
+
+[COM("a5cdda3c-1d4e-4df7-8ef2-b7-3f-ce-04-de-3b")]
+interface IAccelerationStructure : IResourceView
+{
+ DeviceAddress getDeviceAddress();
+};
+
+struct FenceDesc
+{
+ uint64_t initialValue;
+ bool isShared;
+};
+
+[COM("7fe1c283-d3f4-48ed-aaf3-01-51-96-4e-7c-b5")]
+interface IFence
+{
+ /// Returns the currently signaled value on the device.
+ Result getCurrentValue(uint64_t *outValue);
+
+ /// Signals the fence from the host with the specified value.
+ Result setCurrentValue(uint64_t value);
+
+ Result getSharedHandle(InteropHandle *outHandle);
+ Result getNativeHandle(InteropHandle *outNativeHandle);
+};
+
+struct ShaderOffset
+{
+ Int uniformOffset = 0; // TODO: Change to Offset?
+ GfxIndex bindingRangeIndex = 0;
+ GfxIndex bindingArrayIndex = 0;
+}
+
+enum class ShaderObjectContainerType
+{
+ None, Array, StructuredBuffer
+};
+
+[COM("c1fa997e-5ca2-45ae-9bcb-c4-35-9e-85-05-85")]
+interface IShaderObject
+{
+ slang::TypeLayoutReflection* getElementTypeLayout();
+ ShaderObjectContainerType getContainerType();
+ GfxCount getEntryPointCount();
+ Result getEntryPoint(GfxIndex index, out IShaderObject entryPoint);
+ Result setData(ShaderOffset* offset, void *data, Size size);
+ Result getObject(ShaderOffset* offset, out IShaderObject object);
+ Result setObject(ShaderOffset* offset, IShaderObject object);
+ Result setResource(ShaderOffset* offset, IResourceView resourceView);
+ Result setSampler(ShaderOffset* offset, ISamplerState sampler);
+ Result setCombinedTextureSampler(ShaderOffset* offset, IResourceView textureView, ISamplerState sampler);
+
+ /// Manually overrides the specialization argument for the sub-object binding at `offset`.
+ /// Specialization arguments are passed to the shader compiler to specialize the type
+ /// of interface-typed shader parameters.
+ Result setSpecializationArgs(
+ ShaderOffset* offset,
+ slang::SpecializationArg *args,
+ GfxCount count);
+
+ Result getCurrentVersion(
+ ITransientResourceHeap transientHeap,
+ out IShaderObject outObject);
+
+ void* getRawData();
+
+ Size getSize();
+
+ /// Use the provided constant buffer instead of the internally created one.
+ Result setConstantBufferOverride(IBufferResource *constantBuffer);
+};
+
+enum class StencilOp : uint8_t
+{
+ Keep,
+ Zero,
+ Replace,
+ IncrementSaturate,
+ DecrementSaturate,
+ Invert,
+ IncrementWrap,
+ DecrementWrap,
+};
+
+enum class FillMode : uint8_t
+{
+ Solid,
+ Wireframe,
+};
+
+enum class CullMode : uint8_t
+{
+ None,
+ Front,
+ Back,
+};
+
+enum class FrontFaceMode : uint8_t
+{
+ CounterClockwise,
+ Clockwise,
+};
+
+struct DepthStencilOpDesc
+{
+ StencilOp stencilFailOp = StencilOp::Keep;
+ StencilOp stencilDepthFailOp = StencilOp::Keep;
+ StencilOp stencilPassOp = StencilOp::Keep;
+ ComparisonFunc stencilFunc = ComparisonFunc::Always;
+ __init()
+ {
+ stencilFailOp = StencilOp::Keep;
+ stencilDepthFailOp = StencilOp::Keep;
+ stencilPassOp = StencilOp::Keep;
+ stencilFunc = ComparisonFunc::Always;
+ }
+};
+
+struct DepthStencilDesc
+{
+ bool depthTestEnable = false;
+ bool depthWriteEnable = true;
+ ComparisonFunc depthFunc = ComparisonFunc::Less;
+
+ bool stencilEnable = false;
+ uint32_t stencilReadMask = 0xFFFFFFFF;
+ uint32_t stencilWriteMask = 0xFFFFFFFF;
+ DepthStencilOpDesc frontFace;
+ DepthStencilOpDesc backFace;
+
+ uint32_t stencilRef = 0;
+
+ __init()
+ {
+ depthTestEnable = false;
+ depthWriteEnable = true;
+ depthFunc = ComparisonFunc::Less;
+ stencilEnable = false;
+ stencilReadMask = 0xFFFFFFFF;
+ stencilWriteMask = 0xFFFFFFFF;
+ stencilRef = 0;
+ }
+};
+
+struct RasterizerDesc
+{
+ FillMode fillMode = FillMode::Solid;
+ CullMode cullMode = CullMode::None;
+ FrontFaceMode frontFace = FrontFaceMode::CounterClockwise;
+ int32_t depthBias = 0;
+ float depthBiasClamp = 0.0f;
+ float slopeScaledDepthBias = 0.0f;
+ bool depthClipEnable = true;
+ bool scissorEnable = false;
+ bool multisampleEnable = false;
+ bool antialiasedLineEnable = false;
+ bool enableConservativeRasterization = false;
+ uint32_t forcedSampleCount = 0;
+
+ __init()
+ {
+ fillMode = FillMode::Solid;
+ cullMode = CullMode::None;
+ frontFace = FrontFaceMode::CounterClockwise;
+ depthBias = 0;
+ depthBiasClamp = 0.0f;
+ slopeScaledDepthBias = 0.0f;
+ depthClipEnable = true;
+ scissorEnable = false;
+ multisampleEnable = false;
+ antialiasedLineEnable = false;
+ enableConservativeRasterization = false;
+ forcedSampleCount = 0;
+ }
+};
+
+enum class LogicOp
+{
+ NoOp,
+};
+
+enum class BlendOp
+{
+ Add,
+ Subtract,
+ ReverseSubtract,
+ Min,
+ Max,
+};
+
+enum class BlendFactor
+{
+ Zero,
+ One,
+ SrcColor,
+ InvSrcColor,
+ SrcAlpha,
+ InvSrcAlpha,
+ DestAlpha,
+ InvDestAlpha,
+ DestColor,
+ InvDestColor,
+ SrcAlphaSaturate,
+ BlendColor,
+ InvBlendColor,
+ SecondarySrcColor,
+ InvSecondarySrcColor,
+ SecondarySrcAlpha,
+ InvSecondarySrcAlpha,
+};
+
+enum RenderTargetWriteMask
+{
+ EnableNone = 0,
+ EnableRed = 0x01,
+ EnableGreen = 0x02,
+ EnableBlue = 0x04,
+ EnableAlpha = 0x08,
+ EnableAll = 0x0F,
+};
+
+struct AspectBlendDesc
+{
+ BlendFactor srcFactor = BlendFactor::One;
+ BlendFactor dstFactor = BlendFactor::Zero;
+ BlendOp op = BlendOp::Add;
+
+ __init()
+ {
+ srcFactor = BlendFactor::One;
+ dstFactor = BlendFactor::Zero;
+ }
+};
+
+struct TargetBlendDesc
+{
+ AspectBlendDesc color;
+ AspectBlendDesc alpha;
+ bool enableBlend;
+ LogicOp logicOp;
+ RenderTargetWriteMask writeMask;
+ __init()
+ {
+ enableBlend = false;
+ logicOp = LogicOp::NoOp;
+ writeMask = RenderTargetWriteMask::EnableAll;
+ }
+};
+
+struct BlendDesc
+{
+ TargetBlendDesc targets[kMaxRenderTargetCount];
+ GfxCount targetCount;
+
+ bool alphaToCoverageEnable;
+};
+
+struct FramebufferTargetLayout
+{
+ Format format;
+ GfxCount sampleCount;
+};
+
+struct FramebufferLayoutDesc
+{
+ GfxCount renderTargetCount;
+ FramebufferTargetLayout *renderTargets;
+ FramebufferTargetLayout *depthStencil;
+};
+
+[COM("0a838785-c13a-4832-ad88-64-06-b5-4b-5e-ba")]
+interface IFramebufferLayout
+{
+};
+
+struct GraphicsPipelineStateDesc
+{
+ NativeRef<IShaderProgram> program;
+
+ NativeRef<IInputLayout> inputLayout;
+ NativeRef<IFramebufferLayout> framebufferLayout;
+ PrimitiveType primitiveType;
+ DepthStencilDesc depthStencil;
+ RasterizerDesc rasterizer;
+ BlendDesc blend;
+
+ __init()
+ {
+ primitiveType = PrimitiveType::Triangle;
+ }
+};
+
+struct ComputePipelineStateDesc
+{
+ NativeRef<IShaderProgram> program;
+ void *d3d12RootSignatureOverride;
+};
+
+enum RayTracingPipelineFlags
+{
+ None = 0,
+ SkipTriangles = 1,
+ SkipProcedurals = 2,
+};
+
+struct HitGroupDesc
+{
+ NativeString hitGroupName;
+ NativeString closestHitEntryPoint;
+ NativeString anyHitEntryPoint;
+ NativeString intersectionEntryPoint;
+};
+
+struct RayTracingPipelineStateDesc
+{
+ NativeRef<IShaderProgram> program;
+ GfxCount hitGroupCount = 0;
+ HitGroupDesc *hitGroups;
+ int maxRecursion = 0;
+ Size maxRayPayloadSize = 0;
+ Size maxAttributeSizeInBytes = 8;
+ RayTracingPipelineFlags flags = RayTracingPipelineFlags::None;
+};
+
+// Specifies the bytes to overwrite into a record in the shader table.
+struct ShaderRecordOverwrite
+{
+ Offset offset; // Offset within the shader record.
+ Size size; // Number of bytes to overwrite.
+ uint8_t data[8]; // Content to overwrite.
+};
+
+struct ShaderTableDesc
+{
+ GfxCount rayGenShaderCount;
+ NativeString* rayGenShaderEntryPointNames;
+ ShaderRecordOverwrite *rayGenShaderRecordOverwrites;
+
+ GfxCount missShaderCount;
+ NativeString* missShaderEntryPointNames;
+ ShaderRecordOverwrite *missShaderRecordOverwrites;
+
+ GfxCount hitGroupCount;
+ NativeString* hitGroupNames;
+ ShaderRecordOverwrite *hitGroupRecordOverwrites;
+
+ NativeRef<IShaderProgram> program;
+};
+
+[COM("a721522c-df31-4c2f-a5e7-3b-e0-12-4b-31-78")]
+interface IShaderTable
+{
+
+};
+
+[COM("0ca7e57d-8a90-44f3-bdb1-fe-9b-35-3f-5a-72")]
+interface IPipelineState
+{
+ Result getNativeHandle(InteropHandle *outHandle);
+};
+
+struct ScissorRect
+{
+ int32_t minX;
+ int32_t minY;
+ int32_t maxX;
+ int32_t maxY;
+};
+
+struct Viewport
+{
+ float originX = 0.0f;
+ float originY = 0.0f;
+ float extentX = 0.0f;
+ float extentY = 0.0f;
+ float minZ = 0.0f;
+ float maxZ = 1.0f;
+};
+
+struct FramebufferDesc
+{
+ GfxCount renderTargetCount;
+ NativeRef<IResourceView> *renderTargetViews;
+ NativeRef<IResourceView> depthStencilView;
+ NativeRef<IFramebufferLayout> layout;
+};
+
+[COM("0f0c0d9a-4ef3-4e18-9ba9-34-60-ea-69-87-95")]
+interface IFramebuffer
+{
+};
+
+enum class WindowHandleType
+{
+ Unknown,
+ Win32Handle,
+ XLibHandle,
+};
+
+struct WindowHandle
+{
+ WindowHandleType type;
+ void* handleValues[2];
+ static WindowHandle fromHwnd(void *hwnd)
+ {
+ WindowHandle handle = {};
+ handle.type = WindowHandleType::Win32Handle;
+ handle.handleValues[0] = hwnd;
+ return handle;
+ }
+ static WindowHandle fromXWindow(void *xdisplay, uint32_t xwindow)
+ {
+ WindowHandle handle = {};
+ handle.type = WindowHandleType::XLibHandle;
+ handle.handleValues[0] = xdisplay;
+ handle.handleValues[1] = (void*)xwindow;
+ return handle;
+ }
+};
+
+enum FaceMask
+{
+ Front = 1, Back = 2
+};
+
+enum class TargetLoadOp
+{
+ Load, Clear, DontCare
+};
+enum class TargetStoreOp
+{
+ Store, DontCare
+};
+struct TargetAccessDesc
+{
+ TargetLoadOp loadOp;
+ TargetLoadOp stencilLoadOp;
+ TargetStoreOp storeOp;
+ TargetStoreOp stencilStoreOp;
+ ResourceState initialState;
+ ResourceState finalState;
+};
+struct RenderPassLayoutDesc
+{
+ NativeRef<IFramebufferLayout> framebufferLayout;
+ GfxCount renderTargetCount;
+ TargetAccessDesc *renderTargetAccess;
+ TargetAccessDesc *depthStencilAccess;
+};
+
+[COM("daab0b1a-f45d-4ae9-bf2c-e0-bb-76-7d-fa-d1")]
+interface IRenderPassLayout
+{
+};
+
+enum class QueryType
+{
+ Timestamp,
+ AccelerationStructureCompactedSize,
+ AccelerationStructureSerializedSize,
+ AccelerationStructureCurrentSize,
+};
+
+struct QueryPoolDesc
+{
+ QueryType type;
+ GfxCount count;
+};
+
+[COM("c2cc3784-12da-480a-a874-8b-31-96-1c-a4-36")]
+interface IQueryPool
+{
+ Result getResult(GfxIndex queryIndex, GfxCount count, uint64_t *data);
+ Result reset();
+};
+
+[COM("77ea6383-be3d-40aa-8b45-fd-f0-d7-5b-fa-34")]
+interface ICommandEncoder
+{
+ void endEncoding();
+ void writeTimestamp(IQueryPool *queryPool, GfxIndex queryIndex);
+};
+
+struct IndirectDispatchArguments
+{
+ GfxCount ThreadGroupCountX;
+ GfxCount ThreadGroupCountY;
+ GfxCount ThreadGroupCountZ;
+};
+
+struct IndirectDrawArguments
+{
+ GfxCount VertexCountPerInstance;
+ GfxCount InstanceCount;
+ GfxIndex StartVertexLocation;
+ GfxIndex StartInstanceLocation;
+};
+
+struct IndirectDrawIndexedArguments
+{
+ GfxCount IndexCountPerInstance;
+ GfxCount InstanceCount;
+ GfxIndex StartIndexLocation;
+ GfxIndex BaseVertexLocation;
+ GfxIndex StartInstanceLocation;
+};
+
+struct SamplePosition
+{
+ int8_t x;
+ int8_t y;
+};
+
+enum ClearResourceViewFlags
+{
+ None = 0,
+ ClearDepth = 1,
+ ClearStencil = 2,
+ FloatClearValues = 4
+};
+
+[COM("F99A00E9-ED50-4088-8A0E-3B26755031EA")]
+interface IResourceCommandEncoder : ICommandEncoder
+{
+ void copyBuffer(
+ IBufferResource dst,
+ Offset dstOffset,
+ IBufferResource src,
+ Offset srcOffset,
+ Size size);
+ /// Copies texture from src to dst. If dstSubresource and srcSubresource has mipLevelCount = 0
+ /// and layerCount = 0, the entire resource is being copied and dstOffset, srcOffset and extent
+ /// arguments are ignored.
+ void copyTexture(
+ ITextureResource dst,
+ ResourceState dstState,
+ SubresourceRange dstSubresource,
+ int3 dstOffset,
+ ITextureResource *src,
+ ResourceState srcState,
+ SubresourceRange srcSubresource,
+ int3 srcOffset,
+ int3 extent);
+
+ /// Copies texture to a buffer. Each row is aligned to kTexturePitchAlignment.
+ void copyTextureToBuffer(
+ IBufferResource dst,
+ Offset dstOffset,
+ Size dstSize,
+ Size dstRowStride,
+ ITextureResource src,
+ ResourceState srcState,
+ SubresourceRange srcSubresource,
+ int3 srcOffset,
+ int3 extent);
+ void uploadTextureData(
+ ITextureResource dst,
+ SubresourceRange subResourceRange,
+ int3 offset,
+ int3 extent,
+ SubresourceData *subResourceData,
+ GfxCount subResourceDataCount);
+ void uploadBufferData(IBufferResource dst, Offset offset, Size size, void *data);
+ void textureBarrier(
+ GfxCount count, NativeRef<ITextureResource> *textures, ResourceState src, ResourceState dst);
+ void textureSubresourceBarrier(
+ ITextureResource texture,
+ SubresourceRange subresourceRange,
+ ResourceState src,
+ ResourceState dst);
+ void bufferBarrier(
+ GfxCount count, NativeRef<IBufferResource>* buffers, ResourceState src, ResourceState dst);
+ void clearResourceView(
+ IResourceView view, ClearValue *clearValue, ClearResourceViewFlags flags);
+ void resolveResource(
+ ITextureResource source,
+ ResourceState sourceState,
+ SubresourceRange sourceRange,
+ ITextureResource dest,
+ ResourceState destState,
+ SubresourceRange destRange);
+ void resolveQuery(
+ IQueryPool queryPool,
+ GfxIndex index,
+ GfxCount count,
+ IBufferResource buffer,
+ Offset offset);
+ void beginDebugEvent(NativeString name, float rgbColor[3]);
+ void endDebugEvent();
+};
+
+[COM("7A8D56D0-53E6-4AD6-85F7-D14DC110FDCE")]
+interface IRenderCommandEncoder : IResourceCommandEncoder
+{
+ // Sets the current pipeline state. This method returns a transient shader object for
+ // writing shader parameters. This shader object will not retain any resources or
+ // sub-shader-objects bound to it. The user must be responsible for ensuring that any
+ // resources or shader objects that is set into `outRootShaderObject` stays alive during
+ // the execution of the command buffer.
+ Result bindPipeline(IPipelineState state, out IShaderObject outRootShaderObject);
+
+ // Sets the current pipeline state along with a pre-created mutable root shader object.
+ Result bindPipelineWithRootObject(IPipelineState state, IShaderObject *rootObject);
+
+ void setViewports(GfxCount count, Viewport *viewports);
+ void setScissorRects(GfxCount count, ScissorRect *scissors);
+
+ void setPrimitiveTopology(PrimitiveTopology topology);
+ void setVertexBuffers(
+ GfxIndex startSlot,
+ GfxCount slotCount,
+ NativeRef<IBufferResource>* buffers,
+ Offset *offsets);
+
+ void setIndexBuffer(IBufferResource buffer, Format indexFormat, Offset offset);
+ void draw(GfxCount vertexCount, GfxIndex startVertex);
+ void drawIndexed(GfxCount indexCount, GfxIndex startIndex = 0, GfxIndex baseVertex = 0);
+ void drawIndirect(
+ GfxCount maxDrawCount,
+ IBufferResource argBuffer,
+ Offset argOffset,
+ NativeRef<IBufferResource> countBuffer,
+ Offset countOffset = 0);
+ void drawIndexedIndirect(
+ GfxCount maxDrawCount,
+ IBufferResource argBuffer,
+ Offset argOffset,
+ NativeRef<IBufferResource> countBuffer,
+ Offset countOffset = 0);
+ void setStencilReference(uint32_t referenceValue);
+ Result setSamplePositions(
+ GfxCount samplesPerPixel, GfxCount pixelCount, SamplePosition *samplePositions);
+ void drawInstanced(
+ GfxCount vertexCount,
+ GfxCount instanceCount,
+ GfxIndex startVertex,
+ GfxIndex startInstanceLocation);
+ void drawIndexedInstanced(
+ GfxCount indexCount,
+ GfxCount instanceCount,
+ GfxIndex startIndexLocation,
+ GfxIndex baseVertexLocation,
+ GfxIndex startInstanceLocation);
+};
+
+[COM("88AA9322-82F7-4FE6-A68A-29C7FE798737")]
+interface IComputeCommandEncoder : IResourceCommandEncoder
+{
+ // Sets the current pipeline state. This method returns a transient shader object for
+ // writing shader parameters. This shader object will not retain any resources or
+ // sub-shader-objects bound to it. The user must be responsible for ensuring that any
+ // resources or shader objects that is set into `outRooShaderObject` stays alive during
+ // the execution of the command buffer.
+ Result bindPipeline(IPipelineState state, out IShaderObject outRootShaderObject);
+
+ // Sets the current pipeline state along with a pre-created mutable root shader object.
+ Result bindPipelineWithRootObject(IPipelineState state, IShaderObject rootObject);
+
+ void dispatchCompute(int x, int y, int z);
+ void dispatchComputeIndirect(IBufferResource cmdBuffer, Offset offset);
+};
+
+enum class AccelerationStructureCopyMode
+{
+ Clone, Compact
+};
+
+struct AccelerationStructureQueryDesc
+{
+ QueryType queryType;
+
+ NativeRef<IQueryPool> queryPool;
+
+ GfxIndex firstQueryIndex;
+};
+
+[COM("9a672b87-5035-45e3-967c-1f-85-cd-b3-63-4f")]
+interface IRayTracingCommandEncoder : IResourceCommandEncoder
+{
+ void buildAccelerationStructure(
+ AccelerationStructureBuildDesc *desc,
+ GfxCount propertyQueryCount,
+ AccelerationStructureQueryDesc *queryDescs);
+ void copyAccelerationStructure(
+ IAccelerationStructure *dest,
+ IAccelerationStructure *src,
+ AccelerationStructureCopyMode mode);
+ void queryAccelerationStructureProperties(
+ GfxCount accelerationStructureCount,
+ NativeRef<IAccelerationStructure> *accelerationStructures,
+ GfxCount queryCount,
+ AccelerationStructureQueryDesc *queryDescs);
+ void serializeAccelerationStructure(DeviceAddress dest, IAccelerationStructure source);
+ void deserializeAccelerationStructure(IAccelerationStructure dest, DeviceAddress source);
+
+ void bindPipeline(IPipelineState state, out IShaderObject rootObject);
+ // Sets the current pipeline state along with a pre-created mutable root shader object.
+ Result bindPipelineWithRootObject(IPipelineState state, IShaderObject rootObject);
+
+ /// Issues a dispatch command to start ray tracing workload with a ray tracing pipeline.
+ /// `rayGenShaderIndex` specifies the index into the shader table that identifies the ray generation shader.
+ void dispatchRays(
+ GfxIndex rayGenShaderIndex,
+ IShaderTable *shaderTable,
+ GfxCount width,
+ GfxCount height,
+ GfxCount depth);
+};
+
+[COM("5d56063f-91d4-4723-a7a7-7a-15-af-93-eb-48")]
+interface ICommandBuffer
+{
+ // Only one encoder may be open at a time. User must call `ICommandEncoder::endEncoding`
+ // before calling other `encode*Commands` methods.
+ // Once `endEncoding` is called, the `ICommandEncoder` object becomes obsolete and is
+ // invalid for further use. To continue recording, the user must request a new encoder
+ // object by calling one of the `encode*Commands` methods again.
+ void encodeRenderCommands(
+ IRenderPassLayout renderPass,
+ IFramebuffer framebuffer,
+ out IRenderCommandEncoder outEncoder);
+ IRenderCommandEncoder encodeRenderCommands(IRenderPassLayout renderPass, IFramebuffer framebuffer)
+ {
+ IRenderCommandEncoder result;
+ encodeRenderCommands(renderPass, framebuffer, result);
+ return result;
+ }
+
+ void encodeComputeCommands(out IComputeCommandEncoder encoder);
+ IComputeCommandEncoder encodeComputeCommands()
+ {
+ IComputeCommandEncoder result;
+ encodeComputeCommands(result);
+ return result;
+ }
+
+ void encodeResourceCommands(out IResourceCommandEncoder outEncoder);
+ IResourceCommandEncoder encodeResourceCommands()
+ {
+ IResourceCommandEncoder result;
+ encodeResourceCommands(result);
+ return result;
+ }
+
+ void encodeRayTracingCommands(out IRayTracingCommandEncoder outEncoder);
+ IRayTracingCommandEncoder encodeRayTracingCommands()
+ {
+ IRayTracingCommandEncoder result;
+ encodeRayTracingCommands(result);
+ return result;
+ }
+
+ void close();
+
+ Result getNativeHandle(out InteropHandle outHandle);
+};
+
+enum class QueueType
+{
+ Graphics
+};
+struct CommandQueueDesc
+{
+ QueueType type;
+};
+
+[COM("14e2bed0-0ad0-4dc8-b341-06-3f-e7-2d-bf-0e")]
+interface ICommandQueue
+{
+ // For D3D12, this is the pointer to the queue. For Vulkan, this is the queue itself.
+ typedef uint64_t NativeHandle;
+
+ const CommandQueueDesc* getDesc();
+
+ void executeCommandBuffers(
+ GfxCount count,
+ NativeRef<ICommandBuffer> *commandBuffers,
+ Optional<IFence> fenceToSignal,
+ uint64_t newFenceValue);
+ void executeCommandBuffer(
+ ICommandBuffer commandBuffer, Optional<IFence> fenceToSignal = none, uint64_t newFenceValue = 0)
+ {
+ NativeRef<ICommandBuffer> nativeCmdBuffer = NativeRef<ICommandBuffer>(commandBuffer);
+ executeCommandBuffers(1, &nativeCmdBuffer, fenceToSignal, newFenceValue);
+ }
+
+ Result getNativeHandle(out InteropHandle outHandle);
+
+ void waitOnHost();
+
+ /// Queues a device side wait for the given fences.
+ Result waitForFenceValuesOnDevice(GfxCount fenceCount, NativeRef<IFence> *fences, uint64_t *waitValues);
+};
+
+enum TransientResourceHeapFlags
+{
+ None = 0,
+ AllowResizing = 0x1,
+};
+
+struct TransientResourceHeapDesc
+{
+ TransientResourceHeapFlags flags;
+ Size constantBufferSize;
+ GfxCount samplerDescriptorCount;
+ GfxCount uavDescriptorCount;
+ GfxCount srvDescriptorCount;
+ GfxCount constantBufferDescriptorCount;
+ GfxCount accelerationStructureDescriptorCount;
+};
+
+[COM("cd48bd29-ee72-41b8-bcff-0a-2b-3a-aa-6d-0b")]
+interface ITransientResourceHeap
+{
+ // Waits until GPU commands issued before last call to `finish()` has been completed, and resets
+ // all transient resources holds by the heap.
+ // This method must be called before using the transient heap to issue new GPU commands.
+ // In most situations this method should be called at the beginning of each frame.
+ Result synchronizeAndReset();
+
+ // Must be called when the application has done using this heap to issue commands. In most situations
+ // this method should be called at the end of each frame.
+ Result finish();
+
+ // Command buffers are one-time use. Once it is submitted to the queue via
+ // `executeCommandBuffers` a command buffer is no longer valid to be used any more. Command
+ // buffers must be closed before submission. The current D3D12 implementation has a limitation
+ // that only one command buffer maybe recorded at a time. User must finish recording a command
+ // buffer before creating another command buffer.
+ Result createCommandBuffer(out ICommandBuffer outCommandBuffer);
+};
+
+struct SwapchainDesc
+{
+ Format format;
+ GfxCount width, height;
+ GfxCount imageCount;
+ NativeRef<ICommandQueue> queue;
+ bool enableVSync;
+};
+
+[COM("be91ba6c-0784-4308-a1-00-19-c3-66-83-44-b2")]
+interface ISwapchain
+{
+ const SwapchainDesc* getDesc();
+
+ /// Returns the back buffer image at `index`.
+ Result getImage(GfxIndex index, out ITextureResource outResource);
+
+ /// Present the next image in the swapchain.
+ Result present();
+
+ /// Returns the index of next back buffer image that will be presented in the next
+ /// `present` call. If the swapchain is invalid/out-of-date, this method returns -1.
+ int acquireNextImage();
+
+ /// Resizes the back buffers of this swapchain. All render target views and framebuffers
+ /// referencing the back buffer images must be freed before calling this method.
+ Result resize(GfxCount width, GfxCount height);
+
+ // Check if the window is occluded.
+ bool isOccluded();
+
+ // Toggle full screen mode.
+ Result setFullScreenMode(bool mode);
+};
+
+struct DeviceInfo
+{
+ DeviceType deviceType;
+
+ BindingStyle bindingStyle;
+
+ ProjectionStyle projectionStyle;
+
+ /// An projection matrix that ensures x, y mapping to pixels
+ /// is the same on all targets
+ float identityProjectionMatrix[16];
+
+ /// The name of the graphics API being used by this device.
+ NativeString apiName;
+
+ /// The name of the graphics adapter.
+ NativeString adapterName;
+
+ /// The clock frequency used in timestamp queries.
+ uint64_t timestampFrequency;
+};
+
+enum class DebugMessageType
+{
+ Info, Warning, Error
+};
+enum class DebugMessageSource
+{
+ Layer, Driver, Slang
+};
+
+[COM("B219D7E8-255A-2572-D46C-A0E5D99CEB90")]
+interface IDebugCallback
+{
+ void handleMessage(DebugMessageType type, DebugMessageSource source, NativeString message);
+};
+
+struct SlangDesc
+{
+ NativeRef<slang::IGlobalSession> slangGlobalSession; // (optional) A slang global session object. If null will create automatically.
+
+ slang::SlangMatrixLayoutMode defaultMatrixLayoutMode = slang::SlangMatrixLayoutMode::SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+
+ NativeString *searchPaths;
+ GfxCount searchPathCount;
+
+ slang::PreprocessorMacroDesc* preprocessorMacros;
+ GfxCount preprocessorMacroCount = 0;
+
+ NativeString targetProfile; // (optional) Target shader profile. If null this will be set to platform dependent default.
+ slang::SlangFloatingPointMode floatingPointMode = slang::SlangFloatingPointMode::SLANG_FLOATING_POINT_MODE_DEFAULT;
+ slang::SlangOptimizationLevel optimizationLevel = slang::SlangOptimizationLevel::SLANG_OPTIMIZATION_LEVEL_DEFAULT;
+ slang::SlangTargetFlags targetFlags = slang::SlangTargetFlags.None;
+ slang::SlangLineDirectiveMode lineDirectiveMode = slang::SlangLineDirectiveMode::SLANG_LINE_DIRECTIVE_MODE_DEFAULT;
+};
+
+struct DeviceInteropHandles
+{
+ InteropHandle handles[3] = {};
+};
+
+struct DeviceDesc
+{
+ // The underlying API/Platform of the device.
+ DeviceType deviceType = DeviceType::Default;
+ // The device's handles (if they exist) and their associated API. For D3D12, this contains a single InteropHandle
+ // for the ID3D12Device. For Vulkan, the first InteropHandle is the VkInstance, the second is the VkPhysicalDevice,
+ // and the third is the VkDevice. For CUDA, this only contains a single value for the CUDADevice.
+ DeviceInteropHandles existingDeviceHandles;
+ // Name to identify the adapter to use
+ NativeString adapter;
+ // Number of required features.
+ GfxCount requiredFeatureCount = 0;
+ // Array of required feature names, whose size is `requiredFeatureCount`.
+ NativeString *requiredFeatures = nullptr;
+ // A command dispatcher object that intercepts and handles actual low-level API call.
+ void *apiCommandDispatcher = nullptr;
+ // The slot (typically UAV) used to identify NVAPI intrinsics. If >=0 NVAPI is required.
+ GfxIndex nvapiExtnSlot = -1;
+ // The file system for loading cached shader kernels. The layer does not maintain a strong reference to the object,
+ // instead the user is responsible for holding the object alive during the lifetime of an `IDevice`.
+ void *shaderCacheFileSystem = nullptr;
+ // Configurations for Slang compiler.
+ SlangDesc slang = {};
+
+ GfxCount extendedDescCount = 0;
+ void **extendedDescs = nullptr;
+};
+
+[COM("715bdf26-5135-11eb-AE93-02-42-AC-13-00-02")]
+interface IDevice
+{
+ Result getNativeDeviceHandles(out DeviceInteropHandles outHandles);
+
+ bool hasFeature(NativeString feature);
+
+ /// Returns a list of features supported by the renderer.
+ Result getFeatures(NativeString *outFeatures, Size bufferSize, GfxCount *outFeatureCount);
+
+ Result getFormatSupportedResourceStates(Format format, ResourceStateSet *outStates);
+
+ Result getSlangSession(NativeRef<slang::ISession>* outSlangSession);
+
+ Result createTransientResourceHeap(
+ TransientResourceHeapDesc *desc,
+ out ITransientResourceHeap outHeap);
+
+ /// Create a texture resource.
+ ///
+ /// If `initData` is non-null, then it must point to an array of
+ /// `ITextureResource::SubresourceData` with one element for each
+ /// subresource of the texture being created.
+ ///
+ /// The number of subresources in a texture is:
+ ///
+ /// effectiveElementCount * mipLevelCount
+ ///
+ /// where the effective element count is computed as:
+ ///
+ /// effectiveElementCount = (isArray ? arrayElementCount : 1) * (isCube ? 6 : 1);
+ ///
+ Result createTextureResource(
+ TextureResourceDesc* desc,
+ SubresourceData *initData,
+ out ITextureResource outResource);
+
+ Result createTextureFromNativeHandle(
+ InteropHandle handle,
+ TextureResourceDesc* srcDesc,
+ out ITextureResource outResource);
+
+ Result createTextureFromSharedHandle(
+ InteropHandle handle,
+ TextureResourceDesc *srcDesc,
+ Size size,
+ out ITextureResource outResource);
+
+ /// Create a buffer resource
+ Result createBufferResource(
+ BufferResourceDesc* desc,
+ void *initData,
+ out IBufferResource outResource);
+
+ Result createBufferFromNativeHandle(
+ InteropHandle handle,
+ BufferResourceDesc* srcDesc,
+ out IBufferResource outResource);
+
+ Result createBufferFromSharedHandle(
+ InteropHandle handle,
+ BufferResourceDesc* srcDesc,
+ out IBufferResource outResource);
+
+ Result createSamplerState(SamplerStateDesc* desc, out ISamplerState outSampler);
+
+ Result createTextureView(
+ ITextureResource texture, ResourceViewDesc* desc, out IResourceView outView);
+
+ Result createBufferView(
+ IBufferResource buffer,
+ IBufferResource counterBuffer,
+ ResourceViewDesc* desc,
+ out IResourceView outView);
+
+ Result createFramebufferLayout(FramebufferLayoutDesc* desc, out IFramebufferLayout outFrameBuffer);
+
+ Result createFramebuffer(FramebufferDesc* desc, out IFramebuffer outFrameBuffer);
+
+ Result createRenderPassLayout(
+ RenderPassLayoutDesc* desc,
+ out IRenderPassLayout outRenderPassLayout);
+
+ Result createSwapchain(
+ SwapchainDesc* desc, WindowHandle window, out ISwapchain outSwapchain);
+
+ Result createInputLayout(
+ InputLayoutDesc* desc, out IInputLayout outLayout);
+
+ Result createCommandQueue(CommandQueueDesc* desc, out ICommandQueue outQueue);
+
+ Result createShaderObject(
+ slang::TypeReflection *type,
+ ShaderObjectContainerType container,
+ out IShaderObject outObject);
+
+ Result createMutableShaderObject(
+ slang::TypeReflection *type,
+ ShaderObjectContainerType container,
+ out IShaderObject outObject);
+
+ Result createShaderObjectFromTypeLayout(
+ slang::TypeLayoutReflection *typeLayout, out IShaderObject outObject);
+
+ Result createMutableShaderObjectFromTypeLayout(
+ slang::TypeLayoutReflection *typeLayout, out IShaderObject outObject);
+
+ Result createMutableRootShaderObject(
+ IShaderProgram program,
+ out IShaderObject outObject);
+
+ Result createShaderTable(ShaderTableDesc* desc, out IShaderTable outTable);
+
+ Result createProgram(
+ void *desc,
+ out IShaderProgram outProgram,
+ out slang::ISlangBlob outDiagnosticBlob);
+
+ Result createProgram2(
+ ShaderProgramDesc2 *desc,
+ out IShaderProgram outProgram,
+ out slang::ISlangBlob outDiagnosticBlob);
+
+ Result createGraphicsPipelineState(
+ GraphicsPipelineStateDesc* desc,
+ out IPipelineState outState);
+
+ Result createComputePipelineState(
+ ComputePipelineStateDesc* desc,
+ out IPipelineState outState);
+
+ Result createRayTracingPipelineState(
+ RayTracingPipelineStateDesc* desc, out IPipelineState outState);
+
+ /// Read back texture resource and stores the result in `outBlob`.
+ Result readTextureResource(
+ ITextureResource resource,
+ ResourceState state,
+ out slang::ISlangBlob outBlob,
+ out Size outRowPitch,
+ out Size outPixelSize);
+
+ Result readBufferResource(
+ IBufferResource buffer,
+ Offset offset,
+ Size size,
+ out slang::ISlangBlob outBlob);
+
+ /// Get the type of this renderer
+ DeviceInfo* getDeviceInfo();
+
+ Result createQueryPool(
+ QueryPoolDesc* desc, out IQueryPool outPool);
+
+ Result getAccelerationStructurePrebuildInfo(
+ AccelerationStructureBuildInputs* buildInputs,
+ out AccelerationStructurePrebuildInfo outPrebuildInfo);
+
+ Result createAccelerationStructure(
+ AccelerationStructureCreateDesc* desc,
+ out IAccelerationStructure outView);
+
+ Result createFence(FenceDesc* desc, out IFence outFence);
+
+ /// Wait on the host for the fences to signals.
+ /// `timeout` is in nanoseconds, can be set to `kTimeoutInfinite`.
+ Result waitForFences(
+ GfxCount fenceCount,
+ NativeRef<IFence>* fences,
+ uint64_t *values,
+ bool waitForAll,
+ uint64_t timeout);
+
+ Result getTextureAllocationInfo(
+ TextureResourceDesc* desc, out Size outSize, out Size outAlignment);
+
+ Result getTextureRowAlignment(out Size outAlignment);
+};
+
+}
diff --git a/tools/gfx/immediate-renderer-base.cpp b/tools/gfx/immediate-renderer-base.cpp
index 611741c46..57cb7f934 100644
--- a/tools/gfx/immediate-renderer-base.cpp
+++ b/tools/gfx/immediate-renderer-base.cpp
@@ -60,6 +60,27 @@ public:
m_commandBuffer = cmdBuffer;
}
+ virtual void* getInterface(SlangUUID const& uuid)
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ queryInterface(SlangUUID const& uuid, void** outObject) override
+ {
+ if (auto ptr = getInterface(uuid))
+ {
+ *outObject = ptr;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; }
+
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {}
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
IBufferResource* dst,
@@ -242,6 +263,14 @@ public:
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IRenderCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {}
@@ -432,6 +461,14 @@ public:
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoderImpl)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IComputeCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override
{
diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp
index 5d62f7fba..2e5454851 100644
--- a/tools/gfx/renderer-shared.cpp
+++ b/tools/gfx/renderer-shared.cpp
@@ -26,7 +26,11 @@ const Slang::Guid GfxGUID::IID_IDevice = SLANG_UUID_IDevice;
const Slang::Guid GfxGUID::IID_IShaderObject = SLANG_UUID_IShaderObject;
const Slang::Guid GfxGUID::IID_IRenderPassLayout = SLANG_UUID_IRenderPassLayout;
-const Slang::Guid GfxGUID::IID_IRayTracingCommandEncoder = SLANG_UUID_IRayTracingCommandEncoder;
+const Slang::Guid GfxGUID::IID_IRayTracingCommandEncoder = IRayTracingCommandEncoder::getTypeGuid();
+const Slang::Guid GfxGUID::IID_IResourceCommandEncoder = IResourceCommandEncoder::getTypeGuid();
+const Slang::Guid GfxGUID::IID_IComputeCommandEncoder = IComputeCommandEncoder::getTypeGuid();
+const Slang::Guid GfxGUID::IID_IRenderCommandEncoder = IRenderCommandEncoder::getTypeGuid();
+
const Slang::Guid GfxGUID::IID_ICommandBuffer = SLANG_UUID_ICommandBuffer;
const Slang::Guid GfxGUID::IID_ICommandBufferD3D12 = SLANG_UUID_ICommandBufferD3D12;
@@ -462,6 +466,62 @@ SLANG_NO_THROW Result SLANG_MCALL RendererBase::createMutableShaderObject(
return createMutableShaderObject(shaderObjectLayout, outObject);
}
+Result RendererBase::createProgram2(
+ const IShaderProgram::CreateDesc2& desc,
+ IShaderProgram** outProgram,
+ ISlangBlob** outDiagnostic)
+{
+ auto slangSession = slangContext.session.get();
+
+ SLANG_RELEASE_ASSERT(desc.sourceType == ShaderModuleSourceType::SlangSourceFile);
+
+ auto fileName = (char*)desc.sourceData;
+ ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(fileName, diagnosticsBlob.writeRef());
+ if (!module)
+ return SLANG_FAIL;
+
+ Slang::List<ComPtr<slang::IComponentType>> componentTypes;
+ componentTypes.add(ComPtr<slang::IComponentType>(module));
+
+ if (desc.entryPointCount == 0)
+ {
+ for (SlangInt32 i = 0; i < module->getDefinedEntryPointCount(); i++)
+ {
+ ComPtr<slang::IEntryPoint> entryPoint;
+ SLANG_RETURN_ON_FAIL(module->getDefinedEntryPoint(i, entryPoint.writeRef()));
+ componentTypes.add(ComPtr<slang::IComponentType>(entryPoint.get()));
+ }
+ }
+ else
+ {
+ for (GfxCount i = 0; i < desc.entryPointCount; i++)
+ {
+ ComPtr<slang::IEntryPoint> entryPoint;
+ SLANG_RETURN_ON_FAIL(module->findEntryPointByName(desc.entryPointNames[i], entryPoint.writeRef()));
+ componentTypes.add(ComPtr<slang::IComponentType>(entryPoint.get()));
+ }
+ }
+
+ Slang::List<slang::IComponentType*> rawComponentTypes;
+ for (auto& compType : componentTypes)
+ rawComponentTypes.add(compType.get());
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ rawComponentTypes.getBuffer(),
+ rawComponentTypes.getCount(),
+ linkedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ SLANG_RETURN_ON_FAIL(result);
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = linkedProgram;
+ SLANG_RETURN_ON_FAIL(createProgram(programDesc, outProgram, outDiagnostic));
+
+ return SLANG_OK;
+}
+
SLANG_NO_THROW Result SLANG_MCALL RendererBase::createShaderObjectFromTypeLayout(
slang::TypeLayoutReflection* typeLayout, IShaderObject** outObject)
{
diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h
index 601a8ee85..eb3c7cad1 100644
--- a/tools/gfx/renderer-shared.h
+++ b/tools/gfx/renderer-shared.h
@@ -858,6 +858,12 @@ public:
Slang::Result compileShaders();
virtual Slang::Result createShaderModule(
slang::EntryPointReflection* entryPointInfo, Slang::ComPtr<ISlangBlob> kernelCode);
+
+ virtual SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL findTypeByName(const char* name) override
+ {
+ return linkedProgram->getLayout()->findTypeByName(name);
+ }
+
};
class InputLayoutBase
@@ -1237,6 +1243,11 @@ public:
const IBufferResource::Desc& srcDesc,
IBufferResource** outResource) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Result SLANG_MCALL createProgram2(
+ const IShaderProgram::CreateDesc2& desc,
+ IShaderProgram** outProgram,
+ ISlangBlob** outDiagnostic) override;
+
virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(
slang::TypeReflection* type,
ShaderObjectContainerType containerType,
diff --git a/tools/gfx/slang.slang b/tools/gfx/slang.slang
new file mode 100644
index 000000000..56b304efd
--- /dev/null
+++ b/tools/gfx/slang.slang
@@ -0,0 +1,451 @@
+namespace slang
+{
+
+typedef int64_t Result;
+typedef uint64_t Size;
+typedef int64_t Int;
+typedef uint64_t UInt;
+
+/*!
+@brief Severity of a diagnostic generated by the compiler.
+Values come from the enum below, with higher values representing more severe
+conditions, and all values >= SLANG_SEVERITY_ERROR indicating compilation
+failure.
+*/
+enum SlangSeverity
+{
+ SLANG_SEVERITY_DISABLED = 0, /**< A message that is disabled, filtered out. */
+ SLANG_SEVERITY_NOTE, /**< An informative message. */
+ SLANG_SEVERITY_WARNING, /**< A warning, which indicates a possible proble. */
+ SLANG_SEVERITY_ERROR, /**< An error, indicating that compilation failed. */
+ SLANG_SEVERITY_FATAL, /**< An unrecoverable error, which forced compilation to abort. */
+ SLANG_SEVERITY_INTERNAL, /**< An internal error, indicating a logic error in the compiler. */
+};
+
+enum SlangDiagnosticFlags
+{
+ SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS = 0x01,
+ SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS = 0x02
+};
+
+enum SlangBindableResourceType
+{
+ SLANG_NON_BINDABLE = 0,
+ SLANG_TEXTURE,
+ SLANG_SAMPLER,
+ SLANG_UNIFORM_BUFFER,
+ SLANG_STORAGE_BUFFER,
+};
+
+enum SlangCompileTarget
+{
+ SLANG_TARGET_UNKNOWN,
+ SLANG_TARGET_NONE,
+ SLANG_GLSL,
+ SLANG_GLSL_VULKAN, //< deprecated: just use `SLANG_GLSL`
+ SLANG_GLSL_VULKAN_ONE_DESC, //< deprecated
+ SLANG_HLSL,
+ SLANG_SPIRV,
+ SLANG_SPIRV_ASM,
+ SLANG_DXBC,
+ SLANG_DXBC_ASM,
+ SLANG_DXIL,
+ SLANG_DXIL_ASM,
+ SLANG_C_SOURCE, ///< The C language
+ SLANG_CPP_SOURCE, ///< C++ code for shader kernels.
+ SLANG_HOST_EXECUTABLE, ///< Standalone binary executable (for hosting CPU/OS)
+ SLANG_SHADER_SHARED_LIBRARY, ///< A shared library/Dll for shader kernels (for hosting CPU/OS)
+ SLANG_SHADER_HOST_CALLABLE, ///< A CPU target that makes the compiled shader code available to be run immediately
+ SLANG_CUDA_SOURCE, ///< Cuda source
+ SLANG_PTX, ///< PTX
+ SLANG_OBJECT_CODE, ///< Object code that can be used for later linking
+ SLANG_HOST_CPP_SOURCE, ///< C++ code for host library or executable.
+ SLANG_HOST_HOST_CALLABLE, ///<
+ SLANG_TARGET_COUNT_OF,
+};
+
+/* A "container format" describes the way that the outputs
+for multiple files, entry points, targets, etc. should be
+combined into a single artifact for output. */
+enum SlangContainerFormat
+{
+ /* Don't generate a container. */
+ SLANG_CONTAINER_FORMAT_NONE,
+
+ /* Generate a container in the `.slang-module` format,
+ which includes reflection information, compiled kernels, etc. */
+ SLANG_CONTAINER_FORMAT_SLANG_MODULE,
+};
+
+enum SlangPassThrough : int
+{
+ SLANG_PASS_THROUGH_NONE,
+ SLANG_PASS_THROUGH_FXC,
+ SLANG_PASS_THROUGH_DXC,
+ SLANG_PASS_THROUGH_GLSLANG,
+ SLANG_PASS_THROUGH_CLANG, ///< Clang C/C++ compiler
+ SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
+ SLANG_PASS_THROUGH_GCC, ///< GCC C/C++ compiler
+ SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
+ SLANG_PASS_THROUGH_NVRTC, ///< NVRTC Cuda compiler
+ SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler' - includes LLVM and Clang
+ SLANG_PASS_THROUGH_COUNT_OF,
+};
+
+/* Defines an archive type used to holds a 'file system' type structure. */
+enum SlangArchiveType : int
+{
+ SLANG_ARCHIVE_TYPE_UNDEFINED,
+ SLANG_ARCHIVE_TYPE_ZIP,
+ SLANG_ARCHIVE_TYPE_RIFF, ///< Riff container with no compression
+ SLANG_ARCHIVE_TYPE_RIFF_DEFLATE,
+ SLANG_ARCHIVE_TYPE_RIFF_LZ4,
+ SLANG_ARCHIVE_TYPE_COUNT_OF,
+};
+
+/*!
+Flags to control compilation behavior.
+*/
+enum SlangCompileFlags
+{
+ /* Do as little mangling of names as possible, to try to preserve original names */
+ SLANG_COMPILE_FLAG_NO_MANGLING = 1 << 3,
+
+ /* Skip code generation step, just check the code and generate layout */
+ SLANG_COMPILE_FLAG_NO_CODEGEN = 1 << 4,
+
+ /* Obfuscate shader names on release products */
+ SLANG_COMPILE_FLAG_OBFUSCATE = 1 << 5,
+
+ /* Deprecated flags: kept around to allow existing applications to
+ compile. Note that the relevant features will still be left in
+ their default state. */
+ SLANG_COMPILE_FLAG_NO_CHECKING = 0,
+ SLANG_COMPILE_FLAG_SPLIT_MIXED_TYPES = 0,
+};
+
+/*!
+@brief Flags to control code generation behavior of a compilation target */
+enum SlangTargetFlags
+{
+ None = 0,
+
+ /* When compiling for a D3D Shader Model 5.1 or higher target, allocate
+ distinct register spaces for parameter blocks.
+
+ @deprecated This behavior is now enabled unconditionally.
+ */
+ SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES = 1 << 4,
+
+ /* When set, will generate target code that contains all entrypoints defined
+ in the input source or specified via the `spAddEntryPoint` function in a
+ single output module (library/source file).
+ */
+ SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM = 1 << 8,
+
+ /* When set, will dump out the IR between intermediate compilation steps.*/
+ SLANG_TARGET_FLAG_DUMP_IR = 1 << 9,
+
+ /* When set, will generate SPIRV directly instead of going through glslang. */
+ SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY = 1 << 10,
+};
+
+/*!
+@brief Options to control floating-point precision guarantees for a target.
+*/
+enum SlangFloatingPointMode
+{
+ SLANG_FLOATING_POINT_MODE_DEFAULT = 0,
+ SLANG_FLOATING_POINT_MODE_FAST,
+ SLANG_FLOATING_POINT_MODE_PRECISE,
+};
+
+/*!
+@brief Options to control emission of `#line` directives
+*/
+enum SlangLineDirectiveMode
+{
+ SLANG_LINE_DIRECTIVE_MODE_DEFAULT = 0, /**< Default behavior: pick behavior base on target. */
+ SLANG_LINE_DIRECTIVE_MODE_NONE, /**< Don't emit line directives at all. */
+ SLANG_LINE_DIRECTIVE_MODE_STANDARD, /**< Emit standard C-style `#line` directives. */
+ SLANG_LINE_DIRECTIVE_MODE_GLSL, /**< Emit GLSL-style directives with file *number* instead of name */
+};
+
+enum SlangSourceLanguage : int
+{
+ SLANG_SOURCE_LANGUAGE_UNKNOWN,
+ SLANG_SOURCE_LANGUAGE_SLANG,
+ SLANG_SOURCE_LANGUAGE_HLSL,
+ SLANG_SOURCE_LANGUAGE_GLSL,
+ SLANG_SOURCE_LANGUAGE_C,
+ SLANG_SOURCE_LANGUAGE_CPP,
+ SLANG_SOURCE_LANGUAGE_CUDA,
+ SLANG_SOURCE_LANGUAGE_COUNT_OF,
+};
+
+enum SlangProfileID
+{
+ SLANG_PROFILE_UNKNOWN,
+};
+
+enum SlangCapabilityID
+{
+ SLANG_CAPABILITY_UNKNOWN = 0,
+};
+
+enum SlangMatrixLayoutMode
+{
+ SLANG_MATRIX_LAYOUT_MODE_UNKNOWN = 0,
+ SLANG_MATRIX_LAYOUT_ROW_MAJOR,
+ SLANG_MATRIX_LAYOUT_COLUMN_MAJOR,
+};
+
+enum SlangStage
+{
+ SLANG_STAGE_NONE,
+ SLANG_STAGE_VERTEX,
+ SLANG_STAGE_HULL,
+ SLANG_STAGE_DOMAIN,
+ SLANG_STAGE_GEOMETRY,
+ SLANG_STAGE_FRAGMENT,
+ SLANG_STAGE_COMPUTE,
+ SLANG_STAGE_RAY_GENERATION,
+ SLANG_STAGE_INTERSECTION,
+ SLANG_STAGE_ANY_HIT,
+ SLANG_STAGE_CLOSEST_HIT,
+ SLANG_STAGE_MISS,
+ SLANG_STAGE_CALLABLE,
+ SLANG_STAGE_MESH,
+ SLANG_STAGE_AMPLIFICATION,
+};
+
+enum SlangDebugInfoLevel
+{
+ SLANG_DEBUG_INFO_LEVEL_NONE = 0, /**< Don't emit debug information at all. */
+ SLANG_DEBUG_INFO_LEVEL_MINIMAL, /**< Emit as little debug information as possible, while still supporting stack trackes. */
+ SLANG_DEBUG_INFO_LEVEL_STANDARD, /**< Emit whatever is the standard level of debug information for each target. */
+ SLANG_DEBUG_INFO_LEVEL_MAXIMAL, /**< Emit as much debug infromation as possible for each target. */
+};
+
+enum SlangOptimizationLevel
+{
+ SLANG_OPTIMIZATION_LEVEL_NONE = 0, /**< Don't optimize at all. */
+ SLANG_OPTIMIZATION_LEVEL_DEFAULT, /**< Default optimization level: balance code quality and compilation time. */
+ SLANG_OPTIMIZATION_LEVEL_HIGH, /**< Optimize aggressively. */
+ SLANG_OPTIMIZATION_LEVEL_MAXIMAL, /**< Include optimizations that may take a very long time, or may involve severe space-vs-speed tradeoffs */
+};
+enum SlangTypeKind
+{
+ NONE,
+ STRUCT,
+ ARRAY,
+ MATRIX,
+ VECTOR,
+ SCALAR,
+ CONSTANT_BUFFER,
+ RESOURCE,
+ SAMPLER_STATE,
+ TEXTURE_BUFFER,
+ SHADER_STORAGE_BUFFER,
+ PARAMETER_BLOCK,
+ GENERIC_TYPE_PARAMETER,
+ INTERFACE,
+ OUTPUT_STREAM,
+ SPECIALIZED,
+ FEEDBACK,
+ COUNT,
+};
+
+enum SlangScalarType
+{
+ NONE,
+ VOID,
+ BOOL,
+ INT32,
+ UINT32,
+ INT64,
+ UINT64,
+ FLOAT16,
+ FLOAT32,
+ FLOAT64,
+ INT8,
+ UINT8,
+ INT16,
+ UINT16,
+};
+
+struct TypeReflection
+{
+};
+
+enum CompileStdLibFlags
+{
+ WriteDocumentation = 0x1,
+};
+
+[COM("8BA5FB08-5195-40e2-AC58-0D-98-9C-3A-01-02")]
+interface ISlangBlob
+{
+ void *getBufferPointer();
+ Size getBufferSize();
+};
+
+/** Description of a code generation target.
+ */
+struct TargetDesc
+{
+ /** The size of this structure, in bytes.
+ */
+ Size structureSize = 40;
+
+ /** The target format to generate code for (e.g., SPIR-V, DXIL, etc.)
+ */
+ SlangCompileTarget format = SlangCompileTarget.SLANG_TARGET_UNKNOWN;
+
+ /** The compilation profile supported by the target (e.g., "Shader Model 5.1")
+ */
+ SlangProfileID profile = SlangProfileID.SLANG_PROFILE_UNKNOWN;
+
+ /** Flags for the code generation target. Currently unused. */
+ SlangTargetFlags flags = SlangTargetFlags.None;
+
+ /** Default mode to use for floating-point operations on the target.
+ */
+ SlangFloatingPointMode floatingPointMode = SlangFloatingPointMode.SLANG_FLOATING_POINT_MODE_DEFAULT;
+
+ /** Optimization level to use for the target.
+ */
+ SlangOptimizationLevel optimizationLevel = SlangOptimizationLevel.SLANG_OPTIMIZATION_LEVEL_DEFAULT;
+
+ /** The line directive mode for output source code.
+ */
+ SlangLineDirectiveMode lineDirectiveMode = SlangLineDirectiveMode.SLANG_LINE_DIRECTIVE_MODE_DEFAULT;
+
+ /** Whether to force `scalar` layout for glsl shader storage buffers.
+ */
+ bool forceGLSLScalarBufferLayout = false;
+};
+
+enum SessionFlags
+{
+ kSessionFlags_None = 0,
+
+ /** Use application-specific policy for semantics of the `shared` keyword.
+
+ This is a legacy/compatibility flag to help an existing Slang client
+ migrate to new language features, and should *not* be used by other
+ clients. This feature may be removed in a future release without a
+ deprecation warning, and this bit may be re-used for another feature.
+ You have been warned.
+ */
+ kSessionFlag_FalcorCustomSharedKeywordSemantics = 1 << 0,
+};
+
+struct PreprocessorMacroDesc
+{
+ NativeString name;
+ NativeString value;
+};
+
+struct SessionDesc
+{
+ /** The size of this structure, in bytes.
+ */
+ Size structureSize = 72;
+
+ /** Code generation targets to include in the session.
+ */
+ TargetDesc *targets = nullptr;
+ Int targetCount = 0;
+
+ /** Flags to configure the session.
+ */
+ SessionFlags flags = SessionFlags.kSessionFlags_None;
+
+ /** Default layout to assume for variables with matrix types.
+ */
+ SlangMatrixLayoutMode defaultMatrixLayoutMode = SlangMatrixLayoutMode.SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+
+ /** Paths to use when searching for `#include`d or `import`ed files.
+ */
+ NativeString *searchPaths = nullptr;
+ Int searchPathCount = 0;
+
+ PreprocessorMacroDesc *preprocessorMacros = nullptr;
+ Int preprocessorMacroCount = 0;
+
+ void *fileSystem = nullptr;
+};
+
+/** A global session for interaction with the Slang library.
+
+An application may create and re-use a single global session across
+multiple sessions, in order to amortize startups costs (in current
+Slang this is mostly the cost of loading the Slang standard library).
+
+The global session is currently *not* thread-safe and objects created from
+a single global session should only be used from a single thread at
+a time.
+*/
+[COM("c140b5fd-0c78-452e-ba7c-1a-1e-70-c7-f7-1c")]
+interface IGlobalSession
+{
+};
+
+enum class ContainerType
+{
+ None, UnsizedArray, StructuredBuffer, ConstantBuffer, ParameterBlock
+};
+
+/** A session provides a scope for code that is loaded.
+
+A session can be used to load modules of Slang source code,
+and to request target-specific compiled binaries and layout
+information.
+
+In order to be able to load code, the session owns a set
+of active "search paths" for resolving `#include` directives
+and `import` declrations, as well as a set of global
+preprocessor definitions that will be used for all code
+that gets `import`ed in the session.
+
+If multiple user shaders are loaded in the same session,
+and import the same module (e.g., two source files do `import X`)
+then there will only be one copy of `X` loaded within the session.
+
+In order to be able to generate target code, the session
+owns a list of available compilation targets, which specify
+code generation options.
+
+Code loaded and compiled within a session is owned by the session
+and will remain resident in memory until the session is released.
+Applications wishing to control the memory usage for compiled
+and loaded code should use multiple sessions.
+*/
+[COM("67618701-d116-468f-ab3b-47-4b-ed-ce-0e-3d")]
+interface ISession
+{
+};
+
+[COM("5bc42be8-5c50-4929-9e5e-d15e7c24015f")]
+interface IComponentType
+{
+}
+
+struct TypeLayoutReflection { }
+
+/** The kind of specialization argument. */
+enum class SpecializationArgKind : int32_t
+{
+ Unknown, /**< An invalid specialization argument. */
+ Type, /**< Specialize to a type. */
+};
+
+struct SpecializationArg
+{
+ SpecializationArgKind kind;
+ /** A type specialization argument, used for `Kind::Type`. */
+ TypeReflection *type;
+}
+
+} \ No newline at end of file
diff --git a/tools/gfx/vulkan/vk-command-encoder.h b/tools/gfx/vulkan/vk-command-encoder.h
index f71e262c5..0e834a5fb 100644
--- a/tools/gfx/vulkan/vk-command-encoder.h
+++ b/tools/gfx/vulkan/vk-command-encoder.h
@@ -12,7 +12,7 @@ using namespace Slang;
namespace vk
{
-class PipelineCommandEncoder : public RefObject
+class PipelineCommandEncoder : public ComObject
{
public:
CommandBufferImpl* m_commandBuffer;
@@ -54,6 +54,25 @@ class ResourceCommandEncoder
, public PipelineCommandEncoder
{
public:
+ virtual void* getInterface(SlangUUID const& guid)
+ {
+ if (guid == GfxGUID::IID_IResourceCommandEncoder || guid == ISlangUnknown::getTypeGuid())
+ return this;
+ return nullptr;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ queryInterface(SlangUUID const& uuid, void** outObject)
+ {
+ if (auto ptr = getInterface(uuid))
+ {
+ *outObject = ptr;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+ }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; }
+
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
IBufferResource* dst,
Offset dstOffset,
@@ -150,8 +169,16 @@ class RenderCommandEncoder
: public IRenderCommandEncoder
, public ResourceCommandEncoder
{
-public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoder)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IRenderCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
+
public:
List<VkViewport> m_viewports;
List<VkRect2D> m_scissorRects;
@@ -233,7 +260,15 @@ class ComputeCommandEncoder
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoder)
-public:
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IComputeCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
+
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override;
virtual SLANG_NO_THROW Result SLANG_MCALL
@@ -254,7 +289,16 @@ class RayTracingCommandEncoder
{
public:
SLANG_GFX_FORWARD_RESOURCE_COMMAND_ENCODER_IMPL(ResourceCommandEncoder)
+ virtual void* getInterface(SlangUUID const& uuid) override
+ {
+ if (uuid == GfxGUID::IID_IResourceCommandEncoder || uuid == GfxGUID::IID_IRayTracingCommandEncoder || uuid == ISlangUnknown::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
+ }
public:
+
void _memoryBarrier(
int count,
IAccelerationStructure* const* structures,
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 332ba89ff..1490d0e36 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -766,13 +766,13 @@ void RenderTestApp::_initializeAccelerationStructure()
IBufferResource::Desc asBufferDesc = {};
asBufferDesc.type = IResource::Type::Buffer;
asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = compactedSize;
+ asBufferDesc.sizeInBytes = (Size)compactedSize;
m_blasBuffer = m_device->createBufferResource(asBufferDesc);
IAccelerationStructure::CreateDesc createDesc;
createDesc.buffer = m_blasBuffer;
createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
createDesc.offset = 0;
- createDesc.size = compactedSize;
+ createDesc.size = (Size)compactedSize;
m_device->createAccelerationStructure(createDesc, m_bottomLevelAccelerationStructure.writeRef());
commandBuffer = m_transientHeap->createCommandBuffer();