From b34d4c13d1913b9f3b09a0416624bdebeb5c4959 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 14 Jul 2020 11:30:16 +0200 Subject: [PATCH 01/31] Cargo: Update all dependencies --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 786ac83..3205e4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,10 @@ maintenance = { status = "actively-developed" } default-target = "x86_64-pc-windows-msvc" [dependencies] -libloading = "0.5.2" -com-rs = "0.2.0" -winapi = "0.3.7" -bitflags = "1.1.0" +libloading = "0.6.2" +com-rs = "0.2.1" +winapi = "0.3.9" +bitflags = "1.2.1" [dev-dependencies] rspirv = "0.6.0" From a45a97351d16bc1b532c6f29ab3bd87ddcd2689e Mon Sep 17 00:00:00 2001 From: Tomasz Stachowiak Date: Wed, 20 Nov 2019 02:36:41 +0100 Subject: [PATCH 02/31] wip --- src/ffi.rs | 3 +-- src/intellisense/ffi.rs | 4 +--- src/lib.rs | 2 ++ src/os.rs | 17 +++++++++++++++++ src/utils.rs | 8 +++++--- src/wrapper.rs | 3 +-- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 src/os.rs diff --git a/src/ffi.rs b/src/ffi.rs index 7030106..391e8c7 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -1,10 +1,9 @@ #![allow(clippy::transmute_ptr_to_ptr)] #![allow(clippy::too_many_arguments)] +use crate::os::{HRESULT, LPCWSTR, LPWSTR}; use com_rs::{com_interface, iid, IUnknown, IID}; use std::ffi::c_void; -use winapi::shared::ntdef::{LPCWSTR, LPWSTR}; -use winapi::shared::winerror::HRESULT; pub type DxcCreateInstanceProc = extern "system" fn(rclsid: &IID, riid: &IID, ppv: *mut *mut c_void) -> HRESULT; diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index 50855f6..9a29f12 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -1,7 +1,5 @@ +use crate::os::{BSTR, HRESULT, LPCSTR, LPSTR}; use com_rs::{com_interface, iid, IUnknown}; -use winapi::shared::ntdef::{LPCSTR, LPSTR}; -use winapi::shared::winerror::HRESULT; -use winapi::shared::wtypes::BSTR; bitflags! { pub struct DxcGlobalOptions : u32 { diff --git a/src/lib.rs b/src/lib.rs index 1708797..267be76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,11 +36,13 @@ extern crate bitflags; pub mod ffi; +pub mod os; pub mod utils; #[macro_use] pub mod wrapper; +#[cfg(windows)] pub mod intellisense; pub use crate::ffi::*; diff --git a/src/os.rs b/src/os.rs new file mode 100644 index 0000000..e8dbfce --- /dev/null +++ b/src/os.rs @@ -0,0 +1,17 @@ +#[cfg(windows)] +mod os_defs { + pub use winapi::shared{ntdef::{LPSTR, LPWSTR}, wtypes::BSTR}; +} + +#[not(cfg(windows))] +mod os_defs { + use crate::os::raw::c_long; + + pub type LPCSTR = *const CHAR; + pub type LPCWSTR = *const WCHAR; + pub type BSTR = *mut u16; + pub type HRESULT = LONG; + pub type LONG = c_long; +} + +pub use os_defs::*; diff --git a/src/utils.rs b/src/utils.rs index e9f311d..a6b1d23 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,8 +1,8 @@ +use crate::os::{BSTR, LPSTR, LPWSTR}; use crate::wrapper::*; use std::rc::Rc; -use winapi::shared::ntdef::LPSTR; -use winapi::shared::ntdef::LPWSTR; -use winapi::shared::wtypes::BSTR; + +#[cfg(windows)] use winapi::um::oleauto::{SysFreeString, SysStringLen}; pub(crate) fn to_wide(msg: &str) -> Vec { @@ -25,6 +25,7 @@ pub(crate) fn from_wide(wide: LPWSTR) -> String { .unwrap() } +#[cfg(windows)] pub(crate) fn from_bstr(string: BSTR) -> String { unsafe { let len = SysStringLen(string); @@ -36,6 +37,7 @@ pub(crate) fn from_bstr(string: BSTR) -> String { } } +#[cfg(windows)] pub(crate) fn from_lpstr(string: LPSTR) -> String { unsafe { let len = (0..).take_while(|&i| *string.offset(i) != 0).count(); diff --git a/src/wrapper.rs b/src/wrapper.rs index 6f59d46..1c33578 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -1,12 +1,11 @@ use crate::ffi::*; +use crate::os::{HRESULT, LPCSTR, LPSTR}; use crate::utils::{from_wide, to_wide}; use com_rs::ComPtr; use libloading::{Library, Symbol}; use std::convert::Into; use std::ffi::c_void; use std::rc::Rc; -use winapi::shared::ntdef::{LPCWSTR, LPWSTR}; -use winapi::shared::winerror::HRESULT; #[macro_export] macro_rules! return_hr { From c49acdb80a3e51f6ecbb2f26799cc4fe788ed482 Mon Sep 17 00:00:00 2001 From: Tomasz Stachowiak Date: Thu, 21 Nov 2019 00:12:07 +0100 Subject: [PATCH 03/31] well, uh, at least the spirv example doesn't crash... --- Cargo.toml | 1 + src/ffi.rs | 32 ++++++++++++++++++++++++++++++++ src/os.rs | 16 ++++++++++------ src/utils.rs | 30 ++++++++++++------------------ src/wrapper.rs | 41 +++++++++++++++++++++++++++++++++-------- 5 files changed, 88 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3205e4c..6341368 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ libloading = "0.6.2" com-rs = "0.2.1" winapi = "0.3.9" bitflags = "1.2.1" +widestring = "0.4.2" [dev-dependencies] rspirv = "0.6.0" diff --git a/src/ffi.rs b/src/ffi.rs index 391e8c7..f8dc091 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -20,6 +20,8 @@ com_interface! { interface IDxcBlob: IUnknown{ iid: IID_IDxcBlob, vtable: IDxcBlobVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_buffer_pointer() -> *const c_void; fn get_buffer_size() -> usize; } @@ -30,6 +32,8 @@ com_interface! { interface IDxcBlobEncoding: IDxcBlob, IUnknown{ iid: IID_IDxcBlobEncoding, vtable: IDxcBlobEncodingVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_encoding(known: *mut u32, code_page: *mut u32) -> HRESULT; } } @@ -39,6 +43,8 @@ com_interface! { interface IDxcLibrary: IUnknown{ iid: IID_IDxcLibrary, vtable: IDxcLibraryVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn set_malloc(malloc: *const c_void) -> HRESULT; fn create_blob_from_blob(blob: *const IDxcBlob, offset: u32, length: u32, result_blob: *mut *mut IDxcBlob) -> HRESULT; fn create_blob_from_file(filename: LPCWSTR, code_page: *const u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; @@ -57,6 +63,8 @@ com_interface! { interface IDxcOperationResult: IUnknown{ iid: IID_IDxcOperationResult, vtable: IDxcOperationResultVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_status(status: *mut u32) -> HRESULT; fn get_result(result: *mut *mut IDxcBlob) -> HRESULT; fn get_error_buffer(errors: *mut *mut IDxcBlobEncoding) -> HRESULT; @@ -68,6 +76,8 @@ com_interface! { interface IDxcIncludeHandler: IUnknown{ iid: IID_IDxcIncludeHandler, vtable: IDxcIncludeHandlerVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn load_source(filename: LPCWSTR, include_source: *mut *mut IDxcBlob) -> HRESULT; } } @@ -84,6 +94,8 @@ com_interface! { interface IDxcCompiler: IUnknown{ iid: IID_IDxcCompiler, vtable: IDxcCompilerVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn compile( blob: *const IDxcBlob, source_name: LPCWSTR, @@ -117,6 +129,8 @@ com_interface! { interface IDxcCompiler2: IDxcCompiler, IUnknown{ iid: IID_IDxcCompiler2, vtable: IDxcCompiler2Vtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn compile_with_debug( blob: *const IDxcBlob, @@ -139,6 +153,8 @@ com_interface! { interface IDxcLinker: IUnknown{ iid: IID_IDxcLinker, vtable: IDxcLinkerVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn register_library(lib_name: LPCWSTR, lib: *const IDxcBlob) -> HRESULT; @@ -164,6 +180,8 @@ com_interface! { interface IDxcValidator: IUnknown{ iid: IID_IDxcValidator, vtable: IDxcValidatorVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn validate(shader: *const IDxcBlob, flags: u32, result: *mut *mut IDxcOperationResult) -> HRESULT; } @@ -174,6 +192,8 @@ com_interface! { interface IDxcContainerBuilder: IUnknown{ iid: IID_IDxcContainerBuilder, vtable: IDxcContainerBuilderVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn load(dxil_container_header: *const IDxcBlob) -> HRESULT; fn add_part(four_cc: u32, source: *const IDxcBlob) -> HRESULT; @@ -187,6 +207,8 @@ com_interface! { interface IDxcAssembler: IUnknown{ iid: IID_IDxcAssembler, vtable: IDxcAssemblerVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn assemble_to_container(shader: *const IDxcBlob, result: *mut *mut IDxcOperationResult) -> HRESULT; } @@ -197,6 +219,8 @@ com_interface! { interface IDxcContainerReflection: IUnknown{ iid: IID_IDxcContainerReflection, vtable: IDxcContainerReflectionVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn load(container: *const IDxcBlob) -> HRESULT; fn get_part_count(result: *mut u32) -> HRESULT; @@ -212,6 +236,8 @@ com_interface! { interface IDxcOptimizerPass: IUnknown{ iid: IID_IDxcOptimizerPass, vtable: IDxcOptimizerPassVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_option_name(result: *mut LPWSTR) -> HRESULT; fn get_description(result: *mut LPWSTR) -> HRESULT; @@ -226,6 +252,8 @@ com_interface! { interface IDxcOptimizer: IUnknown{ iid: IID_IDxcOptimizer, vtable: IDxcOptimizerVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_available_pass_count(count: *mut u32) -> HRESULT; fn get_available_pass(index: u32, result: *mut *mut IDxcOptimizerPass) -> HRESULT; @@ -247,6 +275,8 @@ com_interface! { interface IDxcVersionInfo: IUnknown{ iid: IID_IDxcVersionInfo, vtable: IDxcVersionInfoVtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_version(major: *mut u32, minor: *mut u32) -> HRESULT; fn get_flags(flags: *mut u32) -> HRESULT; @@ -258,6 +288,8 @@ com_interface! { interface IDxcVersionInfo2: IUnknown{ iid: IID_IDxcVersionInfo2, vtable: IDxcVersionInfo2Vtbl, + fn dummy0() -> HRESULT; + fn dummy1() -> HRESULT; fn get_commit_info(commit_count: *mut u32, commit_hash: *mut *mut u8) -> HRESULT; } diff --git a/src/os.rs b/src/os.rs index e8dbfce..4845427 100644 --- a/src/os.rs +++ b/src/os.rs @@ -1,17 +1,21 @@ #[cfg(windows)] mod os_defs { - pub use winapi::shared{ntdef::{LPSTR, LPWSTR}, wtypes::BSTR}; + pub use winapi::shared::{ + ntdef::{LPSTR, LPWSTR}, + wtypes::BSTR, + }; } -#[not(cfg(windows))] +#[cfg(not(windows))] mod os_defs { - use crate::os::raw::c_long; - + pub type CHAR = i8; + pub type WCHAR = u32; + pub type LPSTR = *mut CHAR; + pub type LPWSTR = *mut WCHAR; pub type LPCSTR = *const CHAR; pub type LPCWSTR = *const WCHAR; - pub type BSTR = *mut u16; pub type HRESULT = LONG; - pub type LONG = c_long; + pub type LONG = i64; } pub use os_defs::*; diff --git a/src/utils.rs b/src/utils.rs index a6b1d23..87ea77f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,35 +1,29 @@ +#[cfg(windows)] use crate::os::{BSTR, LPSTR, LPWSTR}; +use crate::os::{LPWSTR, WCHAR}; use crate::wrapper::*; use std::rc::Rc; #[cfg(windows)] use winapi::um::oleauto::{SysFreeString, SysStringLen}; -pub(crate) fn to_wide(msg: &str) -> Vec { - use std::ffi::OsStr; - use std::iter::once; - use std::os::windows::ffi::OsStrExt; - - let wide: Vec = OsStr::new(msg).encode_wide().chain(once(0)).collect(); - wide +pub(crate) fn to_wide(msg: &str) -> Vec { + widestring::WideCString::from_str(msg).unwrap().into_vec() } pub(crate) fn from_wide(wide: LPWSTR) -> String { - use std::ffi::OsString; - use std::os::windows::ffi::OsStringExt; - - let len = unsafe { (0..).take_while(|&i| *wide.offset(i) != 0).count() }; - - OsString::from_wide(unsafe { std::slice::from_raw_parts(wide, len) }) - .into_string() - .unwrap() + unsafe { + widestring::WideCStr::from_ptr_str(wide) + .to_string() + .expect("utf16 decode failed") + } } #[cfg(windows)] pub(crate) fn from_bstr(string: BSTR) -> String { unsafe { let len = SysStringLen(string); - let slice: &[u16] = ::std::slice::from_raw_parts(string, len as usize); + let slice: &[WCHAR] = ::std::slice::from_raw_parts(string, len as usize); let result = String::from_utf16(slice).unwrap(); SysFreeString(string); @@ -81,10 +75,10 @@ pub fn compile_hlsl( let compiler = dxc.create_compiler().unwrap(); let library = dxc.create_library().unwrap(); - let source = Rc::new(String::from(shader_text)); + //let source = Rc::new(String::from(shader_text)); let blob = library - .create_blob_with_encoding_from_str(Rc::clone(&source)) + .create_blob_with_encoding_from_str(shader_text) .unwrap(); let result = compiler.compile( diff --git a/src/wrapper.rs b/src/wrapper.rs index 1c33578..fa609ca 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -1,5 +1,5 @@ use crate::ffi::*; -use crate::os::{HRESULT, LPCSTR, LPSTR}; +use crate::os::{HRESULT, LPCWSTR, LPWSTR, WCHAR}; use crate::utils::{from_wide, to_wide}; use com_rs::ComPtr; use libloading::{Library, Symbol}; @@ -141,7 +141,8 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { filename: LPCWSTR, include_source: *mut *mut IDxcBlob, ) -> com_rs::HResult { - let me = me as *mut DxcIncludeHandlerWrapper; + unimplemented!(); + /*let me = me as *mut DxcIncludeHandlerWrapper; let filename = crate::utils::from_wide(filename as *mut _); @@ -166,7 +167,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { 0 } else { -2147024894i32 // ERROR_FILE_NOT_FOUND / 0x80070002 - } + }*/ } } @@ -183,7 +184,7 @@ impl DxcCompiler { fn prep_defines( defines: &[(&str, Option<&str>)], - wide_defines: &mut Vec<(Vec, Vec)>, + wide_defines: &mut Vec<(Vec, Vec)>, dxc_defines: &mut Vec, ) { for (name, value) in defines { @@ -202,7 +203,7 @@ impl DxcCompiler { } } - fn prep_args(args: &[&str], wide_args: &mut Vec>, dxc_args: &mut Vec) { + fn prep_args(args: &[&str], wide_args: &mut Vec>, dxc_args: &mut Vec) { for a in args { wide_args.push(to_wide(a)); } @@ -424,11 +425,23 @@ impl DxcLibrary { pub fn create_blob_with_encoding_from_str( &self, - text: Rc, + text: &str, ) -> Result { let mut blob: ComPtr = ComPtr::new(); const CP_UTF8: u32 = 65001; // UTF-8 translation + /*return_hr!( + unsafe { + self.inner.create_blob_with_encoding_on_heap_copy( + text.as_ptr() as *const c_void, + text.len() as u32, + CP_UTF8, + blob.as_mut_ptr(), + ) + }, + DxcBlobEncoding::new(blob) + );*/ + return_hr!( unsafe { self.inner.create_blob_with_encoding_from_pinned( @@ -466,9 +479,21 @@ pub struct Dxc { dxc_lib: Library, } +#[cfg(windows)] +fn dxcompiler_lib_name() -> &'static str { + "dxcompiler.dll" +} + +#[cfg(not(windows))] +fn dxcompiler_lib_name() -> &'static str { + "../dxc-rs/target/debug/build/dxc-rs-05a2fe30f551ddd3/out/lib/libdxcompiler.so" + //"/home/h3/Downloads/ShaderConductor-linux-clang7-x64-Release/Lib/libdxcompiler.so" + //"/home/h3/Downloads/ShaderConductor-linux-clang6-x64-Release/Lib/libdxcompiler.so" +} + impl Dxc { pub fn new() -> Self { - let dxc_lib = Library::new("dxcompiler.dll").expect("Failed to load dxcompiler.dll"); + let dxc_lib = Library::new(dxcompiler_lib_name()).expect("Failed to load dxcompiler.dll"); Self { dxc_lib } } @@ -523,7 +548,7 @@ impl DxcValidator { }; if result_hr != 0 { - return Err(result_hr); + return Err(result_hr as _); } let mut major = 0; From 3c322372f61688377821df8d04bfdfe228f88c5a Mon Sep 17 00:00:00 2001 From: Tomasz Stachowiak Date: Thu, 21 Nov 2019 00:58:50 +0100 Subject: [PATCH 04/31] include example works too --- src/wrapper.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wrapper.rs b/src/wrapper.rs index fa609ca..d956c13 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -106,6 +106,8 @@ struct DxcIncludeHandlerWrapperVtbl { ) -> com_rs::HResult, add_ref: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, release: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, + dummy0: *const c_void, + dummy1: *const c_void, load_source: extern "stdcall" fn(*mut com_rs::IUnknown, LPCWSTR, *mut *mut IDxcBlob) -> com_rs::HResult, } @@ -141,8 +143,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { filename: LPCWSTR, include_source: *mut *mut IDxcBlob, ) -> com_rs::HResult { - unimplemented!(); - /*let me = me as *mut DxcIncludeHandlerWrapper; + let me = me as *mut DxcIncludeHandlerWrapper; let filename = crate::utils::from_wide(filename as *mut _); @@ -154,7 +155,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { let mut blob = unsafe { (*me) .library - .create_blob_with_encoding_from_str(Rc::clone(&pinned_source)) + .create_blob_with_encoding_from_str(&*pinned_source) .unwrap() }; @@ -167,7 +168,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { 0 } else { -2147024894i32 // ERROR_FILE_NOT_FOUND / 0x80070002 - }*/ + } } } @@ -222,6 +223,8 @@ impl DxcCompiler { query_interface: DxcIncludeHandlerWrapper::query_interface, add_ref: DxcIncludeHandlerWrapper::add_ref, release: DxcIncludeHandlerWrapper::release, + dummy0: std::ptr::null(), + dummy1: std::ptr::null(), load_source: DxcIncludeHandlerWrapper::load_source, }; From 14a61ae86510006313cf8434e26d180a75b8176d Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 15:43:17 +0200 Subject: [PATCH 05/31] Type include_handler as *const IDxcIncludeHandler instead of c_void --- src/ffi.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index f8dc091..0ee3f2c 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -105,7 +105,7 @@ com_interface! { arg_count: u32, defines: *const DxcDefine, def_count: u32, - include_handler: *const c_void, + include_handler: *const IDxcIncludeHandler, result: *mut *mut IDxcOperationResult) -> HRESULT; fn preprocess( @@ -115,7 +115,7 @@ com_interface! { arg_count: u32, defines: *const DxcDefine, def_count: u32, - include_handler: *const c_void, + include_handler: *const IDxcIncludeHandler, result: *mut *mut IDxcOperationResult) -> HRESULT; fn disassemble( @@ -141,7 +141,7 @@ com_interface! { arg_count: u32, defines: *const DxcDefine, def_count: u32, - include_handler: *const c_void, + include_handler: *const IDxcIncludeHandler, result: *mut *mut IDxcOperationResult, debug_blob_name: *mut LPWSTR, debug_blob: *mut *mut IDxcBlob) -> HRESULT; From ea093bbfe8db8d2881aebffe3cfefc05a155cc8e Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 27 May 2020 12:13:17 +0200 Subject: [PATCH 06/31] [LINUX] Fix warnings --- src/lib.rs | 1 - src/utils.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 267be76..026e5af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,6 @@ //! ); //! ``` -#[macro_use] extern crate bitflags; pub mod ffi; diff --git a/src/utils.rs b/src/utils.rs index 87ea77f..3002058 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,7 +2,6 @@ use crate::os::{BSTR, LPSTR, LPWSTR}; use crate::os::{LPWSTR, WCHAR}; use crate::wrapper::*; -use std::rc::Rc; #[cfg(windows)] use winapi::um::oleauto::{SysFreeString, SysStringLen}; From 123c99b4b38ba0120e9bd4a487dc4fd73a1e92ce Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 1 Jul 2020 16:09:36 +0200 Subject: [PATCH 07/31] Fix check/clippy warnings --- src/ffi.rs | 18 +++++++++--------- src/wrapper.rs | 10 ++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index 0ee3f2c..3c1fabc 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -295,12 +295,12 @@ com_interface! { } } -iid!(pub CLSID_DxcCompiler = 0x73e22d93, 0xe6ce, 0x47f3, 0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0); -iid!(pub CLSID_DxcLinker = 0xef6a8087, 0xb0ea, 0x4d56, 0x9e, 0x45, 0xd0, 0x7e, 0x1a, 0x8b, 0x78, 0x6); -iid!(pub CLSID_DxcDiaDataSource = 0xcd1f6b73, 0x2ab0, 0x484d, 0x8e, 0xdc, 0xeb, 0xe7, 0xa4, 0x3c, 0xa0, 0x9f ); -iid!(pub CLSID_DxcLibrary = 0x6245d6af, 0x66e0, 0x48fd, 0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c); -iid!(pub CLSID_DxcValidator = 0x8ca3e215, 0xf728, 0x4cf3, 0x8c, 0xdd, 0x88, 0xaf, 0x91, 0x75, 0x87, 0xa1 ); -iid!(pub CLSID_DxcAssembler = 0xd728db68, 0xf903, 0x4f80, 0x94, 0xcd, 0xdc, 0xcf, 0x76, 0xec, 0x71, 0x51); -iid!(pub CLSID_DxcContainerReflection = 0xb9f54489, 0x55b8, 0x400c, 0xba, 0x3a, 0x16, 0x75, 0xe4, 0x72, 0x8b, 0x91); -iid!(pub CLSID_DxcOptimizer = 0xae2cd79f, 0xcc22, 0x453f, 0x9b, 0x6b, 0xb1, 0x24, 0xe7, 0xa5, 0x20, 0x4c); -iid!(pub CLSID_DxcContainerBuilder = 0x94134294, 0x411f, 0x4574, 0xb4, 0xd0, 0x87, 0x41, 0xe2, 0x52, 0x40, 0xd2 ); +iid!(pub CLSID_DxcCompiler = 0x73e2_2d93, 0xe6ce, 0x47f3, 0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0); +iid!(pub CLSID_DxcLinker = 0xef6a_8087, 0xb0ea, 0x4d56, 0x9e, 0x45, 0xd0, 0x7e, 0x1a, 0x8b, 0x78, 0x6); +iid!(pub CLSID_DxcDiaDataSource = 0xcd1f_6b73, 0x2ab0, 0x484d, 0x8e, 0xdc, 0xeb, 0xe7, 0xa4, 0x3c, 0xa0, 0x9f ); +iid!(pub CLSID_DxcLibrary = 0x6245_d6af, 0x66e0, 0x48fd, 0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c); +iid!(pub CLSID_DxcValidator = 0x8ca3_e215, 0xf728, 0x4cf3, 0x8c, 0xdd, 0x88, 0xaf, 0x91, 0x75, 0x87, 0xa1 ); +iid!(pub CLSID_DxcAssembler = 0xd728_db68, 0xf903, 0x4f80, 0x94, 0xcd, 0xdc, 0xcf, 0x76, 0xec, 0x71, 0x51); +iid!(pub CLSID_DxcContainerReflection = 0xb9f5_4489, 0x55b8, 0x400c, 0xba, 0x3a, 0x16, 0x75, 0xe4, 0x72, 0x8b, 0x91); +iid!(pub CLSID_DxcOptimizer = 0xae2c_d79f, 0xcc22, 0x453f, 0x9b, 0x6b, 0xb1, 0x24, 0xe7, 0xa5, 0x20, 0x4c); +iid!(pub CLSID_DxcContainerBuilder = 0x9413_4294, 0x411f, 0x4574, 0xb4, 0xd0, 0x87, 0x41, 0xe2, 0x52, 0x40, 0xd2 ); diff --git a/src/wrapper.rs b/src/wrapper.rs index d956c13..f52d153 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -1,3 +1,9 @@ +#![allow( + clippy::too_many_arguments, + clippy::new_without_default, + clippy::type_complexity +)] + use crate::ffi::*; use crate::os::{HRESULT, LPCWSTR, LPWSTR, WCHAR}; use crate::utils::{from_wide, to_wide}; @@ -167,7 +173,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { 0 } else { - -2147024894i32 // ERROR_FILE_NOT_FOUND / 0x80070002 + -2_147_024_894_i32 // ERROR_FILE_NOT_FOUND / 0x80070002 } } } @@ -209,7 +215,7 @@ impl DxcCompiler { wide_args.push(to_wide(a)); } - for ref a in wide_args { + for a in wide_args { dxc_args.push(a.as_ptr()); } } From 4b1706a5439a8f66829590678653043526b846c2 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 11:57:22 +0200 Subject: [PATCH 08/31] os: Add BSTR type on non-Windows --- src/os.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/os.rs b/src/os.rs index 4845427..50b0aa1 100644 --- a/src/os.rs +++ b/src/os.rs @@ -10,10 +10,13 @@ mod os_defs { mod os_defs { pub type CHAR = i8; pub type WCHAR = u32; + pub type OLECHAR = WCHAR; pub type LPSTR = *mut CHAR; pub type LPWSTR = *mut WCHAR; pub type LPCSTR = *const CHAR; pub type LPCWSTR = *const WCHAR; + pub type BSTR = *mut OLECHAR; + pub type LPBSTR = *mut BSTR; pub type HRESULT = LONG; pub type LONG = i64; } From a9501bd52d2f7263caed8aa0695b6edeaebdf747 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 11:58:08 +0200 Subject: [PATCH 09/31] lib: Fix bitflags macro include extern crate requires deprecated `#[macro_use]`, which should be replaced with `use` instead. --- src/intellisense/ffi.rs | 1 + src/lib.rs | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index 9a29f12..dde8d00 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -1,4 +1,5 @@ use crate::os::{BSTR, HRESULT, LPCSTR, LPSTR}; +use bitflags::bitflags; use com_rs::{com_interface, iid, IUnknown}; bitflags! { diff --git a/src/lib.rs b/src/lib.rs index 026e5af..6941c36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,8 +32,6 @@ //! ); //! ``` -extern crate bitflags; - pub mod ffi; pub mod os; pub mod utils; From 2a5856e4a543f3cafd204cdab21ecaec6d038da4 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 12:15:58 +0200 Subject: [PATCH 10/31] Make intellisense compile on Linux --- src/intellisense/wrapper.rs | 4 +--- src/lib.rs | 1 - src/utils.rs | 13 +++++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/intellisense/wrapper.rs b/src/intellisense/wrapper.rs index 51aa47a..ab303a7 100644 --- a/src/intellisense/wrapper.rs +++ b/src/intellisense/wrapper.rs @@ -1,10 +1,8 @@ use crate::intellisense::ffi::*; +use crate::os::{BSTR, HRESULT, LPSTR}; use crate::wrapper::Dxc; use com_rs::ComPtr; use std::ffi::CString; -use winapi::shared::ntdef::LPSTR; -use winapi::shared::winerror::HRESULT; -use winapi::shared::wtypes::BSTR; #[derive(Debug)] pub struct DxcIntellisense { diff --git a/src/lib.rs b/src/lib.rs index 6941c36..dd2643a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ pub mod utils; #[macro_use] pub mod wrapper; -#[cfg(windows)] pub mod intellisense; pub use crate::ffi::*; diff --git a/src/utils.rs b/src/utils.rs index 3002058..72f11b2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,4 @@ -#[cfg(windows)] -use crate::os::{BSTR, LPSTR, LPWSTR}; -use crate::os::{LPWSTR, WCHAR}; +use crate::os::{BSTR, LPSTR, LPWSTR, WCHAR}; use crate::wrapper::*; #[cfg(windows)] @@ -30,7 +28,14 @@ pub(crate) fn from_bstr(string: BSTR) -> String { } } -#[cfg(windows)] +#[cfg(not(windows))] +pub(crate) fn from_bstr(string: BSTR) -> String { + // TODO (Marijn): This does NOT cover embedded NULLs: + // https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysstringlen#remarks + // Fortunately BSTRs are only used in names currently, which _likely_ don't include NULL characters (like binary data) + from_lpstr(string as LPSTR) +} + pub(crate) fn from_lpstr(string: LPSTR) -> String { unsafe { let len = (0..).take_while(|&i| *string.offset(i) != 0).count(); From d056a6d69b13cf5380b07827c1a9a4201ee278d3 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 12:20:01 +0200 Subject: [PATCH 11/31] [LINUX ONLY] intellisense: Insert the usual destructor dummies --- src/intellisense/ffi.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index dde8d00..9b53f27 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -304,6 +304,8 @@ com_interface! { interface IDxcDiagnostic: IUnknown{ iid: IID_IDxcDiagnostic, vtable: IDxcDiagnosticVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn format_diagnostic(options: DxcDiagnosticDisplayOptions, result: *mut LPSTR) -> HRESULT; fn get_severity(result: *mut DxcDiagnosticSeverity) -> HRESULT; fn get_location(result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -321,6 +323,8 @@ com_interface! { interface IDxcInclusion: IUnknown{ iid: IID_IDxcInclusion, vtable: IDxcInclusionVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_included_file(result: *mut *mut IDxcFile) -> HRESULT; fn get_stack_length(result: *mut u32) -> HRESULT; fn get_stack_item(index: u32, result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -332,6 +336,8 @@ com_interface! { interface IDxcToken: IUnknown{ iid: IID_IDxcToken, vtable: IDxcTokenVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_kind(value: *mut DxcTokenKind) -> HRESULT; fn get_location(value: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_extent(value: *mut *mut IDxcSourceRange) -> HRESULT; @@ -344,6 +350,8 @@ com_interface! { interface IDxcType: IUnknown{ iid: IID_IDxcType, vtable: IDxcTypeVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_spelling(result: *mut LPSTR) -> HRESULT; fn is_equal_to(other: *const IDxcType, result: *mut bool) -> HRESULT; fn get_kind(result: *mut IDxcType) -> HRESULT; @@ -355,9 +363,11 @@ com_interface! { interface IDxcSourceLocation: IUnknown{ iid: IID_IDxcSourceLocation, vtable: IDxcSourceLocationVtbl, - fn is_equal_to(other: *const IDxcSourceLocation, result: *mut bool) ->HRESULT; - fn get_spelling_location(file: *mut *mut IDxcFile, line: *mut u32, col: *mut u32, offset: *mut u32) ->HRESULT; - fn is_null(result: *mut bool) ->HRESULT; + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; + fn is_equal_to(other: *const IDxcSourceLocation, result: *mut bool) -> HRESULT; + fn get_spelling_location(file: *mut *mut IDxcFile, line: *mut u32, col: *mut u32, offset: *mut u32) -> HRESULT; + fn is_null(result: *mut bool) -> HRESULT; } } @@ -366,6 +376,8 @@ com_interface! { interface IDxcSourceRange: IUnknown{ iid: IID_IDxcSourceRange, vtable: IDxcSourceRangeVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn is_null(value: *mut bool) -> HRESULT; fn get_start(value: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_end(value: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -378,6 +390,8 @@ com_interface! { interface IDxcCursor: IUnknown{ iid: IID_IDxcCursor, vtable: IDxcCursorVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_extent(range: *mut *mut IDxcSourceRange) -> HRESULT; fn get_location(result: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_kind(result: *mut DxcCursorKind) -> HRESULT; @@ -407,6 +421,8 @@ com_interface! { interface IDxcUnsavedFile: IUnknown{ iid: IID_IDxcUnsavedFile, vtable: IDxcUnsavedFileVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_file_name(file_name: *mut LPSTR) -> HRESULT; fn get_contents(contents: *mut LPSTR) -> HRESULT; fn get_length(lenth : *mut u32) -> HRESULT; @@ -428,6 +444,8 @@ com_interface! { interface IDxcTranslationUnit: IUnknown{ iid: IID_IDxcTranslationUnit, vtable: IDxcTranslationUnitVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn get_cursor(cursor: *mut *mut IDxcCursor) -> HRESULT; fn tokenize(range: *const IDxcSourceRange, tokens: *mut *mut *mut IDxcToken, token_count: *mut u32) -> HRESULT; fn get_location( file: *mut IDxcFile, line: u32, column: u32, result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -451,6 +469,8 @@ com_interface! { interface IDxcIndex: IUnknown{ iid: IID_IDxcIndex, vtable: IDxcIndexVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn set_global_options(options: DxcGlobalOptions) -> HRESULT; fn get_global_options(options: *mut DxcGlobalOptions) -> HRESULT; fn parse_translation_unit( @@ -469,6 +489,8 @@ com_interface! { interface IDxcIntelliSense: IUnknown{ iid: IID_IDxcIntelliSense, vtable: IDxcIntelliSenseVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; fn create_index(index: *mut *mut IDxcIndex) -> HRESULT; fn get_null_location(location: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_null_range(location: *mut *mut IDxcSourceRange) -> HRESULT; From 7df6938a6bcd3e9b089e77ff2dbafabd0512db8f Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Fri, 3 Jul 2020 02:05:07 +0200 Subject: [PATCH 12/31] [WINDOWS] Make OS wrapper types compatible with Windows again HRESULT is 32-bit: https://en.wikipedia.org/wiki/HRESULT --- src/os.rs | 5 ++--- src/wrapper.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/os.rs b/src/os.rs index 50b0aa1..bda56b8 100644 --- a/src/os.rs +++ b/src/os.rs @@ -1,7 +1,7 @@ #[cfg(windows)] mod os_defs { pub use winapi::shared::{ - ntdef::{LPSTR, LPWSTR}, + ntdef::{HRESULT, LPCSTR, LPCWSTR, LPSTR, LPWSTR, WCHAR}, wtypes::BSTR, }; } @@ -17,8 +17,7 @@ mod os_defs { pub type LPCWSTR = *const WCHAR; pub type BSTR = *mut OLECHAR; pub type LPBSTR = *mut BSTR; - pub type HRESULT = LONG; - pub type LONG = i64; + pub type HRESULT = i32; } pub use os_defs::*; diff --git a/src/wrapper.rs b/src/wrapper.rs index f52d153..f5c3658 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -173,7 +173,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { 0 } else { - -2_147_024_894_i32 // ERROR_FILE_NOT_FOUND / 0x80070002 + -2_147_024_894 // ERROR_FILE_NOT_FOUND / 0x80070002 } } } From 760d493146ab88a513c4c3b45d3e8a5c0bfe92b0 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 13:41:08 +0200 Subject: [PATCH 13/31] Delete dummy functions (virtual dtors) again This assumes a DXC compiled without virtual destructor! Which - as it stands - is invalid with undefined behaviour, but "works". This needs followup in DXC itself. This includes a revert of commit 308dd8625c8eb05d95cf0800918bb418ce837ca5. --- src/ffi.rs | 32 -------------------------------- src/intellisense/ffi.rs | 22 ---------------------- src/wrapper.rs | 4 ---- 3 files changed, 58 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index 3c1fabc..6057012 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -20,8 +20,6 @@ com_interface! { interface IDxcBlob: IUnknown{ iid: IID_IDxcBlob, vtable: IDxcBlobVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_buffer_pointer() -> *const c_void; fn get_buffer_size() -> usize; } @@ -32,8 +30,6 @@ com_interface! { interface IDxcBlobEncoding: IDxcBlob, IUnknown{ iid: IID_IDxcBlobEncoding, vtable: IDxcBlobEncodingVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_encoding(known: *mut u32, code_page: *mut u32) -> HRESULT; } } @@ -43,8 +39,6 @@ com_interface! { interface IDxcLibrary: IUnknown{ iid: IID_IDxcLibrary, vtable: IDxcLibraryVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn set_malloc(malloc: *const c_void) -> HRESULT; fn create_blob_from_blob(blob: *const IDxcBlob, offset: u32, length: u32, result_blob: *mut *mut IDxcBlob) -> HRESULT; fn create_blob_from_file(filename: LPCWSTR, code_page: *const u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; @@ -63,8 +57,6 @@ com_interface! { interface IDxcOperationResult: IUnknown{ iid: IID_IDxcOperationResult, vtable: IDxcOperationResultVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_status(status: *mut u32) -> HRESULT; fn get_result(result: *mut *mut IDxcBlob) -> HRESULT; fn get_error_buffer(errors: *mut *mut IDxcBlobEncoding) -> HRESULT; @@ -76,8 +68,6 @@ com_interface! { interface IDxcIncludeHandler: IUnknown{ iid: IID_IDxcIncludeHandler, vtable: IDxcIncludeHandlerVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn load_source(filename: LPCWSTR, include_source: *mut *mut IDxcBlob) -> HRESULT; } } @@ -94,8 +84,6 @@ com_interface! { interface IDxcCompiler: IUnknown{ iid: IID_IDxcCompiler, vtable: IDxcCompilerVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn compile( blob: *const IDxcBlob, source_name: LPCWSTR, @@ -129,8 +117,6 @@ com_interface! { interface IDxcCompiler2: IDxcCompiler, IUnknown{ iid: IID_IDxcCompiler2, vtable: IDxcCompiler2Vtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn compile_with_debug( blob: *const IDxcBlob, @@ -153,8 +139,6 @@ com_interface! { interface IDxcLinker: IUnknown{ iid: IID_IDxcLinker, vtable: IDxcLinkerVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn register_library(lib_name: LPCWSTR, lib: *const IDxcBlob) -> HRESULT; @@ -180,8 +164,6 @@ com_interface! { interface IDxcValidator: IUnknown{ iid: IID_IDxcValidator, vtable: IDxcValidatorVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn validate(shader: *const IDxcBlob, flags: u32, result: *mut *mut IDxcOperationResult) -> HRESULT; } @@ -192,8 +174,6 @@ com_interface! { interface IDxcContainerBuilder: IUnknown{ iid: IID_IDxcContainerBuilder, vtable: IDxcContainerBuilderVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn load(dxil_container_header: *const IDxcBlob) -> HRESULT; fn add_part(four_cc: u32, source: *const IDxcBlob) -> HRESULT; @@ -207,8 +187,6 @@ com_interface! { interface IDxcAssembler: IUnknown{ iid: IID_IDxcAssembler, vtable: IDxcAssemblerVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn assemble_to_container(shader: *const IDxcBlob, result: *mut *mut IDxcOperationResult) -> HRESULT; } @@ -219,8 +197,6 @@ com_interface! { interface IDxcContainerReflection: IUnknown{ iid: IID_IDxcContainerReflection, vtable: IDxcContainerReflectionVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn load(container: *const IDxcBlob) -> HRESULT; fn get_part_count(result: *mut u32) -> HRESULT; @@ -236,8 +212,6 @@ com_interface! { interface IDxcOptimizerPass: IUnknown{ iid: IID_IDxcOptimizerPass, vtable: IDxcOptimizerPassVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_option_name(result: *mut LPWSTR) -> HRESULT; fn get_description(result: *mut LPWSTR) -> HRESULT; @@ -252,8 +226,6 @@ com_interface! { interface IDxcOptimizer: IUnknown{ iid: IID_IDxcOptimizer, vtable: IDxcOptimizerVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_available_pass_count(count: *mut u32) -> HRESULT; fn get_available_pass(index: u32, result: *mut *mut IDxcOptimizerPass) -> HRESULT; @@ -275,8 +247,6 @@ com_interface! { interface IDxcVersionInfo: IUnknown{ iid: IID_IDxcVersionInfo, vtable: IDxcVersionInfoVtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_version(major: *mut u32, minor: *mut u32) -> HRESULT; fn get_flags(flags: *mut u32) -> HRESULT; @@ -288,8 +258,6 @@ com_interface! { interface IDxcVersionInfo2: IUnknown{ iid: IID_IDxcVersionInfo2, vtable: IDxcVersionInfo2Vtbl, - fn dummy0() -> HRESULT; - fn dummy1() -> HRESULT; fn get_commit_info(commit_count: *mut u32, commit_hash: *mut *mut u8) -> HRESULT; } diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index 9b53f27..ee6220c 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -304,8 +304,6 @@ com_interface! { interface IDxcDiagnostic: IUnknown{ iid: IID_IDxcDiagnostic, vtable: IDxcDiagnosticVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn format_diagnostic(options: DxcDiagnosticDisplayOptions, result: *mut LPSTR) -> HRESULT; fn get_severity(result: *mut DxcDiagnosticSeverity) -> HRESULT; fn get_location(result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -323,8 +321,6 @@ com_interface! { interface IDxcInclusion: IUnknown{ iid: IID_IDxcInclusion, vtable: IDxcInclusionVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_included_file(result: *mut *mut IDxcFile) -> HRESULT; fn get_stack_length(result: *mut u32) -> HRESULT; fn get_stack_item(index: u32, result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -336,8 +332,6 @@ com_interface! { interface IDxcToken: IUnknown{ iid: IID_IDxcToken, vtable: IDxcTokenVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_kind(value: *mut DxcTokenKind) -> HRESULT; fn get_location(value: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_extent(value: *mut *mut IDxcSourceRange) -> HRESULT; @@ -350,8 +344,6 @@ com_interface! { interface IDxcType: IUnknown{ iid: IID_IDxcType, vtable: IDxcTypeVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_spelling(result: *mut LPSTR) -> HRESULT; fn is_equal_to(other: *const IDxcType, result: *mut bool) -> HRESULT; fn get_kind(result: *mut IDxcType) -> HRESULT; @@ -363,8 +355,6 @@ com_interface! { interface IDxcSourceLocation: IUnknown{ iid: IID_IDxcSourceLocation, vtable: IDxcSourceLocationVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn is_equal_to(other: *const IDxcSourceLocation, result: *mut bool) -> HRESULT; fn get_spelling_location(file: *mut *mut IDxcFile, line: *mut u32, col: *mut u32, offset: *mut u32) -> HRESULT; fn is_null(result: *mut bool) -> HRESULT; @@ -376,8 +366,6 @@ com_interface! { interface IDxcSourceRange: IUnknown{ iid: IID_IDxcSourceRange, vtable: IDxcSourceRangeVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn is_null(value: *mut bool) -> HRESULT; fn get_start(value: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_end(value: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -390,8 +378,6 @@ com_interface! { interface IDxcCursor: IUnknown{ iid: IID_IDxcCursor, vtable: IDxcCursorVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_extent(range: *mut *mut IDxcSourceRange) -> HRESULT; fn get_location(result: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_kind(result: *mut DxcCursorKind) -> HRESULT; @@ -421,8 +407,6 @@ com_interface! { interface IDxcUnsavedFile: IUnknown{ iid: IID_IDxcUnsavedFile, vtable: IDxcUnsavedFileVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_file_name(file_name: *mut LPSTR) -> HRESULT; fn get_contents(contents: *mut LPSTR) -> HRESULT; fn get_length(lenth : *mut u32) -> HRESULT; @@ -444,8 +428,6 @@ com_interface! { interface IDxcTranslationUnit: IUnknown{ iid: IID_IDxcTranslationUnit, vtable: IDxcTranslationUnitVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn get_cursor(cursor: *mut *mut IDxcCursor) -> HRESULT; fn tokenize(range: *const IDxcSourceRange, tokens: *mut *mut *mut IDxcToken, token_count: *mut u32) -> HRESULT; fn get_location( file: *mut IDxcFile, line: u32, column: u32, result: *mut *mut IDxcSourceLocation) -> HRESULT; @@ -469,8 +451,6 @@ com_interface! { interface IDxcIndex: IUnknown{ iid: IID_IDxcIndex, vtable: IDxcIndexVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn set_global_options(options: DxcGlobalOptions) -> HRESULT; fn get_global_options(options: *mut DxcGlobalOptions) -> HRESULT; fn parse_translation_unit( @@ -489,8 +469,6 @@ com_interface! { interface IDxcIntelliSense: IUnknown{ iid: IID_IDxcIntelliSense, vtable: IDxcIntelliSenseVtbl, - fn complete_object_destructor() -> HRESULT; - fn deleting_destructor() -> HRESULT; fn create_index(index: *mut *mut IDxcIndex) -> HRESULT; fn get_null_location(location: *mut *mut IDxcSourceLocation) -> HRESULT; fn get_null_range(location: *mut *mut IDxcSourceRange) -> HRESULT; diff --git a/src/wrapper.rs b/src/wrapper.rs index f5c3658..f01bf02 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -112,8 +112,6 @@ struct DxcIncludeHandlerWrapperVtbl { ) -> com_rs::HResult, add_ref: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, release: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, - dummy0: *const c_void, - dummy1: *const c_void, load_source: extern "stdcall" fn(*mut com_rs::IUnknown, LPCWSTR, *mut *mut IDxcBlob) -> com_rs::HResult, } @@ -229,8 +227,6 @@ impl DxcCompiler { query_interface: DxcIncludeHandlerWrapper::query_interface, add_ref: DxcIncludeHandlerWrapper::add_ref, release: DxcIncludeHandlerWrapper::release, - dummy0: std::ptr::null(), - dummy1: std::ptr::null(), load_source: DxcIncludeHandlerWrapper::load_source, }; From c37cb037be072cac43f2706b89f1388b9deee19a Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 6 Jul 2020 20:41:40 +0200 Subject: [PATCH 14/31] [WIN/LINUX] Implement vtable dummies (virtual dtors) through extra trait TODO: Might as well keep the IUnknown name and "hide" the COM one (less changes, as long as the right one is use'd. --- src/ffi.rs | 33 ++++++++++++++------------- src/intellisense/ffi.rs | 25 +++++++++++---------- src/lib.rs | 2 ++ src/unknown.rs | 50 +++++++++++++++++++++++++++++++++++++++++ src/wrapper.rs | 22 ++++++++++-------- 5 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 src/unknown.rs diff --git a/src/ffi.rs b/src/ffi.rs index 6057012..29c9576 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -2,6 +2,7 @@ #![allow(clippy::too_many_arguments)] use crate::os::{HRESULT, LPCWSTR, LPWSTR}; +pub(crate) use crate::unknown::IDxcUnknownShim; use com_rs::{com_interface, iid, IUnknown, IID}; use std::ffi::c_void; @@ -17,7 +18,7 @@ pub type DxcCreateInstanceProc2 = extern "system" fn( iid!(pub IID_IDxcBlob = 0x8BA5_FB08, 0x5195, 0x40e2, 0xAC, 0x58, 0x0D, 0x98, 0x9C, 0x3A, 0x01, 0x02); com_interface! { - interface IDxcBlob: IUnknown{ + interface IDxcBlob: IDxcUnknownShim, IUnknown { iid: IID_IDxcBlob, vtable: IDxcBlobVtbl, fn get_buffer_pointer() -> *const c_void; @@ -27,7 +28,7 @@ com_interface! { iid!(pub IID_IDxcBlobEncoding = 0x7241_d424, 0x2646, 0x4191, 0x97, 0xc0, 0x98, 0xe9, 0x6e, 0x42, 0xfc, 0x68); com_interface! { - interface IDxcBlobEncoding: IDxcBlob, IUnknown{ + interface IDxcBlobEncoding: IDxcBlob, IDxcUnknownShim, IUnknown { iid: IID_IDxcBlobEncoding, vtable: IDxcBlobEncodingVtbl, fn get_encoding(known: *mut u32, code_page: *mut u32) -> HRESULT; @@ -36,7 +37,7 @@ com_interface! { iid!(pub IID_IDxcLibrary = 0xe520_4dc7, 0xd18c, 0x4c3c, 0xbd, 0xfb, 0x85, 0x16, 0x73, 0x98, 0x0f, 0xe7); com_interface! { - interface IDxcLibrary: IUnknown{ + interface IDxcLibrary: IDxcUnknownShim, IUnknown { iid: IID_IDxcLibrary, vtable: IDxcLibraryVtbl, fn set_malloc(malloc: *const c_void) -> HRESULT; @@ -54,7 +55,7 @@ com_interface! { iid!(pub IID_IDxcOperationResult = 0xCEDB_484A, 0xD4E9, 0x445A, 0xB9, 0x91, 0xCA, 0x21, 0xCA, 0x15, 0x7D, 0xC2); com_interface! { - interface IDxcOperationResult: IUnknown{ + interface IDxcOperationResult: IDxcUnknownShim, IUnknown { iid: IID_IDxcOperationResult, vtable: IDxcOperationResultVtbl, fn get_status(status: *mut u32) -> HRESULT; @@ -65,7 +66,7 @@ com_interface! { iid!(pub IID_IDxcIncludeHandler = 0x7f61_fc7d, 0x950d, 0x467f, 0xb3, 0xe3, 0x3c, 0x02, 0xfb, 0x49, 0x18, 0x7c); com_interface! { - interface IDxcIncludeHandler: IUnknown{ + interface IDxcIncludeHandler: IDxcUnknownShim, IUnknown { iid: IID_IDxcIncludeHandler, vtable: IDxcIncludeHandlerVtbl, fn load_source(filename: LPCWSTR, include_source: *mut *mut IDxcBlob) -> HRESULT; @@ -81,7 +82,7 @@ pub struct DxcDefine { iid!(pub IID_IDxcCompiler = 0x8c21_0bf3, 0x011f, 0x4422, 0x8d, 0x70, 0x6f, 0x9a, 0xcb, 0x8d, 0xb6, 0x17); com_interface! { - interface IDxcCompiler: IUnknown{ + interface IDxcCompiler: IDxcUnknownShim, IUnknown { iid: IID_IDxcCompiler, vtable: IDxcCompilerVtbl, fn compile( @@ -114,7 +115,7 @@ com_interface! { iid!(pub IID_IDxcCompiler2 = 0xA005_A9D9, 0xB8BB, 0x4594, 0xB5, 0xC9, 0x0E, 0x63, 0x3B, 0xEC, 0x4D, 0x37); com_interface! { - interface IDxcCompiler2: IDxcCompiler, IUnknown{ + interface IDxcCompiler2: IDxcCompiler, IDxcUnknownShim, IUnknown { iid: IID_IDxcCompiler2, vtable: IDxcCompiler2Vtbl, @@ -136,7 +137,7 @@ com_interface! { iid!(pub IID_IDxcLinker = 0xF1B5_BE2A, 0x62DD, 0x4327, 0xA1, 0xC2, 0x42, 0xAC, 0x1E, 0x1E, 0x78, 0xE6); com_interface! { - interface IDxcLinker: IUnknown{ + interface IDxcLinker: IDxcUnknownShim, IUnknown { iid: IID_IDxcLinker, vtable: IDxcLinkerVtbl, @@ -161,7 +162,7 @@ pub const DXC_VALIDATOR_FLAGS_VALID_MASK: u32 = 0x7; iid!(pub IID_IDxcValidator = 0xA6E8_2BD2, 0x1FD7, 0x4826, 0x98, 0x11, 0x28, 0x57, 0xE7, 0x97, 0xF4, 0x9A); com_interface! { - interface IDxcValidator: IUnknown{ + interface IDxcValidator: IDxcUnknownShim, IUnknown { iid: IID_IDxcValidator, vtable: IDxcValidatorVtbl, @@ -171,7 +172,7 @@ com_interface! { iid!(pub IID_IDxcContainerBuilder = 0x334b_1f50, 0x2292, 0x4b35, 0x99, 0xa1, 0x25, 0x58, 0x8d, 0x8c, 0x17, 0xfe); com_interface! { - interface IDxcContainerBuilder: IUnknown{ + interface IDxcContainerBuilder: IDxcUnknownShim, IUnknown { iid: IID_IDxcContainerBuilder, vtable: IDxcContainerBuilderVtbl, @@ -184,7 +185,7 @@ com_interface! { iid!(pub IID_IDxcAssembler = 0x091f_7a26, 0x1c1f, 0x4948, 0x90, 0x4b, 0xe6, 0xe3, 0xa8, 0xa7, 0x71, 0xd5); com_interface! { - interface IDxcAssembler: IUnknown{ + interface IDxcAssembler: IDxcUnknownShim, IUnknown { iid: IID_IDxcAssembler, vtable: IDxcAssemblerVtbl, @@ -194,7 +195,7 @@ com_interface! { iid!(pub IID_IDxcContainerReflection = 0xd2c2_1b26, 0x8350, 0x4bdc, 0x97, 0x6a, 0x33, 0x1c, 0xe6, 0xf4, 0xc5, 0x4c); com_interface! { - interface IDxcContainerReflection: IUnknown{ + interface IDxcContainerReflection: IDxcUnknownShim, IUnknown { iid: IID_IDxcContainerReflection, vtable: IDxcContainerReflectionVtbl, @@ -209,7 +210,7 @@ com_interface! { iid!(pub IID_IDxcOptimizerPass = 0xAE2C_D79F, 0xCC22, 0x453F, 0x9B, 0x6B, 0xB1, 0x24, 0xE7, 0xA5, 0x20, 0x4C); com_interface! { - interface IDxcOptimizerPass: IUnknown{ + interface IDxcOptimizerPass: IDxcUnknownShim, IUnknown { iid: IID_IDxcOptimizerPass, vtable: IDxcOptimizerPassVtbl, @@ -223,7 +224,7 @@ com_interface! { iid!(pub IID_IDxcOptimizer = 0x2574_0E2E, 0x9CBA, 0x401B, 0x91, 0x19, 0x4F, 0xB4, 0x2F, 0x39, 0xF2, 0x70); com_interface! { - interface IDxcOptimizer: IUnknown{ + interface IDxcOptimizer: IDxcUnknownShim, IUnknown { iid: IID_IDxcOptimizer, vtable: IDxcOptimizerVtbl, @@ -244,7 +245,7 @@ pub const DXC_VERSION_INFO_FLAGS_INTERNAL: u32 = 2; // Internal Validator (non-s iid!(pub IID_IDxcVersionInfo = 0xb04f_5b50, 0x2059, 0x4f12, 0xa8, 0xff, 0xa1, 0xe0, 0xcd, 0xe1, 0xcc, 0x7e); com_interface! { - interface IDxcVersionInfo: IUnknown{ + interface IDxcVersionInfo: IDxcUnknownShim, IUnknown { iid: IID_IDxcVersionInfo, vtable: IDxcVersionInfoVtbl, @@ -255,7 +256,7 @@ com_interface! { iid!(pub IID_IDxcVersionInfo2 = 0xfb69_04c4, 0x42f0, 0x4b62, 0x9c, 0x46, 0x98, 0x3a, 0xf7, 0xda, 0x7c, 0x83); com_interface! { - interface IDxcVersionInfo2: IUnknown{ + interface IDxcVersionInfo2: IDxcUnknownShim, IUnknown { iid: IID_IDxcVersionInfo2, vtable: IDxcVersionInfo2Vtbl, diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index ee6220c..ccda5cb 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -1,4 +1,5 @@ use crate::os::{BSTR, HRESULT, LPCSTR, LPSTR}; +pub(crate) use crate::unknown::IDxcUnknownShim; use bitflags::bitflags; use com_rs::{com_interface, iid, IUnknown}; @@ -301,7 +302,7 @@ bitflags! { iid!(pub IID_IDxcDiagnostic = 0x4f76b234, 0x3659, 0x4d33, 0x99, 0xb0, 0x3b, 0x0d, 0xb9, 0x94, 0xb5, 0x64); com_interface! { - interface IDxcDiagnostic: IUnknown{ + interface IDxcDiagnostic: IDxcUnknownShim, IUnknown { iid: IID_IDxcDiagnostic, vtable: IDxcDiagnosticVtbl, fn format_diagnostic(options: DxcDiagnosticDisplayOptions, result: *mut LPSTR) -> HRESULT; @@ -318,7 +319,7 @@ com_interface! { iid!(pub IID_IDxcInclusion = 0x0c364d65, 0xdf44, 0x4412, 0x88, 0x8e, 0x4e, 0x55, 0x2f, 0xc5, 0xe3, 0xd6); com_interface! { - interface IDxcInclusion: IUnknown{ + interface IDxcInclusion: IDxcUnknownShim, IUnknown { iid: IID_IDxcInclusion, vtable: IDxcInclusionVtbl, fn get_included_file(result: *mut *mut IDxcFile) -> HRESULT; @@ -329,7 +330,7 @@ com_interface! { iid!(pub IID_IDxcToken = 0x7f90b9ff, 0xa275, 0x4932, 0x97, 0xd8, 0x3c, 0xfd, 0x23, 0x44, 0x82, 0xa2); com_interface! { - interface IDxcToken: IUnknown{ + interface IDxcToken: IDxcUnknownShim, IUnknown { iid: IID_IDxcToken, vtable: IDxcTokenVtbl, fn get_kind(value: *mut DxcTokenKind) -> HRESULT; @@ -341,7 +342,7 @@ com_interface! { iid!(pub IID_IDxcType = 0x2ec912fd, 0xb144, 0x4a15, 0xad, 0x0d, 0x1c, 0x54, 0x39, 0xc8, 0x1e, 0x46); com_interface! { - interface IDxcType: IUnknown{ + interface IDxcType: IDxcUnknownShim, IUnknown { iid: IID_IDxcType, vtable: IDxcTypeVtbl, fn get_spelling(result: *mut LPSTR) -> HRESULT; @@ -352,7 +353,7 @@ com_interface! { iid!(pub IID_IDxcSourceLocation = 0x8e7ddf1c, 0xd7d3, 0x4d69, 0xb2, 0x86, 0x85, 0xfc, 0xcb, 0xa1, 0xe0, 0xcf); com_interface! { - interface IDxcSourceLocation: IUnknown{ + interface IDxcSourceLocation: IDxcUnknownShim, IUnknown { iid: IID_IDxcSourceLocation, vtable: IDxcSourceLocationVtbl, fn is_equal_to(other: *const IDxcSourceLocation, result: *mut bool) -> HRESULT; @@ -363,7 +364,7 @@ com_interface! { iid!(pub IID_IDxcSourceRange = 0xf1359b36, 0xa53f, 0x4e81, 0xb5, 0x14, 0xb6, 0xb8, 0x41, 0x22, 0xa1, 0x3f); com_interface! { - interface IDxcSourceRange: IUnknown{ + interface IDxcSourceRange: IDxcUnknownShim, IUnknown { iid: IID_IDxcSourceRange, vtable: IDxcSourceRangeVtbl, fn is_null(value: *mut bool) -> HRESULT; @@ -375,7 +376,7 @@ com_interface! { iid!(pub IID_IDxcCursor = 0x1467b985, 0x288d, 0x4d2a, 0x80, 0xc1, 0xef, 0x89, 0xc4, 0x2c, 0x40, 0xbc); com_interface! { - interface IDxcCursor: IUnknown{ + interface IDxcCursor: IDxcUnknownShim, IUnknown { iid: IID_IDxcCursor, vtable: IDxcCursorVtbl, fn get_extent(range: *mut *mut IDxcSourceRange) -> HRESULT; @@ -404,7 +405,7 @@ com_interface! { iid!(pub IID_IDxcUnsavedFile = 0x8ec00f98, 0x07d0, 0x4e60, 0x9d, 0x7c, 0x5a, 0x50, 0xb5, 0xb0, 0x01, 0x7f); com_interface! { - interface IDxcUnsavedFile: IUnknown{ + interface IDxcUnsavedFile: IDxcUnknownShim, IUnknown { iid: IID_IDxcUnsavedFile, vtable: IDxcUnsavedFileVtbl, fn get_file_name(file_name: *mut LPSTR) -> HRESULT; @@ -415,7 +416,7 @@ com_interface! { iid!(pub IID_IDxcFile = 0xbb2fca9e, 0x1478, 0x47ba, 0xb0, 0x8c, 0x2c, 0x50, 0x2a, 0xda, 0x48, 0x95); com_interface! { - interface IDxcFile: IUnknown{ + interface IDxcFile: IDxcUnknownShim, IUnknown { iid: IID_IDxcFile, vtable: IDxcFileVtbl, fn get_name(result: *mut LPSTR) -> HRESULT; @@ -425,7 +426,7 @@ com_interface! { iid!(pub IID_IDxcTranslationUnit = 0x9677dee0, 0xc0e5, 0x46a1, 0x8b, 0x40, 0x3d, 0xb3, 0x16, 0x8b, 0xe6, 0x3d); com_interface! { - interface IDxcTranslationUnit: IUnknown{ + interface IDxcTranslationUnit: IDxcUnknownShim, IUnknown { iid: IID_IDxcTranslationUnit, vtable: IDxcTranslationUnitVtbl, fn get_cursor(cursor: *mut *mut IDxcCursor) -> HRESULT; @@ -448,7 +449,7 @@ com_interface! { iid!(pub IID_IDxcIndex = 0x937824a0, 0x7f5a, 0x4815, 0x9b, 0xa, 0x7c, 0xc0, 0x42, 0x4f, 0x41, 0x73); com_interface! { - interface IDxcIndex: IUnknown{ + interface IDxcIndex: IDxcUnknownShim, IUnknown { iid: IID_IDxcIndex, vtable: IDxcIndexVtbl, fn set_global_options(options: DxcGlobalOptions) -> HRESULT; @@ -466,7 +467,7 @@ com_interface! { iid!(pub IID_IDxcIntelliSense = 0xb1f99513, 0x46d6, 0x4112, 0x81, 0x69, 0xdd, 0x0d, 0x60, 0x53, 0xf1, 0x7d); com_interface! { - interface IDxcIntelliSense: IUnknown{ + interface IDxcIntelliSense: IDxcUnknownShim, IUnknown { iid: IID_IDxcIntelliSense, vtable: IDxcIntelliSenseVtbl, fn create_index(index: *mut *mut IDxcIndex) -> HRESULT; diff --git a/src/lib.rs b/src/lib.rs index dd2643a..a3ba223 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,8 @@ //! ); //! ``` +pub(crate) mod unknown; + pub mod ffi; pub mod os; pub mod utils; diff --git a/src/unknown.rs b/src/unknown.rs new file mode 100644 index 0000000..739dd60 --- /dev/null +++ b/src/unknown.rs @@ -0,0 +1,50 @@ +#[cfg(not(windows))] +use crate::os::HRESULT; +use com_rs::{com_interface, IUnknown, IID}; + +extern "C" { + static IID_IUnknown: IID; +} + +#[cfg(not(windows))] +// Steal the interface ID from IUnknown: +com_interface! { + /// Insert complete object and deleting destructor on non-Windows platforms, where Dxc shims IUnknown in WinAdapter. + /// This requires a virtual destructor (delete is actually used on the base class) which unfortunately makes the struct + /// binary incompatible. + /// + /// See the third and fourth entry: + /// ``` + /// vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): + /// [0]: 0x7ffff6a56d40 + /// [1]: 0x7ffff6a56d20 + /// [2]: 0x7ffff6a56d30 + /// [3]: 0x7ffff6b36bc0 + /// [4]: 0x7ffff6a57130 + /// [5]: 0x7ffff6a56d50 + /// [6]: 0x7ffff6a56d60 + /// [7]: 0x7ffff6a56d70 + /// [8]: 0x7ffff6a56d80 + /// [9]: 0x7ffff6a56d90 + /// [10]: 0x7ffff6a56da0 + /// [11]: 0x7ffff6a56db0 + /// [12]: 0x7ffff6a56dc0 + /// [13]: 0x7ffff6a56dd0 + /// [14]: 0x7ffff6a56e90 + /// ``` + interface IDxcUnknownShim: IUnknown { + iid: IID_IUnknown, + vtable: IDxcUnknownShimVtbl, + fn complete_object_destructor() -> HRESULT; + fn deleting_destructor() -> HRESULT; + } +} + +#[cfg(windows)] +com_interface! { + /// Forwards to IUnknown. No-op on Windows + interface IDxcUnknownShim: IUnknown { + iid: IID_IUnknown, + vtable: IDxcUnknownShimVtbl, + } +} diff --git a/src/wrapper.rs b/src/wrapper.rs index f01bf02..4ec1e9d 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -110,8 +110,12 @@ struct DxcIncludeHandlerWrapperVtbl { &com_rs::IID, *mut *mut core::ffi::c_void, ) -> com_rs::HResult, - add_ref: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, - release: extern "stdcall" fn(*const com_rs::IUnknown) -> u32, + add_ref: extern "stdcall" fn(*const com_rs::IUnknown) -> HRESULT, + release: extern "stdcall" fn(*const com_rs::IUnknown) -> HRESULT, + #[cfg(not(windows))] + complete_object_destructor: extern "stdcall" fn(*const com_rs::IUnknown) -> HRESULT, + #[cfg(not(windows))] + deleting_destructor: extern "stdcall" fn(*const com_rs::IUnknown) -> HRESULT, load_source: extern "stdcall" fn(*mut com_rs::IUnknown, LPCWSTR, *mut *mut IDxcBlob) -> com_rs::HResult, } @@ -134,11 +138,7 @@ impl<'a> DxcIncludeHandlerWrapper<'a> { 0 // dummy impl } - extern "stdcall" fn add_ref(_me: *const com_rs::IUnknown) -> u32 { - 0 // dummy impl - } - - extern "stdcall" fn release(_me: *const com_rs::IUnknown) -> u32 { + extern "stdcall" fn dummy(_me: *const com_rs::IUnknown) -> HRESULT { 0 // dummy impl } @@ -225,8 +225,12 @@ impl DxcCompiler { if let Some(include_handler) = include_handler { let vtable = DxcIncludeHandlerWrapperVtbl { query_interface: DxcIncludeHandlerWrapper::query_interface, - add_ref: DxcIncludeHandlerWrapper::add_ref, - release: DxcIncludeHandlerWrapper::release, + add_ref: DxcIncludeHandlerWrapper::dummy, + release: DxcIncludeHandlerWrapper::dummy, + #[cfg(not(windows))] + complete_object_destructor: DxcIncludeHandlerWrapper::dummy, + #[cfg(not(windows))] + deleting_destructor: DxcIncludeHandlerWrapper::dummy, load_source: DxcIncludeHandlerWrapper::load_source, }; From 0cdd30670c6be1a8d5436c4015b48ae7027f3a38 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 13 Jul 2020 11:32:22 +0200 Subject: [PATCH 15/31] [LINUX] wrapper: Library is in PWD --- src/wrapper.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wrapper.rs b/src/wrapper.rs index 4ec1e9d..b0aee77 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -495,14 +495,14 @@ fn dxcompiler_lib_name() -> &'static str { #[cfg(not(windows))] fn dxcompiler_lib_name() -> &'static str { - "../dxc-rs/target/debug/build/dxc-rs-05a2fe30f551ddd3/out/lib/libdxcompiler.so" - //"/home/h3/Downloads/ShaderConductor-linux-clang7-x64-Release/Lib/libdxcompiler.so" - //"/home/h3/Downloads/ShaderConductor-linux-clang6-x64-Release/Lib/libdxcompiler.so" + "./libdxcompiler.so" } impl Dxc { pub fn new() -> Self { - let dxc_lib = Library::new(dxcompiler_lib_name()).expect("Failed to load dxcompiler.dll"); + let lib_name = dxcompiler_lib_name(); + let dxc_lib = + Library::new(lib_name).unwrap_or_else(|_| panic!("Failed to load {}", lib_name)); Self { dxc_lib } } From f8f1dc8a815b2db7ac05c5a75b4c0e9aa858c6bb Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Wed, 15 Jul 2020 16:51:52 +0100 Subject: [PATCH 16/31] Add error type --- Cargo.toml | 1 + src/utils.rs | 61 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6341368..822ec6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ com-rs = "0.2.1" winapi = "0.3.9" bitflags = "1.2.1" widestring = "0.4.2" +thiserror = "1.0" [dev-dependencies] rspirv = "0.6.0" diff --git a/src/utils.rs b/src/utils.rs index 72f11b2..e84d9cf 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,6 @@ -use crate::os::{BSTR, LPSTR, LPWSTR, WCHAR}; +use crate::os::{BSTR, HRESULT, LPSTR, LPWSTR, WCHAR}; use crate::wrapper::*; +use thiserror::Error; #[cfg(windows)] use winapi::um::oleauto::{SysFreeString, SysStringLen}; @@ -61,6 +62,16 @@ impl DxcIncludeHandler for DefaultIncludeHandler { } } +#[derive(Error, Debug)] +pub enum HassleError { + #[error("Win32 error: {0}")] + Win32Error(HRESULT), + #[error("Compile error: {0}")] + CompileError(String), + #[error("Validation error: {0}")] + ValidationError(String), +} + /// Helper function to directly compile a HLSL shader to an intermediate language, /// this function expects `dxcompiler.dll` to be available in the current /// executable environment. @@ -73,17 +84,21 @@ pub fn compile_hlsl( target_profile: &str, args: &[&str], defines: &[(&str, Option<&str>)], -) -> Result, String> { +) -> Result, HassleError> { let dxc = Dxc::new(); - let compiler = dxc.create_compiler().unwrap(); - let library = dxc.create_library().unwrap(); + let compiler = dxc + .create_compiler() + .map_err(|e| HassleError::Win32Error(e))?; + let library = dxc + .create_library() + .map_err(|e| HassleError::Win32Error(e))?; //let source = Rc::new(String::from(shader_text)); let blob = library .create_blob_with_encoding_from_str(shader_text) - .unwrap(); + .map_err(|e| HassleError::Win32Error(e))?; let result = compiler.compile( &blob, @@ -97,11 +112,18 @@ pub fn compile_hlsl( match result { Err(result) => { - let error_blob = result.0.get_error_buffer().unwrap(); - Err(library.get_blob_as_string(&error_blob)) + let error_blob = result + .0 + .get_error_buffer() + .map_err(|e| HassleError::Win32Error(e))?; + Err(HassleError::CompileError( + library.get_blob_as_string(&error_blob), + )) } Ok(result) => { - let result_blob = result.get_result().unwrap(); + let result_blob = result + .get_result() + .map_err(|e| HassleError::Win32Error(e))?; Ok(result_blob.to_vec()) } @@ -111,20 +133,31 @@ pub fn compile_hlsl( /// Helper function to validate a DXIL binary independant from the compilation process, /// this function expected `dxcompiler.dll` and `dxil.dll` to be available in the current /// execution environment. -pub fn validate_dxil(data: &[u8]) -> Result, String> { +pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { let dxc = Dxc::new(); let dxil = Dxil::new(); - let validator = dxil.create_validator().unwrap(); - let library = dxc.create_library().unwrap(); + let validator = dxil + .create_validator() + .map_err(|e| HassleError::Win32Error(e))?; + let library = dxc + .create_library() + .map_err(|e| HassleError::Win32Error(e))?; - let blob_encoding = library.create_blob_with_encoding(&data).unwrap(); + let blob_encoding = library + .create_blob_with_encoding(&data) + .map_err(|e| HassleError::Win32Error(e))?; match validator.validate(blob_encoding.into()) { Ok(blob) => Ok(blob.to_vec()), Err(result) => { - let error_blob = result.0.get_error_buffer().unwrap(); - Err(library.get_blob_as_string(&error_blob)) + let error_blob = result + .0 + .get_error_buffer() + .map_err(|e| HassleError::Win32Error(e))?; + Err(HassleError::ValidationError( + library.get_blob_as_string(&error_blob), + )) } } } From a5f295d6b7ad66465e8edcc2d4fd8ee5c8ffa289 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 15 Jul 2020 21:10:39 +0200 Subject: [PATCH 17/31] Fix return type of IDxcType::get_kind --- src/intellisense/ffi.rs | 59 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/intellisense/ffi.rs b/src/intellisense/ffi.rs index ccda5cb..8e29e6b 100644 --- a/src/intellisense/ffi.rs +++ b/src/intellisense/ffi.rs @@ -36,6 +36,63 @@ bitflags! { } } +bitflags! { + pub struct DxcTypeKind : u32 { + const Invalid = 0; // Reprents an invalid type (e.g., where no type is available). + const Unexposed = 1; // A type whose specific kind is not exposed via this interface. + // Builtin types + const Void = 2; + const Bool = 3; + const Char_U = 4; + const UChar = 5; + const Char16 = 6; + const Char32 = 7; + const UShort = 8; + const UInt = 9; + const ULong = 10; + const ULongLong = 11; + const UInt128 = 12; + const Char_S = 13; + const SChar = 14; + const WChar = 15; + const Short = 16; + const Int = 17; + const Long = 18; + const LongLong = 19; + const Int128 = 20; + const Float = 21; + const Double = 22; + const LongDouble = 23; + const NullPtr = 24; + const Overload = 25; + const Dependent = 26; + const ObjCId = 27; + const ObjCClass = 28; + const ObjCSel = 29; + const FirstBuiltin = DxcTypeKind::Void.bits; + const LastBuiltin = DxcTypeKind::ObjCSel.bits; + + const Complex = 100; + const Pointer = 101; + const BlockPointer = 102; + const LValueReference = 103; + const RValueReference = 104; + const Record = 105; + const Enum = 106; + const Typedef = 107; + const ObjCInterface = 108; + const ObjCObjectPointer = 109; + const FunctionNoProto = 110; + const FunctionProto = 111; + const ConstantArray = 112; + const Vector = 113; + const IncompleteArray = 114; + const VariableArray = 115; + const DependentSizedArray = 116; + const MemberPointer = 117; + } +} + bitflags! { pub struct DxcCursorFormatting : u32 { const DEFAULT = 0x0; @@ -347,7 +404,7 @@ com_interface! { vtable: IDxcTypeVtbl, fn get_spelling(result: *mut LPSTR) -> HRESULT; fn is_equal_to(other: *const IDxcType, result: *mut bool) -> HRESULT; - fn get_kind(result: *mut IDxcType) -> HRESULT; + fn get_kind(result: *mut DxcTypeKind) -> HRESULT; } } From b9c441a2a01bd96e91c439882c0b70b902bee2ac Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 16 Jul 2020 22:34:08 +0200 Subject: [PATCH 18/31] ffi: Replace c_void with the respective interface type get_buffer_pointer returns a mutable (non-const) void ptr, create_include_handler returns an IDxcIncludeHandler, and annotate some c_void types. All the remaining c_void uses are that way in the official API. --- src/ffi.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index 29c9576..67e06eb 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -10,7 +10,7 @@ pub type DxcCreateInstanceProc = extern "system" fn(rclsid: &IID, riid: &IID, ppv: *mut *mut c_void) -> HRESULT; pub type DxcCreateInstanceProc2 = extern "system" fn( - malloc: *const c_void, + malloc: /* IMalloc */ *const c_void, rclsid: &IID, riid: &IID, ppv: *mut *mut c_void, @@ -21,7 +21,7 @@ com_interface! { interface IDxcBlob: IDxcUnknownShim, IUnknown { iid: IID_IDxcBlob, vtable: IDxcBlobVtbl, - fn get_buffer_pointer() -> *const c_void; + fn get_buffer_pointer() -> *mut c_void; fn get_buffer_size() -> usize; } } @@ -45,9 +45,9 @@ com_interface! { fn create_blob_from_file(filename: LPCWSTR, code_page: *const u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; fn create_blob_with_encoding_from_pinned(text: *const c_void, size: u32, code_page: u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; fn create_blob_with_encoding_on_heap_copy(text: *const c_void, size: u32, code_page: u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; - fn create_blob_with_encoding_on_malloc(text: *const c_void, malloc: *const c_void, size: u32, code_page: u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; - fn create_include_handler(include_handler: *mut *mut c_void) -> HRESULT; - fn create_stream_from_blob_read_only(blob: *const IDxcBlob, stream: *mut *mut c_void) -> HRESULT; + fn create_blob_with_encoding_on_malloc(text: *const c_void, malloc: /* IMalloc */ *const c_void, size: u32, code_page: u32, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; + fn create_include_handler(include_handler: *mut *mut IDxcIncludeHandler) -> HRESULT; + fn create_stream_from_blob_read_only(blob: *const IDxcBlob, stream: /* IStream */ *mut *mut c_void) -> HRESULT; fn get_blob_as_utf8(blob: *const IDxcBlob, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; fn get_blob_as_utf16(blob: *const IDxcBlob, blob_encoding: *mut *mut IDxcBlobEncoding) -> HRESULT; } From 6400883882878f357b948aecce3a37f6474fefe9 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 16 Jul 2020 23:04:58 +0200 Subject: [PATCH 19/31] Cargo.toml: Only include winapi dependency on cfg(windows) Using winapi on not(windows) is a no-op already, but saves pulling in this extra dependency. --- Cargo.toml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 822ec6f..642d398 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,13 +26,12 @@ default-target = "x86_64-pc-windows-msvc" [dependencies] libloading = "0.6.2" com-rs = "0.2.1" -winapi = "0.3.9" bitflags = "1.2.1" widestring = "0.4.2" thiserror = "1.0" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3.9", features = ["wtypes", "oleauto"] } + [dev-dependencies] rspirv = "0.6.0" - -[features] -default = ["winapi/wtypes", "winapi/oleauto"] From df99e0978fd6f2eb7971680b2955e8636dd67b4c Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 20 Jul 2020 11:00:22 +0200 Subject: [PATCH 20/31] [LINUX] Disable DXIL validation at compile-time --- examples/validate.rs | 13 +++++++++---- src/lib.rs | 4 +++- src/utils.rs | 4 +++- src/wrapper.rs | 2 ++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/examples/validate.rs b/examples/validate.rs index d043365..640f6d8 100644 --- a/examples/validate.rs +++ b/examples/validate.rs @@ -39,11 +39,16 @@ fn main() { zero_digest(&mut dxil); let without_digest = get_digest(&dxil); + println!("Before validation: {:?}", without_digest); - let validated_dxil = validate_dxil(&dxil).unwrap(); + #[cfg(windows)] + { + let validated_dxil = validate_dxil(&dxil).unwrap(); - let with_digest = get_digest(&validated_dxil); + let with_digest = get_digest(&validated_dxil); - println!("Before validation: {:?}", without_digest); - println!("After validation: {:?}", with_digest); + println!("After validation: {:?}", with_digest); + } + #[cfg(not(windows))] + println!("Validation only available on Windows"); } diff --git a/src/lib.rs b/src/lib.rs index a3ba223..5aafec6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,5 +44,7 @@ pub mod wrapper; pub mod intellisense; pub use crate::ffi::*; -pub use crate::utils::{compile_hlsl, validate_dxil}; +pub use crate::utils::compile_hlsl; +#[cfg(windows)] +pub use crate::utils::validate_dxil; pub use crate::wrapper::*; diff --git a/src/utils.rs b/src/utils.rs index e84d9cf..fc675f9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -131,8 +131,10 @@ pub fn compile_hlsl( } /// Helper function to validate a DXIL binary independant from the compilation process, -/// this function expected `dxcompiler.dll` and `dxil.dll` to be available in the current +/// this function expects `dxcompiler.dll` and `dxil.dll` to be available in the current /// execution environment. +/// `dxil.dll` is currently not available on Linux. +#[cfg(windows)] pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { let dxc = Dxc::new(); let dxil = Dxil::new(); diff --git a/src/wrapper.rs b/src/wrapper.rs index b0aee77..15deafd 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -590,11 +590,13 @@ impl DxcValidator { } } +#[cfg(windows)] #[derive(Debug)] pub struct Dxil { dxil_lib: Library, } +#[cfg(windows)] impl Dxil { pub fn new() -> Self { let dxil_lib = Library::new("dxil.dll").expect("Failed to load dxil.dll"); From 20b9a9b21ec2d992374e0ddef81ae8cfb19106cd Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 20 Jul 2020 11:03:09 +0200 Subject: [PATCH 21/31] README: Mention libdxcompiler.so requirement on Linux --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69de543..dd4c409 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ and add this to your crate root: extern crate hassle_rs; ``` -Then acquire `dxcompiler.dll` directly from [AppVeyor](https://ci.appveyor.com/project/antiagainst/directxshadercompiler/branch/master/artifacts) or compile it from source according to the instructions in the [DirectXShaderCompiler](https://github.com/Microsoft/DirectXShaderCompiler) GitHub repository and make sure it's in the executable enviroment. +Then acquire `dxcompiler.dll` on Windows or `libdxcompiler.so` on Linux directly from [AppVeyor](https://ci.appveyor.com/project/antiagainst/directxshadercompiler/branch/master/artifacts), or compile it from source according to the instructions in the [DirectXShaderCompiler](https://github.com/Microsoft/DirectXShaderCompiler) GitHub repository and make sure it's in the executable environment. DxcValidator also requires `dxil.dll` which can be grabbed from any recent Windows 10 SDK flight. More info: https://www.wihlidal.com/blog/pipeline/2018-09-16-dxil-signing-post-compile/ From af94d9929068a13328753981699565cbd072ad68 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 20 Jul 2020 11:22:55 +0200 Subject: [PATCH 22/31] Fix most clippy warnings --- examples/file-ast.rs | 2 +- examples/intellisense-tu.rs | 2 +- examples/validate.rs | 2 +- src/intellisense/wrapper.rs | 6 +++--- src/utils.rs | 28 +++++++++------------------- 5 files changed, 15 insertions(+), 25 deletions(-) diff --git a/examples/file-ast.rs b/examples/file-ast.rs index adec1ef..6811bbc 100644 --- a/examples/file-ast.rs +++ b/examples/file-ast.rs @@ -88,7 +88,7 @@ fn main() { let unsaved_file = intellisense.create_unsaved_file(name, source).unwrap(); let translation_unit = index - .parse_translation_unit(name, &args, &vec![&unsaved_file], local_options) + .parse_translation_unit(name, &args, &[&unsaved_file], local_options) .unwrap(); let cursor = translation_unit.get_cursor().unwrap(); diff --git a/examples/intellisense-tu.rs b/examples/intellisense-tu.rs index 6e8cf88..7dcdfb3 100644 --- a/examples/intellisense-tu.rs +++ b/examples/intellisense-tu.rs @@ -18,7 +18,7 @@ fn main() { let unsaved_file = intellisense.create_unsaved_file(name, source).unwrap(); let translation_unit = index - .parse_translation_unit(name, &args, &vec![&unsaved_file], local_options) + .parse_translation_unit(name, &args, &[&unsaved_file], local_options) .unwrap(); let cursor = translation_unit.get_cursor().unwrap(); diff --git a/examples/validate.rs b/examples/validate.rs index 640f6d8..22add7d 100644 --- a/examples/validate.rs +++ b/examples/validate.rs @@ -8,7 +8,7 @@ pub struct MinimalHeader { // zero_digest & get_digest from https://github.com/gwihlidal/dxil-signing/blob/master/rust/src/main.rs -fn zero_digest(buffer: &mut [u8]) -> () { +fn zero_digest(buffer: &mut [u8]) { let buffer_ptr: *mut u8 = buffer.as_mut_ptr(); let header_ptr: *mut MinimalHeader = buffer_ptr as *mut _; let header_mut: &mut MinimalHeader = unsafe { &mut *header_ptr }; diff --git a/src/intellisense/wrapper.rs b/src/intellisense/wrapper.rs index ab303a7..c998a00 100644 --- a/src/intellisense/wrapper.rs +++ b/src/intellisense/wrapper.rs @@ -64,7 +64,7 @@ pub struct DxcIndex { impl DxcIndex { fn new(inner: ComPtr) -> Self { - return Self { inner }; + Self { inner } } } @@ -89,7 +89,7 @@ impl DxcIndex { let mut c_args: Vec = vec![]; let mut cliargs = vec![]; - for arg in args.into_iter() { + for arg in args.iter() { let c_arg = CString::new(*arg).expect("Failed to convert `arg`"); cliargs.push(c_arg.as_ptr() as *const u8); c_args.push(c_arg); @@ -463,7 +463,7 @@ impl DxcCursor { let source_range = (start_offset as usize)..(end_offset as usize); - return Ok(&source[source_range]); + Ok(&source[source_range]) } } diff --git a/src/utils.rs b/src/utils.rs index fc675f9..5bd4391 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -87,18 +87,14 @@ pub fn compile_hlsl( ) -> Result, HassleError> { let dxc = Dxc::new(); - let compiler = dxc - .create_compiler() - .map_err(|e| HassleError::Win32Error(e))?; - let library = dxc - .create_library() - .map_err(|e| HassleError::Win32Error(e))?; + let compiler = dxc.create_compiler().map_err(HassleError::Win32Error)?; + let library = dxc.create_library().map_err(HassleError::Win32Error)?; //let source = Rc::new(String::from(shader_text)); let blob = library .create_blob_with_encoding_from_str(shader_text) - .map_err(|e| HassleError::Win32Error(e))?; + .map_err(HassleError::Win32Error)?; let result = compiler.compile( &blob, @@ -115,15 +111,13 @@ pub fn compile_hlsl( let error_blob = result .0 .get_error_buffer() - .map_err(|e| HassleError::Win32Error(e))?; + .map_err(HassleError::Win32Error)?; Err(HassleError::CompileError( library.get_blob_as_string(&error_blob), )) } Ok(result) => { - let result_blob = result - .get_result() - .map_err(|e| HassleError::Win32Error(e))?; + let result_blob = result.get_result().map_err(HassleError::Win32Error)?; Ok(result_blob.to_vec()) } @@ -139,16 +133,12 @@ pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { let dxc = Dxc::new(); let dxil = Dxil::new(); - let validator = dxil - .create_validator() - .map_err(|e| HassleError::Win32Error(e))?; - let library = dxc - .create_library() - .map_err(|e| HassleError::Win32Error(e))?; + let validator = dxil.create_validator().map_err(HassleError::Win32Error)?; + let library = dxc.create_library().map_err(HassleError::Win32Error)?; let blob_encoding = library .create_blob_with_encoding(&data) - .map_err(|e| HassleError::Win32Error(e))?; + .map_err(HassleError::Win32Error)?; match validator.validate(blob_encoding.into()) { Ok(blob) => Ok(blob.to_vec()), @@ -156,7 +146,7 @@ pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { let error_blob = result .0 .get_error_buffer() - .map_err(|e| HassleError::Win32Error(e))?; + .map_err(HassleError::Win32Error)?; Err(HassleError::ValidationError( library.get_blob_as_string(&error_blob), )) From 6f9f4814628dd7491c118554a296f907ce2d0e0b Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 20 Jul 2020 11:53:07 +0200 Subject: [PATCH 23/31] Remove dead code --- src/utils.rs | 2 -- src/wrapper.rs | 14 +------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 5bd4391..bca6896 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -90,8 +90,6 @@ pub fn compile_hlsl( let compiler = dxc.create_compiler().map_err(HassleError::Win32Error)?; let library = dxc.create_library().map_err(HassleError::Win32Error)?; - //let source = Rc::new(String::from(shader_text)); - let blob = library .create_blob_with_encoding_from_str(shader_text) .map_err(HassleError::Win32Error)?; diff --git a/src/wrapper.rs b/src/wrapper.rs index 15deafd..4e506f5 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -439,18 +439,6 @@ impl DxcLibrary { let mut blob: ComPtr = ComPtr::new(); const CP_UTF8: u32 = 65001; // UTF-8 translation - /*return_hr!( - unsafe { - self.inner.create_blob_with_encoding_on_heap_copy( - text.as_ptr() as *const c_void, - text.len() as u32, - CP_UTF8, - blob.as_mut_ptr(), - ) - }, - DxcBlobEncoding::new(blob) - );*/ - return_hr!( unsafe { self.inner.create_blob_with_encoding_from_pinned( @@ -557,7 +545,7 @@ impl DxcValidator { }; if result_hr != 0 { - return Err(result_hr as _); + return Err(result_hr); } let mut major = 0; From 808dea6e006e13dd87186af173172d137a26b234 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 11:29:35 +0100 Subject: [PATCH 24/31] Silence clippy warnings in toplevel project --- src/lib.rs | 5 +++++ src/utils.rs | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5aafec6..5cdb58d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,11 @@ #![allow(dead_code)] #![allow(non_upper_case_globals)] +#![allow( + clippy::transmute_ptr_to_ptr, // Introduced by com-rs + clippy::too_many_arguments, // We're wrapping and API outside of our control +)] + //! # Hassle //! //! This crate provides an FFI layer and idiomatic rust wrappers for the new [DirectXShaderCompiler](https://github.com/Microsoft/DirectXShaderCompiler) library. diff --git a/src/utils.rs b/src/utils.rs index bca6896..25e9094 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -24,8 +24,7 @@ pub(crate) fn from_bstr(string: BSTR) -> String { let slice: &[WCHAR] = ::std::slice::from_raw_parts(string, len as usize); let result = String::from_utf16(slice).unwrap(); SysFreeString(string); - - return result; + result } } From 9d0735864896691533ada73c7b9bb10adc32fa98 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 11:36:21 +0100 Subject: [PATCH 25/31] Fix clippy warnings in example projects --- examples/validate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/validate.rs b/examples/validate.rs index 22add7d..25d6cce 100644 --- a/examples/validate.rs +++ b/examples/validate.rs @@ -1,6 +1,7 @@ use hassle_rs::*; #[repr(C)] +#[repr(packed)] pub struct MinimalHeader { four_cc: u32, hash_digest: [u32; 4], From 0272110c6b23b962e59ec4f0eee1a6a06f99d57e Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 11:36:33 +0100 Subject: [PATCH 26/31] Formatting --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5cdb58d..294e3c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![allow(dead_code)] #![allow(non_upper_case_globals)] - #![allow( clippy::transmute_ptr_to_ptr, // Introduced by com-rs clippy::too_many_arguments, // We're wrapping and API outside of our control From 1c9a7601b9414f59342a9af1cbeb032747e77ff9 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 11:59:26 +0100 Subject: [PATCH 27/31] Improve error handling --- examples/file-ast.rs | 2 +- examples/intellisense-tu.rs | 2 +- examples/validate.rs | 11 ++----- src/intellisense/wrapper.rs | 7 ++-- src/utils.rs | 18 ++++++---- src/wrapper.rs | 65 +++++++++++++++++++++++-------------- 6 files changed, 61 insertions(+), 44 deletions(-) diff --git a/examples/file-ast.rs b/examples/file-ast.rs index 6811bbc..552fecc 100644 --- a/examples/file-ast.rs +++ b/examples/file-ast.rs @@ -77,7 +77,7 @@ fn main() { let args = vec![]; - let dxc = Dxc::new(); + let dxc = Dxc::new().unwrap(); let intellisense = dxc.create_intellisense().unwrap(); diff --git a/examples/intellisense-tu.rs b/examples/intellisense-tu.rs index 7dcdfb3..fcdd8f5 100644 --- a/examples/intellisense-tu.rs +++ b/examples/intellisense-tu.rs @@ -7,7 +7,7 @@ fn main() { let args = vec![]; - let dxc = Dxc::new(); + let dxc = Dxc::new().unwrap(); let intellisense = dxc.create_intellisense().unwrap(); diff --git a/examples/validate.rs b/examples/validate.rs index 25d6cce..484b5a5 100644 --- a/examples/validate.rs +++ b/examples/validate.rs @@ -42,14 +42,9 @@ fn main() { let without_digest = get_digest(&dxil); println!("Before validation: {:?}", without_digest); - #[cfg(windows)] - { - let validated_dxil = validate_dxil(&dxil).unwrap(); + let validated_dxil = validate_dxil(&dxil).unwrap(); - let with_digest = get_digest(&validated_dxil); + let with_digest = get_digest(&validated_dxil); - println!("After validation: {:?}", with_digest); - } - #[cfg(not(windows))] - println!("Validation only available on Windows"); + println!("After validation: {:?}", with_digest); } diff --git a/src/intellisense/wrapper.rs b/src/intellisense/wrapper.rs index c998a00..0a42080 100644 --- a/src/intellisense/wrapper.rs +++ b/src/intellisense/wrapper.rs @@ -1,5 +1,6 @@ use crate::intellisense::ffi::*; use crate::os::{BSTR, HRESULT, LPSTR}; +use crate::utils::HassleError; use crate::wrapper::Dxc; use com_rs::ComPtr; use std::ffi::CString; @@ -544,10 +545,10 @@ impl DxcFile { } impl Dxc { - pub fn create_intellisense(&self) -> Result { + pub fn create_intellisense(&self) -> Result { let mut intellisense: ComPtr = ComPtr::new(); - return_hr!( - self.get_dxc_create_instance()( + return_hr_wrapped!( + self.get_dxc_create_instance()?( &CLSID_DxcIntelliSense, &IID_IDxcIntelliSense, intellisense.as_mut_ptr(), diff --git a/src/utils.rs b/src/utils.rs index 25e9094..75048b8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -69,6 +69,10 @@ pub enum HassleError { CompileError(String), #[error("Validation error: {0}")] ValidationError(String), + #[error("Error loading library")] + LoadLibraryError(#[from] libloading::Error), + #[error("Windows only")] + WindowsOnly(String), } /// Helper function to directly compile a HLSL shader to an intermediate language, @@ -84,10 +88,10 @@ pub fn compile_hlsl( args: &[&str], defines: &[(&str, Option<&str>)], ) -> Result, HassleError> { - let dxc = Dxc::new(); + let dxc = Dxc::new()?; - let compiler = dxc.create_compiler().map_err(HassleError::Win32Error)?; - let library = dxc.create_library().map_err(HassleError::Win32Error)?; + let compiler = dxc.create_compiler()?; + let library = dxc.create_library()?; let blob = library .create_blob_with_encoding_from_str(shader_text) @@ -127,11 +131,11 @@ pub fn compile_hlsl( /// `dxil.dll` is currently not available on Linux. #[cfg(windows)] pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { - let dxc = Dxc::new(); - let dxil = Dxil::new(); + let dxc = Dxc::new()?; + let dxil = Dxil::new()?; - let validator = dxil.create_validator().map_err(HassleError::Win32Error)?; - let library = dxc.create_library().map_err(HassleError::Win32Error)?; + let validator = dxil.create_validator()?; + let library = dxc.create_library()?; let blob_encoding = library .create_blob_with_encoding(&data) diff --git a/src/wrapper.rs b/src/wrapper.rs index 4e506f5..1ab6d3b 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -6,7 +6,7 @@ use crate::ffi::*; use crate::os::{HRESULT, LPCWSTR, LPWSTR, WCHAR}; -use crate::utils::{from_wide, to_wide}; +use crate::utils::{from_wide, to_wide, HassleError}; use com_rs::ComPtr; use libloading::{Library, Symbol}; use std::convert::Into; @@ -25,6 +25,17 @@ macro_rules! return_hr { }; } +macro_rules! return_hr_wrapped { + ($hr:expr, $v: expr) => { + let hr = $hr; + if hr == 0 { + return Ok($v); + } else { + return Err(HassleError::Win32Error(hr)); + } + }; +} + #[derive(Debug)] pub struct DxcBlob { inner: ComPtr, @@ -487,34 +498,35 @@ fn dxcompiler_lib_name() -> &'static str { } impl Dxc { - pub fn new() -> Self { + pub fn new() -> Result { let lib_name = dxcompiler_lib_name(); - let dxc_lib = - Library::new(lib_name).unwrap_or_else(|_| panic!("Failed to load {}", lib_name)); + let dxc_lib = Library::new(lib_name)?; - Self { dxc_lib } + Ok(Self { dxc_lib }) } - pub(crate) fn get_dxc_create_instance(&self) -> Symbol { - unsafe { self.dxc_lib.get(b"DxcCreateInstance\0").unwrap() } + pub(crate) fn get_dxc_create_instance( + &self, + ) -> Result, HassleError> { + Ok(unsafe { self.dxc_lib.get(b"DxcCreateInstance\0")? }) } - pub fn create_compiler(&self) -> Result { + pub fn create_compiler(&self) -> Result { let mut compiler: ComPtr = ComPtr::new(); - return_hr!( - self.get_dxc_create_instance()( + return_hr_wrapped!( + self.get_dxc_create_instance()?( &CLSID_DxcCompiler, &IID_IDxcCompiler2, compiler.as_mut_ptr(), ), - DxcCompiler::new(compiler, self.create_library().unwrap()) + DxcCompiler::new(compiler, self.create_library()?) ); } - pub fn create_library(&self) -> Result { + pub fn create_library(&self) -> Result { let mut library: ComPtr = ComPtr::new(); - return_hr!( - self.get_dxc_create_instance()( + return_hr_wrapped!( + self.get_dxc_create_instance()?( &CLSID_DxcLibrary, &IID_IDxcLibrary, library.as_mut_ptr(), @@ -578,27 +590,32 @@ impl DxcValidator { } } -#[cfg(windows)] #[derive(Debug)] pub struct Dxil { dxil_lib: Library, } -#[cfg(windows)] impl Dxil { - pub fn new() -> Self { - let dxil_lib = Library::new("dxil.dll").expect("Failed to load dxil.dll"); - Self { dxil_lib } + pub fn new() -> Result { + #[cfg(not(windows))] + { + return Err(HassleError::WindowsOnly( + "DXIL Signing is only supported on windows at the moment", + )); + } + + let dxil_lib = Library::new("dxil.dll")?; + Ok(Self { dxil_lib }) } - fn get_dxc_create_instance(&self) -> Symbol { - unsafe { self.dxil_lib.get(b"DxcCreateInstance\0").unwrap() } + fn get_dxc_create_instance(&self) -> Result, HassleError> { + Ok(unsafe { self.dxil_lib.get(b"DxcCreateInstance\0")? }) } - pub fn create_validator(&self) -> Result { + pub fn create_validator(&self) -> Result { let mut validator: ComPtr = ComPtr::new(); - return_hr!( - self.get_dxc_create_instance()( + return_hr_wrapped!( + self.get_dxc_create_instance()?( &CLSID_DxcValidator, &IID_IDxcValidator, validator.as_mut_ptr(), From 5c569487dcc66e2d88c5fd4f2a109cf51d5d9d6d Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 12:06:57 +0100 Subject: [PATCH 28/31] Add more context about the .dll / .so we're trying to load --- src/utils.rs | 9 +++++++-- src/wrapper.rs | 11 +++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 75048b8..8f65e9b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -69,8 +69,13 @@ pub enum HassleError { CompileError(String), #[error("Validation error: {0}")] ValidationError(String), - #[error("Error loading library")] - LoadLibraryError(#[from] libloading::Error), + #[error("Error loading library {filename:?} / {inner:?}")] + LoadLibraryError { + filename: String, + inner: libloading::Error, + }, + #[error("LibLoading error: {0:?}")] + LibLoadingError(#[from] libloading::Error), #[error("Windows only")] WindowsOnly(String), } diff --git a/src/wrapper.rs b/src/wrapper.rs index 1ab6d3b..0d2c4ad 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -500,7 +500,10 @@ fn dxcompiler_lib_name() -> &'static str { impl Dxc { pub fn new() -> Result { let lib_name = dxcompiler_lib_name(); - let dxc_lib = Library::new(lib_name)?; + let dxc_lib = Library::new(lib_name).map_err(|e| HassleError::LoadLibraryError { + filename: lib_name.to_string(), + inner: e, + })?; Ok(Self { dxc_lib }) } @@ -604,7 +607,11 @@ impl Dxil { )); } - let dxil_lib = Library::new("dxil.dll")?; + let dxil_lib = Library::new("dxil.dll").map_err(|e| HassleError::LoadLibraryError { + filename: "dxil".to_string(), + inner: e, + })?; + Ok(Self { dxil_lib }) } From 4a21203c08b155b1fd54ca0e4c211d76597c75e1 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 12:16:54 +0100 Subject: [PATCH 29/31] Linux compilation fix --- src/wrapper.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/wrapper.rs b/src/wrapper.rs index 0d2c4ad..a5d3b66 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -602,17 +602,20 @@ impl Dxil { pub fn new() -> Result { #[cfg(not(windows))] { - return Err(HassleError::WindowsOnly( - "DXIL Signing is only supported on windows at the moment", - )); + Err(HassleError::WindowsOnly( + "DXIL Signing is only supported on windows at the moment".to_string(), + )) } - let dxil_lib = Library::new("dxil.dll").map_err(|e| HassleError::LoadLibraryError { - filename: "dxil".to_string(), - inner: e, - })?; + #[cfg(windows)] + { + let dxil_lib = Library::new("dxil.dll").map_err(|e| HassleError::LoadLibraryError { + filename: "dxil".to_string(), + inner: e, + })?; - Ok(Self { dxil_lib }) + Ok(Self { dxil_lib }) + } } fn get_dxc_create_instance(&self) -> Result, HassleError> { From 44a31961975874834f2e900d0e0b32f1f36b17bd Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 12:18:19 +0100 Subject: [PATCH 30/31] Expose helper on Linux as well even though it always returns an error, makes the API slightly easier to use --- src/utils.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils.rs b/src/utils.rs index 8f65e9b..b0527b4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -134,7 +134,6 @@ pub fn compile_hlsl( /// this function expects `dxcompiler.dll` and `dxil.dll` to be available in the current /// execution environment. /// `dxil.dll` is currently not available on Linux. -#[cfg(windows)] pub fn validate_dxil(data: &[u8]) -> Result, HassleError> { let dxc = Dxc::new()?; let dxil = Dxil::new()?; From 4c6a388a4f7b5258751f3fdee03f825e1dbb8346 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 21 Jul 2020 12:19:34 +0100 Subject: [PATCH 31/31] And export it --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 294e3c4..f852ea6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,5 @@ pub mod intellisense; pub use crate::ffi::*; pub use crate::utils::compile_hlsl; -#[cfg(windows)] pub use crate::utils::validate_dxil; pub use crate::wrapper::*;