hassle_rs/
ffi.rs

1#![allow(clippy::transmute_ptr_to_ptr)]
2#![allow(clippy::too_many_arguments)]
3
4use crate::os::{HRESULT, LPCWSTR, LPWSTR};
5use com::{interfaces, interfaces::IUnknown, IID};
6use std::ffi::c_void;
7
8pub type DxcCreateInstanceProc<T> =
9    extern "system" fn(rclsid: &IID, riid: &IID, ppv: *mut Option<T>) -> HRESULT;
10
11pub type DxcCreateInstanceProc2 = extern "system" fn(
12    malloc: /* IMalloc */ *const c_void,
13    rclsid: &IID,
14    riid: &IID,
15    ppv: *mut *mut c_void,
16) -> HRESULT;
17
18pub const DFCC_DXIL: u32 = u32::from_le_bytes([b'D', b'X', b'I', b'L']);
19
20interfaces! {
21    #[uuid("8ba5fb08-5195-40e2-ac58-0d989c3a0102")]
22    pub(crate) unsafe interface IDxcBlob: IUnknown {
23        pub(crate) fn get_buffer_pointer(&self) -> *mut c_void;
24        pub(crate) fn get_buffer_size(&self) -> usize;
25    }
26
27    #[uuid("7241d424-2646-4191-97c0-98e96e42fc68")]
28    pub(crate) unsafe interface IDxcBlobEncoding: IDxcBlob {
29        pub(crate) fn get_encoding(&self, known: *mut u32, code_page: *mut u32) -> HRESULT;
30    }
31
32    #[uuid("e5204dc7-d18c-4c3c-bdfb-851673980fe7")]
33    pub(crate) unsafe interface IDxcLibrary: IUnknown {
34        pub(crate) fn set_malloc(&self, malloc: *const c_void) -> HRESULT;
35        pub(crate) fn create_blob_from_blob(
36            &self,
37            blob: IDxcBlob,
38            offset: u32,
39            length: u32,
40            result_blob: *mut Option<IDxcBlob>,
41        ) -> HRESULT;
42        pub(crate) fn create_blob_from_file(
43            &self,
44            filename: LPCWSTR,
45            code_page: *const u32,
46            blob_encoding: *mut Option<IDxcBlobEncoding>,
47        ) -> HRESULT;
48        pub(crate) fn create_blob_with_encoding_from_pinned(
49            &self,
50            text: *const c_void,
51            size: u32,
52            code_page: u32,
53            blob_encoding: *mut Option<IDxcBlobEncoding>,
54        ) -> HRESULT;
55        pub(crate) fn create_blob_with_encoding_on_heap_copy(
56            &self,
57            text: *const c_void,
58            size: u32,
59            code_page: u32,
60            blob_encoding: *mut Option<IDxcBlobEncoding>,
61        ) -> HRESULT;
62        pub(crate) fn create_blob_with_encoding_on_malloc(
63            &self,
64            text: *const c_void,
65            malloc: *const /* IMalloc */ c_void,
66            size: u32,
67            code_page: u32,
68            blob_encoding: *mut Option<IDxcBlobEncoding>,
69        ) -> HRESULT;
70        pub(crate) fn create_include_handler(
71            &self,
72            include_handler: *mut Option<IDxcIncludeHandler>,
73        ) -> HRESULT;
74        pub(crate) fn create_stream_from_blob_read_only(
75            &self,
76            blob: IDxcBlob,
77            stream: *mut *mut /* IStream */ c_void,
78        ) -> HRESULT;
79        pub(crate) fn get_blob_as_utf8(
80            &self,
81            blob: IDxcBlob,
82            blob_encoding: *mut Option<IDxcBlobEncoding>,
83        ) -> HRESULT;
84        pub(crate) fn get_blob_as_utf16(
85            &self,
86            blob: IDxcBlob,
87            blob_encoding: *mut Option<IDxcBlobEncoding>,
88        ) -> HRESULT;
89    }
90
91    #[uuid("cedb484a-d4e9-445a-b991-ca21ca157dc2")]
92    pub(crate) unsafe interface IDxcOperationResult: IUnknown {
93        pub(crate) fn get_status(&self, status: *mut u32) -> HRESULT;
94        pub(crate) fn get_result(&self, result: *mut Option<IDxcBlob>) -> HRESULT;
95        pub(crate) fn get_error_buffer(&self, errors: *mut Option<IDxcBlobEncoding>) -> HRESULT;
96    }
97
98    #[uuid("7f61fc7d-950d-467f-b3e3-3c02fb49187c")]
99    pub(crate) unsafe interface IDxcIncludeHandler: IUnknown {
100        pub(crate) fn load_source(
101            &self,
102            filename: LPCWSTR,
103            include_source: *mut Option<IDxcBlob>,
104        ) -> HRESULT;
105    }
106}
107
108#[repr(C)]
109pub struct DxcDefine {
110    pub name: LPCWSTR,
111    pub value: LPCWSTR,
112}
113
114interfaces! {
115    #[uuid("8c210bf3-011f-4422-8d70-6f9acb8db617")]
116    pub(crate) unsafe interface IDxcCompiler: IUnknown {
117        pub(crate) fn compile(
118            &self,
119            blob: IDxcBlob,
120            source_name: LPCWSTR,
121            entry_point: LPCWSTR,
122            target_profile: LPCWSTR,
123            arguments: *const LPCWSTR,
124            arg_count: u32,
125            defines: *const DxcDefine,
126            def_count: u32,
127            include_handler: Option<IDxcIncludeHandler>,
128            result: *mut Option<IDxcOperationResult>,
129        ) -> HRESULT;
130
131        pub(crate) fn preprocess(
132            &self,
133            blob: IDxcBlob,
134            source_name: LPCWSTR,
135            arguments: *const LPCWSTR,
136            arg_count: u32,
137            defines: *const DxcDefine,
138            def_count: u32,
139            include_handler: Option<IDxcIncludeHandler>,
140            result: *mut Option<IDxcOperationResult>,
141        ) -> HRESULT;
142
143        pub(crate) fn disassemble(
144            &self,
145            blob: IDxcBlob,
146            disassembly: *mut Option<IDxcBlobEncoding>,
147        ) -> HRESULT;
148    }
149
150    #[uuid("a005a9d9-b8bb-4594-b5c9-0e633bec4d37")]
151    pub(crate) unsafe interface IDxcCompiler2: IDxcCompiler {
152        pub(crate) fn compile_with_debug(
153            &self,
154            blob: IDxcBlob,
155            source_name: LPCWSTR,
156            entry_point: LPCWSTR,
157            target_profile: LPCWSTR,
158            arguments: *const LPCWSTR,
159            arg_count: u32,
160            defines: *const DxcDefine,
161            def_count: u32,
162            include_handler: Option<IDxcIncludeHandler>,
163            result: *mut Option<IDxcOperationResult>,
164            debug_blob_name: *mut LPWSTR,
165            debug_blob: *mut Option<IDxcBlob>,
166        ) -> HRESULT;
167    }
168
169    #[uuid("f1b5be2a-62dd-4327-a1c2-42ac1e1e78e6")]
170    pub(crate) unsafe interface IDxcLinker: IUnknown {
171        pub(crate) fn register_library(&self, lib_name: LPCWSTR, lib: IDxcBlob) -> HRESULT;
172
173        pub(crate) fn link(
174            &self,
175            entry_name: LPCWSTR,
176            target_profile: LPCWSTR,
177            lib_names: *const LPCWSTR,
178            lib_count: u32,
179            arguments: *const LPCWSTR,
180            arg_count: u32,
181            result: *mut Option<IDxcOperationResult>,
182        ) -> HRESULT;
183    }
184}
185
186pub const DXC_VALIDATOR_FLAGS_DEFAULT: u32 = 0;
187pub const DXC_VALIDATOR_FLAGS_IN_PLACE_EDIT: u32 = 1; // Validator is allowed to update shader blob in-place.
188pub const DXC_VALIDATOR_FLAGS_ROOT_SIGNATURE_ONLY: u32 = 2;
189pub const DXC_VALIDATOR_FLAGS_MODULE_ONLY: u32 = 4;
190pub const DXC_VALIDATOR_FLAGS_VALID_MASK: u32 = 0x7;
191
192interfaces! {
193    #[uuid("a6e82bd2-1fd7-4826-9811-2857e797f49a")]
194    pub(crate) unsafe interface IDxcValidator: IUnknown {
195        pub(crate) fn validate(
196            &self,
197            shader: IDxcBlob,
198            flags: u32,
199            result: *mut Option<IDxcOperationResult>,
200        ) -> HRESULT;
201    }
202
203    #[uuid("334b1f50-2292-4b35-99a1-25588d8c17fe")]
204    pub(crate) unsafe interface IDxcContainerBuilder: IUnknown {
205        pub(crate) fn load(&self, dxil_container_header: IDxcBlob) -> HRESULT;
206        pub(crate) fn add_part(&self, four_cc: u32, source: IDxcBlob) -> HRESULT;
207        pub(crate) fn remove_part(&self, four_cc: u32) -> HRESULT;
208        pub(crate) fn seralize_container(
209            &self,
210            result: *mut Option<IDxcOperationResult>,
211        ) -> HRESULT;
212    }
213
214    #[uuid("091f7a26-1c1f-4948-904b-e6e3a8a771d5")]
215    pub(crate) unsafe interface IDxcAssembler: IUnknown {
216        pub(crate) fn assemble_to_container(
217            &self,
218            shader: IDxcBlob,
219            result: *mut Option<IDxcOperationResult>,
220        ) -> HRESULT;
221    }
222
223    #[uuid("d2c21b26-8350-4bdc-976a-331ce6f4c54c")]
224    pub(crate) unsafe interface IDxcContainerReflection: IUnknown {
225        pub(crate) fn load(&self, container: IDxcBlob) -> HRESULT;
226        pub(crate) fn get_part_count(&self, result: *mut u32) -> HRESULT;
227        pub(crate) fn get_part_kind(&self, idx: u32, result: *mut u32) -> HRESULT;
228        pub(crate) fn get_part_content(&self, idx: u32, result: *mut Option<IDxcBlob>) -> HRESULT;
229        pub(crate) fn find_first_part_kind(&self, kind: u32, result: *mut u32) -> HRESULT;
230        pub(crate) fn get_part_reflection(
231            &self,
232            idx: u32,
233            iid: *const IID,
234            object: *mut Option<IUnknown>,
235        ) -> HRESULT;
236    }
237
238    #[uuid("5a58797d-a72c-478d-8ba2-efc6b0efe88e")]
239    pub(crate) unsafe interface ID3D12ShaderReflection: IUnknown {
240        pub(crate) fn get_desc(&self, p_desc: *mut c_void) -> HRESULT;
241        pub(crate) fn get_constant_buffer_by_index(&self, index: u32) -> *mut c_void;
242        pub(crate) fn get_constant_buffer_by_name(&self, name: *const c_void) -> *mut c_void;
243        pub(crate) fn get_resource_binding_desc(
244            &self,
245            resource_index: u32,
246            p_desc: *mut c_void,
247        ) -> HRESULT;
248        pub(crate) fn get_input_parameter_desc(
249            &self,
250            parameter_index: u32,
251            p_desc: *mut c_void,
252        ) -> HRESULT;
253        pub(crate) fn get_output_parameter_desc(
254            &self,
255            parameter_index: u32,
256            p_desc: *mut c_void,
257        ) -> HRESULT;
258        pub(crate) fn get_patch_constant_parameter_desc(
259            &self,
260            parameter_index: u32,
261            p_desc: *mut c_void,
262        ) -> HRESULT;
263        pub(crate) fn get_variable_by_name(&self, name: *const c_void) -> *mut c_void;
264        pub(crate) fn get_resource_binding_desc_by_name(
265            &self,
266            name: *const c_void,
267            p_desc: *mut c_void,
268        ) -> HRESULT;
269        pub(crate) fn get_mov_instruction_count(&self) -> u32;
270        pub(crate) fn get_movc_instruction_count(&self) -> u32;
271        pub(crate) fn get_conversion_instruction_count(&self) -> u32;
272        pub(crate) fn get_bitwise_instruction_count(&self) -> u32;
273        pub(crate) fn get_gs_input_primitive(&self) -> u32;
274        pub(crate) fn is_sample_frequency_shader(&self) -> bool;
275        pub(crate) fn get_num_interface_slots(&self) -> u32;
276        pub(crate) fn get_min_feature_level(&self, p_level: *mut c_void) -> HRESULT;
277        pub(crate) fn get_thread_group_size(
278            &self,
279            size_x: *mut u32,
280            size_y: *mut u32,
281            size_z: *mut u32,
282        ) -> u32;
283        pub(crate) fn get_requires_flags(&self) -> u64;
284    }
285
286    #[uuid("ae2cd79f-cc22-453f-9b6b-b124e7a5204c")]
287    pub(crate) unsafe interface IDxcOptimizerPass: IUnknown {
288        pub(crate) fn get_option_name(&self, result: *mut LPWSTR) -> HRESULT;
289        pub(crate) fn get_description(&self, result: *mut LPWSTR) -> HRESULT;
290        pub(crate) fn get_option_arg_count(&self, count: *mut u32) -> HRESULT;
291        pub(crate) fn get_option_arg_name(&self, arg_idx: u32, result: *mut LPWSTR) -> HRESULT;
292        pub(crate) fn get_option_arg_description(
293            &self,
294            arg_idx: u32,
295            result: *mut LPWSTR,
296        ) -> HRESULT;
297    }
298
299    #[uuid("25740e2e-9cba-401b-9119-4fb42f39f270")]
300    pub(crate) unsafe interface IDxcOptimizer: IUnknown {
301        pub(crate) fn get_available_pass_count(&self, count: *mut u32) -> HRESULT;
302        pub(crate) fn get_available_pass(
303            &self,
304            index: u32,
305            result: *mut Option<IDxcOptimizerPass>,
306        ) -> HRESULT;
307        pub(crate) fn run_optimizer(
308            &self,
309            blob: IDxcBlob,
310            options: *const LPCWSTR,
311            option_count: u32,
312            output_module: *mut Option<IDxcBlob>,
313            output_text: *mut Option<IDxcBlobEncoding>,
314        ) -> HRESULT;
315    }
316}
317
318pub const DXC_VERSION_INFO_FLAGS_NONE: u32 = 0;
319pub const DXC_VERSION_INFO_FLAGS_DEBUG: u32 = 1; // Matches VS_FF_DEBUG
320pub const DXC_VERSION_INFO_FLAGS_INTERNAL: u32 = 2; // Internal Validator (non-signing)
321
322interfaces! {
323    #[uuid("b04f5b50-2059-4f12-a8ff-a1e0cde1cc7e")]
324    pub(crate) unsafe interface IDxcVersionInfo: IUnknown {
325        pub(crate) fn get_version(&self, major: *mut u32, minor: *mut u32) -> HRESULT;
326        pub(crate) fn get_flags(&self, flags: *mut u32) -> HRESULT;
327    }
328
329    #[uuid("fb6904c4-42f0-4b62-9c46-983af7da7c83")]
330    pub(crate) unsafe interface IDxcVersionInfo2: IUnknown {
331        pub(crate) fn get_commit_info(
332            &self,
333            commit_count: *mut u32,
334            commit_hash: *mut *mut u8,
335        ) -> HRESULT;
336    }
337}
338
339pub const CLSID_DxcCompiler: IID = IID {
340    data1: 0x73e22d93,
341    data2: 0xe6ce,
342    data3: 0x47f3,
343    data4: [0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0],
344};
345pub const CLSID_DxcLinker: IID = IID {
346    data1: 0xef6a8087,
347    data2: 0xb0ea,
348    data3: 0x4d56,
349    data4: [0x9e, 0x45, 0xd0, 0x7e, 0x1a, 0x8b, 0x78, 0x6],
350};
351pub const CLSID_DxcDiaDataSource: IID = IID {
352    data1: 0xcd1f6b73,
353    data2: 0x2ab0,
354    data3: 0x484d,
355    data4: [0x8e, 0xdc, 0xeb, 0xe7, 0xa4, 0x3c, 0xa0, 0x9f],
356};
357pub const CLSID_DxcLibrary: IID = IID {
358    data1: 0x6245d6af,
359    data2: 0x66e0,
360    data3: 0x48fd,
361    data4: [0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c],
362};
363pub const CLSID_DxcValidator: IID = IID {
364    data1: 0x8ca3e215,
365    data2: 0xf728,
366    data3: 0x4cf3,
367    data4: [0x8c, 0xdd, 0x88, 0xaf, 0x91, 0x75, 0x87, 0xa1],
368};
369pub const CLSID_DxcAssembler: IID = IID {
370    data1: 0xd728db68,
371    data2: 0xf903,
372    data3: 0x4f80,
373    data4: [0x94, 0xcd, 0xdc, 0xcf, 0x76, 0xec, 0x71, 0x51],
374};
375pub const CLSID_DxcContainerReflection: IID = IID {
376    data1: 0xb9f54489,
377    data2: 0x55b8,
378    data3: 0x400c,
379    data4: [0xba, 0x3a, 0x16, 0x75, 0xe4, 0x72, 0x8b, 0x91],
380};
381pub const CLSID_DxcOptimizer: IID = IID {
382    data1: 0xae2cd79f,
383    data2: 0xcc22,
384    data3: 0x453f,
385    data4: [0x9b, 0x6b, 0xb1, 0x24, 0xe7, 0xa5, 0x20, 0x4c],
386};
387pub const CLSID_DxcContainerBuilder: IID = IID {
388    data1: 0x94134294,
389    data2: 0x411f,
390    data3: 0x4574,
391    data4: [0xb4, 0xd0, 0x87, 0x41, 0xe2, 0x52, 0x40, 0xd2],
392};