Skip to content
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

Add DirectXShaderCompiler example #802

Closed
wants to merge 5 commits into from
Closed

Conversation

MarijnS95
Copy link
Contributor

Depends on #747, #800

Following the discussion in https://github.com/microsoft/windows-rs/discussions/566#discussioncomment-467792 and the acknowledgement to have something in the tree that could possibly run on the Linux CI (more requirements in https://github.com/microsoft/windows-rs/discussions/566#discussioncomment-701806). Now there's a use for #747 too :)

TODO

  • Should I put dxcompiler.dll (and later libdxcompiler.so) in .windows/<arch>?
  • Should I remove the include handler (last commit) until proper COM overriding/implementing is finished? It's a complete hack anyway.


[dependencies]
bindings = { package = "dxc_bindings", path = "bindings" }
libloading = "0.7"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this adds a dependency on winapi :/

Comment on lines +14 to +15
// Only exists in newer DXC headers
const DXC_CP_UTF8: u32 = CP_UTF8;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be cleaned/gone when microsoft/win32metadata#474 lands, like: MarijnS95@6e7d02d

Comment on lines 66 to 67
// let mut compiler: Option<IDxcCompiler2> = None;
// let compiler = unsafe { create(&CLSID_DxcCompiler, &IDxcCompiler2::IID, compiler.set_abi()) }
// .and_some(compiler)
// .unwrap();
let compiler: IDxcCompiler2 = unsafe { DxcCreateInstanceProc(&create, &CLSID_DxcCompiler) }?;
let library: IDxcLibrary = unsafe { DxcCreateInstanceProc(&create, &CLSID_DxcLibrary) }?;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#747 ^^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the thinking that the commented out code would replace the explicit calls to DxcCreateInstanceProc when 747 lands? Or is it the other way round?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented out code would disappear, in favour of a single call to DxcCreateInstanceProc.

let this = &mut *(this as *mut IncludeHandlerData);
dbg!(&this, pfilename, ppincludesource);

if pfilename != "./foo/bar/copy.hlsl" {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comparison needs #800.

// Virtual destructors breaking the vtable, hack for !windows DXC
#[cfg(not(windows))]
dtor,
#[cfg(not(windows))]
dtor,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be removed - I'll have to take this up with DXC but it's a tricky one. For more details: Traverse-Research/hassle-rs@c37cb03#diff-8202c69531938d4c80a8f8a9190be8b98a026d2bd0364b97a0c7a32e8ae21ac6

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll ask around to find out the history here. Looks like IUnknown explicitly has a virtual destructor on non-Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that'd be nice. Non-Windows support is fairly recent and it looks mostly used for the ./dxc binary, not the library. I've already submitted some fixes over time to make the library workable, and this seems to be the final step to make it truly cross-compatible. I mentioned this issue a while ago but didn't get to report a standalone issue yet nor dig and fix it myself.

Looks like IUnknown explicitly has a virtual destructor on non-Windows.

Correct: https://github.com/microsoft/DirectXShaderCompiler/blob/aa4f5176ebba010a860a214d73f33bdc5b5042ce/include/dxc/Support/WinAdapter.h#L627

I already tried removing it but that results in tons of compiler warnings, though it should work since on Windows these objects aren't cleaned up through a virtual DTOR either... I'll revisit this again on both GCC and Clang, and see what happens. My C++ knowledge isn't up there so I don't know if we can simply disable the warning without breaking anything. Note that Release calls delete on itself which would call the destructor and deallocate: https://github.com/microsoft/DirectXShaderCompiler/blob/aa4f5176ebba010a860a214d73f33bdc5b5042ce/lib/DxcSupport/WinAdapter.cpp#L24. Aside, the vtable clearly shows a destructor specific to DxcLibrary even though it has no members that need destructing - that already happens the release function. I vaguely recall reading something about passing the pointer and size to delete under the hood, that might be why DxcLibrary has its own deleting destructor in place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally found some time to report this at 2AM: microsoft/DirectXShaderCompiler#3783

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damyanp For the record (in case you're still asking around) there's now a PR open: microsoft/DirectXShaderCompiler#3793

Removing the destructor is totally fine, and even MSVC complains about missing virtual dtors on the "official" IUnknown from the Windows headers, if enough warnings are enabled: https://godbolt.org/z/hKPT6ThEf

examples/dxc/Cargo.toml Outdated Show resolved Hide resolved
Comment on lines 66 to 67
// let mut compiler: Option<IDxcCompiler2> = None;
// let compiler = unsafe { create(&CLSID_DxcCompiler, &IDxcCompiler2::IID, compiler.set_abi()) }
// .and_some(compiler)
// .unwrap();
let compiler: IDxcCompiler2 = unsafe { DxcCreateInstanceProc(&create, &CLSID_DxcCompiler) }?;
let library: IDxcLibrary = unsafe { DxcCreateInstanceProc(&create, &CLSID_DxcLibrary) }?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the thinking that the commented out code would replace the explicit calls to DxcCreateInstanceProc when 747 lands? Or is it the other way round?

// Virtual destructors breaking the vtable, hack for !windows DXC
#[cfg(not(windows))]
dtor,
#[cfg(not(windows))]
dtor,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll ask around to find out the history here. Looks like IUnknown explicitly has a virtual destructor on non-Windows.

@kennykerr
Copy link
Collaborator

Should I put dxcompiler.dll (and later libdxcompiler.so) in .windows/?

@damyanp are these Microsoft binaries your team distributes?

@damyanp
Copy link
Member

damyanp commented May 18, 2021

They're distributed by a team I work closely with.

Can you explain more what it means to put them in "./windows/"? Does this involve somehow redistributing them? Or is this something that would happen at build time?

@MarijnS95
Copy link
Contributor Author

MarijnS95 commented May 18, 2021

Can you explain more what it means to put them in "./windows/"? Does this involve somehow redistributing them? Or is this something that would happen at build time?

Redistributing in the .windows/ directory in this repository so that the CI can run the example for testing, preferably both Linux and Windows. It's not distrbuted with the crate itself on crates.io however.

@kennykerr
Copy link
Collaborator

The Windows crate doesn't distribute these but any crate may place dependencies in the '.windows' folder of their crate or workspace and the Windows crate will copy them to the target directory for convenience.

@damyanp
Copy link
Member

damyanp commented May 18, 2021

Would this only be used for the tests? End users would still need to obtain the dll through the official distribution? What we want to avoid doing is making this crate become another vector for distributing the compiler dll. We should expect users to want control over which version of the dll they're using, and not have the Windows crate dictate which version they use.

@kennykerr
Copy link
Collaborator

Yes, this is only to enable examples/tests in this repo. You can see existing binaries here. I'm not saying I want to add these necessarily. I'm just explaining how it works.

@damyanp
Copy link
Member

damyanp commented May 18, 2021

Would an option be to have the CI build pick up the binaries that are built from the shader compiler project?

@kennykerr
Copy link
Collaborator

That's an option. I'd rather not complicate the tests and examples with such build dependencies here.

@MarijnS95
Copy link
Contributor Author

That would also complicate local testing if a script is necessary to fetch and unpack the sources. Note that the GH releases don't include Linux binaries, those are only provided on AppVeyor (microsoft/DirectXShaderCompiler#3686).

On the other hand these binaries would add quite a few megabytes to this repo.

@kennykerr
Copy link
Collaborator

Probably not worth adding such an example to this repo. It's also not something I have any experience with so I'm a little hesitant to take it on.

@damyanp
Copy link
Member

damyanp commented May 18, 2021

I'm going to work with the dxcompiler team to try and figure out how they work with these efforts. Although a version of the compiler is included in the SDK, most users get their version from the github project.

@MarijnS95
Copy link
Contributor Author

Probably not worth adding such an example to this repo. It's also not something I have any experience with so I'm a little hesitant to take it on.

We can have the example without the library checked in, assuming those wanting to test it need the dll from the SDK or downloaded from GH releases/AppVeyor.

@kennykerr
Copy link
Collaborator

Feel free to share this example in a dedicate repo. I'm sure it will benefit developers in interested in DirectX.

@kennykerr kennykerr closed this May 19, 2021
@MarijnS95
Copy link
Contributor Author

No further discussion whether this can make it in without having the library checked in?

@kennykerr
Copy link
Collaborator

As I'm not a DirectX expert, I don't want to carry examples that I can't verify myself simply by running cargo run.

@MarijnS95
Copy link
Contributor Author

As I'm not a DirectX expert, I don't want to carry examples that I can't verify myself simply by running cargo run.

No-one else to carry that effort? As said the library should be included with the SDK thus available on most developer machines?

I had plans to use DXC through windows-rs but all my efforts thus far have been nullified 😞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants