-
Notifications
You must be signed in to change notification settings - Fork 122
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
Bug: ID3D12InfoQueue1::RegisterMessageCallback context pointer type does not match D3D12MessageFunc #1677
Comments
Thanks for reporting! This looks like a discrepancy in the Win32 metadata. I'll forward this issue for consideration. |
@kennykerr could you clarify what metadata change is required here? |
@damyanp @MarijnS95 Heads up, this typedef is missing annotations in typedef void (__stdcall *D3D12MessageFunc) (D3D12_MESSAGE_CATEGORY Category,
D3D12_MESSAGE_SEVERITY Severity,
D3D12_MESSAGE_ID ID,
LPCSTR pDescription,
void* pContext);
...
HRESULT RegisterMessageCallback(
[annotation("_In_")] D3D12MessageFunc CallbackFunc,
[annotation("_In_")] D3D12_MESSAGE_CALLBACK_FLAGS CallbackFilterFlags,
[annotation("_In_")] void* pContext,
[annotation("_Inout_")] DWORD *pCallbackCookie); @mikebattista Shall we wait for the DirectX folks to fixup the IDL? Or fix it here and upstream it? |
I'd prefer blocking on upstream but here's a branch if you need (rafael/d3d12_const_ctx) |
I'm trying to figure out what the right fix is (sorry, I'm having to page in Rust, D3D12 and SAL at the moment!) The callback should be allowed to write to the memory void MyMessageFunc(D3D12_MESSAGE_CATEGORY Category,
D3D12_MESSAGE_SEVERITY Severity,
D3D12_MESSAGE_ID ID,
LPCSTR pDescription,
void* pContext)
{
MessageContainer* messages = reinterpret_cast<MessageContainer*>(pContext);
message->Add(Category, Severity, ID, pDescription);
} Wouldn't this mean we need pContext to be InOut? |
Assuming those annotations are supposed to be SAL markings, the void Foo(..., _in_ void* pContext)
{
*pContext = 42; // Bad
} I don't think msxml6.h getURI https://learn.microsoft.com/previous-versions/windows/desktop/ms762697(v=vs.85) contains an dbgmodel.h IModelMethod https://learn.microsoft.com/windows-hardware/drivers/ddi/dbgmodel/nf-dbgmodel-imodelmethod-call has a |
Yup - here's a modified version of my example that I think is clearer: void MyMessageFunc(D3D12_MESSAGE_CATEGORY Category,
D3D12_MESSAGE_SEVERITY Severity,
D3D12_MESSAGE_ID ID,
LPCSTR pDescription,
_InOut_ void* pContext)
{
// pContext points to our count of messages
size_t* messages = reinterpret_cast<size_t*>(pContext);
*messages = *messages + 1;
} |
Ah, if that's also a supported scenario in D3D12, then agreed! The details are fuzzy re: who's on the hook here since we ingest an external Agility SDK. Maybe we bias to action here and file a change request on Agility SDK repository + fix it locally so folks get immediate benefits. (We'll have to keep an eye out for regression risk on the next sdk ingest.) |
I'm following up with the D3D team now. |
While doing that, I think that getting the correct SAL on this won't necessarily resolve the original problem reported here which is specific to Rust. The SAL captures what may/may not happen in the general case, but Rust has the additional policy that values shared between threads should be const. So, I'm wondering if doing something different for Rust might be appropriate here? |
Rust turns non-output pointer parameters into In this case, the metadata looks like this: unsafe HRESULT RegisterMessageCallback([In] D3D12MessageFunc CallbackFunc, [In] D3D12_MESSAGE_CALLBACK_FLAGS CallbackFilterFlags, [In] void* pContext, [In][Out] uint* pCallbackCookie); Notice the So in Rust it ends up like this: fn RegisterMessageCallback(&self, callbackfunc: D3D12MessageFunc, callbackfilterflags: D3D12_MESSAGE_CALLBACK_FLAGS, pcontext: *const ::core::ffi::c_void, pcallbackcookie: *mut u32) -> ::windows_core::Result<()>; Notice the |
Right. I'm recommending we fix both cases to explicitly be My concern is that while this is the correct annotation in general for Win32Metadata, a Rust projection may want to consider making them |
For that I think we'd need metadata that says this parameter is shared as opposed to merely transferred or assume that all pointers are shared. But I'm not sure the aliasing rules apply to raw pointers so this may be a non-issue. |
Specifically, the optimizations and assumptions around aliasing are for shared |
The next Agility SDK will have RegisterMessageCallback updated to match the callback: HRESULT RegisterMessageCallback(
[annotation("_In_")] D3D12MessageFunc CallbackFunc,
[annotation("_In_")] D3D12_MESSAGE_CALLBACK_FLAGS CallbackFilterFlags,
[annotation("_Inout_")] void* pContext,
[annotation("_Inout_")] DWORD *pCallbackCookie); |
It doesn't look like #1727 included this change. Were you expecting this to be in there? |
Thanks for pointing this out. This change was intended to be there, but I missed it. It will be included in the next update, 1.611.1. (I expect there to be a 1.611.1 update, but if there's not, it will be in 1.612) |
Which crate is this about?
windows
Crate version
0.48.0
Summary
RegisterMessageCallback
takes as itspcontext
pointer a*const c_void
. However,D3D12MessageFunc
takes a*mut c_void
.Toolchain version/configuration
Default host: x86_64-pc-windows-msvc
rustup home: C:\Users\David.rustup
stable-x86_64-pc-windows-msvc (default)
rustc 1.70.0 (90c541806 2023-05-31)
Reproducible example
No response
Crate manifest
No response
Expected behavior
No response
Actual behavior
No response
Additional comments
Thank you for your hard work!
The correct behavior is unclear from context. However, it seems it should probably be
const
since the callback can be called from multiple threads a la this document.Edit: Fix links
The text was updated successfully, but these errors were encountered: