diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2023-02-14 16:21:07 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-14 13:21:07 -0800 |
| commit | b92a75db2aab1adffe08ae0103cafb080f9795e2 (patch) | |
| tree | f8d27bcd76a78f5d66e40a2f2f970b0335b74e97 | |
| parent | ec49215d711fff9356663390a31182e811e27467 (diff) | |
Preliminary debugBreak support (#2647)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Preliminary support for debug break.
* Add C++ debug break support.
Add details about usage.
* Improve debug break test details.
* Make HLSL output a comment about no support.
* Handle specialize for target assert, without a body if it has spv_instruction/target intrinsic
| -rw-r--r-- | docs/target-compatibility.md | 16 | ||||
| -rw-r--r-- | prelude/slang-cpp-prelude.h | 11 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 19 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 10 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/debug-break.slang | 23 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/debug-break.slang.expected | 24 |
6 files changed, 99 insertions, 4 deletions
diff --git a/docs/target-compatibility.md b/docs/target-compatibility.md index 08819ac17..7769fe8db 100644 --- a/docs/target-compatibility.md +++ b/docs/target-compatibility.md @@ -42,6 +42,7 @@ Items with ^ means there is some discussion about support later in the document | Atomics on RWBuffer | Yes | Yes | Yes | No | No + | Sampler Feedback | No | Yes | No + | No | Yes ^ | RWByteAddressBuffer Atomic | No | Yes ^ | Yes ^ | Yes | No + +| debugBreak | No | No | Yes | Yes | Yes ## Half Type @@ -223,4 +224,17 @@ in the separate [NVAPI Support](nvapi-support.md) document. On Vulkan, for float the [`GL_EXT_shader_atomic_float`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_EXT_shader_atomic_float.html) extension is required. For int64 the [`GL_EXT_shader_atomic_int64`](https://raw.githubusercontent.com/KhronosGroup/GLSL/master/extensions/ext/GL_EXT_shader_atomic_int64.txt) extension is required. -CUDA requires SM6.0 or higher for int64 support. +CUDA requires SM6.0 or higher for int64 support. + +## debugBreak + +Slang has preliminary support for `debugBreak()` intrinsic. With the appropriate tooling, when `debugBreak` is hit it will cause execution to halt and display in the attached debugger. + +Currently this is supported in all targets except HLSL. Note that on some targets if there isn't an appropriate debugging environment the debugBreak might cause execution to fail or potentially it is ignored. + +On C++ targets debugBreak is implemented using SLANG_BREAKPOINT defined in "slang-cpp-prelude.h". If there isn't a suitable intrinsic, this will default to attempting to write to `nullptr` leading to a crash. + +Some additional details: + +* If [slang-llvm](cpu-target.md#slang-llvm) is being used as the downstream compiler (as is typical with `host-callable`), it will crash into the debugger, but may not produce a usable stack trace. +* For "normal" C++ downstream compilers such as Clang/Gcc/Visual Studio, to break into readable source code, debug information is typically necessary. Disabling optimizations may be useful to break on the appropriate specific line, and have variables inspectable.
\ No newline at end of file diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h index b2a8dd6ac..84a61f929 100644 --- a/prelude/slang-cpp-prelude.h +++ b/prelude/slang-cpp-prelude.h @@ -207,6 +207,9 @@ Any platforms not detected by the above logic are now now explicitly zeroed out. // GCC Specific #if SLANG_GCC_FAMILY # define SLANG_ALIGN_OF(T) __alignof__(T) + +# define SLANG_BREAKPOINT(id) __builtin_trap() + // Use this macro instead of offsetof, because gcc produces warning if offsetof is used on a // non POD type, even though it produces the correct result # define SLANG_OFFSET_OF(T, ELEMENT) (size_t(&((T*)1)->ELEMENT) - 1) @@ -215,6 +218,9 @@ Any platforms not detected by the above logic are now now explicitly zeroed out. // Microsoft VC specific #if SLANG_VC # define SLANG_ALIGN_OF(T) __alignof(T) + +# define SLANG_BREAKPOINT(id) __debugbreak(); + #endif // SLANG_VC // Default impls @@ -223,6 +229,11 @@ Any platforms not detected by the above logic are now now explicitly zeroed out. # define SLANG_OFFSET_OF(X, Y) offsetof(X, Y) #endif +#ifndef SLANG_BREAKPOINT +// Make it crash with a write to 0! +# define SLANG_BREAKPOINT(id) (*((int*)0) = int(id)); +#endif + // If slang.h has been included we don't need any of these definitions #ifndef SLANG_H diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 306e0dbb9..464811a96 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -5688,10 +5688,10 @@ Ref<T> __hitObjectAttributes<T>() // Next is the custom intrinsic that will compute the hitObjectAttributes location // for GLSL-based targets. // -__generic<Payload> +__generic<Attributes> __target_intrinsic(__glslRayTracing, "$XH") [__readNone] -int __hitObjectAttributesLocation(__ref Payload payload); +int __hitObjectAttributesLocation(__ref Attributes attributes); /// Immutable data type representing a ray hit or a miss. Can be used to invoke hit or miss shading, /// or as a key in ReorderThread. Created by one of several methods described below. HitObject @@ -6471,3 +6471,18 @@ __target_intrinsic(hlsl, "NvReorderThread") __glsl_extension(GL_NV_shader_invocation_reorder) __target_intrinsic(glsl, "reorderThreadNV") void ReorderThread( HitObject HitOrMiss ); + + +/// +/// DebugBreak support +/// +/// There doesn't appear to be an equivalent for debugBreak for HLSL + +__target_intrinsic(hlsl, "/* debugBreak() not currently supported for HLSL */") +__target_intrinsic(cuda,"__brkpt()") +__target_intrinsic(cpp, "SLANG_BREAKPOINT(0)") +void debugBreak(); + +__specialized_for_target(glsl) +[[vk::spirv_instruction(1, "NonSemantic.DebugBreak")]] +void debugBreak(); diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 7e8e94d95..837dcb8eb 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -5372,7 +5372,15 @@ namespace Slang // If it's specialized for target it should have a body... if (auto funcDecl = as<FunctionDeclBase>(decl)) { - SLANG_ASSERT(funcDecl->body); + // Normally if we have specialization for target it must have a body. + if (funcDecl->body == nullptr) + { + // If it doesn't have a body but does have a target intrinsic/SPIRVInstructionOp + // it's probably ok + + SLANG_ASSERT(funcDecl->findModifier<SPIRVInstructionOpAttribute>() || + funcDecl->findModifier<TargetIntrinsicModifier>()); + } } Name* targetName = specializedModifier->targetToken.getName(); diff --git a/tests/hlsl-intrinsic/debug-break.slang b/tests/hlsl-intrinsic/debug-break.slang new file mode 100644 index 000000000..e46c42004 --- /dev/null +++ b/tests/hlsl-intrinsic/debug-break.slang @@ -0,0 +1,23 @@ +//TEST:SIMPLE:-stage compute -entry computeMain -target glsl -line-directive-mode none +// We can't enable because output source includes path to prelude. +//DISABLE_TEST:SIMPLE:-stage compute -entry computeMain -target cpp -line-directive-mode none +//DISABLE_TEST:SIMPLE:-stage compute -entry computeMain -target cuda -line-directive-mode none +// Not currently supported on HLSL +//DISABLE_TEST:SIMPLE:-stage compute -entry computeMain -target hlsl -line-directive-mode none +// With `slang-llvm` this will crash, but the call stack isn't really usable. +// With downstream host compilers this should break into the debugger. It's not enabled as that isn't testable. +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -shaderobj -Xslang... -O0 -g -X. + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer + +RWStructuredBuffer<int> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + const int idx = int(dispatchThreadID.x); + + debugBreak(); + + outputBuffer[idx] = idx; +}
\ No newline at end of file diff --git a/tests/hlsl-intrinsic/debug-break.slang.expected b/tests/hlsl-intrinsic/debug-break.slang.expected new file mode 100644 index 000000000..fbd1faa9b --- /dev/null +++ b/tests/hlsl-intrinsic/debug-break.slang.expected @@ -0,0 +1,24 @@ +result code = 0 +standard error = { +} +standard output = { +#version 450 +#extension GL_EXT_spirv_intrinsics : require +layout(row_major) uniform; +layout(row_major) buffer; +spirv_instruction(id = 1, set = "NonSemantic.DebugBreak") +void debugBreak_0(); + +layout(std430, binding = 0) buffer _S1 { + int _data[]; +} outputBuffer_0; +layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in; +void main() +{ + int idx_0 = int(gl_GlobalInvocationID.x); + debugBreak_0(); + ((outputBuffer_0)._data[(uint(idx_0))]) = idx_0; + return; +} + +} |
