-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Display useful pixel shader compilation errors #17436
Conversation
More descriptive warnings are triggered when custom pixel shader compilation fails. Tests performed: 1. Compile time error 2. File not found 3. Path not found 4. Access denied
@microsoft-github-policy-service agree |
Ran Invoke-CodeFormat
BackendD3D.cpp line 457: The error message generated by the compiler is correctly converted to a wstring. Made changes to TermControl.cpp (_RendererWarning function) and Resource.resw to make sure that the file location shows up when an 'unexpected error' occurs.
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.
Thanks so much for doing this! It will be a huge quality of life improvement for shader authors. Just a quick question :)
<data name="RendererErrorOther" xml:space="preserve"> | ||
<value>Renderer encountered an unexpected error: {0:#010x} {1}</value> | ||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment> | ||
<value>Renderer encountered an unexpected error: {0:#010x} {1} "{2}"</value> | ||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message. {2} is the filename.</comment> | ||
</data> |
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.
Is there a chance that parameter
will be empty for non-shader-related Renderer errors? If so, should we conditionally add the filename or parameter to the message, when we construct it?
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.
Hello Dustin! I stared at the code for a while, I think it is safe to conclude that parameter won't be empty for non-shader-related Renderer errors.
BackendD3D.cpp Line 453 to 470
In the event that the compiler returns an error (faulty shader code), parameter = compiler related error message
, else parameter = file path
. Unless D3DCompileFromFile function, line 409 BackendD3D.cpp
returns an invalid hr
, we should not have problems.
TermControl.cpp _RendererWarning function
I am new to this project, infact this is my first contribution; I have a lot of code analysis to do before I can make claims/conclusions with resonable confidene. So, let me know if I'm missing something here : )
Edit: I had a quick question. What about other languages? It would be nice to have native language speakers edit the respective Resource.resw files; reason being that online translators aren't exactly accurate.
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.
Sorry, I missed your edit! Don't worry too much about other languages - the automatic translation service should come through and automatically update the messages.
Your analysis makes sense of when and where the filename/parameters come from, as well. I appreciate it!
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.
Oh, I think I found what I was worried about!
There is one more call to p.warningCallback
in AtlasEngine.r.cpp
:
if (_p.warningCallback)
{
try
{
_p.warningCallback(hr, {});
}
CATCH_LOG()
}
If the render engine fails for a non-shader-related reason, like DirectWrite ran out of memory or the graphics hardware did not respond in time, I think we will display an error message with empty quotes in it:
/!\ Error [X]
The renderer encountered an unexpected error: 0x80070057 Invalid Parameter ""
[ OK ]
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 default case in TermControl.cpp _rendererWarning function now conditionally constructs the warning message. If the parameter is not empty, we add "{2}" to the 'resourceString'. Removed the "{2}" from resources.resw to accommodate this mechanism.
if (!parameter.empty()) | ||
{ | ||
resourceString += L" \"{2}\""; | ||
message = winrt::hstring{ fmt::format(std::wstring_view{ resourceString }, hr, msg, parameter) }; | ||
} | ||
else | ||
{ | ||
message = winrt::hstring{ fmt::format(std::wstring_view{ resourceString }, hr, msg) }; | ||
} |
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.
if (!parameter.empty()) | |
{ | |
resourceString += L" \"{2}\""; | |
message = winrt::hstring{ fmt::format(std::wstring_view{ resourceString }, hr, msg, parameter) }; | |
} | |
else | |
{ | |
message = winrt::hstring{ fmt::format(std::wstring_view{ resourceString }, hr, msg) }; | |
} | |
std::wstring partialMessage = fmt::format(std::wstring_view{ resourceString }, hr, msg); | |
if (!parameter.empty()) | |
{ | |
fmt::format_to(std::back_inserter(partialMessage), FMT_COMPILE(LR"( "{2}")"), parameter); | |
} | |
message = winrt::hstring{ partialMessage }; |
How does this sound? It simplifies the logic (there is only one format call that uses the resource string) and reduces the dependency on the number of format specifiers in the resource (e.g. we don't need to be as careful when we change the resource string)
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 made sense; learnt something new today! Thank you for the review!
Edit: also next time I'll stick to referencing code via text and not screenshots, I imagine it makes a little bit of a mess.
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.
Thank you for bearing with my questions! I really appreciate you contributing this fix - this problem has annoyed me too 🙂
More descriptive warnings are triggered when custom pixel shader compilation fails.
If D3DCompileFromFile fails and the compiler generates an error message- the message is converted to a wstring and is sent as a parameter when calling p.warningCallback.
Changes were made to resources.resw and TermControl.cpp to accommodate this.
Validation Steps Performed
I tested the following errors that may be encountered while developing a custom pixel shader:
Fixes #17435
TAEF tests passed:
Summary: Total=294, Passed=294, Failed=0, Blocked=0, Not Run=0, Skipped=0