thindx/headers/d3d11shader.h/interfaces/shader_reflection.rs
1use crate::*;
2use crate::ctypes::*;
3use crate::d3d::*;
4use crate::d3d11::*;
5
6use std::ptr::*;
7
8
9
10/// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nn-d3d11shader-id3d11shaderreflection)\]
11/// ID3D11ShaderReflection
12///
13/// A shader-reflection interface accesses shader information.
14///
15/// ### Example
16/// ```rust
17/// # use thindx::*;
18/// let d3dc = d3d::Compiler::load_system(47).unwrap();
19/// let vs = d3dc.compile_from_file(
20/// r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0",
21/// d3d::Compile::Debug, d3d::CompileEffect::None
22/// ).unwrap();
23/// let _vs : d3d11::ShaderReflection = d3dc.reflect(&vs).unwrap();
24/// let vs = d3dc.reflect11(&vs).unwrap();
25/// ```
26///
27/// ### See Also
28/// * [d3d::Compiler::reflect]
29/// * [d3d::Compiler::reflect11]
30/// * [examples::d3dcompiler_04_reflect_shader]
31#[derive(Clone)] #[repr(transparent)]
32pub struct ShaderReflection(pub(crate) mcom::Rc<winapi::um::d3d11shader::ID3D11ShaderReflection>);
33
34convert!(unsafe ShaderReflection => Unknown, winapi::um::d3d11shader::ID3D11ShaderReflection);
35
36impl ShaderReflection {
37 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getbitwiseinstructioncount)\]
38 /// ID3D11ShaderReflection::GetBitwiseInstructionCount
39 ///
40 /// Gets the number of bitwise instructions.
41 ///
42 /// ### Example
43 /// ```rust
44 /// # use thindx::*;
45 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
46 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
47 /// # let vs = d3dc.reflect11(&vs).unwrap();
48 /// let count = vs.get_bitwise_instruction_count();
49 /// ```
50 pub fn get_bitwise_instruction_count(&self) -> u32 {
51 unsafe { self.0.GetBitwiseInstructionCount() }
52 }
53
54 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getconstantbufferbyindex)\]
55 /// ID3D11ShaderReflection::GetConstantBufferByIndex
56 ///
57 /// Get a constant buffer by index.
58 ///
59 /// ### Returns
60 /// * If the index is out of bounds, a stub object will still be returned. The stub object will return [E::FAIL] from most methods.
61 ///
62 /// ### Example
63 /// ```rust
64 /// # use thindx::*;
65 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
66 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
67 /// # let vs = d3dc.reflect11(&vs).unwrap();
68 /// let cb0 = vs.get_constant_buffer_by_index(0);
69 /// let _ = cb0.get_desc().unwrap();
70 ///
71 /// let cb1 = vs.get_constant_buffer_by_index(1);
72 /// assert_eq!(Some(E::FAIL), cb1.get_desc().err().map(|err| err.kind()));
73 /// #
74 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(100).get_desc().err().map(|err| err.kind()));
75 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(10000).get_desc().err().map(|err| err.kind()));
76 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(1000000).get_desc().err().map(|err| err.kind()));
77 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0-100).get_desc().err().map(|err| err.kind()));
78 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0-16).get_desc().err().map(|err| err.kind()));
79 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0-10).get_desc().err().map(|err| err.kind()));
80 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0-4).get_desc().err().map(|err| err.kind()));
81 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0-1).get_desc().err().map(|err| err.kind()));
82 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_index(!0).get_desc().err().map(|err| err.kind()));
83 /// ```
84 //#allow_missing_argument_docs
85 pub fn get_constant_buffer_by_index(&self, index: u32) -> ShaderReflectionConstantBuffer {
86 let ptr = unsafe { self.0.GetConstantBufferByIndex(index) };
87 unsafe { ShaderReflectionConstantBuffer::from_raw(self, ptr) }
88 }
89
90 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getconstantbufferbyname)\]
91 /// ID3D11ShaderReflection::GetConstantBufferByName
92 ///
93 /// Get a constant buffer by name.
94 ///
95 /// ### Returns
96 /// * If the name doesn't match a valid constant buffer, a stub object will still be returned. The stub object will return [E::FAIL] from most methods.
97 ///
98 /// ### Example
99 /// ```rust
100 /// # use thindx::*;
101 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
102 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
103 /// # let vs = d3dc.reflect11(&vs).unwrap();
104 /// let cb0 = vs.get_constant_buffer_by_name("ExampleCBuffer");
105 /// let _ = cb0.get_desc().unwrap();
106 ///
107 /// let cb1 = vs.get_constant_buffer_by_name("Invalid");
108 /// assert_eq!(Some(E::FAIL), cb1.get_desc().err().map(|err| err.kind()));
109 /// #
110 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_name("").get_desc().err().map(|err| err.kind()));
111 /// # assert_eq!(Some(E::FAIL), vs.get_constant_buffer_by_name("ExampleCBuffer\0").get_desc().err().map(|err| err.kind()));
112 /// ```
113 //#allow_missing_argument_docs
114 pub fn get_constant_buffer_by_name(&self, name: impl TryIntoAsCStr) -> ShaderReflectionConstantBuffer {
115 let name = name.try_into().ok();
116 let name = name.as_ref().map_or(cstr!("").as_cstr(), |n| n.as_cstr());
117 let ptr = unsafe { self.0.GetConstantBufferByName(name) };
118 unsafe { ShaderReflectionConstantBuffer::from_raw(self, ptr) }
119 }
120
121 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getconversioninstructioncount)\]
122 /// ID3D11ShaderReflection::GetConversionInstructionCount
123 ///
124 /// Gets the number of conversion instructions.
125 ///
126 /// ### Example
127 /// ```rust
128 /// # use thindx::*;
129 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
130 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
131 /// # let vs = d3dc.reflect11(&vs).unwrap();
132 /// let count : u32 = vs.get_conversion_instruction_count();
133 /// ```
134 pub fn get_conversion_instruction_count(&self) -> u32 {
135 unsafe { self.0.GetConversionInstructionCount() }
136 }
137
138 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getdesc)\]
139 /// ID3D11ShaderReflection::GetDesc
140 ///
141 /// Get a shader description.
142 ///
143 /// ### Errors
144 /// * ...perhaps [`E::FAIL`] if reflection was called on invalid or incompatible bytecode?
145 ///
146 /// ### Example
147 /// ```rust
148 /// # use thindx::*;
149 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
150 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
151 /// # let vs = d3dc.reflect11(&vs).unwrap();
152 /// let desc = vs.get_desc().unwrap();
153 /// assert_eq!(desc.version.shver(), d3d11::ShVer::VertexShader);
154 /// assert_eq!(desc.version.major(), 4);
155 /// assert_eq!(desc.version.minor(), 0);
156 /// ```
157 pub fn get_desc(&self) -> Result<ShaderDesc, MethodError> {
158 let mut desc = ShaderDesc::default();
159 let hr = unsafe { self.0.GetDesc(desc.as_mut_ptr()) };
160 MethodError::check("ID3D11ShaderReflection::GetDesc", hr)?;
161 Ok(desc)
162 }
163
164 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getgsinputprimitive)\]
165 /// ID3D11ShaderReflection::GetGSInputPrimitive
166 ///
167 /// Gets the geometry-shader input-primitive description.
168 ///
169 /// ### Returns
170 /// * [`d3d::Primitive::Undefined`] if `self` is not a geometry shader
171 ///
172 /// ### Example
173 /// ```rust
174 /// # use thindx::*;
175 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
176 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
177 /// # let vs = d3dc.reflect11(&vs).unwrap();
178 /// assert_eq!(vs.get_gs_input_primitive(), d3d::Primitive::Undefined);
179 /// ```
180 pub fn get_gs_input_primitive(&self) -> Primitive {
181 Primitive::from_unchecked(unsafe { self.0.GetGSInputPrimitive() })
182 }
183
184 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getinputparameterdesc)\]
185 /// ID3D11ShaderReflection::GetInputParameterDesc
186 ///
187 /// Get an input-parameter description for a shader.
188 ///
189 /// ### Errors
190 /// * [E::INVALIDARG] - if `parameter_index` >= `self.get_desc().unwrap().input_parameters`
191 ///
192 /// ### Example
193 /// ```rust
194 /// # use thindx::*;
195 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
196 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
197 /// # let vs = d3dc.reflect11(&vs).unwrap();
198 /// assert_eq!(0, vs.get_input_parameter_desc(0).unwrap().semantic_index);
199 /// assert_eq!(0, vs.get_input_parameter_desc(1).unwrap().semantic_index);
200 /// assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(2).unwrap_err().kind());
201 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(100).unwrap_err().kind());
202 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(10000).unwrap_err().kind());
203 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(1000000).unwrap_err().kind());
204 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0-100).unwrap_err().kind());
205 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0-16).unwrap_err().kind());
206 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0-8).unwrap_err().kind());
207 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0-4).unwrap_err().kind());
208 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0-1).unwrap_err().kind());
209 /// # assert_eq!(E::INVALIDARG, vs.get_input_parameter_desc(!0).unwrap_err().kind());
210 /// ```
211 //#allow_missing_argument_docs
212 pub fn get_input_parameter_desc(&self, parameter_index: u32) -> Result<SignatureParameterDesc, MethodError> {
213 let mut desc = SignatureParameterDesc::default();
214 let hr = unsafe { self.0.GetInputParameterDesc(parameter_index, desc.as_mut_ptr()) };
215 MethodError::check("ID3D11ShaderReflection::GetInputParameterDesc", hr)?;
216 Ok(desc)
217 }
218
219 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getminfeaturelevel)\]
220 /// ID3D11ShaderReflection::GetMinFeatureLevel
221 ///
222 /// Gets the minimum feature level.
223 ///
224 /// ### Errors
225 /// * ...?
226 ///
227 /// ### Example
228 /// ```rust
229 /// # use thindx::*;
230 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
231 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
232 /// # let vs = d3dc.reflect11(&vs).unwrap();
233 /// assert_eq!(vs.get_min_feature_level().unwrap(), d3d::FeatureLevel::_10_0);
234 /// ```
235 pub fn get_min_feature_level(&self) -> Result<FeatureLevel, MethodError> {
236 let mut fl = 0;
237 let hr = unsafe { self.0.GetMinFeatureLevel(&mut fl) };
238 MethodError::check("ID3D11ShaderReflection::GetMinFeatureLevel", hr)?;
239 Ok(FeatureLevel::from_unchecked(fl))
240 }
241
242 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getmovcinstructioncount)\]
243 /// ID3D11ShaderReflection::GetMovcInstructionCount
244 ///
245 /// Gets the number of Movc instructions.
246 ///
247 /// ### Example
248 /// ```rust
249 /// # use thindx::*;
250 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
251 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
252 /// # let vs = d3dc.reflect11(&vs).unwrap();
253 /// let count = vs.get_movc_instruction_count();
254 /// ```
255 pub fn get_movc_instruction_count(&self) -> u32 {
256 unsafe { self.0.GetMovcInstructionCount() }
257 }
258
259 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getmovinstructioncount)\]
260 /// ID3D11ShaderReflection::GetMovInstructionCount
261 ///
262 /// Gets the number of Mov instructions.
263 ///
264 /// ### Example
265 /// ```rust
266 /// # use thindx::*;
267 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
268 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
269 /// # let vs = d3dc.reflect11(&vs).unwrap();
270 /// let count : u32 = vs.get_mov_instruction_count();
271 /// ```
272 pub fn get_mov_instruction_count(&self) -> u32 {
273 unsafe { self.0.GetMovInstructionCount() }
274 }
275
276 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getnuminterfaceslots)\]
277 /// ID3D11ShaderReflection::GetNumInterfaceSlots
278 ///
279 /// Gets the number of interface slots in a shader.
280 ///
281 /// ### Example
282 /// ```rust
283 /// # use thindx::*;
284 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
285 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
286 /// # let vs = d3dc.reflect11(&vs).unwrap();
287 /// let slots : u32 = vs.get_num_interface_slots();
288 /// ```
289 pub fn get_num_interface_slots(&self) -> u32 {
290 unsafe { self.0.GetNumInterfaceSlots() }
291 }
292
293 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getoutputparameterdesc)\]
294 /// ID3D11ShaderReflection::GetOutputParameterDesc
295 ///
296 /// Get an output-parameter description for a shader.
297 ///
298 /// ### Errors
299 /// * [E::INVALIDARG] - if `parameter_index` >= `self.get_desc().unwrap().output_parameters`
300 ///
301 /// ### Example
302 /// ```rust
303 /// # use thindx::*;
304 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
305 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
306 /// # let vs = d3dc.reflect11(&vs).unwrap();
307 /// assert_eq!(0, vs.get_output_parameter_desc(0).unwrap().semantic_index);
308 /// assert_eq!(0, vs.get_output_parameter_desc(1).unwrap().semantic_index);
309 /// assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(2).unwrap_err().kind());
310 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(100).unwrap_err().kind());
311 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(10000).unwrap_err().kind());
312 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(1000000).unwrap_err().kind());
313 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0-100).unwrap_err().kind());
314 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0-16).unwrap_err().kind());
315 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0-8).unwrap_err().kind());
316 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0-4).unwrap_err().kind());
317 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0-1).unwrap_err().kind());
318 /// # assert_eq!(E::INVALIDARG, vs.get_output_parameter_desc(!0).unwrap_err().kind());
319 /// ```
320 //#allow_missing_argument_docs
321 pub fn get_output_parameter_desc(&self, parameter_index: u32) -> Result<SignatureParameterDesc, MethodError> {
322 let mut desc = SignatureParameterDesc::default();
323 let hr = unsafe { self.0.GetOutputParameterDesc(parameter_index, desc.as_mut_ptr()) };
324 MethodError::check("ID3D11ShaderReflection::GetOutputParameterDesc", hr)?;
325 Ok(desc)
326 }
327
328 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getpatchconstantparameterdesc)\]
329 /// ID3D11ShaderReflection::GetPatchConstantParameterDesc
330 ///
331 /// Get a patch-constant parameter description for a shader.
332 ///
333 /// ### Errors
334 /// * [E::INVALIDARG] - if `parameter_index` >= `self.get_desc().unwrap().patch_constant_parameters`
335 ///
336 /// ### Example
337 /// ```rust
338 /// # use thindx::*;
339 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
340 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
341 /// # let vs = d3dc.reflect11(&vs).unwrap();
342 /// // TODO: proper examples
343 /// assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(2).unwrap_err().kind());
344 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(100).unwrap_err().kind());
345 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(10000).unwrap_err().kind());
346 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(1000000).unwrap_err().kind());
347 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0-100).unwrap_err().kind());
348 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0-16).unwrap_err().kind());
349 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0-8).unwrap_err().kind());
350 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0-4).unwrap_err().kind());
351 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0-1).unwrap_err().kind());
352 /// # assert_eq!(E::INVALIDARG, vs.get_patch_constant_parameter_desc(!0).unwrap_err().kind());
353 /// ```
354 //#allow_missing_argument_docs
355 pub fn get_patch_constant_parameter_desc(&self, parameter_index: u32) -> Result<SignatureParameterDesc, MethodError> {
356 let mut desc = SignatureParameterDesc::default();
357 let hr = unsafe { self.0.GetPatchConstantParameterDesc(parameter_index, desc.as_mut_ptr()) };
358 MethodError::check("ID3D11ShaderReflection::GetPatchConstantParameterDesc", hr)?;
359 Ok(desc)
360 }
361
362 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getrequiresflags)\]
363 /// ID3D11ShaderReflection::GetRequiresFlags
364 ///
365 /// Gets a group of flags that indicates the requirements of a shader.
366 ///
367 /// ### Example
368 /// ```rust
369 /// # use thindx::*;
370 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
371 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
372 /// # let vs = d3dc.reflect11(&vs).unwrap();
373 /// assert_eq!(vs.get_requires_flags(), d3d::ShaderRequires::None);
374 /// ```
375 pub fn get_requires_flags(&self) -> ShaderRequires {
376 ShaderRequires::from_unchecked(unsafe { self.0.GetRequiresFlags() })
377 }
378
379 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getresourcebindingdesc)\]
380 /// ID3D11ShaderReflection::GetResourceBindingDesc
381 ///
382 /// Get a description of how a resource is bound to a shader.
383 ///
384 /// ### Errors
385 /// * [E::INVALIDARG] - if `resource_index` >= `self.get_desc().unwrap().bound_resources`
386 ///
387 /// ### Example
388 /// ```rust
389 /// # use thindx::*;
390 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
391 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
392 /// # let vs = d3dc.reflect11(&vs).unwrap();
393 /// let ex = vs.get_resource_binding_desc(0).unwrap();
394 /// assert_eq!(ex.ty, d3d::SIT::CBuffer);
395 ///
396 /// let err = vs.get_resource_binding_desc(1).err().unwrap().kind();
397 /// assert_eq!(err, E::INVALIDARG);
398 /// #
399 /// # assert_eq!(vs.get_resource_binding_desc(100).err().unwrap().kind(), E::INVALIDARG);
400 /// # assert_eq!(vs.get_resource_binding_desc(10000).err().unwrap().kind(), E::INVALIDARG);
401 /// # assert_eq!(vs.get_resource_binding_desc(1000000).err().unwrap().kind(), E::INVALIDARG);
402 /// # assert_eq!(vs.get_resource_binding_desc(!0-100).err().unwrap().kind(), E::INVALIDARG);
403 /// # assert_eq!(vs.get_resource_binding_desc(!0-16).err().unwrap().kind(), E::INVALIDARG);
404 /// # assert_eq!(vs.get_resource_binding_desc(!0-10).err().unwrap().kind(), E::INVALIDARG);
405 /// # assert_eq!(vs.get_resource_binding_desc(!0-8).err().unwrap().kind(), E::INVALIDARG);
406 /// # assert_eq!(vs.get_resource_binding_desc(!0-4).err().unwrap().kind(), E::INVALIDARG);
407 /// # assert_eq!(vs.get_resource_binding_desc(!0-1).err().unwrap().kind(), E::INVALIDARG);
408 /// # assert_eq!(vs.get_resource_binding_desc(!0).err().unwrap().kind(), E::INVALIDARG);
409 /// ```
410 //#allow_missing_argument_docs
411 pub fn get_resource_binding_desc(&self, resource_index: u32) -> Result<ShaderInputBindDesc, MethodError> {
412 let mut desc = ShaderInputBindDesc::default();
413 let hr = unsafe { self.0.GetResourceBindingDesc(resource_index, desc.as_mut_ptr()) };
414 MethodError::check("ID3D11ShaderReflection::GetResourceBindingDesc", hr)?;
415 Ok(desc)
416 }
417
418 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getresourcebindingdescbyname)\]
419 /// ID3D11ShaderReflection::GetResourceBindingDescByName
420 ///
421 /// Get a description of how a resource is bound to a shader.
422 ///
423 /// ### Errors
424 /// * [E::INVALIDARG] - If `name` doesn't name a valid resource binding for the shader
425 ///
426 /// ### Example
427 /// ```rust
428 /// # use thindx::*;
429 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
430 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
431 /// # let vs = d3dc.reflect11(&vs).unwrap();
432 /// let ex = vs.get_resource_binding_desc_by_name("ExampleCBuffer").unwrap();
433 /// assert_eq!(ex.ty, d3d::SIT::CBuffer);
434 ///
435 /// let err = vs.get_resource_binding_desc_by_name("Invalid").err().unwrap().kind();
436 /// assert_eq!(err, E::INVALIDARG);
437 /// #
438 /// # assert_eq!(vs.get_resource_binding_desc_by_name("ExampleCBuffer\0").err().unwrap().kind(), E::INVALIDARG);
439 /// # assert_eq!(vs.get_resource_binding_desc_by_name("").err().unwrap().kind(), E::INVALIDARG);
440 /// ```
441 //#allow_missing_argument_docs
442 pub fn get_resource_binding_desc_by_name(&self, name: impl TryIntoAsCStr) -> Result<ShaderInputBindDesc, MethodError> {
443 let name = name.try_into();
444 let name = name.as_ref().map_or(null(), |name| name.as_cstr());
445 let mut desc = ShaderInputBindDesc::default();
446 let hr = unsafe { self.0.GetResourceBindingDescByName(name, desc.as_mut_ptr()) };
447 MethodError::check("ID3D11ShaderReflection::GetResourceBindingDescByName", hr)?;
448 Ok(desc)
449 }
450
451 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getthreadgroupsize)\]
452 /// ID3D11ShaderReflection::GetThreadGroupSize
453 ///
454 /// Retrieves the sizes, in units of threads, of the X, Y, and Z dimensions of the shader's thread-group grid.
455 ///
456 /// ### Returns
457 /// * `(0, 0, 0)` if not specified
458 ///
459 /// ### Example
460 /// ```rust
461 /// # use thindx::*;
462 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
463 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
464 /// # let vs = d3dc.reflect11(&vs).unwrap();
465 /// assert_eq!(vs.get_thread_group_size(), (0, 0, 0));
466 /// ```
467 pub fn get_thread_group_size(&self) -> (u32, u32, u32) {
468 let (mut x, mut y, mut z) = (0, 0, 0);
469 let _total = unsafe { self.0.GetThreadGroupSize(&mut x, &mut y, &mut z) };
470 debug_assert_eq!(_total, x*y*z, "ID3D11ShaderReflection::GetThreadGroupSize was supposed to return x*y*z");
471 (x, y, z)
472 }
473
474 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-getvariablebyname)\]
475 /// ID3D11ShaderReflection::GetVariableByName
476 ///
477 /// Gets a variable by name.
478 ///
479 /// ### Returns
480 /// * If `name` doesn't name a valid cbuffer variable, a stub object will still be returned. The stub object will return [E::FAIL] from most methods.
481 ///
482 /// ### Example
483 /// ```rust
484 /// # use thindx::*;
485 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
486 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
487 /// # let vs = d3dc.reflect11(&vs).unwrap();
488 /// let tint = vs.get_variable_by_name("tint").get_desc().unwrap();
489 /// assert_eq!(tint.start_offset, 0, "unexpected tint.start_offset");
490 /// assert_eq!(tint.size, 16, "unexpected tint.size");
491 ///
492 /// let invalid = vs.get_variable_by_name("invalid").get_desc().unwrap_err();
493 /// assert_eq!(invalid.kind(), E::FAIL);
494 /// #
495 /// # assert_eq!(vs.get_variable_by_name("tint\0").get_desc().unwrap_err().kind(), E::FAIL);
496 /// # assert_eq!(vs.get_variable_by_name("").get_desc().unwrap_err().kind(), E::FAIL);
497 /// ```
498 //#allow_missing_argument_docs
499 pub fn get_variable_by_name(&self, name: impl TryIntoAsCStr) -> ShaderReflectionVariable {
500 let name = name.try_into().ok();
501 let name = name.as_ref().map_or(cstr!("").as_cstr(), |n| n.as_cstr());
502 let ptr = unsafe { self.0.GetVariableByName(name) };
503 unsafe { ShaderReflectionVariable::from_raw(self, ptr) }
504 }
505
506 /// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/d3d11shader/nf-d3d11shader-id3d11shaderreflection-issamplefrequencyshader)\]
507 /// ID3D11ShaderReflection::IsSampleFrequencyShader
508 ///
509 /// Indicates whether a shader is a sample frequency shader.
510 ///
511 /// ### Example
512 /// ```rust
513 /// # use thindx::*;
514 /// # let d3dc = d3d::Compiler::load_system(47).unwrap();
515 /// # let vs = d3dc.compile_from_file(r"test\data\basic.hlsl", None, None, "vs_main", "vs_4_0", d3d::Compile::Debug, d3d::CompileEffect::None).unwrap();
516 /// # let vs = d3dc.reflect11(&vs).unwrap();
517 /// assert_eq!(vs.is_sample_frequency_shader(), false);
518 /// ```
519 pub fn is_sample_frequency_shader(&self) -> bool {
520 0 != unsafe { self.0.IsSampleFrequencyShader() }
521 }
522}