-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dxil] Proposal to add new debug printf dxil op #324
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Dxil Debug Printf | ||
|
||
* Proposal: [NNNN](NNNN-debug-printf.md) | ||
* Author(s): [Jiao Lu](https://github.com/jiaolu) | ||
* Sponsor: TBD | ||
* Status: **Under Consideration** | ||
|
||
## Introduction | ||
|
||
Add new dxil op to allow c/c++ like *printf* intrinsic instructions can be | ||
generated in the dxil sourced from hlsl. | ||
|
||
## Motivation | ||
|
||
As the new shader models, i.e. RayTracing, RayQuery, Workgraph, and more complex | ||
algorithms and structure emerges in recent time, we meet many more requirements of | ||
debugging capabilities of hlsl coding in game, application and driver development. | ||
|
||
The dxil counterpart spirv has a similar feature, | ||
[NonSemantic.DebugPrintf extention](https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.DebugPrintf.asciidoc) | ||
to generate DebugPrintf spirvOp souced from hlsl/glsl. Based on the spirvOp | ||
extention, some vendor drivers and Valve lunarG has | ||
[debug printf layer](https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md) | ||
to dump printf expression, "hlsl/glsl variables" into stdio or file. | ||
|
||
## Proposed solution | ||
|
||
The printf expression in hlsl mostly like this example. | ||
```c++ hlsl: | ||
|
||
const string str0= "str0"; | ||
string str1 = "str1"; | ||
|
||
void main() { | ||
printf(str0); | ||
printf(str1); | ||
printf("Variables are: %d %d %.2f", 1u, 2u, 1.5f); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we decide to go further with this, we'll need to specify exactly how these format strings are interpreted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The format specifier generally follow the c/c++ format specifiers as here, https://www.geeksforgeeks.org/format-specifiers-in-c/, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we want to build a feature that DXC doesn't validate and where all behavior is undefined. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is part of design has been changed. |
||
} | ||
|
||
``` | ||
|
||
The format specifier generally follow the c/c++ format specifiers as here, https://www.geeksforgeeks.org/format-specifiers-in-c/, | ||
Though how the final string representation after printf output is implementation dependent. | ||
|
||
|
||
DirectXCompiler at present can parse "printf" statement in hlsl as dx.hl.op | ||
instructions, | ||
``` | ||
dx.hl.op..void (i32, i8*, ...); | ||
``` | ||
The printf format string, the second argument of the printf instruction of | ||
dx.hl.op is a global *constant* variable or a GEP constant expression. | ||
|
||
The parsing is called from ast frontend into the | ||
HandleTranslationUnit-->TranslatePrintf.The function *TranslatePrintf* itself | ||
is empty implementation. | ||
|
||
The implementation of debug printf dxil op will be | ||
|
||
1) assign new dxil op code to the debug printf. | ||
2) Finished the TranslatePrintf implementation, create dxil op instruction with | ||
a proper dxil op code, and replace dx.hl.op. the dxil op instruction function | ||
will be a variable arguments function. | ||
|
||
|
||
## Detailed design | ||
|
||
1. The printf dxil op will be non-semantic, it does not affect final hlsl code/algorithm. | ||
Non-semantic dxil op code can be counted down from 0xffff, or 0xffffffff, it will give a hint to the client api | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don’t have any notion of “non-semantic” operations in DXIL today, so this is a new concept. Also DIXL is not modifiable by the client API, which seems like a problem for this design. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i change the wording a little , from non-semantic to the debug purpose dxil There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing the words doesn't solve the problem. We don't have a notion of instructions or operations that the client API can remove or that drivers can just ignore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. okay, i will remove this part of the design. |
||
to remove the non semantic dxil safely | ||
2. Add a option to enable printf dxil op generation to dxc, try to separate hlsl code for debugging | ||
and for production, if printf option is disabled, the printf in hlsl will be report a error | ||
3. We should not support dynamic string variable, a string variable content. | ||
retrieved from buffer. The string variable should be explicited defined and can | ||
be retrieved directly/indirectly from global constant variable. | ||
4. The format string input to the dx.hl.op..void, could be llvm constant | ||
expression, we need to retrieve global variable from the constant expression. | ||
5. The validation for the dxil overloading checking should be ignored. Because | ||
of printf variable arguments, there is no definite function type can be validated. | ||
6. dxc does not valiate format specifier to the c/c++ format speicifer standard, or the matching relation between | ||
format specifier and argument. If the number and type don't match, they will produce undefined result from | ||
client api, e.g. driver. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this proposal is adding a new data type to HLSL,
string
? Or does this exist already? Are the semantics of this well understood? Can they be passed to / from functions, for example? How do they interact with any other existing builtin functions / operators?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
string
is part of current semantics, for example.const string first = "node"; [Shader(first)]
it can be used with the intrinsic which accept strings. but from my experimentation, it can not be used in function argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there are restrictions on where strings can appear.
This example seems to be passing a string as a function argument, is this going to be supported now?
This seems to have a string literal being passed as a function argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function mentioned is user defined function, but it seem instrinsic functions can use string variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to be in a situation where built-in functions behave in a fundamentally different way to user-defined functions. Where this has been done in the past, this has led to inconsistent behavior with things like overload resolution. This is something we've been actively trying to address in the implementation of HLSL in Clang, and so any new features we add we want to be sure to add in a way that is compatible with that goal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string seems touching some history baggage from clang. Now removing the string variables from this hlsl example.