Skip to main content

dxplr/
d3d11.rs

1use crate::api::Rect;
2use crate::api::*;
3use crate::d3d;
4#[cfg(feature = "d3d11sdklayers")]
5pub use crate::d3d11sdklayers::*;
6#[cfg(feature = "dxgi")]
7use crate::dxgi;
8use crate::result::{hresult, HResult};
9use crate::utility::*;
10use crate::Interface;
11use crate::{impl_bitflag_operators, impl_interface};
12use com_ptr::ComPtr;
13use std::ffi::OsString;
14use std::os::windows::ffi::OsStringExt;
15use winapi::ctypes::c_void;
16use winapi::shared::windef::RECT;
17use winapi::um::d3d11::*;
18use winapi::um::d3dcommon::*;
19
20#[derive(Clone, Copy, PartialEq, Eq, Debug)]
21pub struct AsyncGetDataFlag(u32);
22#[allow(non_upper_case_globals)]
23impl AsyncGetDataFlag {
24    pub const DoNotFlush: Self = Self(D3D11_ASYNC_GETDATA_DONOTFLUSH);
25}
26impl_bitflag_operators!(AsyncGetDataFlag);
27
28#[derive(Clone, Copy, PartialEq, Eq, Debug)]
29#[repr(u32)]
30pub enum AuthenticatedChannelType {
31    D3D11 = D3D11_AUTHENTICATED_CHANNEL_D3D11,
32    DriverSoftware = D3D11_AUTHENTICATED_CHANNEL_DRIVER_SOFTWARE,
33    DriverHardware = D3D11_AUTHENTICATED_CHANNEL_DRIVER_HARDWARE,
34}
35
36#[derive(Clone, Copy, PartialEq, Eq, Debug)]
37#[repr(u32)]
38pub enum AuthenticatedProcessIdentifierType {
39    Unknown = D3D11_PROCESSIDTYPE_UNKNOWN,
40    DWM = D3D11_PROCESSIDTYPE_DWM,
41    Handle = D3D11_PROCESSIDTYPE_HANDLE,
42}
43
44#[derive(Clone, Copy, PartialEq, Eq, Debug)]
45pub struct BindFlags(pub(crate) u32);
46#[allow(non_upper_case_globals)]
47impl BindFlags {
48    pub const VertexBuffer: Self = Self(D3D11_BIND_VERTEX_BUFFER);
49    pub const IndexBuffer: Self = Self(D3D11_BIND_INDEX_BUFFER);
50    pub const ConstantBuffer: Self = Self(D3D11_BIND_CONSTANT_BUFFER);
51    pub const ShaderResource: Self = Self(D3D11_BIND_SHADER_RESOURCE);
52    pub const StreamOutput: Self = Self(D3D11_BIND_STREAM_OUTPUT);
53    pub const RenderTarget: Self = Self(D3D11_BIND_RENDER_TARGET);
54    pub const DepthStencil: Self = Self(D3D11_BIND_DEPTH_STENCIL);
55    pub const UnorderedAccess: Self = Self(D3D11_BIND_UNORDERED_ACCESS);
56    pub const Decoder: Self = Self(D3D11_BIND_DECODER);
57    pub const VideoEncoder: Self = Self(D3D11_BIND_VIDEO_ENCODER);
58}
59impl_bitflag_operators!(BindFlags);
60
61#[derive(Clone, Copy, PartialEq, Eq, Debug)]
62#[repr(u32)]
63pub enum Blend {
64    Zero = D3D11_BLEND_ZERO,
65    One = D3D11_BLEND_ONE,
66    SrcColor = D3D11_BLEND_SRC_COLOR,
67    InvSrcColor = D3D11_BLEND_INV_SRC_COLOR,
68    SrcAlpha = D3D11_BLEND_SRC_ALPHA,
69    InvSrcAlpha = D3D11_BLEND_INV_SRC_ALPHA,
70    DestAlpha = D3D11_BLEND_DEST_ALPHA,
71    InvDestAlpha = D3D11_BLEND_INV_DEST_ALPHA,
72    DestColor = D3D11_BLEND_DEST_COLOR,
73    InvDestColor = D3D11_BLEND_INV_DEST_COLOR,
74    SrcAlphaSat = D3D11_BLEND_SRC_ALPHA_SAT,
75    BlendFactor = D3D11_BLEND_BLEND_FACTOR,
76    InvBlendFactor = D3D11_BLEND_INV_BLEND_FACTOR,
77    Src1Color = D3D11_BLEND_SRC1_COLOR,
78    InvSrc1Color = D3D11_BLEND_INV_SRC1_COLOR,
79    Src1Alpha = D3D11_BLEND_SRC1_ALPHA,
80    InvSrc1Alpha = D3D11_BLEND_INV_SRC1_ALPHA,
81}
82
83#[derive(Clone, Copy, PartialEq, Eq, Debug)]
84#[repr(u32)]
85pub enum BlendOp {
86    Add = D3D11_BLEND_OP_ADD,
87    Subtract = D3D11_BLEND_OP_SUBTRACT,
88    RevSubtract = D3D11_BLEND_OP_REV_SUBTRACT,
89    Min = D3D11_BLEND_OP_MIN,
90    Max = D3D11_BLEND_OP_MAX,
91}
92
93#[derive(Clone, Copy, PartialEq, Eq, Debug)]
94pub struct BufferUAVFlags(u32);
95#[allow(non_upper_case_globals)]
96impl BufferUAVFlags {
97    pub const Raw: Self = Self(D3D11_BUFFER_UAV_FLAG_RAW);
98    pub const Append: Self = Self(D3D11_BUFFER_UAV_FLAG_APPEND);
99    pub const Counter: Self = Self(D3D11_BUFFER_UAV_FLAG_COUNTER);
100}
101impl_bitflag_operators!(BufferUAVFlags);
102
103#[derive(Clone, Copy, PartialEq, Eq, Debug)]
104pub struct BufferExSRVFlags(u32);
105#[allow(non_upper_case_globals)]
106impl BufferExSRVFlags {
107    pub const Raw: Self = Self(D3D11_BUFFEREX_SRV_FLAG_RAW);
108}
109impl_bitflag_operators!(BufferExSRVFlags);
110
111#[derive(Clone, Copy, PartialEq, Eq, Debug)]
112#[repr(u32)]
113pub enum BusType {
114    Other = D3D11_BUS_TYPE_OTHER,
115    PCI = D3D11_BUS_TYPE_PCI,
116    PCIX = D3D11_BUS_TYPE_PCIX,
117    PCIExpress = D3D11_BUS_TYPE_PCIEXPRESS,
118    AGP = D3D11_BUS_TYPE_AGP,
119    ModifierInsideOfChipset = D3D11_BUS_IMPL_MODIFIER_INSIDE_OF_CHIPSET,
120    ModifierTracksOnMotherBoardToChip = D3D11_BUS_IMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_CHIP,
121    ModifierTracksOnMotherBoardToSocket = D3D11_BUS_IMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_SOCKET,
122    ModifierDaughterBoardConnector = D3D11_BUS_IMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR,
123    ModifierDaughterBoardConnectorInsideOfNuae =
124        D3D11_BUS_IMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR_INSIDE_OF_NUAE,
125    ModifierNonStandard = D3D11_BUS_IMPL_MODIFIER_NON_STANDARD,
126}
127
128#[derive(Clone, Copy, PartialEq, Eq, Debug)]
129pub struct ClearFlags(u32);
130#[allow(non_upper_case_globals)]
131impl ClearFlags {
132    pub const Depth: Self = Self(D3D11_CLEAR_DEPTH);
133    pub const Stencil: Self = Self(D3D11_CLEAR_STENCIL);
134}
135impl_bitflag_operators!(ClearFlags);
136
137#[derive(Clone, Copy, PartialEq, Eq, Debug)]
138pub struct ColorWriteEnable(u32);
139#[allow(non_upper_case_globals)]
140impl ColorWriteEnable {
141    pub const Red: Self = Self(D3D11_COLOR_WRITE_ENABLE_RED);
142    pub const Green: Self = Self(D3D11_COLOR_WRITE_ENABLE_GREEN);
143    pub const Blue: Self = Self(D3D11_COLOR_WRITE_ENABLE_BLUE);
144    pub const Alpha: Self = Self(D3D11_COLOR_WRITE_ENABLE_ALPHA);
145    pub const All: Self = Self(D3D11_COLOR_WRITE_ENABLE_ALL);
146}
147impl_bitflag_operators!(ColorWriteEnable);
148
149#[derive(Clone, Copy, PartialEq, Eq, Debug)]
150#[repr(u32)]
151pub enum ComparisonFunc {
152    Never = D3D11_COMPARISON_NEVER,
153    Less = D3D11_COMPARISON_LESS,
154    Equal = D3D11_COMPARISON_EQUAL,
155    LessEqual = D3D11_COMPARISON_LESS_EQUAL,
156    Greater = D3D11_COMPARISON_GREATER,
157    NotEqual = D3D11_COMPARISON_NOT_EQUAL,
158    GreaterEqual = D3D11_COMPARISON_GREATER_EQUAL,
159    Always = D3D11_COMPARISON_ALWAYS,
160}
161
162#[derive(Clone, Copy, PartialEq, Eq, Debug)]
163#[repr(u32)]
164pub enum ConservativeRasterizationTier {
165    NotSupported = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED,
166    Tier1 = D3D11_CONSERVATIVE_RASTERIZATION_TIER_1,
167    Tier2 = D3D11_CONSERVATIVE_RASTERIZATION_TIER_2,
168    Tier3 = D3D11_CONSERVATIVE_RASTERIZATION_TIER_3,
169}
170
171#[derive(Clone, Copy, PartialEq, Eq, Debug)]
172pub struct ContentProtectionCaps(u32);
173#[allow(non_upper_case_globals)]
174impl ContentProtectionCaps {
175    pub const Software: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE);
176    pub const Hardware: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE);
177    pub const AlwaysOn: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_PROTECTION_ALWAYS_ON);
178    pub const PartialDecryption: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_PARTIAL_DECRYPTION);
179    pub const ContentKey: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY);
180    pub const FreshenSessionKey: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_FRESHEN_SESSION_KEY);
181    pub const EncryptedReadBack: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_ENCRYPTED_READ_BACK);
182    pub const EncryptedReadBackKey: Self =
183        Self(D3D11_CONTENT_PROTECTION_CAPS_ENCRYPTED_READ_BACK_KEY);
184    pub const SequentialCTRIV: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_SEQUENTIAL_CTR_IV);
185    pub const EncryptSliceDataOnly: Self =
186        Self(D3D11_CONTENT_PROTECTION_CAPS_ENCRYPT_SLICEDATA_ONLY);
187    pub const DecryptionBlt: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_DECRYPTION_BLT);
188    pub const HardwareProtectUncompressed: Self =
189        Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_PROTECT_UNCOMPRESSED);
190    pub const HardwareProtectedMemoryPageable: Self =
191        Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_PROTECTED_MEMORY_PAGEABLE);
192    pub const HardwareTeardown: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_TEARDOWN);
193    pub const HardwareDRMCommunication: Self =
194        Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_DRM_COMMUNICATION);
195    // pub const HardwareDRMCommunicationMultiThreaded: Self = Self(D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_DRM_COMMUNICATION_MULTI_THREADED);
196}
197impl_bitflag_operators!(ContentProtectionCaps);
198
199pub const COUNTER_DEVICE_DEPENDENT_0: u32 = D3D11_COUNTER_DEVICE_DEPENDENT_0;
200
201#[derive(Clone, Copy, PartialEq, Eq, Debug)]
202#[repr(u32)]
203pub enum CounterType {
204    Float32 = D3D11_COUNTER_TYPE_FLOAT32,
205    Uint16 = D3D11_COUNTER_TYPE_UINT16,
206    Uint32 = D3D11_COUNTER_TYPE_UINT32,
207    Uint64 = D3D11_COUNTER_TYPE_UINT64,
208}
209
210#[derive(Clone, Copy, PartialEq, Eq, Debug)]
211pub struct CPUAccessFlags(pub(crate) u32);
212#[allow(non_upper_case_globals)]
213impl CPUAccessFlags {
214    pub const Write: Self = Self(D3D11_CPU_ACCESS_WRITE);
215    pub const Read: Self = Self(D3D11_CPU_ACCESS_READ);
216}
217impl_bitflag_operators!(CPUAccessFlags);
218
219#[derive(Clone, Copy, PartialEq, Eq, Debug)]
220pub struct CreateDeviceFlags(pub(crate) u32);
221#[allow(non_upper_case_globals)]
222impl CreateDeviceFlags {
223    pub const SingleThreaded: Self = Self(D3D11_CREATE_DEVICE_SINGLETHREADED);
224    pub const Debug: Self = Self(D3D11_CREATE_DEVICE_DEBUG);
225    pub const SwitchToRef: Self = Self(D3D11_CREATE_DEVICE_SWITCH_TO_REF);
226    pub const PreventInternalThreadingOptimizations: Self =
227        Self(D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS);
228    pub const BGRASupport: Self = Self(D3D11_CREATE_DEVICE_BGRA_SUPPORT);
229    pub const Debuggable: Self = Self(D3D11_CREATE_DEVICE_DEBUGGABLE);
230    pub const PreventAlteringLayerSettingsFromRegistry: Self =
231        Self(D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY);
232    pub const DisableGPUTimeout: Self = Self(D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT);
233    pub const VideoSupport: Self = Self(D3D11_CREATE_DEVICE_VIDEO_SUPPORT);
234}
235impl_bitflag_operators!(CreateDeviceFlags);
236
237#[derive(Clone, Copy, PartialEq, Eq, Debug)]
238#[repr(u32)]
239pub enum CullMode {
240    None = D3D11_CULL_NONE,
241    Front = D3D11_CULL_FRONT,
242    Back = D3D11_CULL_BACK,
243}
244
245#[derive(Clone, Copy, PartialEq, Eq, Debug)]
246#[repr(u32)]
247pub enum DepthWriteMask {
248    Zero = D3D11_DEPTH_WRITE_MASK_ZERO,
249    All = D3D11_DEPTH_WRITE_MASK_ALL,
250}
251
252#[derive(Clone, Copy, PartialEq, Eq, Debug)]
253#[repr(u32)]
254pub enum DeviceContextType {
255    Immediate = D3D11_DEVICE_CONTEXT_IMMEDIATE,
256    Deferred = D3D11_DEVICE_CONTEXT_DEFERRED,
257}
258
259#[derive(Clone, Copy, PartialEq, Eq, Debug)]
260#[repr(u32)]
261pub enum DSVDimension {
262    Unknown = D3D11_DSV_DIMENSION_UNKNOWN,
263    Texture1D = D3D11_DSV_DIMENSION_TEXTURE1D,
264    Texture1DArray = D3D11_DSV_DIMENSION_TEXTURE1DARRAY,
265    Texture2D = D3D11_DSV_DIMENSION_TEXTURE2D,
266    Texture2DArray = D3D11_DSV_DIMENSION_TEXTURE2DARRAY,
267    Texture2DMS = D3D11_DSV_DIMENSION_TEXTURE2DMS,
268    Texture2DMSArray = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY,
269}
270
271#[derive(Clone, Copy, PartialEq, Eq, Debug)]
272pub struct DSVFlags(u32);
273#[allow(non_upper_case_globals)]
274impl DSVFlags {
275    pub const ReadOnlyDepth: Self = Self(D3D11_DSV_READ_ONLY_DEPTH);
276    pub const ReadOnlyStencil: Self = Self(D3D11_DSV_READ_ONLY_STENCIL);
277}
278impl_bitflag_operators!(DSVFlags);
279
280#[derive(Clone, Copy, PartialEq, Eq, Debug)]
281#[repr(u32)]
282pub enum FillMode {
283    Wireframe = D3D11_FILL_WIREFRAME,
284    Solid = D3D11_FILL_SOLID,
285}
286
287#[derive(Clone, Copy, PartialEq, Eq, Debug)]
288#[repr(u32)]
289pub enum Filter {
290    MinMagMipPoint = D3D11_FILTER_MIN_MAG_MIP_POINT,
291    MinMagPointMipLinear = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR,
292    MinPointMagLinearMipPoint = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
293    MinPointMagMipLinear = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR,
294    MinLinearMagMipPoint = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT,
295    MinLinearMagPointMipLinear = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
296    MinMagLinearMipPoint = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT,
297    MinMagMipLinear = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
298    Anisotropic = D3D11_FILTER_ANISOTROPIC,
299    ComparisonMinMagMipPoint = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT,
300    ComparisonMinMagPointMipLinear = D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR,
301    ComparisonMinPointMagLinearMipPoint = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT,
302    ComparisonMinPointMagMipLinear = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR,
303    ComparisonMinLinearMagMipPoint = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT,
304    ComparisonMinLinearMagPointMipLinear = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
305    ComparisonMinMagLinearMipPoint = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT,
306    ComparisonMinMagMipLinear = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR,
307    ComparisonAnisotropic = D3D11_FILTER_COMPARISON_ANISOTROPIC,
308    MinimumMinMagMipPoint = D3D11_FILTER_MINIMUM_MIN_MAG_MIP_POINT,
309    MinimumMinMagPointMipLinear = D3D11_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR,
310    MinimumMinPointMagLinearMipPoint = D3D11_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
311    MinimumMinPointMagMipLinear = D3D11_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR,
312    MinimumMinLinearMagMipPoint = D3D11_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT,
313    MinimumMinLinearMagPointMipLinear = D3D11_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
314    MinimumMinMagLinearMipPoint = D3D11_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT,
315    MinimumMinMagMipLinear = D3D11_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR,
316    MinimumAnisotropic = D3D11_FILTER_MINIMUM_ANISOTROPIC,
317    MaximumMinMagMipPoint = D3D11_FILTER_MAXIMUM_MIN_MAG_MIP_POINT,
318    MaximumMinMagPointMipLinear = D3D11_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR,
319    MaximumPointMagLinearMipPoint = D3D11_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
320    MaximumMinPointMagMipLinear = D3D11_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR,
321    MaximumMinLinearMagMipPoint = D3D11_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT,
322    MaximumMinLinearMagPointMipLinear = D3D11_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
323    MaximumMinMagLinearMipPoint = D3D11_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT,
324    MaximumMinMagMipLinear = D3D11_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR,
325    MaximumAnisotropic = D3D11_FILTER_MAXIMUM_ANISOTROPIC,
326}
327
328#[derive(Clone, Copy, PartialEq, Eq, Debug)]
329#[repr(u32)]
330pub enum FilterReductionType {
331    Standard = D3D11_FILTER_REDUCTION_TYPE_STANDARD,
332    Comparison = D3D11_FILTER_REDUCTION_TYPE_COMPARISON,
333    Minimum = D3D11_FILTER_REDUCTION_TYPE_MINIMUM,
334    Maximum = D3D11_FILTER_REDUCTION_TYPE_MAXIMUM,
335}
336
337#[derive(Clone, Copy, PartialEq, Eq, Debug)]
338#[repr(u32)]
339pub enum FilterType {
340    Point = D3D11_FILTER_TYPE_POINT,
341    Linear = D3D11_FILTER_TYPE_LINEAR,
342}
343
344#[derive(Clone, Copy, PartialEq, Eq, Debug)]
345pub struct FormatSupport(u32);
346#[allow(non_upper_case_globals)]
347impl FormatSupport {
348    pub const Buffer: Self = Self(D3D11_FORMAT_SUPPORT_BUFFER);
349    pub const IAVertexBuffer: Self = Self(D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER);
350    pub const IAIndxBuffer: Self = Self(D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER);
351    pub const SOBuffer: Self = Self(D3D11_FORMAT_SUPPORT_SO_BUFFER);
352    pub const Texture1D: Self = Self(D3D11_FORMAT_SUPPORT_TEXTURE1D);
353    pub const Texture2D: Self = Self(D3D11_FORMAT_SUPPORT_TEXTURE2D);
354    pub const Texture3D: Self = Self(D3D11_FORMAT_SUPPORT_TEXTURE3D);
355    pub const TextureCube: Self = Self(D3D11_FORMAT_SUPPORT_TEXTURECUBE);
356    pub const ShaderLoad: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_LOAD);
357    pub const Sample: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
358    pub const SampleComparison: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON);
359    pub const ShaderSampleMonoText: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT);
360    pub const Mip: Self = Self(D3D11_FORMAT_SUPPORT_MIP);
361    pub const MipAutogen: Self = Self(D3D11_FORMAT_SUPPORT_MIP_AUTOGEN);
362    pub const RenderTarget: Self = Self(D3D11_FORMAT_SUPPORT_RENDER_TARGET);
363    pub const Blendable: Self = Self(D3D11_FORMAT_SUPPORT_BLENDABLE);
364    pub const DepthStencil: Self = Self(D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
365    pub const CPULockable: Self = Self(D3D11_FORMAT_SUPPORT_CPU_LOCKABLE);
366    pub const MultisampleResolve: Self = Self(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE);
367    pub const Display: Self = Self(D3D11_FORMAT_SUPPORT_DISPLAY);
368    pub const CastWithinBitLayout: Self = Self(D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT);
369    pub const MultisampleRenderTarget: Self = Self(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET);
370    pub const MultisampleLoad: Self = Self(D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD);
371    pub const ShaderGather: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_GATHER);
372    pub const BackBufferCast: Self = Self(D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST);
373    pub const TypedUnorderedAccessView: Self =
374        Self(D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW);
375    pub const ShaderGatherComparison: Self = Self(D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON);
376    pub const DecodeOutput: Self = Self(D3D11_FORMAT_SUPPORT_DECODER_OUTPUT);
377    pub const VideoProcessorOutput: Self = Self(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT);
378    pub const VideoProcessorInput: Self = Self(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT);
379    pub const VideoEncoder: Self = Self(D3D11_FORMAT_SUPPORT_VIDEO_ENCODER);
380}
381impl_bitflag_operators!(FormatSupport);
382
383#[derive(Clone, Copy, PartialEq, Eq, Debug)]
384pub struct FormatSupport2(u32);
385#[allow(non_upper_case_globals)]
386impl FormatSupport2 {
387    pub const UAVAtomicAdd: Self = Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD);
388    pub const UAVAtomicBitwiseOps: Self = Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS);
389    pub const UAVAtomicCompareStoreOrCompareExchange: Self =
390        Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE);
391    pub const UAVAtomicExchange: Self = Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE);
392    pub const UAVAtomicSignedMinOrMax: Self =
393        Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX);
394    pub const UAVAtomicUnsignedMinOrMax: Self =
395        Self(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX);
396    pub const UAVTypedLoad: Self = Self(D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD);
397    pub const UAVTypedStore: Self = Self(D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE);
398    pub const OutputMergerLogicOp: Self = Self(D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP);
399    pub const Tiled: Self = Self(D3D11_FORMAT_SUPPORT2_TILED);
400    pub const Shareable: Self = Self(D3D11_FORMAT_SUPPORT2_SHAREABLE);
401    pub const MultiplaneOverlay: Self = Self(D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY);
402}
403impl_bitflag_operators!(FormatSupport2);
404
405#[derive(Clone, Copy, PartialEq, Eq, Debug)]
406#[repr(u32)]
407pub enum InputClassification {
408    PerVertexData = D3D11_INPUT_PER_VERTEX_DATA,
409    PerInstanceData = D3D11_INPUT_PER_INSTANCE_DATA,
410}
411
412#[derive(Clone, Copy, PartialEq, Eq, Debug)]
413#[repr(u32)]
414pub enum MapType {
415    Read = D3D11_MAP_READ,
416    Write = D3D11_MAP_WRITE,
417    ReadWrite = D3D11_MAP_READ_WRITE,
418    WriteDiscard = D3D11_MAP_WRITE_DISCARD,
419    WriteNoOverwrite = D3D11_MAP_WRITE_NO_OVERWRITE,
420}
421
422#[derive(Clone, Copy, PartialEq, Eq, Debug)]
423pub struct MapFlag(u32);
424#[allow(non_upper_case_globals)]
425impl MapFlag {
426    pub const DoNotWait: MapFlag = MapFlag(D3D11_MAP_FLAG_DO_NOT_WAIT);
427}
428impl_bitflag_operators!(MapFlag);
429
430pub type Primitive = d3d::Primitive;
431pub type PrimitiveTopology = d3d::PrimitiveTopology;
432
433#[derive(Clone, Copy, PartialEq, Eq, Debug)]
434#[repr(u32)]
435pub enum QueryType {
436    Event = D3D11_QUERY_EVENT,
437    Occlusion = D3D11_QUERY_OCCLUSION,
438    Timestamp = D3D11_QUERY_TIMESTAMP,
439    TimestampDisjoint = D3D11_QUERY_TIMESTAMP_DISJOINT,
440    PipelineStatistics = D3D11_QUERY_PIPELINE_STATISTICS,
441    OcclustionPredicate = D3D11_QUERY_OCCLUSION_PREDICATE,
442    SOStatistics = D3D11_QUERY_SO_STATISTICS,
443    SOOverflowPredicate = D3D11_QUERY_SO_OVERFLOW_PREDICATE,
444    SOStatisticsStream0 = D3D11_QUERY_SO_STATISTICS_STREAM0,
445    SOOverflowPredicateStream0 = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0,
446    SOStatisticsStream1 = D3D11_QUERY_SO_STATISTICS_STREAM1,
447    SOOverflowPredicateStream1 = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1,
448    SOStatisticsStream2 = D3D11_QUERY_SO_STATISTICS_STREAM2,
449    SOOverflowPredicateStream2 = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2,
450    SOStatisticsStream3 = D3D11_QUERY_SO_STATISTICS_STREAM3,
451    SOOverflowPredicateStream3 = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3,
452}
453
454#[derive(Clone, Copy, PartialEq, Eq, Debug)]
455pub struct QueryMiscFlags(u32);
456#[allow(non_upper_case_globals)]
457impl QueryMiscFlags {
458    pub const PredicateHint: Self = Self(D3D11_QUERY_MISC_PREDICATEHINT);
459}
460impl_bitflag_operators!(QueryMiscFlags);
461
462#[derive(Clone, Copy, PartialEq, Eq, Debug)]
463pub struct RaiseFlags(u32);
464#[allow(non_upper_case_globals)]
465impl RaiseFlags {
466    pub const DriverInternalError: Self = Self(D3D11_RAISE_FLAG_DRIVER_INTERNAL_ERROR);
467}
468impl_bitflag_operators!(RaiseFlags);
469
470#[derive(Clone, Copy, PartialEq, Eq, Debug)]
471#[repr(u32)]
472pub enum ResourceDimension {
473    Unknown = D3D11_RESOURCE_DIMENSION_UNKNOWN,
474    Buffer = D3D11_RESOURCE_DIMENSION_BUFFER,
475    Texture1D = D3D11_RESOURCE_DIMENSION_TEXTURE1D,
476    Texture2D = D3D11_RESOURCE_DIMENSION_TEXTURE2D,
477    Texture3D = D3D11_RESOURCE_DIMENSION_TEXTURE3D,
478}
479
480#[derive(Clone, Copy, PartialEq, Eq, Debug)]
481pub struct ResourceMiscFlags(pub(crate) u32);
482#[allow(non_upper_case_globals)]
483impl ResourceMiscFlags {
484    pub const GenerateMips: Self = Self(D3D11_RESOURCE_MISC_GENERATE_MIPS);
485    pub const Shared: Self = Self(D3D11_RESOURCE_MISC_SHARED);
486    pub const TextureCube: Self = Self(D3D11_RESOURCE_MISC_TEXTURECUBE);
487    pub const DrawIndirectArgs: Self = Self(D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS);
488    pub const BufferAllowRawViews: Self = Self(D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS);
489    pub const BufferStructured: Self = Self(D3D11_RESOURCE_MISC_BUFFER_STRUCTURED);
490    pub const ResourceClamp: Self = Self(D3D11_RESOURCE_MISC_RESOURCE_CLAMP);
491    pub const SharedKeyedMutex: Self = Self(D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX);
492    pub const GDICompatible: Self = Self(D3D11_RESOURCE_MISC_GDI_COMPATIBLE);
493    pub const SharedNTHandle: Self = Self(D3D11_RESOURCE_MISC_SHARED_NTHANDLE);
494    pub const RestrictedContent: Self = Self(D3D11_RESOURCE_MISC_RESTRICTED_CONTENT);
495    pub const RestrictSharedResource: Self = Self(D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE);
496    pub const RestrictSharedResourceDriver: Self =
497        Self(D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE_DRIVER);
498    pub const Guarded: Self = Self(D3D11_RESOURCE_MISC_GUARDED);
499    pub const TilePool: Self = Self(D3D11_RESOURCE_MISC_TILE_POOL);
500    pub const Tiled: Self = Self(D3D11_RESOURCE_MISC_TILED);
501    pub const HWProtected: Self = Self(D3D11_RESOURCE_MISC_HW_PROTECTED);
502}
503impl_bitflag_operators!(ResourceMiscFlags);
504
505#[derive(Clone, Copy, PartialEq, Eq, Debug)]
506#[repr(u32)]
507pub enum RTVDimension {
508    Unknown = D3D11_RTV_DIMENSION_UNKNOWN,
509    Buffer = D3D11_RTV_DIMENSION_BUFFER,
510    Texture1D = D3D11_RTV_DIMENSION_TEXTURE1D,
511    Texture1DArray = D3D11_RTV_DIMENSION_TEXTURE1DARRAY,
512    Texture2D = D3D11_RTV_DIMENSION_TEXTURE2D,
513    Texture2DArray = D3D11_RTV_DIMENSION_TEXTURE2DARRAY,
514    Texture2DMS = D3D11_RTV_DIMENSION_TEXTURE2DMS,
515    Texture2DMSArray = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY,
516    Texture3D = D3D11_RTV_DIMENSION_TEXTURE3D,
517}
518
519/*
520#[derive(Clone, Copy, PartialEq, Eq, Debug)]
521pub struct ShaderCacheSupportFlags(u32);
522#[allow(non_upper_case_globals)]
523impl ShaderCacheSupportFlags {
524    pub const None: Self = Self(D3D11_SHADER_CACHE_SUPPORT_NONE);
525    pub const AutomaticInprocCache: Self = Self(D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE);
526    pub const AutomaticDiskCache: Self = Self(D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE);
527}
528impl_bitflag_operators!(ShaderCacheSupportFlags);
529*/
530
531#[derive(Clone, Copy, PartialEq, Eq, Debug)]
532#[repr(u32)]
533pub enum ShaderMinPrecisionSupport {
534    _10Bit = D3D11_SHADER_MIN_PRECISION_10_BIT,
535    _16Bit = D3D11_SHADER_MIN_PRECISION_16_BIT,
536}
537
538#[derive(Clone, Copy, PartialEq, Eq, Debug)]
539#[repr(u32)]
540pub enum StandardMultisampleQualityLevels {
541    StandardMultisamplePattern = D3D11_STANDARD_MULTISAMPLE_PATTERN,
542    CenterMultisamplePattern = D3D11_CENTER_MULTISAMPLE_PATTERN,
543}
544
545#[derive(Clone, Copy, PartialEq, Eq, Debug)]
546#[repr(u32)]
547pub enum StencilOp {
548    Keep = D3D11_STENCIL_OP_KEEP,
549    Zero = D3D11_STENCIL_OP_ZERO,
550    Replace = D3D11_STENCIL_OP_REPLACE,
551    IncrSat = D3D11_STENCIL_OP_INCR_SAT,
552    DecrSat = D3D11_STENCIL_OP_DECR_SAT,
553    Invert = D3D11_STENCIL_OP_INVERT,
554    Incr = D3D11_STENCIL_OP_INCR,
555    Decr = D3D11_STENCIL_OP_DECR,
556}
557
558#[derive(Clone, Copy, PartialEq, Eq, Debug)]
559#[repr(u32)]
560pub enum TextureAddressMode {
561    Wrap = D3D11_TEXTURE_ADDRESS_WRAP,
562    Mirror = D3D11_TEXTURE_ADDRESS_MIRROR,
563    Clamp = D3D11_TEXTURE_ADDRESS_CLAMP,
564    Border = D3D11_TEXTURE_ADDRESS_BORDER,
565    Once = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE,
566}
567
568#[derive(Clone, Copy, PartialEq, Eq, Debug)]
569#[repr(u32)]
570pub enum TextureCubeFace {
571    PositiveX = D3D11_TEXTURECUBE_FACE_POSITIVE_X,
572    NegativeX = D3D11_TEXTURECUBE_FACE_NEGATIVE_X,
573    PositiveY = D3D11_TEXTURECUBE_FACE_POSITIVE_Y,
574    NegativeY = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y,
575    PositiveZ = D3D11_TEXTURECUBE_FACE_POSITIVE_Z,
576    NegativeZ = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z,
577}
578
579#[derive(Clone, Copy, PartialEq, Eq, Debug)]
580#[repr(u32)]
581pub enum TiledResourcesTier {
582    NotSupported = D3D11_TILED_RESOURCES_NOT_SUPPORTED,
583    Tier1 = D3D11_TILED_RESOURCES_TIER_1,
584    Tier2 = D3D11_TILED_RESOURCES_TIER_2,
585    Tier3 = D3D11_TILED_RESOURCES_TIER_3,
586}
587
588#[derive(Clone, Copy, PartialEq, Eq, Debug)]
589#[repr(u32)]
590pub enum UAVDimension {
591    Unknown = D3D11_UAV_DIMENSION_UNKNOWN,
592    Buffer = D3D11_UAV_DIMENSION_BUFFER,
593    Texture1D = D3D11_UAV_DIMENSION_TEXTURE1D,
594    Texture1DArray = D3D11_UAV_DIMENSION_TEXTURE1DARRAY,
595    Texture2D = D3D11_UAV_DIMENSION_TEXTURE2D,
596    Texture2DArray = D3D11_UAV_DIMENSION_TEXTURE2DARRAY,
597    Texture3D = D3D11_UAV_DIMENSION_TEXTURE3D,
598}
599
600#[derive(Clone, Copy, PartialEq, Eq, Debug)]
601#[repr(u32)]
602pub enum Usage {
603    Default = D3D11_USAGE_DEFAULT,
604    Immutable = D3D11_USAGE_IMMUTABLE,
605    Dynamic = D3D11_USAGE_DYNAMIC,
606    Staging = D3D11_USAGE_STAGING,
607}
608
609#[derive(Clone, Copy, PartialEq, Eq, Debug)]
610#[repr(u32)]
611pub enum VDOVDimension {
612    Unknown = D3D11_VDOV_DIMENSION_UNKNOWN,
613    Texture2D = D3D11_VDOV_DIMENSION_TEXTURE2D,
614}
615
616#[derive(Clone, Copy, PartialEq, Eq, Debug)]
617#[repr(u32)]
618pub enum VideoDecoderBufferType {
619    PictureParameters = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS,
620    MacroblockControl = D3D11_VIDEO_DECODER_BUFFER_MACROBLOCK_CONTROL,
621    ResidualDifference = D3D11_VIDEO_DECODER_BUFFER_RESIDUAL_DIFFERENCE,
622    DeblockingControl = D3D11_VIDEO_DECODER_BUFFER_DEBLOCKING_CONTROL,
623    InverseQuantizationMatrix = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX,
624    SliceControl = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL,
625    Bitstream = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM,
626    MotionVector = D3D11_VIDEO_DECODER_BUFFER_MOTION_VECTOR,
627    FilmGrain = D3D11_VIDEO_DECODER_BUFFER_FILM_GRAIN,
628}
629
630#[derive(Clone, Copy, PartialEq, Eq, Debug)]
631#[repr(u32)]
632pub enum VideoFrameFormat {
633    Progressive = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
634    InterlacedTopFieldFirst = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST,
635    InterlacedBottomFieldFirst = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST,
636}
637
638#[derive(Clone, Copy, PartialEq, Eq, Debug)]
639#[repr(u32)]
640pub enum VideoProcessorAlphaFillMode {
641    Opaque = D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_OPAQUE,
642    Background = D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_BACKGROUND,
643    Destination = D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_DESTINATION,
644    SourceStream = D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_SOURCE_STREAM,
645}
646
647#[derive(Clone, Copy, PartialEq, Eq, Debug)]
648pub struct VideoProcessorAutoStreamCaps(u32);
649#[allow(non_upper_case_globals)]
650impl VideoProcessorAutoStreamCaps {
651    pub const Denoise: Self = Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_DENOISE);
652    pub const Deringing: Self = Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_DERINGING);
653    pub const EdgeEnhancement: Self = Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_EDGE_ENHANCEMENT);
654    pub const ColorCorrection: Self = Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_COLOR_CORRECTION);
655    pub const FleshToneMapping: Self =
656        Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_FLESH_TONE_MAPPING);
657    pub const ImageStabilization: Self =
658        Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_IMAGE_STABILIZATION);
659    pub const SuperResolution: Self = Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_SUPER_RESOLUTION);
660    pub const AnamorphicScaling: Self =
661        Self(D3D11_VIDEO_PROCESSOR_AUTO_STREAM_CAPS_ANAMORPHIC_SCALING);
662}
663impl_bitflag_operators!(VideoProcessorAutoStreamCaps);
664
665#[derive(Clone, Copy, PartialEq, Eq, Debug)]
666pub struct VideoProcessorDeviceCaps(u32);
667#[allow(non_upper_case_globals)]
668impl VideoProcessorDeviceCaps {
669    pub const LinearSpace: Self = Self(D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_LINEAR_SPACE);
670    pub const xvYCC: Self = Self(D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_xvYCC);
671    pub const RGBRangeConversion: Self =
672        Self(D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_RGB_RANGE_CONVERSION);
673    pub const YCbCrMatrixConversion: Self =
674        Self(D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_YCbCr_MATRIX_CONVERSION);
675    pub const NominalRange: Self = Self(D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_NOMINAL_RANGE);
676}
677impl_bitflag_operators!(VideoProcessorDeviceCaps);
678
679#[derive(Clone, Copy, PartialEq, Eq, Debug)]
680pub struct VideoProcessorFeatureCaps(u32);
681#[allow(non_upper_case_globals)]
682impl VideoProcessorFeatureCaps {
683    pub const AlphaFill: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ALPHA_FILL);
684    pub const Constriction: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_CONSTRICTION);
685    pub const LumaKey: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_LUMA_KEY);
686    pub const AlphaPalette: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ALPHA_PALETTE);
687    pub const Legacy: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_LEGACY);
688    pub const Stereo: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_STEREO);
689    pub const Rotation: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ROTATION);
690    pub const AlphaStream: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ALPHA_STREAM);
691    pub const PixelAspectRatio: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_PIXEL_ASPECT_RATIO);
692    pub const Mirror: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_MIRROR);
693    pub const ShaderUsage: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_SHADER_USAGE);
694    // pub const MetadataHDR10: Self = Self(D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_METADATA_HDR10);
695}
696impl_bitflag_operators!(VideoProcessorFeatureCaps);
697
698#[derive(Clone, Copy, PartialEq, Eq, Debug)]
699#[repr(u32)]
700pub enum VideoProcessorFilter {
701    Brightness = D3D11_VIDEO_PROCESSOR_FILTER_BRIGHTNESS,
702    Contrast = D3D11_VIDEO_PROCESSOR_FILTER_CONTRAST,
703    Hue = D3D11_VIDEO_PROCESSOR_FILTER_HUE,
704    Saturation = D3D11_VIDEO_PROCESSOR_FILTER_SATURATION,
705    NoiseReduction = D3D11_VIDEO_PROCESSOR_FILTER_NOISE_REDUCTION,
706    EdgeEnhancement = D3D11_VIDEO_PROCESSOR_FILTER_EDGE_ENHANCEMENT,
707    AnamorphicScaling = D3D11_VIDEO_PROCESSOR_FILTER_ANAMORPHIC_SCALING,
708    StereoAdjustment = D3D11_VIDEO_PROCESSOR_FILTER_STEREO_ADJUSTMENT,
709}
710
711#[derive(Clone, Copy, PartialEq, Eq, Debug)]
712pub struct VideoProcessorFilterCaps(u32);
713#[allow(non_upper_case_globals)]
714impl VideoProcessorFilterCaps {
715    pub const Brightness: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_BRIGHTNESS);
716    pub const Contrast: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_CONTRAST);
717    pub const Hue: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_HUE);
718    pub const Saturation: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_SATURATION);
719    pub const NoiseReduction: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_NOISE_REDUCTION);
720    pub const EdgeEnhancement: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_EDGE_ENHANCEMENT);
721    pub const AnamorphicScaling: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_ANAMORPHIC_SCALING);
722    pub const StereoAdjustment: Self = Self(D3D11_VIDEO_PROCESSOR_FILTER_CAPS_STEREO_ADJUSTMENT);
723}
724impl_bitflag_operators!(VideoProcessorFilterCaps);
725
726#[derive(Clone, Copy, PartialEq, Eq, Debug)]
727pub struct VideoProcessorFormatCaps(u32);
728#[allow(non_upper_case_globals)]
729impl VideoProcessorFormatCaps {
730    pub const RGBInterlaced: Self = Self(D3D11_VIDEO_PROCESSOR_FORMAT_CAPS_RGB_INTERLACED);
731    pub const RGBProcmap: Self = Self(D3D11_VIDEO_PROCESSOR_FORMAT_CAPS_RGB_PROCAMP);
732    pub const RGBLumaKey: Self = Self(D3D11_VIDEO_PROCESSOR_FORMAT_CAPS_RGB_LUMA_KEY);
733    pub const PaletteInterlaced: Self = Self(D3D11_VIDEO_PROCESSOR_FORMAT_CAPS_PALETTE_INTERLACED);
734}
735impl_bitflag_operators!(VideoProcessorFormatCaps);
736
737#[derive(Clone, Copy, PartialEq, Eq, Debug)]
738#[repr(u32)]
739pub enum VideoProcessorFormatSupport {
740    Input = D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT,
741    Output = D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT,
742}
743
744#[derive(Clone, Copy, PartialEq, Eq, Debug)]
745pub struct VideoProcessorItelecineCaps(u32);
746#[allow(non_upper_case_globals)]
747impl VideoProcessorItelecineCaps {
748    pub const _32: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_32);
749    pub const _22: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_22);
750    pub const _2224: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_2224);
751    pub const _2332: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_2332);
752    pub const _32322: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_32322);
753    pub const _55: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_55);
754    pub const _64: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_64);
755    pub const _87: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_87);
756    pub const _222222222223: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_222222222223);
757    pub const Other: Self = Self(D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_OTHER);
758}
759impl_bitflag_operators!(VideoProcessorItelecineCaps);
760
761#[derive(Clone, Copy, PartialEq, Eq, Debug)]
762#[repr(u32)]
763pub enum VideoProcessorNominalRange {
764    Undefined = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_UNDEFINED,
765    _16_235 = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_16_235,
766    _0_255 = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255,
767}
768
769#[derive(Clone, Copy, PartialEq, Eq, Debug)]
770#[repr(u32)]
771pub enum VideoProcessorOutputRate {
772    Normal = D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_NORMAL,
773    Half = D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_HALF,
774    Custom = D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_CUSTOM,
775}
776
777#[derive(Clone, Copy, PartialEq, Eq, Debug)]
778pub struct VideoProcessorProcessorCaps(u32);
779#[allow(non_upper_case_globals)]
780impl VideoProcessorProcessorCaps {
781    pub const DeinterlaceBlend: Self = Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND);
782    pub const DeinterlaceBob: Self = Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB);
783    pub const DeinterlaceAdaptive: Self =
784        Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_ADAPTIVE);
785    pub const DeinterlaceMotionCompensation: Self =
786        Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_MOTION_COMPENSATION);
787    pub const InverseTelecine: Self = Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE);
788    pub const FrameRateConversion: Self =
789        Self(D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION);
790}
791impl_bitflag_operators!(VideoProcessorProcessorCaps);
792
793#[derive(Clone, Copy, PartialEq, Eq, Debug)]
794#[repr(u32)]
795pub enum ProcessorRotation {
796    Identity = D3D11_VIDEO_PROCESSOR_ROTATION_IDENTITY,
797    _90 = D3D11_VIDEO_PROCESSOR_ROTATION_90,
798    _180 = D3D11_VIDEO_PROCESSOR_ROTATION_180,
799    _270 = D3D11_VIDEO_PROCESSOR_ROTATION_270,
800}
801
802#[derive(Clone, Copy, PartialEq, Eq, Debug)]
803pub struct VideoProcessorStereoCaps(u32);
804#[allow(non_upper_case_globals)]
805impl VideoProcessorStereoCaps {
806    pub const MonoOffset: Self = Self(D3D11_VIDEO_PROCESSOR_STEREO_CAPS_MONO_OFFSET);
807    pub const RowInterleaved: Self = Self(D3D11_VIDEO_PROCESSOR_STEREO_CAPS_ROW_INTERLEAVED);
808    pub const ColumnInterleaved: Self = Self(D3D11_VIDEO_PROCESSOR_STEREO_CAPS_COLUMN_INTERLEAVED);
809    pub const CapsCheckerBoard: Self = Self(D3D11_VIDEO_PROCESSOR_STEREO_CAPS_CHECKERBOARD);
810    pub const FlipMode: Self = Self(D3D11_VIDEO_PROCESSOR_STEREO_CAPS_FLIP_MODE);
811}
812impl_bitflag_operators!(VideoProcessorStereoCaps);
813
814#[derive(Clone, Copy, PartialEq, Eq, Debug)]
815#[repr(u32)]
816pub enum VideoProcessorStereoFlipMode {
817    None = D3D11_VIDEO_PROCESSOR_STEREO_FLIP_NONE,
818    Frame0 = D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME0,
819    Frame1 = D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME1,
820}
821
822#[derive(Clone, Copy, PartialEq, Eq, Debug)]
823#[repr(u32)]
824pub enum VideoProcessorStereoFormat {
825    Mono = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO,
826    Horizontal = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_HORIZONTAL,
827    Vertical = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_VERTICAL,
828    Separate = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_SEPARATE,
829    MonoOffset = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO_OFFSET,
830    RowInterleaved = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_ROW_INTERLEAVED,
831    ColumnInterleaved = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_COLUMN_INTERLEAVED,
832    CheckerBoard = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_CHECKERBOARD,
833}
834
835#[derive(Clone, Copy, PartialEq, Eq, Debug)]
836#[repr(u32)]
837pub enum VideoUsage {
838    PlaybackNormal = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL,
839    OptimalSpeed = D3D11_VIDEO_USAGE_OPTIMAL_SPEED,
840    OptimalQuality = D3D11_VIDEO_USAGE_OPTIMAL_QUALITY,
841}
842
843#[derive(Clone, Copy, PartialEq, Eq, Debug)]
844#[repr(u32)]
845pub enum VPIVDimension {
846    Unknown = D3D11_VPIV_DIMENSION_UNKNOWN,
847    Texture2D = D3D11_VPIV_DIMENSION_TEXTURE2D,
848}
849
850#[derive(Clone, Copy, PartialEq, Eq, Debug)]
851#[repr(u32)]
852pub enum VPOVDimension {
853    Unknown = D3D11_VPOV_DIMENSION_UNKNOWN,
854    Texture2D = D3D11_VPOV_DIMENSION_TEXTURE2D,
855    Texture2DArray = D3D11_VPOV_DIMENSION_TEXTURE2DARRAY,
856}
857
858#[derive(Clone, Debug)]
859#[repr(C)]
860#[allow(non_snake_case)]
861pub struct AESCTRIV {
862    pub IV: u64,
863    pub Count: u64,
864}
865
866#[derive(Clone, Debug)]
867pub struct BlendDesc {
868    pub alpha_to_coverage_enable: bool,
869    pub independent_blend_enable: bool,
870    pub render_target: Vec<RenderTargetBlendDesc>,
871}
872impl BlendDesc {
873    fn to_c_struct(&self) -> D3D11_BLEND_DESC {
874        assert!(self.render_target.len() <= 8);
875        let mut render_target: [D3D11_RENDER_TARGET_BLEND_DESC; 8] = Default::default();
876        for i in 0..self.render_target.len() {
877            render_target[i] = self.render_target[i].to_c_struct();
878        }
879        for i in self.render_target.len()..8 {
880            render_target[i] = RenderTargetBlendDesc::default().to_c_struct();
881        }
882        D3D11_BLEND_DESC {
883            AlphaToCoverageEnable: to_BOOL(self.alpha_to_coverage_enable),
884            IndependentBlendEnable: to_BOOL(self.independent_blend_enable),
885            RenderTarget: render_target,
886        }
887    }
888}
889impl Default for BlendDesc {
890    fn default() -> Self {
891        Self {
892            alpha_to_coverage_enable: false,
893            independent_blend_enable: false,
894            render_target: vec![Default::default()],
895        }
896    }
897}
898impl From<D3D11_BLEND_DESC> for BlendDesc {
899    fn from(src: D3D11_BLEND_DESC) -> BlendDesc {
900        BlendDesc {
901            alpha_to_coverage_enable: src.AlphaToCoverageEnable != 0,
902            independent_blend_enable: src.IndependentBlendEnable != 0,
903            render_target: src
904                .RenderTarget
905                .iter()
906                .map(|&rt| rt.into())
907                .collect::<Vec<_>>(),
908        }
909    }
910}
911
912#[derive(Clone, Copy, PartialEq, Eq, Debug)]
913#[repr(C)]
914pub struct Box3D {
915    pub left: u32,
916    pub top: u32,
917    pub fromt: u32,
918    pub right: u32,
919    pub bottom: u32,
920    pub back: u32,
921}
922impl Box3D {
923    pub fn as_c_ptr(&self) -> *const D3D11_BOX {
924        self as *const Box3D as *const D3D11_BOX
925    }
926}
927
928#[derive(Clone, Debug)]
929pub struct BufferDesc<Bw, U, Bf> {
930    pub byte_width: Bw,
931    pub usage: U,
932    pub bind_flags: Bf,
933    pub cpu_access_flags: Option<CPUAccessFlags>,
934    pub misc_flags: Option<ResourceMiscFlags>,
935    pub structure_byte_stride: u32,
936}
937impl BufferDesc<(), (), ()> {
938    pub fn new() -> Self {
939        Self {
940            byte_width: (),
941            usage: (),
942            bind_flags: (),
943            cpu_access_flags: None,
944            misc_flags: None,
945            structure_byte_stride: 0,
946        }
947    }
948}
949impl<Bw, U, Bf> BufferDesc<Bw, U, Bf> {
950    pub fn byte_width(self, byte_width: u32) -> BufferDesc<u32, U, Bf> {
951        BufferDesc {
952            byte_width,
953            usage: self.usage,
954            bind_flags: self.bind_flags,
955            cpu_access_flags: self.cpu_access_flags,
956            misc_flags: self.misc_flags,
957            structure_byte_stride: self.structure_byte_stride,
958        }
959    }
960    pub fn usage(self, usage: Usage) -> BufferDesc<Bw, Usage, Bf> {
961        BufferDesc {
962            byte_width: self.byte_width,
963            usage,
964            bind_flags: self.bind_flags,
965            cpu_access_flags: self.cpu_access_flags,
966            misc_flags: self.misc_flags,
967            structure_byte_stride: self.structure_byte_stride,
968        }
969    }
970    pub fn bind_flags(self, bind_flags: BindFlags) -> BufferDesc<Bw, U, BindFlags> {
971        BufferDesc {
972            byte_width: self.byte_width,
973            usage: self.usage,
974            bind_flags,
975            cpu_access_flags: self.cpu_access_flags,
976            misc_flags: self.misc_flags,
977            structure_byte_stride: self.structure_byte_stride,
978        }
979    }
980    pub fn cpu_access_flags(mut self, cpu_access_flags: CPUAccessFlags) -> Self {
981        self.cpu_access_flags = Some(cpu_access_flags);
982        self
983    }
984    pub fn misc_flags(mut self, misc_flags: ResourceMiscFlags) -> Self {
985        self.misc_flags = Some(misc_flags);
986        self
987    }
988    pub fn structure_byte_stride(mut self, structure_byte_stride: u32) -> Self {
989        self.structure_byte_stride = structure_byte_stride;
990        self
991    }
992}
993impl BufferDesc<u32, Usage, BindFlags> {
994    fn to_c_struct(&self) -> D3D11_BUFFER_DESC {
995        D3D11_BUFFER_DESC {
996            ByteWidth: self.byte_width,
997            Usage: self.usage as u32,
998            BindFlags: self.bind_flags.0,
999            CPUAccessFlags: self.cpu_access_flags.map_or(0, |f| f.0),
1000            MiscFlags: self.misc_flags.map_or(0, |f| f.0),
1001            StructureByteStride: self.structure_byte_stride,
1002        }
1003    }
1004}
1005impl From<D3D11_BUFFER_DESC> for BufferDesc<u32, Usage, BindFlags> {
1006    fn from(src: D3D11_BUFFER_DESC) -> BufferDesc<u32, Usage, BindFlags> {
1007        unsafe {
1008            BufferDesc {
1009                byte_width: src.ByteWidth,
1010                usage: std::mem::transmute(src.Usage),
1011                bind_flags: BindFlags(src.BindFlags),
1012                cpu_access_flags: if src.CPUAccessFlags == 0 {
1013                    None
1014                } else {
1015                    Some(CPUAccessFlags(src.CPUAccessFlags))
1016                },
1017                misc_flags: if src.MiscFlags == 0 {
1018                    None
1019                } else {
1020                    Some(ResourceMiscFlags(src.MiscFlags))
1021                },
1022                structure_byte_stride: src.StructureByteStride,
1023            }
1024        }
1025    }
1026}
1027
1028#[derive(Clone, Debug)]
1029pub struct ClassInstanceDesc {
1030    pub instance_id: u32,
1031    pub instance_index: u32,
1032    pub type_id: u32,
1033    pub constant_buffer: u32,
1034    pub base_constant_buffer_offset: u32,
1035    pub base_texture: u32,
1036    pub base_sampler: u32,
1037    pub created: bool,
1038}
1039impl From<D3D11_CLASS_INSTANCE_DESC> for ClassInstanceDesc {
1040    fn from(src: D3D11_CLASS_INSTANCE_DESC) -> ClassInstanceDesc {
1041        ClassInstanceDesc {
1042            instance_id: src.InstanceId,
1043            instance_index: src.InstanceIndex,
1044            type_id: src.TypeId,
1045            constant_buffer: src.ConstantBuffer,
1046            base_constant_buffer_offset: src.BaseConstantBufferOffset,
1047            base_texture: src.BaseTexture,
1048            base_sampler: src.BaseSampler,
1049            created: src.Created != 0,
1050        }
1051    }
1052}
1053
1054#[derive(Clone, Debug)]
1055pub struct CounterDesc {
1056    pub counter: u32,
1057    pub misc_flags: u32,
1058}
1059impl CounterDesc {
1060    fn to_c_struct(&self) -> D3D11_COUNTER_DESC {
1061        D3D11_COUNTER_DESC {
1062            Counter: self.counter as u32,
1063            MiscFlags: self.misc_flags,
1064        }
1065    }
1066}
1067impl From<D3D11_COUNTER_DESC> for CounterDesc {
1068    fn from(src: D3D11_COUNTER_DESC) -> CounterDesc {
1069        CounterDesc {
1070            counter: unsafe { std::mem::transmute(src.Counter) },
1071            misc_flags: src.MiscFlags,
1072        }
1073    }
1074}
1075
1076#[derive(Clone, Debug)]
1077#[repr(C)]
1078pub struct CounterInfo {
1079    pub last_device_dependent_counter: u32,
1080    pub num_simultaneous_counters: u32,
1081    pub num_detectable_parallel_units: u8,
1082}
1083impl From<D3D11_COUNTER_INFO> for CounterInfo {
1084    fn from(src: D3D11_COUNTER_INFO) -> CounterInfo {
1085        CounterInfo {
1086            last_device_dependent_counter: src.LastDeviceDependentCounter,
1087            num_simultaneous_counters: src.NumSimultaneousCounters,
1088            num_detectable_parallel_units: src.NumDetectableParallelUnits,
1089        }
1090    }
1091}
1092
1093pub const DEFAULT_STENCIL_READ_MASK: u8 = 0xff;
1094pub const DEFAULT_STENCIL_WRITE_MASK: u8 = 0xff;
1095
1096#[derive(Clone, Debug)]
1097pub struct DepthStencilDesc {
1098    pub depth_enable: bool,
1099    pub depth_write_mask: DepthWriteMask,
1100    pub depth_func: ComparisonFunc,
1101    pub stencil_enable: bool,
1102    pub stencil_read_mask: u8,
1103    pub stencil_write_mask: u8,
1104    pub front_face: DepthStencilOpDesc,
1105    pub back_face: DepthStencilOpDesc,
1106}
1107impl DepthStencilDesc {
1108    pub fn new() -> Self {
1109        Default::default()
1110    }
1111    pub fn depth_enable(mut self, depth_enable: bool) -> Self {
1112        self.depth_enable = depth_enable;
1113        self
1114    }
1115    pub fn depth_write_mask(mut self, depth_write_mask: DepthWriteMask) -> Self {
1116        self.depth_write_mask = depth_write_mask;
1117        self
1118    }
1119    pub fn depth_func(mut self, depth_func: ComparisonFunc) -> Self {
1120        self.depth_func = depth_func;
1121        self
1122    }
1123    pub fn stencil_enable(mut self, stencil_enable: bool) -> Self {
1124        self.stencil_enable = stencil_enable;
1125        self
1126    }
1127    pub fn stencil_read_mask(mut self, stencil_read_mask: u8) -> Self {
1128        self.stencil_read_mask = stencil_read_mask;
1129        self
1130    }
1131    pub fn stencil_write_mask(mut self, stencil_write_mask: u8) -> Self {
1132        self.stencil_write_mask = stencil_write_mask;
1133        self
1134    }
1135    pub fn front_face(mut self, front_face: DepthStencilOpDesc) -> Self {
1136        self.front_face = front_face;
1137        self
1138    }
1139    pub fn back_face(mut self, back_face: DepthStencilOpDesc) -> Self {
1140        self.back_face = back_face;
1141        self
1142    }
1143    fn to_c_struct(&self) -> D3D11_DEPTH_STENCIL_DESC {
1144        D3D11_DEPTH_STENCIL_DESC {
1145            DepthEnable: to_BOOL(self.depth_enable),
1146            DepthWriteMask: self.depth_write_mask as u32,
1147            DepthFunc: self.depth_func as u32,
1148            StencilEnable: to_BOOL(self.stencil_enable),
1149            StencilReadMask: self.stencil_read_mask,
1150            StencilWriteMask: self.stencil_write_mask,
1151            FrontFace: self.front_face.to_c_struct(),
1152            BackFace: self.back_face.to_c_struct(),
1153        }
1154    }
1155}
1156impl Default for DepthStencilDesc {
1157    fn default() -> Self {
1158        Self {
1159            depth_enable: true,
1160            depth_write_mask: DepthWriteMask::All,
1161            depth_func: ComparisonFunc::Less,
1162            stencil_enable: false,
1163            stencil_read_mask: DEFAULT_STENCIL_READ_MASK,
1164            stencil_write_mask: DEFAULT_STENCIL_WRITE_MASK,
1165            front_face: Default::default(),
1166            back_face: Default::default(),
1167        }
1168    }
1169}
1170impl From<D3D11_DEPTH_STENCIL_DESC> for DepthStencilDesc {
1171    fn from(src: D3D11_DEPTH_STENCIL_DESC) -> DepthStencilDesc {
1172        unsafe {
1173            DepthStencilDesc {
1174                depth_enable: src.DepthEnable != 0,
1175                depth_write_mask: std::mem::transmute(src.DepthWriteMask),
1176                depth_func: std::mem::transmute(src.DepthFunc),
1177                stencil_enable: src.StencilEnable != 0,
1178                stencil_read_mask: src.StencilReadMask,
1179                stencil_write_mask: src.StencilWriteMask,
1180                front_face: src.FrontFace.into(),
1181                back_face: src.BackFace.into(),
1182            }
1183        }
1184    }
1185}
1186
1187#[derive(Clone, Debug)]
1188pub enum DepthStencilViewDesc {
1189    Texture1D {
1190        format: dxgi::Format,
1191        flags: Option<DSVFlags>,
1192        mip_slice: u32,
1193    },
1194    Texture1DArray {
1195        format: dxgi::Format,
1196        flags: Option<DSVFlags>,
1197        mip_slice: u32,
1198        first_array_slice: u32,
1199        array_size: u32,
1200    },
1201    Texture2D {
1202        format: dxgi::Format,
1203        flags: Option<DSVFlags>,
1204        mip_slice: u32,
1205    },
1206    Texture2DArray {
1207        format: dxgi::Format,
1208        flags: Option<DSVFlags>,
1209        mip_slice: u32,
1210        first_array_slice: u32,
1211        array_size: u32,
1212    },
1213    Texture2DMS {
1214        format: dxgi::Format,
1215        flags: Option<DSVFlags>,
1216    },
1217    Texture2DMSArray {
1218        format: dxgi::Format,
1219        flags: Option<DSVFlags>,
1220        first_array_slice: u32,
1221        array_size: u32,
1222    },
1223}
1224impl DepthStencilViewDesc {
1225    fn to_c_struct(&self) -> D3D11_DEPTH_STENCIL_VIEW_DESC {
1226        let mut obj = D3D11_DEPTH_STENCIL_VIEW_DESC::default();
1227        match self {
1228            &DepthStencilViewDesc::Texture1D {
1229                format,
1230                flags,
1231                mip_slice,
1232            } => unsafe {
1233                obj.Format = format as u32;
1234                obj.ViewDimension = DSVDimension::Texture1D as u32;
1235                obj.Flags = flags.map_or(0, |f| f.0);
1236                obj.u.Texture1D_mut().MipSlice = mip_slice;
1237            },
1238            &DepthStencilViewDesc::Texture1DArray {
1239                format,
1240                flags,
1241                mip_slice,
1242                first_array_slice,
1243                array_size,
1244            } => unsafe {
1245                obj.Format = format as u32;
1246                obj.ViewDimension = DSVDimension::Texture1DArray as u32;
1247                obj.Flags = flags.map_or(0, |f| f.0);
1248                obj.u.Texture1DArray_mut().MipSlice = mip_slice;
1249                obj.u.Texture1DArray_mut().FirstArraySlice = first_array_slice;
1250                obj.u.Texture1DArray_mut().ArraySize = array_size;
1251            },
1252            &DepthStencilViewDesc::Texture2D {
1253                format,
1254                flags,
1255                mip_slice,
1256            } => unsafe {
1257                obj.Format = format as u32;
1258                obj.ViewDimension = DSVDimension::Texture2D as u32;
1259                obj.Flags = flags.map_or(0, |f| f.0);
1260                obj.u.Texture2D_mut().MipSlice = mip_slice;
1261            },
1262            &DepthStencilViewDesc::Texture2DArray {
1263                format,
1264                flags,
1265                mip_slice,
1266                first_array_slice,
1267                array_size,
1268            } => unsafe {
1269                obj.Format = format as u32;
1270                obj.ViewDimension = DSVDimension::Texture2DArray as u32;
1271                obj.Flags = flags.map_or(0, |f| f.0);
1272                obj.u.Texture2DArray_mut().MipSlice = mip_slice;
1273                obj.u.Texture2DArray_mut().FirstArraySlice = first_array_slice;
1274                obj.u.Texture2DArray_mut().ArraySize = array_size;
1275            },
1276            &DepthStencilViewDesc::Texture2DMS { format, flags } => unsafe {
1277                obj.Format = format as u32;
1278                obj.ViewDimension = DSVDimension::Texture2DMS as u32;
1279                obj.Flags = flags.map_or(0, |f| f.0);
1280                obj.u.Texture2DMS_mut().UnusedField_NothingToDefine = 0;
1281            },
1282            &DepthStencilViewDesc::Texture2DMSArray {
1283                format,
1284                flags,
1285                first_array_slice,
1286                array_size,
1287            } => unsafe {
1288                obj.Format = format as u32;
1289                obj.ViewDimension = DSVDimension::Texture2DMSArray as u32;
1290                obj.Flags = flags.map_or(0, |f| f.0);
1291                obj.u.Texture2DMSArray_mut().FirstArraySlice = first_array_slice;
1292                obj.u.Texture2DMSArray_mut().ArraySize = array_size;
1293            },
1294        }
1295        obj
1296    }
1297}
1298impl From<D3D11_DEPTH_STENCIL_VIEW_DESC> for DepthStencilViewDesc {
1299    fn from(src: D3D11_DEPTH_STENCIL_VIEW_DESC) -> DepthStencilViewDesc {
1300        unsafe {
1301            match src.ViewDimension {
1302                D3D11_DSV_DIMENSION_TEXTURE1D => DepthStencilViewDesc::Texture1D {
1303                    format: std::mem::transmute(src.Format),
1304                    flags: if src.Flags == 0 {
1305                        None
1306                    } else {
1307                        Some(DSVFlags(src.Flags))
1308                    },
1309                    mip_slice: src.u.Texture1D().MipSlice,
1310                },
1311                D3D11_DSV_DIMENSION_TEXTURE1DARRAY => DepthStencilViewDesc::Texture1DArray {
1312                    format: std::mem::transmute(src.Format),
1313                    flags: if src.Flags == 0 {
1314                        None
1315                    } else {
1316                        Some(DSVFlags(src.Flags))
1317                    },
1318                    mip_slice: src.u.Texture1DArray().MipSlice,
1319                    first_array_slice: src.u.Texture1DArray().FirstArraySlice,
1320                    array_size: src.u.Texture1DArray().ArraySize,
1321                },
1322                D3D11_DSV_DIMENSION_TEXTURE2D => DepthStencilViewDesc::Texture2D {
1323                    format: std::mem::transmute(src.Format),
1324                    flags: if src.Flags == 0 {
1325                        None
1326                    } else {
1327                        Some(DSVFlags(src.Flags))
1328                    },
1329                    mip_slice: src.u.Texture2D().MipSlice,
1330                },
1331                D3D11_DSV_DIMENSION_TEXTURE2DARRAY => DepthStencilViewDesc::Texture2DArray {
1332                    format: std::mem::transmute(src.Format),
1333                    flags: if src.Flags == 0 {
1334                        None
1335                    } else {
1336                        Some(DSVFlags(src.Flags))
1337                    },
1338                    mip_slice: src.u.Texture2DArray().MipSlice,
1339                    first_array_slice: src.u.Texture2DArray().FirstArraySlice,
1340                    array_size: src.u.Texture2DArray().ArraySize,
1341                },
1342                D3D11_DSV_DIMENSION_TEXTURE2DMS => DepthStencilViewDesc::Texture2DMS {
1343                    format: std::mem::transmute(src.Format),
1344                    flags: if src.Flags == 0 {
1345                        None
1346                    } else {
1347                        Some(DSVFlags(src.Flags))
1348                    },
1349                },
1350                D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY => DepthStencilViewDesc::Texture2DMSArray {
1351                    format: std::mem::transmute(src.Format),
1352                    flags: if src.Flags == 0 {
1353                        None
1354                    } else {
1355                        Some(DSVFlags(src.Flags))
1356                    },
1357                    first_array_slice: src.u.Texture2DMSArray().FirstArraySlice,
1358                    array_size: src.u.Texture2DMSArray().ArraySize,
1359                },
1360                _ => unreachable!(),
1361            }
1362        }
1363    }
1364}
1365
1366#[derive(Clone, Debug)]
1367pub struct DepthStencilOpDesc {
1368    pub stencil_fail_op: StencilOp,
1369    pub stencil_depth_fail_op: StencilOp,
1370    pub stencil_pass_op: StencilOp,
1371    pub stencil_func: ComparisonFunc,
1372}
1373impl DepthStencilOpDesc {
1374    pub fn new() -> Self {
1375        Default::default()
1376    }
1377    pub fn stencil_fail_op(mut self, stencil_fail_op: StencilOp) -> Self {
1378        self.stencil_fail_op = stencil_fail_op;
1379        self
1380    }
1381    pub fn stencil_depth_fail_op(mut self, stencil_depth_fail_op: StencilOp) -> Self {
1382        self.stencil_depth_fail_op = stencil_depth_fail_op;
1383        self
1384    }
1385    pub fn stencil_pass_op(mut self, stencil_pass_op: StencilOp) -> Self {
1386        self.stencil_pass_op = stencil_pass_op;
1387        self
1388    }
1389    pub fn stencil_func(mut self, stencil_func: ComparisonFunc) -> Self {
1390        self.stencil_func = stencil_func;
1391        self
1392    }
1393    fn to_c_struct(&self) -> D3D11_DEPTH_STENCILOP_DESC {
1394        D3D11_DEPTH_STENCILOP_DESC {
1395            StencilFailOp: self.stencil_fail_op as u32,
1396            StencilDepthFailOp: self.stencil_depth_fail_op as u32,
1397            StencilPassOp: self.stencil_pass_op as u32,
1398            StencilFunc: self.stencil_func as u32,
1399        }
1400    }
1401}
1402impl Default for DepthStencilOpDesc {
1403    fn default() -> Self {
1404        Self {
1405            stencil_fail_op: StencilOp::Keep,
1406            stencil_depth_fail_op: StencilOp::Keep,
1407            stencil_pass_op: StencilOp::Keep,
1408            stencil_func: ComparisonFunc::Always,
1409        }
1410    }
1411}
1412impl From<D3D11_DEPTH_STENCILOP_DESC> for DepthStencilOpDesc {
1413    fn from(src: D3D11_DEPTH_STENCILOP_DESC) -> DepthStencilOpDesc {
1414        unsafe {
1415            DepthStencilOpDesc {
1416                stencil_fail_op: std::mem::transmute(src.StencilFailOp),
1417                stencil_depth_fail_op: std::mem::transmute(src.StencilDepthFailOp),
1418                stencil_pass_op: std::mem::transmute(src.StencilPassOp),
1419                stencil_func: std::mem::transmute(src.StencilFunc),
1420            }
1421        }
1422    }
1423}
1424
1425#[derive(Clone, Debug)]
1426#[repr(C)]
1427pub struct DrawIndexedInstancedIndirectArgs {
1428    pub index_count_per_instance: u32,
1429    pub instance_count: u32,
1430    pub start_index_location: u32,
1431    pub base_vertex_location: i32,
1432    pub start_instance_location: u32,
1433}
1434
1435#[derive(Clone, Debug)]
1436#[repr(C)]
1437pub struct DrawInstancedIndirectArgs {
1438    pub vertex_count_per_instance: u32,
1439    pub instance_count: u32,
1440    pub start_vertex_location: u32,
1441    pub start_instance_location: u32,
1442}
1443
1444#[derive(Clone, Debug)]
1445#[repr(C)]
1446pub struct EncryptedBlockInfo {
1447    pub num_encrypted_bytes_at_beginning: u32,
1448    pub num_bytes_in_skip_pattern: u32,
1449    pub num_bytes_in_encrypt_pattern: u32,
1450}
1451
1452pub trait CheckFeatureSupport
1453where
1454    Self: Sized,
1455{
1456    type Args;
1457    fn check_feature_support(device: *mut ID3D11Device, args: Self::Args) -> Result<Self, HResult>;
1458}
1459
1460pub mod feature_data {
1461    use super::*;
1462
1463    #[derive(Clone, Debug)]
1464    pub struct ArchitectureInfo {
1465        pub tile_based_deferred_renderer: bool,
1466    }
1467    impl From<D3D11_FEATURE_DATA_ARCHITECTURE_INFO> for ArchitectureInfo {
1468        fn from(src: D3D11_FEATURE_DATA_ARCHITECTURE_INFO) -> ArchitectureInfo {
1469            ArchitectureInfo {
1470                tile_based_deferred_renderer: src.TileBasedDeferredRenderer != 0,
1471            }
1472        }
1473    }
1474    impl CheckFeatureSupport for ArchitectureInfo {
1475        type Args = ();
1476        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1477            let mut obj = D3D11_FEATURE_DATA_ARCHITECTURE_INFO::default();
1478            let res = unsafe {
1479                (*device).CheckFeatureSupport(
1480                    D3D11_FEATURE_ARCHITECTURE_INFO,
1481                    as_c_void_mut(&mut obj),
1482                    std::mem::size_of_val(&obj) as u32,
1483                )
1484            };
1485            hresult(obj.into(), res)
1486        }
1487    }
1488
1489    #[derive(Clone, Debug)]
1490    pub struct D3D10XHardwareOptions {
1491        pub compute_shaders_plus_raw_and_structured_buffers_via_shader_4_x: bool,
1492    }
1493    impl From<D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS> for D3D10XHardwareOptions {
1494        fn from(src: D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS) -> D3D10XHardwareOptions {
1495            D3D10XHardwareOptions {
1496                compute_shaders_plus_raw_and_structured_buffers_via_shader_4_x: src
1497                    .ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x
1498                    != 0,
1499            }
1500        }
1501    }
1502    impl CheckFeatureSupport for D3D10XHardwareOptions {
1503        type Args = ();
1504        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1505            let mut obj = D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS::default();
1506            let res = unsafe {
1507                (*device).CheckFeatureSupport(
1508                    D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS,
1509                    as_c_void_mut(&mut obj),
1510                    std::mem::size_of_val(&obj) as u32,
1511                )
1512            };
1513            hresult(obj.into(), res)
1514        }
1515    }
1516
1517    #[derive(Clone, Debug)]
1518    pub struct D3D11Options {
1519        pub output_merger_logic_op: bool,
1520        pub uav_only_rendering_forced_sample_count: bool,
1521        pub discard_apis_seen_by_driver: bool,
1522        pub flags_for_update_and_copy_seen_by_driver: bool,
1523        pub clear_view: bool,
1524        pub copy_with_overlap: bool,
1525        pub constant_buffer_partial_update: bool,
1526        pub constant_buffer_offsetting: bool,
1527        pub map_no_overwirte_on_dynamic_constant_buffer: bool,
1528        pub map_no_overwrite_on_dynamic_buffer_srv: bool,
1529        pub multisample_rtv_with_forced_sample_count_one: bool,
1530        pub sad_4_shader_instructions: bool,
1531        pub extended_doubles_shader_instructions: bool,
1532        pub extended_resource_sharing: bool,
1533    }
1534    impl From<D3D11_FEATURE_DATA_D3D11_OPTIONS> for D3D11Options {
1535        fn from(src: D3D11_FEATURE_DATA_D3D11_OPTIONS) -> D3D11Options {
1536            D3D11Options {
1537                output_merger_logic_op: src.OutputMergerLogicOp != 0,
1538                uav_only_rendering_forced_sample_count: src.UAVOnlyRenderingForcedSampleCount != 0,
1539                discard_apis_seen_by_driver: src.DiscardAPIsSeenByDriver != 0,
1540                flags_for_update_and_copy_seen_by_driver: src.FlagsForUpdateAndCopySeenByDriver
1541                    != 0,
1542                clear_view: src.ClearView != 0,
1543                copy_with_overlap: src.CopyWithOverlap != 0,
1544                constant_buffer_partial_update: src.ConstantBufferPartialUpdate != 0,
1545                constant_buffer_offsetting: src.ConstantBufferOffsetting != 0,
1546                map_no_overwirte_on_dynamic_constant_buffer: src
1547                    .MapNoOverwriteOnDynamicConstantBuffer
1548                    != 0,
1549                map_no_overwrite_on_dynamic_buffer_srv: src.MapNoOverwriteOnDynamicBufferSRV != 0,
1550                multisample_rtv_with_forced_sample_count_one: src
1551                    .MultisampleRTVWithForcedSampleCountOne
1552                    != 0,
1553                sad_4_shader_instructions: src.SAD4ShaderInstructions != 0,
1554                extended_doubles_shader_instructions: src.ExtendedDoublesShaderInstructions != 0,
1555                extended_resource_sharing: src.ExtendedResourceSharing != 0,
1556            }
1557        }
1558    }
1559    impl CheckFeatureSupport for D3D11Options {
1560        type Args = ();
1561        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1562            let mut obj = D3D11_FEATURE_DATA_D3D11_OPTIONS::default();
1563            let res = unsafe {
1564                (*device).CheckFeatureSupport(
1565                    D3D11_FEATURE_D3D11_OPTIONS,
1566                    as_c_void_mut(&mut obj),
1567                    std::mem::size_of_val(&obj) as u32,
1568                )
1569            };
1570            hresult(obj.into(), res)
1571        }
1572    }
1573
1574    #[derive(Clone, Debug)]
1575    pub struct D3D11Options2 {
1576        pub ps_specified_stencil_ref_supported: bool,
1577        pub typed_uav_load_additional_formats: bool,
1578        pub rovs_supported: bool,
1579        pub conservative_rasterization_iter: ConservativeRasterizationTier,
1580        pub tiled_resources_tier: TiledResourcesTier,
1581        pub map_on_default_textures: bool,
1582        pub standard_swizzle: bool,
1583        pub unified_memory_architecture: bool,
1584    }
1585    impl From<D3D11_FEATURE_DATA_D3D11_OPTIONS2> for D3D11Options2 {
1586        fn from(src: D3D11_FEATURE_DATA_D3D11_OPTIONS2) -> D3D11Options2 {
1587            D3D11Options2 {
1588                ps_specified_stencil_ref_supported: src.PSSpecifiedStencilRefSupported != 0,
1589                typed_uav_load_additional_formats: src.TypedUAVLoadAdditionalFormats != 0,
1590                rovs_supported: src.ROVsSupported != 0,
1591                conservative_rasterization_iter: unsafe {
1592                    std::mem::transmute(src.ConservativeRasterizationTier)
1593                },
1594                tiled_resources_tier: unsafe { std::mem::transmute(src.TiledResourcesTier) },
1595                map_on_default_textures: src.MapOnDefaultTextures != 0,
1596                standard_swizzle: src.StandardSwizzle != 0,
1597                unified_memory_architecture: src.UnifiedMemoryArchitecture != 0,
1598            }
1599        }
1600    }
1601    impl CheckFeatureSupport for D3D11Options2 {
1602        type Args = ();
1603        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1604            let mut obj = D3D11_FEATURE_DATA_D3D11_OPTIONS2::default();
1605            let res = unsafe {
1606                (*device).CheckFeatureSupport(
1607                    D3D11_FEATURE_D3D11_OPTIONS2,
1608                    as_c_void_mut(&mut obj),
1609                    std::mem::size_of_val(&obj) as u32,
1610                )
1611            };
1612            hresult(obj.into(), res)
1613        }
1614    }
1615
1616    #[derive(Clone, Debug)]
1617    pub struct D3D11Options3 {
1618        pub vp_and_rt_array_index_from_any_shader_feeding_resterizer: bool,
1619    }
1620    impl From<D3D11_FEATURE_DATA_D3D11_OPTIONS3> for D3D11Options3 {
1621        fn from(src: D3D11_FEATURE_DATA_D3D11_OPTIONS3) -> D3D11Options3 {
1622            D3D11Options3 {
1623                vp_and_rt_array_index_from_any_shader_feeding_resterizer: src
1624                    .VPAndRTArrayIndexFromAnyShaderFeedingRasterizer
1625                    != 0,
1626            }
1627        }
1628    }
1629    impl CheckFeatureSupport for D3D11Options3 {
1630        type Args = ();
1631        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1632            let mut obj = D3D11_FEATURE_DATA_D3D11_OPTIONS3::default();
1633            let res = unsafe {
1634                (*device).CheckFeatureSupport(
1635                    D3D11_FEATURE_D3D11_OPTIONS3,
1636                    as_c_void_mut(&mut obj),
1637                    std::mem::size_of_val(&obj) as u32,
1638                )
1639            };
1640            hresult(obj.into(), res)
1641        }
1642    }
1643
1644    #[derive(Clone, Debug)]
1645    pub struct D3D9Options {
1646        pub full_non_pow2_texture_support: bool,
1647    }
1648    impl From<D3D11_FEATURE_DATA_D3D9_OPTIONS> for D3D9Options {
1649        fn from(src: D3D11_FEATURE_DATA_D3D9_OPTIONS) -> D3D9Options {
1650            D3D9Options {
1651                full_non_pow2_texture_support: src.FullNonPow2TextureSupport != 0,
1652            }
1653        }
1654    }
1655    impl CheckFeatureSupport for D3D9Options {
1656        type Args = ();
1657        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1658            let mut obj = D3D11_FEATURE_DATA_D3D9_OPTIONS::default();
1659            let res = unsafe {
1660                (*device).CheckFeatureSupport(
1661                    D3D11_FEATURE_D3D9_OPTIONS,
1662                    as_c_void_mut(&mut obj),
1663                    std::mem::size_of_val(&obj) as u32,
1664                )
1665            };
1666            hresult(obj.into(), res)
1667        }
1668    }
1669
1670    #[derive(Clone, Debug)]
1671    pub struct D3D9Options1 {
1672        pub full_non_pow2_texture_supported: bool,
1673        pub depth_as_texture_with_less_equal_comparison_filter_supported: bool,
1674        pub simple_instancing_supported: bool,
1675        pub texture_cube_face_render_target_with_non_cube_depth_stencil_supported: bool,
1676    }
1677    impl From<D3D11_FEATURE_DATA_D3D9_OPTIONS1> for D3D9Options1 {
1678        fn from(src: D3D11_FEATURE_DATA_D3D9_OPTIONS1) -> D3D9Options1 {
1679            D3D9Options1 {
1680                full_non_pow2_texture_supported: src.FullNonPow2TextureSupported != 0,
1681                depth_as_texture_with_less_equal_comparison_filter_supported: src
1682                    .DepthAsTextureWithLessEqualComparisonFilterSupported
1683                    != 0,
1684                simple_instancing_supported: src.SimpleInstancingSupported != 0,
1685                texture_cube_face_render_target_with_non_cube_depth_stencil_supported: src
1686                    .TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported
1687                    != 0,
1688            }
1689        }
1690    }
1691    impl CheckFeatureSupport for D3D9Options1 {
1692        type Args = ();
1693        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1694            let mut obj = D3D11_FEATURE_DATA_D3D9_OPTIONS1::default();
1695            let res = unsafe {
1696                (*device).CheckFeatureSupport(
1697                    D3D11_FEATURE_D3D9_OPTIONS1,
1698                    as_c_void_mut(&mut obj),
1699                    std::mem::size_of_val(&obj) as u32,
1700                )
1701            };
1702            hresult(obj.into(), res)
1703        }
1704    }
1705
1706    #[derive(Clone, Debug)]
1707    pub struct D3D9ShadowSupport {
1708        pub supports_depth_as_texture_with_less_equal_comparison_filter: bool,
1709    }
1710    impl From<D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT> for D3D9ShadowSupport {
1711        fn from(src: D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT) -> D3D9ShadowSupport {
1712            D3D9ShadowSupport {
1713                supports_depth_as_texture_with_less_equal_comparison_filter: src
1714                    .SupportsDepthAsTextureWithLessEqualComparisonFilter
1715                    != 0,
1716            }
1717        }
1718    }
1719    impl CheckFeatureSupport for D3D9ShadowSupport {
1720        type Args = ();
1721        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1722            let mut obj = D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT::default();
1723            let res = unsafe {
1724                (*device).CheckFeatureSupport(
1725                    D3D11_FEATURE_D3D9_SHADOW_SUPPORT,
1726                    as_c_void_mut(&mut obj),
1727                    std::mem::size_of_val(&obj) as u32,
1728                )
1729            };
1730            hresult(obj.into(), res)
1731        }
1732    }
1733
1734    #[derive(Clone, Debug)]
1735    pub struct D3D9SimpleInstancingSupport {
1736        pub simple_instancing_supported: bool,
1737    }
1738    impl From<D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT> for D3D9SimpleInstancingSupport {
1739        fn from(
1740            src: D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT,
1741        ) -> D3D9SimpleInstancingSupport {
1742            D3D9SimpleInstancingSupport {
1743                simple_instancing_supported: src.SimpleInstancingSupported != 0,
1744            }
1745        }
1746    }
1747    impl CheckFeatureSupport for D3D9SimpleInstancingSupport {
1748        type Args = ();
1749        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1750            let mut obj = D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT::default();
1751            let res = unsafe {
1752                (*device).CheckFeatureSupport(
1753                    D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT,
1754                    as_c_void_mut(&mut obj),
1755                    std::mem::size_of_val(&obj) as u32,
1756                )
1757            };
1758            hresult(obj.into(), res)
1759        }
1760    }
1761
1762    #[derive(Clone, Debug)]
1763    pub struct Doubles {
1764        pub double_precision_float_shader_ops: bool,
1765    }
1766    impl From<D3D11_FEATURE_DATA_DOUBLES> for Doubles {
1767        fn from(src: D3D11_FEATURE_DATA_DOUBLES) -> Doubles {
1768            Doubles {
1769                double_precision_float_shader_ops: src.DoublePrecisionFloatShaderOps != 0,
1770            }
1771        }
1772    }
1773    impl CheckFeatureSupport for Doubles {
1774        type Args = ();
1775        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1776            let mut obj = D3D11_FEATURE_DATA_DOUBLES::default();
1777            let res = unsafe {
1778                (*device).CheckFeatureSupport(
1779                    D3D11_FEATURE_DOUBLES,
1780                    as_c_void_mut(&mut obj),
1781                    std::mem::size_of_val(&obj) as u32,
1782                )
1783            };
1784            hresult(obj.into(), res)
1785        }
1786    }
1787
1788    #[derive(Clone, Debug)]
1789    pub struct FormatSupport {
1790        pub in_format: dxgi::Format,
1791        pub out_format_support: super::FormatSupport,
1792    }
1793    impl From<D3D11_FEATURE_DATA_FORMAT_SUPPORT> for FormatSupport {
1794        fn from(src: D3D11_FEATURE_DATA_FORMAT_SUPPORT) -> FormatSupport {
1795            FormatSupport {
1796                in_format: unsafe { std::mem::transmute(src.InFormat) },
1797                out_format_support: super::FormatSupport(src.OutFormatSupport),
1798            }
1799        }
1800    }
1801    impl CheckFeatureSupport for FormatSupport {
1802        type Args = dxgi::Format;
1803        fn check_feature_support(
1804            device: *mut ID3D11Device,
1805            in_format: dxgi::Format,
1806        ) -> Result<Self, HResult> {
1807            let mut obj = D3D11_FEATURE_DATA_FORMAT_SUPPORT::default();
1808            obj.InFormat = in_format as u32;
1809            let res = unsafe {
1810                (*device).CheckFeatureSupport(
1811                    D3D11_FEATURE_FORMAT_SUPPORT,
1812                    as_c_void_mut(&mut obj),
1813                    std::mem::size_of_val(&obj) as u32,
1814                )
1815            };
1816            hresult(obj.into(), res)
1817        }
1818    }
1819
1820    #[derive(Clone, Debug)]
1821    pub struct FormatSupport2 {
1822        pub in_format: dxgi::Format,
1823        pub out_format_support2: super::FormatSupport2,
1824    }
1825    impl From<D3D11_FEATURE_DATA_FORMAT_SUPPORT2> for FormatSupport2 {
1826        fn from(src: D3D11_FEATURE_DATA_FORMAT_SUPPORT2) -> FormatSupport2 {
1827            FormatSupport2 {
1828                in_format: unsafe { std::mem::transmute(src.InFormat) },
1829                out_format_support2: super::FormatSupport2(src.OutFormatSupport2),
1830            }
1831        }
1832    }
1833    impl CheckFeatureSupport for FormatSupport2 {
1834        type Args = dxgi::Format;
1835        fn check_feature_support(
1836            device: *mut ID3D11Device,
1837            in_format: dxgi::Format,
1838        ) -> Result<Self, HResult> {
1839            let mut obj = D3D11_FEATURE_DATA_FORMAT_SUPPORT2::default();
1840            obj.InFormat = in_format as u32;
1841            let res = unsafe {
1842                (*device).CheckFeatureSupport(
1843                    D3D11_FEATURE_FORMAT_SUPPORT2,
1844                    as_c_void_mut(&mut obj),
1845                    std::mem::size_of_val(&obj) as u32,
1846                )
1847            };
1848            hresult(obj.into(), res)
1849        }
1850    }
1851
1852    #[derive(Clone, Debug)]
1853    pub struct GPUVirtualAddressSupport {
1854        pub max_gpu_virtual_address_bits_per_resource: u32,
1855        pub max_gpu_virtual_address_bits_per_process: u32,
1856    }
1857    impl From<D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT> for GPUVirtualAddressSupport {
1858        fn from(src: D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT) -> GPUVirtualAddressSupport {
1859            GPUVirtualAddressSupport {
1860                max_gpu_virtual_address_bits_per_resource: src.MaxGPUVirtualAddressBitsPerResource,
1861                max_gpu_virtual_address_bits_per_process: src.MaxGPUVirtualAddressBitsPerProcess,
1862            }
1863        }
1864    }
1865    impl CheckFeatureSupport for GPUVirtualAddressSupport {
1866        type Args = ();
1867        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1868            let mut obj = D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT::default();
1869            let res = unsafe {
1870                (*device).CheckFeatureSupport(
1871                    D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT,
1872                    as_c_void_mut(&mut obj),
1873                    std::mem::size_of_val(&obj) as u32,
1874                )
1875            };
1876            hresult(obj.into(), res)
1877        }
1878    }
1879
1880    #[derive(Clone, Debug)]
1881    pub struct MarkerSupport {
1882        pub profile: bool,
1883    }
1884    impl From<D3D11_FEATURE_DATA_MARKER_SUPPORT> for MarkerSupport {
1885        fn from(src: D3D11_FEATURE_DATA_MARKER_SUPPORT) -> MarkerSupport {
1886            MarkerSupport {
1887                profile: src.Profile != 0,
1888            }
1889        }
1890    }
1891    impl CheckFeatureSupport for MarkerSupport {
1892        type Args = ();
1893        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1894            let mut obj = D3D11_FEATURE_DATA_MARKER_SUPPORT::default();
1895            let res = unsafe {
1896                (*device).CheckFeatureSupport(
1897                    D3D11_FEATURE_MARKER_SUPPORT,
1898                    as_c_void_mut(&mut obj),
1899                    std::mem::size_of_val(&obj) as u32,
1900                )
1901            };
1902            hresult(obj.into(), res)
1903        }
1904    }
1905
1906    #[derive(Clone, Debug)]
1907    pub struct ShaderMinPrecisionSupport {
1908        pub pixel_shader_min_precition: u32,
1909        pub all_other_shader_stages_min_precision: u32,
1910    }
1911    impl From<D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT> for ShaderMinPrecisionSupport {
1912        fn from(src: D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT) -> ShaderMinPrecisionSupport {
1913            ShaderMinPrecisionSupport {
1914                pixel_shader_min_precition: src.PixelShaderMinPrecision,
1915                all_other_shader_stages_min_precision: src.AllOtherShaderStagesMinPrecision,
1916            }
1917        }
1918    }
1919    impl CheckFeatureSupport for ShaderMinPrecisionSupport {
1920        type Args = ();
1921        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1922            let mut obj = D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT::default();
1923            let res = unsafe {
1924                (*device).CheckFeatureSupport(
1925                    D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT,
1926                    as_c_void_mut(&mut obj),
1927                    std::mem::size_of_val(&obj) as u32,
1928                )
1929            };
1930            hresult(obj.into(), res)
1931        }
1932    }
1933
1934    #[derive(Clone, Debug)]
1935    pub struct Threading {
1936        pub driver_concurrent_creates: bool,
1937        pub driver_command_lists: bool,
1938    }
1939    impl From<D3D11_FEATURE_DATA_THREADING> for Threading {
1940        fn from(src: D3D11_FEATURE_DATA_THREADING) -> Threading {
1941            Threading {
1942                driver_concurrent_creates: src.DriverConcurrentCreates != 0,
1943                driver_command_lists: src.DriverCommandLists != 0,
1944            }
1945        }
1946    }
1947    impl CheckFeatureSupport for Threading {
1948        type Args = ();
1949        fn check_feature_support(device: *mut ID3D11Device, _args: ()) -> Result<Self, HResult> {
1950            let mut obj = D3D11_FEATURE_DATA_THREADING::default();
1951            let res = unsafe {
1952                (*device).CheckFeatureSupport(
1953                    D3D11_FEATURE_THREADING,
1954                    as_c_void_mut(&mut obj),
1955                    std::mem::size_of_val(&obj) as u32,
1956                )
1957            };
1958            hresult(obj.into(), res)
1959        }
1960    }
1961}
1962
1963pub const APPEND_ALIGNED_ELEMENT: u32 = D3D11_APPEND_ALIGNED_ELEMENT;
1964
1965#[derive(Clone, Debug)]
1966pub struct InputElementDesc<'a> {
1967    pub semantic_name: &'a str,
1968    pub semantic_index: u32,
1969    pub format: dxgi::Format,
1970    pub input_slot: u32,
1971    pub aligned_byte_offset: u32,
1972    pub input_slot_class: InputClassification,
1973    pub instance_data_step_rate: u32,
1974}
1975impl<'a> InputElementDesc<'a> {
1976    fn to_c_struct(&self) -> (D3D11_INPUT_ELEMENT_DESC, std::ffi::CString) {
1977        let name = std::ffi::CString::new(self.semantic_name).unwrap();
1978        (
1979            D3D11_INPUT_ELEMENT_DESC {
1980                SemanticName: name.as_ptr(),
1981                SemanticIndex: self.semantic_index,
1982                Format: self.format as u32,
1983                InputSlot: self.input_slot,
1984                AlignedByteOffset: self.aligned_byte_offset,
1985                InputSlotClass: self.input_slot_class as u32,
1986                InstanceDataStepRate: self.instance_data_step_rate,
1987            },
1988            name,
1989        )
1990    }
1991}
1992
1993/// Helper macro for a d3d11::InputElementDesc
1994///
1995/// ## Examples
1996///
1997/// ```
1998/// use dxplr::d3d11_input_element_descs;
1999///
2000/// let descs = d3d11_input_element_descs![
2001///     {"POSITION", 0, dxplr::dxgi::Format::R32G32B32Float, 0, 0, dxplr::d3d11::InputClassification::PerVertexData, 0},
2002///     {"COLOR", 0, dxplr::dxgi::Format::R32G32B32A32Float, 0, dxplr::d3d11::APPEND_ALIGNED_ELEMENT, dxplr::d3d11::InputClassification::PerVertexData, 0}
2003/// ];
2004/// ```
2005///
2006#[macro_export]
2007macro_rules! d3d11_input_element_descs {
2008    ($({$name: expr, $index: expr, $format: expr, $slot: expr, $offset: expr, $class: expr, $rate: expr}),* $(,)?) => {
2009        vec![
2010            $(
2011                $crate::d3d11::InputElementDesc {
2012                    semantic_name: $name,
2013                    semantic_index: $index,
2014                    format: $format,
2015                    input_slot: $slot,
2016                    aligned_byte_offset: $offset,
2017                    input_slot_class: $class,
2018                    instance_data_step_rate: $rate,
2019                },
2020            )*
2021        ]
2022    };
2023}
2024
2025#[derive(Clone, Debug)]
2026pub struct MappedSubresource {
2027    pub data: *mut c_void,
2028    pub row_pitch: u32,
2029    pub depth_pitch: u32,
2030}
2031impl From<D3D11_MAPPED_SUBRESOURCE> for MappedSubresource {
2032    fn from(src: D3D11_MAPPED_SUBRESOURCE) -> MappedSubresource {
2033        MappedSubresource {
2034            data: src.pData,
2035            row_pitch: src.RowPitch,
2036            depth_pitch: src.DepthPitch,
2037        }
2038    }
2039}
2040
2041/*
2042#[derive(Clone, Debug)]
2043pub struct OMAC {
2044    omac: [u8; 16],
2045}
2046impl OMAC {
2047    fn to_c_struct(&self) -> D3D11_OMAC {
2048        D3D11_OMAC {
2049            Omac: self.omac.clone(),
2050        }
2051    }
2052}
2053*/
2054
2055pub mod query_data {
2056    use super::*;
2057
2058    #[derive(Clone, Debug)]
2059    pub struct PipelineStatistics {
2060        pub ia_vertices: u64,
2061        pub ia_primitives: u64,
2062        pub vs_invocations: u64,
2063        pub gs_invocations: u64,
2064        pub gs_primitives: u64,
2065        pub c_invocations: u64,
2066        pub c_primitives: u64,
2067        pub ps_invocations: u64,
2068        pub hs_invocations: u64,
2069        pub ds_invocations: u64,
2070        pub cs_invocations: u64,
2071    }
2072    impl From<D3D11_QUERY_DATA_PIPELINE_STATISTICS> for PipelineStatistics {
2073        fn from(src: D3D11_QUERY_DATA_PIPELINE_STATISTICS) -> PipelineStatistics {
2074            PipelineStatistics {
2075                ia_vertices: src.IAVertices,
2076                ia_primitives: src.IAPrimitives,
2077                vs_invocations: src.VSInvocations,
2078                gs_invocations: src.GSInvocations,
2079                gs_primitives: src.GSPrimitives,
2080                c_invocations: src.CInvocations,
2081                c_primitives: src.CPrimitives,
2082                ps_invocations: src.PSInvocations,
2083                hs_invocations: src.HSInvocations,
2084                ds_invocations: src.DSInvocations,
2085                cs_invocations: src.CSInvocations,
2086            }
2087        }
2088    }
2089
2090    #[derive(Clone, Debug)]
2091    pub struct SOStatistics {
2092        pub num_primitives_written: u64,
2093        pub primitives_storage_needed: u64,
2094    }
2095    impl From<D3D11_QUERY_DATA_SO_STATISTICS> for SOStatistics {
2096        fn from(src: D3D11_QUERY_DATA_SO_STATISTICS) -> SOStatistics {
2097            SOStatistics {
2098                num_primitives_written: src.NumPrimitivesWritten,
2099                primitives_storage_needed: src.PrimitivesStorageNeeded,
2100            }
2101        }
2102    }
2103
2104    #[derive(Clone, Debug)]
2105    pub struct TimestampDisjoint {
2106        pub frequency: u64,
2107        pub disjoint: bool,
2108    }
2109    impl From<D3D11_QUERY_DATA_TIMESTAMP_DISJOINT> for TimestampDisjoint {
2110        fn from(src: D3D11_QUERY_DATA_TIMESTAMP_DISJOINT) -> TimestampDisjoint {
2111            TimestampDisjoint {
2112                frequency: src.Frequency,
2113                disjoint: src.Disjoint != 0,
2114            }
2115        }
2116    }
2117}
2118
2119#[derive(Clone, Debug)]
2120pub struct QueryDesc {
2121    pub query: QueryType,
2122    pub misc_flags: Option<QueryMiscFlags>,
2123}
2124impl QueryDesc {
2125    fn to_c_struct(&self) -> D3D11_QUERY_DESC {
2126        D3D11_QUERY_DESC {
2127            Query: self.query as u32,
2128            MiscFlags: self.misc_flags.map_or(0, |f| f.0),
2129        }
2130    }
2131}
2132impl From<D3D11_QUERY_DESC> for QueryDesc {
2133    fn from(src: D3D11_QUERY_DESC) -> QueryDesc {
2134        QueryDesc {
2135            query: unsafe { std::mem::transmute(src.Query) },
2136            misc_flags: if src.MiscFlags == 0 {
2137                None
2138            } else {
2139                Some(QueryMiscFlags(src.MiscFlags))
2140            },
2141        }
2142    }
2143}
2144
2145pub const DEFAULT_DEPTH_BIAS: u32 = D3D11_DEFAULT_DEPTH_BIAS;
2146pub const DEFAULT_DEPTH_BIAS_CLAMP: f32 = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
2147pub const DEFAULT_SLOPE_SCALED_DEPTH_BIAS: f32 = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
2148
2149#[derive(Clone, Debug)]
2150pub struct RasterizerDesc {
2151    pub fill_mode: FillMode,
2152    pub cull_mode: CullMode,
2153    pub front_counter_clockwise: bool,
2154    pub depth_bias: i32,
2155    pub depth_bias_clamp: f32,
2156    pub slope_scaled_depth_bias: f32,
2157    pub depth_clip_enable: bool,
2158    pub scissor_enable: bool,
2159    pub multisample_enable: bool,
2160    pub antialiased_line_enable: bool,
2161}
2162impl RasterizerDesc {
2163    pub fn new() -> Self {
2164        Default::default()
2165    }
2166    pub fn fill_mode(mut self, mode: FillMode) -> Self {
2167        self.fill_mode = mode;
2168        self
2169    }
2170    pub fn cull_mode(mut self, mode: CullMode) -> Self {
2171        self.cull_mode = mode;
2172        self
2173    }
2174    pub fn front_counter_clockwise(mut self, front_counter_clockwise: bool) -> Self {
2175        self.front_counter_clockwise = front_counter_clockwise;
2176        self
2177    }
2178    pub fn depth_bias(mut self, depth_bias: i32) -> Self {
2179        self.depth_bias = depth_bias;
2180        self
2181    }
2182    pub fn depth_bias_clamp(mut self, depth_bias_clamp: f32) -> Self {
2183        self.depth_bias_clamp = depth_bias_clamp;
2184        self
2185    }
2186    pub fn slope_scaled_depth_bias(mut self, slope_scaled_depth_bias: f32) -> Self {
2187        self.slope_scaled_depth_bias = slope_scaled_depth_bias;
2188        self
2189    }
2190    pub fn depth_clip_enable(mut self, depth_clip_enable: bool) -> Self {
2191        self.depth_clip_enable = depth_clip_enable;
2192        self
2193    }
2194    pub fn scissor_enable(mut self, scissor_enable: bool) -> Self {
2195        self.scissor_enable = scissor_enable;
2196        self
2197    }
2198    pub fn multisample_enable(mut self, multisample_enable: bool) -> Self {
2199        self.multisample_enable = multisample_enable;
2200        self
2201    }
2202    pub fn antialiased_line_enable(mut self, antialiased_line_enable: bool) -> Self {
2203        self.antialiased_line_enable = antialiased_line_enable;
2204        self
2205    }
2206    fn to_c_struct(&self) -> D3D11_RASTERIZER_DESC {
2207        D3D11_RASTERIZER_DESC {
2208            FillMode: self.fill_mode as u32,
2209            CullMode: self.cull_mode as u32,
2210            FrontCounterClockwise: to_BOOL(self.front_counter_clockwise),
2211            DepthBias: self.depth_bias,
2212            DepthBiasClamp: self.depth_bias_clamp,
2213            SlopeScaledDepthBias: self.slope_scaled_depth_bias,
2214            DepthClipEnable: to_BOOL(self.depth_clip_enable),
2215            ScissorEnable: to_BOOL(self.scissor_enable),
2216            MultisampleEnable: to_BOOL(self.multisample_enable),
2217            AntialiasedLineEnable: to_BOOL(self.antialiased_line_enable),
2218        }
2219    }
2220}
2221impl Default for RasterizerDesc {
2222    fn default() -> Self {
2223        Self {
2224            fill_mode: FillMode::Solid,
2225            cull_mode: CullMode::Back,
2226            front_counter_clockwise: false,
2227            depth_bias: 0,
2228            depth_bias_clamp: 0.0,
2229            slope_scaled_depth_bias: 0.0,
2230            depth_clip_enable: true,
2231            scissor_enable: false,
2232            multisample_enable: false,
2233            antialiased_line_enable: false,
2234        }
2235    }
2236}
2237impl From<D3D11_RASTERIZER_DESC> for RasterizerDesc {
2238    fn from(src: D3D11_RASTERIZER_DESC) -> RasterizerDesc {
2239        unsafe {
2240            RasterizerDesc {
2241                fill_mode: std::mem::transmute(src.FillMode),
2242                cull_mode: std::mem::transmute(src.CullMode),
2243                front_counter_clockwise: src.FrontCounterClockwise != 0,
2244                depth_bias: src.DepthBias,
2245                depth_bias_clamp: src.DepthBiasClamp,
2246                slope_scaled_depth_bias: src.SlopeScaledDepthBias,
2247                depth_clip_enable: src.DepthClipEnable != 0,
2248                scissor_enable: src.ScissorEnable != 0,
2249                multisample_enable: src.MultisampleEnable != 0,
2250                antialiased_line_enable: src.AntialiasedLineEnable != 0,
2251            }
2252        }
2253    }
2254}
2255
2256#[derive(Clone, Debug)]
2257pub struct RenderTargetBlendDesc {
2258    pub blend_enable: bool,
2259    pub src_blend: Blend,
2260    pub dest_blend: Blend,
2261    pub blend_op: BlendOp,
2262    pub src_blend_alpha: Blend,
2263    pub dest_blend_alpha: Blend,
2264    pub blend_op_alpha: BlendOp,
2265    pub render_target_write_mask: ColorWriteEnable,
2266}
2267impl RenderTargetBlendDesc {
2268    fn to_c_struct(&self) -> D3D11_RENDER_TARGET_BLEND_DESC {
2269        D3D11_RENDER_TARGET_BLEND_DESC {
2270            BlendEnable: to_BOOL(self.blend_enable),
2271            SrcBlend: self.src_blend as u32,
2272            DestBlend: self.dest_blend as u32,
2273            BlendOp: self.blend_op as u32,
2274            SrcBlendAlpha: self.src_blend_alpha as u32,
2275            DestBlendAlpha: self.dest_blend_alpha as u32,
2276            BlendOpAlpha: self.blend_op_alpha as u32,
2277            RenderTargetWriteMask: self.render_target_write_mask.0 as u8,
2278        }
2279    }
2280}
2281impl Default for RenderTargetBlendDesc {
2282    fn default() -> Self {
2283        Self {
2284            blend_enable: false,
2285            src_blend: Blend::One,
2286            dest_blend: Blend::Zero,
2287            blend_op: BlendOp::Add,
2288            src_blend_alpha: Blend::One,
2289            dest_blend_alpha: Blend::Zero,
2290            blend_op_alpha: BlendOp::Add,
2291            render_target_write_mask: ColorWriteEnable::All,
2292        }
2293    }
2294}
2295impl From<D3D11_RENDER_TARGET_BLEND_DESC> for RenderTargetBlendDesc {
2296    fn from(src: D3D11_RENDER_TARGET_BLEND_DESC) -> RenderTargetBlendDesc {
2297        unsafe {
2298            RenderTargetBlendDesc {
2299                blend_enable: src.BlendEnable != 0,
2300                src_blend: std::mem::transmute(src.SrcBlend),
2301                dest_blend: std::mem::transmute(src.DestBlend),
2302                blend_op: std::mem::transmute(src.BlendOp),
2303                src_blend_alpha: std::mem::transmute(src.SrcBlendAlpha),
2304                dest_blend_alpha: std::mem::transmute(src.DestBlendAlpha),
2305                blend_op_alpha: std::mem::transmute(src.BlendOpAlpha),
2306                render_target_write_mask: ColorWriteEnable(src.RenderTargetWriteMask as u32),
2307            }
2308        }
2309    }
2310}
2311
2312#[derive(Clone, Debug)]
2313pub enum RenderTargetViewDesc {
2314    Buffer {
2315        format: dxgi::Format,
2316        first_element: u32,
2317        num_elements: u32,
2318    },
2319    Texture1D {
2320        format: dxgi::Format,
2321        mip_slice: u32,
2322    },
2323    Texture1DArray {
2324        format: dxgi::Format,
2325        mip_slice: u32,
2326        first_array_slice: u32,
2327        array_size: u32,
2328    },
2329    Texture2D {
2330        format: dxgi::Format,
2331        mip_slice: u32,
2332    },
2333    Texture2DArray {
2334        format: dxgi::Format,
2335        mip_slice: u32,
2336        first_array_slice: u32,
2337        array_size: u32,
2338    },
2339    Texture2DMS {
2340        format: dxgi::Format,
2341    },
2342    Texture2DMSArray {
2343        format: dxgi::Format,
2344        first_array_slice: u32,
2345        array_size: u32,
2346    },
2347    Texture3D {
2348        format: dxgi::Format,
2349        mip_slice: u32,
2350        first_w_slice: u32,
2351        w_size: u32,
2352    },
2353}
2354impl RenderTargetViewDesc {
2355    fn to_c_struct(&self) -> D3D11_RENDER_TARGET_VIEW_DESC {
2356        let mut desc = D3D11_RENDER_TARGET_VIEW_DESC::default();
2357        match self {
2358            &RenderTargetViewDesc::Buffer {
2359                format,
2360                first_element,
2361                num_elements,
2362            } => unsafe {
2363                desc.Format = format as u32;
2364                desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
2365                *desc.u.Buffer_mut().u1.FirstElement_mut() = first_element;
2366                *desc.u.Buffer_mut().u2.NumElements_mut() = num_elements;
2367            },
2368            &RenderTargetViewDesc::Texture1D { format, mip_slice } => unsafe {
2369                desc.Format = format as u32;
2370                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
2371                desc.u.Texture1D_mut().MipSlice = mip_slice;
2372            },
2373            &RenderTargetViewDesc::Texture1DArray {
2374                format,
2375                mip_slice,
2376                first_array_slice,
2377                array_size,
2378            } => unsafe {
2379                desc.Format = format as u32;
2380                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
2381                desc.u.Texture1DArray_mut().MipSlice = mip_slice;
2382                desc.u.Texture1DArray_mut().FirstArraySlice = first_array_slice;
2383                desc.u.Texture1DArray_mut().ArraySize = array_size;
2384            },
2385            &RenderTargetViewDesc::Texture2D { format, mip_slice } => unsafe {
2386                desc.Format = format as u32;
2387                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
2388                desc.u.Texture2D_mut().MipSlice = mip_slice;
2389            },
2390            &RenderTargetViewDesc::Texture2DArray {
2391                format,
2392                mip_slice,
2393                first_array_slice,
2394                array_size,
2395            } => unsafe {
2396                desc.Format = format as u32;
2397                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2398                desc.u.Texture2DArray_mut().MipSlice = mip_slice;
2399                desc.u.Texture2DArray_mut().FirstArraySlice = first_array_slice;
2400                desc.u.Texture2DArray_mut().ArraySize = array_size;
2401            },
2402            &RenderTargetViewDesc::Texture2DMS { format } => {
2403                desc.Format = format as u32;
2404                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
2405            }
2406            &RenderTargetViewDesc::Texture2DMSArray {
2407                format,
2408                first_array_slice,
2409                array_size,
2410            } => unsafe {
2411                desc.Format = format as u32;
2412                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
2413                desc.u.Texture2DArray_mut().FirstArraySlice = first_array_slice;
2414                desc.u.Texture2DArray_mut().ArraySize = array_size;
2415            },
2416            &RenderTargetViewDesc::Texture3D {
2417                format,
2418                mip_slice,
2419                first_w_slice,
2420                w_size,
2421            } => unsafe {
2422                desc.Format = format as u32;
2423                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
2424                desc.u.Texture3D_mut().MipSlice = mip_slice;
2425                desc.u.Texture3D_mut().FirstWSlice = first_w_slice;
2426                desc.u.Texture3D_mut().WSize = w_size;
2427            },
2428        }
2429        desc
2430    }
2431}
2432impl From<D3D11_RENDER_TARGET_VIEW_DESC> for RenderTargetViewDesc {
2433    fn from(src: D3D11_RENDER_TARGET_VIEW_DESC) -> RenderTargetViewDesc {
2434        unsafe {
2435            match src.ViewDimension {
2436                D3D11_RTV_DIMENSION_BUFFER => RenderTargetViewDesc::Buffer {
2437                    format: std::mem::transmute(src.Format),
2438                    first_element: *src.u.Buffer().u1.FirstElement(),
2439                    num_elements: *src.u.Buffer().u2.NumElements(),
2440                },
2441                D3D11_RTV_DIMENSION_TEXTURE1D => RenderTargetViewDesc::Texture1D {
2442                    format: std::mem::transmute(src.Format),
2443                    mip_slice: src.u.Texture1D().MipSlice,
2444                },
2445                D3D11_RTV_DIMENSION_TEXTURE1DARRAY => RenderTargetViewDesc::Texture1DArray {
2446                    format: std::mem::transmute(src.Format),
2447                    mip_slice: src.u.Texture1DArray().MipSlice,
2448                    first_array_slice: src.u.Texture1DArray().FirstArraySlice,
2449                    array_size: src.u.Texture1DArray().ArraySize,
2450                },
2451                D3D11_RTV_DIMENSION_TEXTURE2D => RenderTargetViewDesc::Texture2D {
2452                    format: std::mem::transmute(src.Format),
2453                    mip_slice: src.u.Texture2D().MipSlice,
2454                },
2455                D3D11_RTV_DIMENSION_TEXTURE2DARRAY => RenderTargetViewDesc::Texture2DArray {
2456                    format: std::mem::transmute(src.Format),
2457                    mip_slice: src.u.Texture2DArray().MipSlice,
2458                    first_array_slice: src.u.Texture2DArray().FirstArraySlice,
2459                    array_size: src.u.Texture2DArray().ArraySize,
2460                },
2461                D3D11_RTV_DIMENSION_TEXTURE2DMS => RenderTargetViewDesc::Texture2DMS {
2462                    format: std::mem::transmute(src.Format),
2463                },
2464                D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY => RenderTargetViewDesc::Texture2DMSArray {
2465                    format: std::mem::transmute(src.Format),
2466                    first_array_slice: src.u.Texture2DMSArray().FirstArraySlice,
2467                    array_size: src.u.Texture2DMSArray().ArraySize,
2468                },
2469                D3D11_RTV_DIMENSION_TEXTURE3D => RenderTargetViewDesc::Texture3D {
2470                    format: std::mem::transmute(src.Format),
2471                    mip_slice: src.u.Texture3D().MipSlice,
2472                    first_w_slice: src.u.Texture3D().FirstWSlice,
2473                    w_size: src.u.Texture3D().WSize,
2474                },
2475                _ => unreachable!(),
2476            }
2477        }
2478    }
2479}
2480
2481pub const MAX_MAXANISOTROPY: u32 = D3D11_MAX_MAXANISOTROPY;
2482
2483#[derive(Clone, Debug)]
2484pub struct SamplerDesc<F> {
2485    pub filter: F,
2486    pub address_u: TextureAddressMode,
2487    pub address_v: TextureAddressMode,
2488    pub address_w: TextureAddressMode,
2489    pub mip_lod_bias: f32,
2490    pub max_anisotropy: u32,
2491    pub comparison_func: ComparisonFunc,
2492    pub border_color: dxgi::RGBA,
2493    pub min_lod: f32,
2494    pub max_lod: f32,
2495}
2496impl SamplerDesc<()> {
2497    pub fn new() -> Self {
2498        Self {
2499            filter: (),
2500            address_u: TextureAddressMode::Wrap,
2501            address_v: TextureAddressMode::Wrap,
2502            address_w: TextureAddressMode::Wrap,
2503            mip_lod_bias: 0.0,
2504            max_anisotropy: MAX_MAXANISOTROPY,
2505            comparison_func: ComparisonFunc::Never,
2506            border_color: dxgi::RGBA {
2507                r: 0.0,
2508                g: 0.0,
2509                b: 0.0,
2510                a: 0.0,
2511            },
2512            min_lod: 0.0,
2513            max_lod: std::f32::MAX,
2514        }
2515    }
2516}
2517impl<F> SamplerDesc<F> {
2518    pub fn filter(self, filter: Filter) -> SamplerDesc<Filter> {
2519        SamplerDesc {
2520            filter,
2521            address_u: self.address_u,
2522            address_v: self.address_v,
2523            address_w: self.address_w,
2524            mip_lod_bias: self.mip_lod_bias,
2525            max_anisotropy: self.max_anisotropy,
2526            comparison_func: self.comparison_func,
2527            border_color: self.border_color,
2528            min_lod: self.min_lod,
2529            max_lod: self.max_lod,
2530        }
2531    }
2532    pub fn address_u(mut self, address_u: TextureAddressMode) -> Self {
2533        self.address_u = address_u;
2534        self
2535    }
2536    pub fn address_v(mut self, address_v: TextureAddressMode) -> Self {
2537        self.address_v = address_v;
2538        self
2539    }
2540    pub fn address_w(mut self, address_w: TextureAddressMode) -> Self {
2541        self.address_w = address_w;
2542        self
2543    }
2544    pub fn mip_lod_bias(mut self, mip_lod_bias: f32) -> Self {
2545        self.mip_lod_bias = mip_lod_bias;
2546        self
2547    }
2548    pub fn max_anisotropy(mut self, max_anisotropy: u32) -> Self {
2549        self.max_anisotropy = max_anisotropy;
2550        self
2551    }
2552    pub fn comparison_func(mut self, comparison_func: ComparisonFunc) -> Self {
2553        self.comparison_func = comparison_func;
2554        self
2555    }
2556    pub fn border_color(mut self, border_color: dxgi::RGBA) -> Self {
2557        self.border_color = border_color;
2558        self
2559    }
2560    pub fn min_lod(mut self, min_lod: f32) -> Self {
2561        self.min_lod = min_lod;
2562        self
2563    }
2564    pub fn max_lod(mut self, max_lod: f32) -> Self {
2565        self.max_lod = max_lod;
2566        self
2567    }
2568}
2569impl SamplerDesc<Filter> {
2570    fn to_c_struct(&self) -> D3D11_SAMPLER_DESC {
2571        D3D11_SAMPLER_DESC {
2572            Filter: self.filter as u32,
2573            AddressU: self.address_u as u32,
2574            AddressV: self.address_v as u32,
2575            AddressW: self.address_w as u32,
2576            MipLODBias: self.mip_lod_bias,
2577            MaxAnisotropy: self.max_anisotropy,
2578            ComparisonFunc: self.comparison_func as u32,
2579            BorderColor: [
2580                self.border_color.r,
2581                self.border_color.g,
2582                self.border_color.b,
2583                self.border_color.a,
2584            ],
2585            MinLOD: self.min_lod,
2586            MaxLOD: self.max_lod,
2587        }
2588    }
2589}
2590impl From<D3D11_SAMPLER_DESC> for SamplerDesc<Filter> {
2591    fn from(src: D3D11_SAMPLER_DESC) -> SamplerDesc<Filter> {
2592        unsafe {
2593            SamplerDesc {
2594                filter: std::mem::transmute(src.Filter),
2595                address_u: std::mem::transmute(src.AddressU),
2596                address_v: std::mem::transmute(src.AddressV),
2597                address_w: std::mem::transmute(src.AddressW),
2598                mip_lod_bias: src.MipLODBias,
2599                max_anisotropy: src.MaxAnisotropy,
2600                comparison_func: std::mem::transmute(src.ComparisonFunc),
2601                border_color: dxgi::RGBA {
2602                    r: src.BorderColor[0],
2603                    g: src.BorderColor[1],
2604                    b: src.BorderColor[2],
2605                    a: src.BorderColor[3],
2606                },
2607                min_lod: src.MinLOD,
2608                max_lod: src.MaxLOD,
2609            }
2610        }
2611    }
2612}
2613
2614#[derive(Clone, Debug)]
2615pub enum ShaderResourceViewDesc {
2616    Buffer {
2617        format: dxgi::Format,
2618        first_element: u32,
2619        num_elements: u32,
2620    },
2621    Texture1D {
2622        format: dxgi::Format,
2623        most_detailed_mip: u32,
2624        mip_levels: u32,
2625    },
2626    Texture1DArray {
2627        format: dxgi::Format,
2628        most_detailed_mip: u32,
2629        mip_levels: u32,
2630        first_array_slice: u32,
2631        array_size: u32,
2632    },
2633    Texture2D {
2634        format: dxgi::Format,
2635        most_detailed_mip: u32,
2636        mip_levels: u32,
2637    },
2638    Texture2DArray {
2639        format: dxgi::Format,
2640        most_detailed_mip: u32,
2641        mip_levels: u32,
2642        first_array_slice: u32,
2643        array_size: u32,
2644    },
2645    Texture2DMS {
2646        format: dxgi::Format,
2647    },
2648    Texture2DMSArray {
2649        format: dxgi::Format,
2650        first_array_slice: u32,
2651        array_size: u32,
2652    },
2653    Texture3D {
2654        format: dxgi::Format,
2655        most_detailed_mip: u32,
2656        mip_levels: u32,
2657    },
2658    TextureCube {
2659        format: dxgi::Format,
2660        most_detailed_mip: u32,
2661        mip_levels: u32,
2662    },
2663    TextureCubeArray {
2664        format: dxgi::Format,
2665        most_detailed_mip: u32,
2666        mip_levels: u32,
2667        first_2d_array_face: u32,
2668        num_cubes: u32,
2669    },
2670    BufferEx {
2671        format: dxgi::Format,
2672        first_element: u32,
2673        num_elements: u32,
2674        flags: Option<BufferExSRVFlags>,
2675    },
2676}
2677impl ShaderResourceViewDesc {
2678    fn to_c_struct(&self) -> D3D11_SHADER_RESOURCE_VIEW_DESC {
2679        let mut desc = D3D11_SHADER_RESOURCE_VIEW_DESC::default();
2680        match self {
2681            &ShaderResourceViewDesc::Buffer {
2682                format,
2683                first_element,
2684                num_elements,
2685            } => unsafe {
2686                desc.Format = format as u32;
2687                desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
2688                *desc.u.Buffer_mut().u1.FirstElement_mut() = first_element;
2689                *desc.u.Buffer_mut().u2.NumElements_mut() = num_elements;
2690            },
2691            &ShaderResourceViewDesc::Texture1D {
2692                format,
2693                most_detailed_mip,
2694                mip_levels,
2695            } => unsafe {
2696                desc.Format = format as u32;
2697                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
2698                desc.u.Texture1D_mut().MostDetailedMip = most_detailed_mip;
2699                desc.u.Texture1D_mut().MipLevels = mip_levels;
2700            },
2701            &ShaderResourceViewDesc::Texture1DArray {
2702                format,
2703                most_detailed_mip,
2704                mip_levels,
2705                first_array_slice,
2706                array_size,
2707            } => unsafe {
2708                desc.Format = format as u32;
2709                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
2710                desc.u.Texture1DArray_mut().MostDetailedMip = most_detailed_mip;
2711                desc.u.Texture1DArray_mut().MipLevels = mip_levels;
2712                desc.u.Texture1DArray_mut().FirstArraySlice = first_array_slice;
2713                desc.u.Texture1DArray_mut().ArraySize = array_size;
2714            },
2715            &ShaderResourceViewDesc::Texture2D {
2716                format,
2717                most_detailed_mip,
2718                mip_levels,
2719            } => unsafe {
2720                desc.Format = format as u32;
2721                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
2722                desc.u.Texture2D_mut().MostDetailedMip = most_detailed_mip;
2723                desc.u.Texture2D_mut().MipLevels = mip_levels;
2724            },
2725            &ShaderResourceViewDesc::Texture2DArray {
2726                format,
2727                most_detailed_mip,
2728                mip_levels,
2729                first_array_slice,
2730                array_size,
2731            } => unsafe {
2732                desc.Format = format as u32;
2733                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
2734                desc.u.Texture2DArray_mut().MostDetailedMip = most_detailed_mip;
2735                desc.u.Texture2DArray_mut().MipLevels = mip_levels;
2736                desc.u.Texture2DArray_mut().FirstArraySlice = first_array_slice;
2737                desc.u.Texture2DArray_mut().ArraySize = array_size;
2738            },
2739            &ShaderResourceViewDesc::Texture2DMS { format } => {
2740                desc.Format = format as u32;
2741                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
2742            }
2743            &ShaderResourceViewDesc::Texture2DMSArray {
2744                format,
2745                first_array_slice,
2746                array_size,
2747            } => unsafe {
2748                desc.Format = format as u32;
2749                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
2750                desc.u.Texture2DMSArray_mut().FirstArraySlice = first_array_slice;
2751                desc.u.Texture2DMSArray_mut().ArraySize = array_size;
2752            },
2753            &ShaderResourceViewDesc::Texture3D {
2754                format,
2755                most_detailed_mip,
2756                mip_levels,
2757            } => unsafe {
2758                desc.Format = format as u32;
2759                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
2760                desc.u.Texture3D_mut().MostDetailedMip = most_detailed_mip;
2761                desc.u.Texture3D_mut().MipLevels = mip_levels;
2762            },
2763            &ShaderResourceViewDesc::TextureCube {
2764                format,
2765                most_detailed_mip,
2766                mip_levels,
2767            } => unsafe {
2768                desc.Format = format as u32;
2769                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
2770                desc.u.TextureCube_mut().MostDetailedMip = most_detailed_mip;
2771                desc.u.TextureCube_mut().MipLevels = mip_levels;
2772            },
2773            &ShaderResourceViewDesc::TextureCubeArray {
2774                format,
2775                most_detailed_mip,
2776                mip_levels,
2777                first_2d_array_face,
2778                num_cubes,
2779            } => unsafe {
2780                desc.Format = format as u32;
2781                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
2782                desc.u.TextureCubeArray_mut().MostDetailedMip = most_detailed_mip;
2783                desc.u.TextureCubeArray_mut().MipLevels = mip_levels;
2784                desc.u.TextureCubeArray_mut().First2DArrayFace = first_2d_array_face;
2785                desc.u.TextureCubeArray_mut().NumCubes = num_cubes;
2786            },
2787            &ShaderResourceViewDesc::BufferEx {
2788                format,
2789                first_element,
2790                num_elements,
2791                flags,
2792            } => unsafe {
2793                desc.Format = format as u32;
2794                desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
2795                desc.u.BufferEx_mut().FirstElement = first_element;
2796                desc.u.BufferEx_mut().NumElements = num_elements;
2797                desc.u.BufferEx_mut().Flags = flags.map_or(0, |f| f.0);
2798            },
2799        }
2800        desc
2801    }
2802}
2803impl From<D3D11_SHADER_RESOURCE_VIEW_DESC> for ShaderResourceViewDesc {
2804    fn from(src: D3D11_SHADER_RESOURCE_VIEW_DESC) -> ShaderResourceViewDesc {
2805        unsafe {
2806            match src.ViewDimension {
2807                D3D11_SRV_DIMENSION_BUFFER => ShaderResourceViewDesc::Buffer {
2808                    format: std::mem::transmute(src.Format),
2809                    first_element: *src.u.Buffer().u1.FirstElement(),
2810                    num_elements: *src.u.Buffer().u2.NumElements(),
2811                },
2812                D3D11_SRV_DIMENSION_TEXTURE1D => ShaderResourceViewDesc::Texture1D {
2813                    format: std::mem::transmute(src.Format),
2814                    most_detailed_mip: src.u.Texture1D().MostDetailedMip,
2815                    mip_levels: src.u.Texture1D().MipLevels,
2816                },
2817                D3D11_SRV_DIMENSION_TEXTURE1DARRAY => ShaderResourceViewDesc::Texture1DArray {
2818                    format: std::mem::transmute(src.Format),
2819                    most_detailed_mip: src.u.Texture1DArray().MostDetailedMip,
2820                    mip_levels: src.u.Texture1DArray().MipLevels,
2821                    first_array_slice: src.u.Texture1DArray().FirstArraySlice,
2822                    array_size: src.u.Texture1DArray().ArraySize,
2823                },
2824                D3D11_SRV_DIMENSION_TEXTURE2D => ShaderResourceViewDesc::Texture2D {
2825                    format: std::mem::transmute(src.Format),
2826                    most_detailed_mip: src.u.Texture2D().MostDetailedMip,
2827                    mip_levels: src.u.Texture2D().MipLevels,
2828                },
2829                D3D11_SRV_DIMENSION_TEXTURE2DARRAY => ShaderResourceViewDesc::Texture2DArray {
2830                    format: std::mem::transmute(src.Format),
2831                    most_detailed_mip: src.u.Texture2DArray().MostDetailedMip,
2832                    mip_levels: src.u.Texture2DArray().MipLevels,
2833                    first_array_slice: src.u.Texture2DArray().FirstArraySlice,
2834                    array_size: src.u.Texture2DArray().ArraySize,
2835                },
2836                D3D11_SRV_DIMENSION_TEXTURE2DMS => ShaderResourceViewDesc::Texture2DMS {
2837                    format: std::mem::transmute(src.Format),
2838                },
2839                D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY => ShaderResourceViewDesc::Texture2DMSArray {
2840                    format: std::mem::transmute(src.Format),
2841                    first_array_slice: src.u.Texture2DMSArray().FirstArraySlice,
2842                    array_size: src.u.Texture2DMSArray().ArraySize,
2843                },
2844                D3D11_SRV_DIMENSION_TEXTURE3D => ShaderResourceViewDesc::Texture3D {
2845                    format: std::mem::transmute(src.Format),
2846                    most_detailed_mip: src.u.Texture3D().MostDetailedMip,
2847                    mip_levels: src.u.Texture3D().MipLevels,
2848                },
2849                D3D11_SRV_DIMENSION_TEXTURECUBE => ShaderResourceViewDesc::TextureCube {
2850                    format: std::mem::transmute(src.Format),
2851                    most_detailed_mip: src.u.TextureCube().MostDetailedMip,
2852                    mip_levels: src.u.TextureCube().MipLevels,
2853                },
2854                D3D11_SRV_DIMENSION_TEXTURECUBEARRAY => ShaderResourceViewDesc::TextureCubeArray {
2855                    format: std::mem::transmute(src.Format),
2856                    most_detailed_mip: src.u.TextureCubeArray().MostDetailedMip,
2857                    mip_levels: src.u.TextureCubeArray().MipLevels,
2858                    first_2d_array_face: src.u.TextureCubeArray().First2DArrayFace,
2859                    num_cubes: src.u.TextureCubeArray().NumCubes,
2860                },
2861                D3D11_SRV_DIMENSION_BUFFEREX => ShaderResourceViewDesc::BufferEx {
2862                    format: std::mem::transmute(src.Format),
2863                    first_element: src.u.BufferEx().FirstElement,
2864                    num_elements: src.u.BufferEx().NumElements,
2865                    flags: if src.u.BufferEx().Flags == 0 {
2866                        None
2867                    } else {
2868                        Some(BufferExSRVFlags(src.u.BufferEx().Flags))
2869                    },
2870                },
2871                _ => unreachable!(),
2872            }
2873        }
2874    }
2875}
2876
2877#[derive(Clone, Debug)]
2878pub struct SODeclarationEntry<'a> {
2879    pub stream: u32,
2880    pub semantic_name: Option<&'a str>,
2881    pub semantic_index: u32,
2882    pub start_component: u8,
2883    pub component_count: u8,
2884    pub output_slot: u8,
2885}
2886impl<'a> SODeclarationEntry<'a> {
2887    fn to_c_struct(&self) -> (D3D11_SO_DECLARATION_ENTRY, Option<std::ffi::CString>) {
2888        let name = self
2889            .semantic_name
2890            .map_or(None, |s| Some(std::ffi::CString::new(s).unwrap()));
2891        (
2892            D3D11_SO_DECLARATION_ENTRY {
2893                Stream: self.stream,
2894                SemanticName: name.as_ref().map_or(std::ptr::null(), |n| n.as_ptr()),
2895                SemanticIndex: self.semantic_index,
2896                StartComponent: self.start_component,
2897                ComponentCount: self.component_count,
2898                OutputSlot: self.output_slot,
2899            },
2900            name,
2901        )
2902    }
2903}
2904
2905#[derive(Clone, Debug)]
2906pub struct SubresourceData<M, P, S> {
2907    pub sys_mem: M,
2908    pub sys_mem_pitch: P,
2909    pub sys_mem_slice_pitch: S,
2910}
2911impl SubresourceData<(), (), ()> {
2912    pub fn new() -> Self {
2913        Self {
2914            sys_mem: (),
2915            sys_mem_pitch: (),
2916            sys_mem_slice_pitch: (),
2917        }
2918    }
2919}
2920impl<M, P, S> SubresourceData<M, P, S> {
2921    pub fn sys_mem<T>(self, sys_mem: *const T) -> SubresourceData<*const c_void, P, S> {
2922        SubresourceData {
2923            sys_mem: sys_mem as *const c_void,
2924            sys_mem_pitch: self.sys_mem_pitch,
2925            sys_mem_slice_pitch: self.sys_mem_slice_pitch,
2926        }
2927    }
2928    pub fn sys_mem_pitch(self, sys_mem_pitch: u32) -> SubresourceData<M, u32, S> {
2929        SubresourceData {
2930            sys_mem: self.sys_mem,
2931            sys_mem_pitch,
2932            sys_mem_slice_pitch: self.sys_mem_slice_pitch,
2933        }
2934    }
2935    pub fn sys_mem_slice_pitch(self, sys_mem_slice_pitch: u32) -> SubresourceData<M, P, u32> {
2936        SubresourceData {
2937            sys_mem: self.sys_mem,
2938            sys_mem_pitch: self.sys_mem_pitch,
2939            sys_mem_slice_pitch,
2940        }
2941    }
2942}
2943impl SubresourceData<*const c_void, (), ()> {
2944    fn to_c_struct(&self) -> D3D11_SUBRESOURCE_DATA {
2945        D3D11_SUBRESOURCE_DATA {
2946            pSysMem: self.sys_mem,
2947            SysMemPitch: 0,
2948            SysMemSlicePitch: 0,
2949        }
2950    }
2951}
2952impl SubresourceData<*const c_void, u32, ()> {
2953    fn to_c_struct(&self) -> D3D11_SUBRESOURCE_DATA {
2954        D3D11_SUBRESOURCE_DATA {
2955            pSysMem: self.sys_mem,
2956            SysMemPitch: self.sys_mem_pitch,
2957            SysMemSlicePitch: 0,
2958        }
2959    }
2960}
2961impl SubresourceData<*const c_void, u32, u32> {
2962    fn to_c_struct(&self) -> D3D11_SUBRESOURCE_DATA {
2963        D3D11_SUBRESOURCE_DATA {
2964            pSysMem: self.sys_mem,
2965            SysMemPitch: self.sys_mem_pitch,
2966            SysMemSlicePitch: self.sys_mem_slice_pitch,
2967        }
2968    }
2969}
2970
2971#[derive(Clone, Debug)]
2972pub struct Texture1DDesc<W, F, U> {
2973    pub width: W,
2974    pub mip_levels: u32,
2975    pub array_size: u32,
2976    pub format: F,
2977    pub usage: U,
2978    pub bind_flags: BindFlags,
2979    pub cpu_access_flags: Option<CPUAccessFlags>,
2980    pub misc_flags: Option<ResourceMiscFlags>,
2981}
2982impl Texture1DDesc<(), (), ()> {
2983    pub fn new() -> Self {
2984        Self {
2985            width: (),
2986            mip_levels: 0,
2987            array_size: 1,
2988            format: (),
2989            usage: (),
2990            bind_flags: BindFlags::ShaderResource,
2991            cpu_access_flags: None,
2992            misc_flags: None,
2993        }
2994    }
2995}
2996impl<W, F, U> Texture1DDesc<W, F, U> {
2997    pub fn width(self, width: u32) -> Texture1DDesc<u32, F, U> {
2998        Texture1DDesc {
2999            width,
3000            mip_levels: self.mip_levels,
3001            array_size: self.array_size,
3002            format: self.format,
3003            usage: self.usage,
3004            bind_flags: self.bind_flags,
3005            cpu_access_flags: self.cpu_access_flags,
3006            misc_flags: self.misc_flags,
3007        }
3008    }
3009    pub fn mip_levels(mut self, mip_levels: u32) -> Self {
3010        self.mip_levels = mip_levels;
3011        self
3012    }
3013    pub fn array_size(mut self, array_size: u32) -> Self {
3014        self.array_size = array_size;
3015        self
3016    }
3017    pub fn format(self, format: dxgi::Format) -> Texture1DDesc<W, dxgi::Format, U> {
3018        Texture1DDesc {
3019            width: self.width,
3020            mip_levels: self.mip_levels,
3021            array_size: self.array_size,
3022            format,
3023            usage: self.usage,
3024            bind_flags: self.bind_flags,
3025            cpu_access_flags: self.cpu_access_flags,
3026            misc_flags: self.misc_flags,
3027        }
3028    }
3029    pub fn usage(self, usage: Usage) -> Texture1DDesc<W, F, Usage> {
3030        Texture1DDesc {
3031            width: self.width,
3032            mip_levels: self.mip_levels,
3033            array_size: self.array_size,
3034            format: self.format,
3035            usage,
3036            bind_flags: self.bind_flags,
3037            cpu_access_flags: self.cpu_access_flags,
3038            misc_flags: self.misc_flags,
3039        }
3040    }
3041    pub fn bind_flags(mut self, bind_flags: BindFlags) -> Self {
3042        self.bind_flags = bind_flags;
3043        self
3044    }
3045    pub fn cpu_access_flags(mut self, cpu_access_flags: CPUAccessFlags) -> Self {
3046        self.cpu_access_flags = Some(cpu_access_flags);
3047        self
3048    }
3049    pub fn misc_flags(mut self, misc_flags: ResourceMiscFlags) -> Self {
3050        self.misc_flags = Some(misc_flags);
3051        self
3052    }
3053}
3054impl Texture1DDesc<u32, dxgi::Format, Usage> {
3055    fn to_c_struct(&self) -> D3D11_TEXTURE1D_DESC {
3056        D3D11_TEXTURE1D_DESC {
3057            Width: self.width,
3058            MipLevels: self.mip_levels,
3059            ArraySize: self.array_size,
3060            Format: self.format as u32,
3061            Usage: self.usage as u32,
3062            BindFlags: self.bind_flags.0,
3063            CPUAccessFlags: self.cpu_access_flags.map_or(0, |f| f.0),
3064            MiscFlags: self.misc_flags.map_or(0, |f| f.0),
3065        }
3066    }
3067}
3068impl From<D3D11_TEXTURE1D_DESC> for Texture1DDesc<u32, dxgi::Format, Usage> {
3069    fn from(src: D3D11_TEXTURE1D_DESC) -> Texture1DDesc<u32, dxgi::Format, Usage> {
3070        unsafe {
3071            Texture1DDesc {
3072                width: src.Width,
3073                mip_levels: src.MipLevels,
3074                array_size: src.ArraySize,
3075                format: std::mem::transmute(src.Format),
3076                usage: std::mem::transmute(src.Usage),
3077                bind_flags: BindFlags(src.BindFlags),
3078                cpu_access_flags: if src.CPUAccessFlags == 0 {
3079                    None
3080                } else {
3081                    Some(CPUAccessFlags(src.CPUAccessFlags))
3082                },
3083                misc_flags: if src.MiscFlags == 0 {
3084                    None
3085                } else {
3086                    Some(ResourceMiscFlags(src.MiscFlags))
3087                },
3088            }
3089        }
3090    }
3091}
3092
3093#[derive(Clone, Debug)]
3094pub struct Texture2DDesc<W, H, F, U> {
3095    pub width: W,
3096    pub height: H,
3097    pub mip_levels: u32,
3098    pub array_size: u32,
3099    pub format: F,
3100    pub sample_desc: dxgi::SampleDesc,
3101    pub usage: U,
3102    pub bind_flags: BindFlags,
3103    pub cpu_access_flags: Option<CPUAccessFlags>,
3104    pub misc_flags: Option<ResourceMiscFlags>,
3105}
3106impl Texture2DDesc<(), (), (), ()> {
3107    pub fn new() -> Self {
3108        Self {
3109            width: (),
3110            height: (),
3111            mip_levels: 1,
3112            array_size: 1,
3113            format: (),
3114            sample_desc: Default::default(),
3115            usage: (),
3116            bind_flags: BindFlags::ShaderResource,
3117            cpu_access_flags: None,
3118            misc_flags: None,
3119        }
3120    }
3121}
3122impl<W, H, F, U> Texture2DDesc<W, H, F, U> {
3123    pub fn width(self, width: u32) -> Texture2DDesc<u32, H, F, U> {
3124        Texture2DDesc {
3125            width,
3126            height: self.height,
3127            mip_levels: self.mip_levels,
3128            array_size: self.array_size,
3129            format: self.format,
3130            sample_desc: self.sample_desc,
3131            usage: self.usage,
3132            bind_flags: self.bind_flags,
3133            cpu_access_flags: self.cpu_access_flags,
3134            misc_flags: self.misc_flags,
3135        }
3136    }
3137    pub fn height(self, height: u32) -> Texture2DDesc<W, u32, F, U> {
3138        Texture2DDesc {
3139            width: self.width,
3140            height,
3141            mip_levels: self.mip_levels,
3142            array_size: self.array_size,
3143            format: self.format,
3144            sample_desc: self.sample_desc,
3145            usage: self.usage,
3146            bind_flags: self.bind_flags,
3147            cpu_access_flags: self.cpu_access_flags,
3148            misc_flags: self.misc_flags,
3149        }
3150    }
3151    pub fn mip_levels(mut self, mip_levels: u32) -> Self {
3152        self.mip_levels = mip_levels;
3153        self
3154    }
3155    pub fn array_size(mut self, array_size: u32) -> Self {
3156        self.array_size = array_size;
3157        self
3158    }
3159    pub fn format(self, format: dxgi::Format) -> Texture2DDesc<W, H, dxgi::Format, U> {
3160        Texture2DDesc {
3161            width: self.width,
3162            height: self.height,
3163            mip_levels: self.mip_levels,
3164            array_size: self.array_size,
3165            format,
3166            sample_desc: self.sample_desc,
3167            usage: self.usage,
3168            bind_flags: self.bind_flags,
3169            cpu_access_flags: self.cpu_access_flags,
3170            misc_flags: self.misc_flags,
3171        }
3172    }
3173    pub fn sample_desc(mut self, sample_desc: dxgi::SampleDesc) -> Self {
3174        self.sample_desc = sample_desc;
3175        self
3176    }
3177    pub fn usage(self, usage: Usage) -> Texture2DDesc<W, H, F, Usage> {
3178        Texture2DDesc {
3179            width: self.width,
3180            height: self.height,
3181            mip_levels: self.mip_levels,
3182            array_size: self.array_size,
3183            format: self.format,
3184            sample_desc: self.sample_desc,
3185            usage,
3186            bind_flags: self.bind_flags,
3187            cpu_access_flags: self.cpu_access_flags,
3188            misc_flags: self.misc_flags,
3189        }
3190    }
3191    pub fn bind_flags(mut self, bind_flags: BindFlags) -> Self {
3192        self.bind_flags = bind_flags;
3193        self
3194    }
3195    pub fn cpu_access_flags(mut self, cpu_access_flags: CPUAccessFlags) -> Self {
3196        self.cpu_access_flags = Some(cpu_access_flags);
3197        self
3198    }
3199    pub fn misc_flags(mut self, misc_flags: ResourceMiscFlags) -> Self {
3200        self.misc_flags = Some(misc_flags);
3201        self
3202    }
3203}
3204impl Texture2DDesc<u32, u32, dxgi::Format, Usage> {
3205    fn to_c_struct(&self) -> D3D11_TEXTURE2D_DESC {
3206        D3D11_TEXTURE2D_DESC {
3207            Width: self.width,
3208            Height: self.height,
3209            MipLevels: self.mip_levels,
3210            ArraySize: self.array_size,
3211            Format: self.format as u32,
3212            SampleDesc: self.sample_desc.to_c_struct(),
3213            Usage: self.usage as u32,
3214            BindFlags: self.bind_flags.0,
3215            CPUAccessFlags: self.cpu_access_flags.map_or(0, |f| f.0),
3216            MiscFlags: self.misc_flags.map_or(0, |f| f.0),
3217        }
3218    }
3219}
3220impl From<D3D11_TEXTURE2D_DESC> for Texture2DDesc<u32, u32, dxgi::Format, Usage> {
3221    fn from(src: D3D11_TEXTURE2D_DESC) -> Texture2DDesc<u32, u32, dxgi::Format, Usage> {
3222        unsafe {
3223            Texture2DDesc {
3224                width: src.Width,
3225                height: src.Height,
3226                mip_levels: src.MipLevels,
3227                array_size: src.ArraySize,
3228                format: std::mem::transmute(src.Format),
3229                sample_desc: src.SampleDesc.into(),
3230                usage: std::mem::transmute(src.Usage),
3231                bind_flags: BindFlags(src.BindFlags),
3232                cpu_access_flags: if src.CPUAccessFlags == 0 {
3233                    None
3234                } else {
3235                    Some(CPUAccessFlags(src.CPUAccessFlags))
3236                },
3237                misc_flags: if src.MiscFlags == 0 {
3238                    None
3239                } else {
3240                    Some(ResourceMiscFlags(src.MiscFlags))
3241                },
3242            }
3243        }
3244    }
3245}
3246
3247#[derive(Clone, Debug)]
3248pub struct Texture3DDesc<W, H, D, F, U> {
3249    pub width: W,
3250    pub height: H,
3251    pub depth: D,
3252    pub mip_levels: u32,
3253    pub format: F,
3254    pub usage: U,
3255    pub bind_flags: BindFlags,
3256    pub cpu_access_flags: Option<CPUAccessFlags>,
3257    pub misc_flags: Option<ResourceMiscFlags>,
3258}
3259impl Texture3DDesc<(), (), (), (), ()> {
3260    pub fn new() -> Self {
3261        Self {
3262            width: (),
3263            height: (),
3264            depth: (),
3265            mip_levels: 0,
3266            format: (),
3267            usage: (),
3268            bind_flags: BindFlags::ShaderResource,
3269            cpu_access_flags: None,
3270            misc_flags: None,
3271        }
3272    }
3273}
3274impl<W, H, D, F, U> Texture3DDesc<W, H, D, F, U> {
3275    pub fn width(self, width: u32) -> Texture3DDesc<u32, H, D, F, U> {
3276        Texture3DDesc {
3277            width,
3278            height: self.height,
3279            depth: self.depth,
3280            mip_levels: self.mip_levels,
3281            format: self.format,
3282            usage: self.usage,
3283            bind_flags: self.bind_flags,
3284            cpu_access_flags: self.cpu_access_flags,
3285            misc_flags: self.misc_flags,
3286        }
3287    }
3288    pub fn height(self, height: u32) -> Texture3DDesc<W, u32, D, F, U> {
3289        Texture3DDesc {
3290            width: self.width,
3291            height,
3292            depth: self.depth,
3293            mip_levels: self.mip_levels,
3294            format: self.format,
3295            usage: self.usage,
3296            bind_flags: self.bind_flags,
3297            cpu_access_flags: self.cpu_access_flags,
3298            misc_flags: self.misc_flags,
3299        }
3300    }
3301    pub fn depth(self, depth: u32) -> Texture3DDesc<W, H, u32, F, U> {
3302        Texture3DDesc {
3303            width: self.width,
3304            height: self.height,
3305            depth,
3306            mip_levels: self.mip_levels,
3307            format: self.format,
3308            usage: self.usage,
3309            bind_flags: self.bind_flags,
3310            cpu_access_flags: self.cpu_access_flags,
3311            misc_flags: self.misc_flags,
3312        }
3313    }
3314    pub fn mip_levels(mut self, mip_levels: u32) -> Self {
3315        self.mip_levels = mip_levels;
3316        self
3317    }
3318    pub fn format(self, format: dxgi::Format) -> Texture3DDesc<W, H, D, dxgi::Format, U> {
3319        Texture3DDesc {
3320            width: self.width,
3321            height: self.height,
3322            depth: self.depth,
3323            mip_levels: self.mip_levels,
3324            format,
3325            usage: self.usage,
3326            bind_flags: self.bind_flags,
3327            cpu_access_flags: self.cpu_access_flags,
3328            misc_flags: self.misc_flags,
3329        }
3330    }
3331    pub fn usage(self, usage: Usage) -> Texture3DDesc<W, H, D, F, Usage> {
3332        Texture3DDesc {
3333            width: self.width,
3334            height: self.height,
3335            depth: self.depth,
3336            mip_levels: self.mip_levels,
3337            format: self.format,
3338            usage,
3339            bind_flags: self.bind_flags,
3340            cpu_access_flags: self.cpu_access_flags,
3341            misc_flags: self.misc_flags,
3342        }
3343    }
3344    pub fn bind_flags(mut self, bind_flags: BindFlags) -> Self {
3345        self.bind_flags = bind_flags;
3346        self
3347    }
3348    pub fn cpu_access_flags(mut self, cpu_access_flags: CPUAccessFlags) -> Self {
3349        self.cpu_access_flags = Some(cpu_access_flags);
3350        self
3351    }
3352    pub fn misc_flags(mut self, misc_flags: ResourceMiscFlags) -> Self {
3353        self.misc_flags = Some(misc_flags);
3354        self
3355    }
3356}
3357impl Texture3DDesc<u32, u32, u32, dxgi::Format, Usage> {
3358    fn to_c_struct(&self) -> D3D11_TEXTURE3D_DESC {
3359        D3D11_TEXTURE3D_DESC {
3360            Width: self.width,
3361            Height: self.height,
3362            Depth: self.depth,
3363            MipLevels: self.mip_levels,
3364            Format: self.format as u32,
3365            Usage: self.usage as u32,
3366            BindFlags: self.bind_flags.0,
3367            CPUAccessFlags: self.cpu_access_flags.map_or(0, |f| f.0),
3368            MiscFlags: self.misc_flags.map_or(0, |f| f.0),
3369        }
3370    }
3371}
3372impl From<D3D11_TEXTURE3D_DESC> for Texture3DDesc<u32, u32, u32, dxgi::Format, Usage> {
3373    fn from(src: D3D11_TEXTURE3D_DESC) -> Texture3DDesc<u32, u32, u32, dxgi::Format, Usage> {
3374        unsafe {
3375            Texture3DDesc {
3376                width: src.Width,
3377                height: src.Height,
3378                depth: src.Depth,
3379                mip_levels: src.MipLevels,
3380                format: std::mem::transmute(src.Format),
3381                usage: std::mem::transmute(src.Usage),
3382                bind_flags: BindFlags(src.BindFlags),
3383                cpu_access_flags: if src.CPUAccessFlags == 0 {
3384                    None
3385                } else {
3386                    Some(CPUAccessFlags(src.CPUAccessFlags))
3387                },
3388                misc_flags: if src.MiscFlags == 0 {
3389                    None
3390                } else {
3391                    Some(ResourceMiscFlags(src.MiscFlags))
3392                },
3393            }
3394        }
3395    }
3396}
3397
3398#[derive(Clone, Debug)]
3399pub enum UnorderedAccessViewDesc {
3400    Buffer {
3401        format: dxgi::Format,
3402        first_element: u32,
3403        num_elements: u32,
3404        flags: Option<BufferUAVFlags>,
3405    },
3406    Texture1D {
3407        format: dxgi::Format,
3408        mip_slice: u32,
3409    },
3410    Texture1DArray {
3411        format: dxgi::Format,
3412        mip_slice: u32,
3413        first_array_slice: u32,
3414        array_size: u32,
3415    },
3416    Texture2D {
3417        format: dxgi::Format,
3418        mip_slice: u32,
3419    },
3420    Texture2DArray {
3421        format: dxgi::Format,
3422        mip_slice: u32,
3423        first_array_slice: u32,
3424        array_size: u32,
3425    },
3426    Texture3D {
3427        format: dxgi::Format,
3428        mip_slice: u32,
3429        first_w_slice: u32,
3430        w_size: u32,
3431    },
3432}
3433impl UnorderedAccessViewDesc {
3434    fn to_c_struct(&self) -> D3D11_UNORDERED_ACCESS_VIEW_DESC {
3435        let mut desc = D3D11_UNORDERED_ACCESS_VIEW_DESC::default();
3436        match self {
3437            &UnorderedAccessViewDesc::Buffer {
3438                format,
3439                first_element,
3440                num_elements,
3441                flags,
3442            } => unsafe {
3443                desc.Format = format as u32;
3444                desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
3445                desc.u.Buffer_mut().FirstElement = first_element;
3446                desc.u.Buffer_mut().NumElements = num_elements;
3447                desc.u.Buffer_mut().Flags = flags.map_or(0, |f| f.0);
3448            },
3449            &UnorderedAccessViewDesc::Texture1D { format, mip_slice } => unsafe {
3450                desc.Format = format as u32;
3451                desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
3452                desc.u.Texture1D_mut().MipSlice = mip_slice;
3453            },
3454            &UnorderedAccessViewDesc::Texture1DArray {
3455                format,
3456                mip_slice,
3457                first_array_slice,
3458                array_size,
3459            } => unsafe {
3460                desc.Format = format as u32;
3461                desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY;
3462                desc.u.Texture1DArray_mut().MipSlice = mip_slice;
3463                desc.u.Texture1DArray_mut().FirstArraySlice = first_array_slice;
3464                desc.u.Texture1DArray_mut().ArraySize = array_size;
3465            },
3466            &UnorderedAccessViewDesc::Texture2D { format, mip_slice } => unsafe {
3467                desc.Format = format as u32;
3468                desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
3469                desc.u.Texture2D_mut().MipSlice = mip_slice;
3470            },
3471            &UnorderedAccessViewDesc::Texture2DArray {
3472                format,
3473                mip_slice,
3474                first_array_slice,
3475                array_size,
3476            } => unsafe {
3477                desc.Format = format as u32;
3478                desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
3479                desc.u.Texture2DArray_mut().MipSlice = mip_slice;
3480                desc.u.Texture2DArray_mut().FirstArraySlice = first_array_slice;
3481                desc.u.Texture2DArray_mut().ArraySize = array_size;
3482            },
3483            &UnorderedAccessViewDesc::Texture3D {
3484                format,
3485                mip_slice,
3486                first_w_slice,
3487                w_size,
3488            } => unsafe {
3489                desc.Format = format as u32;
3490                desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
3491                desc.u.Texture3D_mut().MipSlice = mip_slice;
3492                desc.u.Texture3D_mut().FirstWSlice = first_w_slice;
3493                desc.u.Texture3D_mut().WSize = w_size;
3494            },
3495        }
3496        desc
3497    }
3498}
3499impl From<D3D11_UNORDERED_ACCESS_VIEW_DESC> for UnorderedAccessViewDesc {
3500    fn from(src: D3D11_UNORDERED_ACCESS_VIEW_DESC) -> UnorderedAccessViewDesc {
3501        unsafe {
3502            match src.ViewDimension {
3503                D3D11_UAV_DIMENSION_BUFFER => UnorderedAccessViewDesc::Buffer {
3504                    format: std::mem::transmute(src.Format),
3505                    first_element: src.u.Buffer().FirstElement,
3506                    num_elements: src.u.Buffer().NumElements,
3507                    flags: if src.u.Buffer().Flags == 0 {
3508                        None
3509                    } else {
3510                        Some(BufferUAVFlags(src.u.Buffer().Flags))
3511                    },
3512                },
3513                D3D11_UAV_DIMENSION_TEXTURE1D => UnorderedAccessViewDesc::Texture1D {
3514                    format: std::mem::transmute(src.Format),
3515                    mip_slice: src.u.Texture1D().MipSlice,
3516                },
3517                D3D11_UAV_DIMENSION_TEXTURE1DARRAY => UnorderedAccessViewDesc::Texture1DArray {
3518                    format: std::mem::transmute(src.Format),
3519                    mip_slice: src.u.Texture1DArray().MipSlice,
3520                    first_array_slice: src.u.Texture1DArray().FirstArraySlice,
3521                    array_size: src.u.Texture1DArray().ArraySize,
3522                },
3523                D3D11_UAV_DIMENSION_TEXTURE2D => UnorderedAccessViewDesc::Texture2D {
3524                    format: std::mem::transmute(src.Format),
3525                    mip_slice: src.u.Texture2D().MipSlice,
3526                },
3527                D3D11_UAV_DIMENSION_TEXTURE2DARRAY => UnorderedAccessViewDesc::Texture2DArray {
3528                    format: std::mem::transmute(src.Format),
3529                    mip_slice: src.u.Texture2DArray().MipSlice,
3530                    first_array_slice: src.u.Texture2DArray().FirstArraySlice,
3531                    array_size: src.u.Texture2DArray().ArraySize,
3532                },
3533                D3D11_UAV_DIMENSION_TEXTURE3D => UnorderedAccessViewDesc::Texture3D {
3534                    format: std::mem::transmute(src.Format),
3535                    mip_slice: src.u.Texture3D().MipSlice,
3536                    first_w_slice: src.u.Texture3D().FirstWSlice,
3537                    w_size: src.u.Texture3D().WSize,
3538                },
3539                _ => unreachable!(),
3540            }
3541        }
3542    }
3543}
3544
3545/*
3546#[derive(Clone, Debug)]
3547pub enum VideoColor {
3548    YCbCr {
3549        y: f32,
3550        cb: f32,
3551        cr: f32,
3552        a: f32,
3553    },
3554    RGBA {
3555        r: f32,
3556        g: f32,
3557        b: f32,
3558        a: f32,
3559    },
3560}
3561impl VideoColor {
3562    fn to_c_struct(&self) -> D3D11_VIDEO_COLOR {
3563        let mut obj = D3D11_VIDEO_COLOR::default();
3564        match self {
3565            &VideoColor::YCbCr { y, cb, cr, a } => unsafe {
3566                obj.YCbCr_mut().Y = y;
3567                obj.YCbCr_mut().Cb = cb;
3568                obj.YCbCr_mut().Cr = cr;
3569                obj.YCbCr_mut().A = a;
3570            },
3571            &VideoColor::RGBA { r, g, b, a } => unsafe {
3572                obj.RGBA_mut().R = r;
3573                obj.RGBA_mut().G = g;
3574                obj.RGBA_mut().B = b;
3575                obj.RGBA_mut().A = a;
3576            },
3577        }
3578        obj
3579    }
3580}
3581*/
3582
3583#[derive(Clone, Debug)]
3584#[repr(C)]
3585pub struct VideoContentProtectionCaps {
3586    pub caps: u32,
3587    pub key_exchange_type_count: u32,
3588    pub block_alignment_size: u32,
3589    pub protected_memory_size: u64,
3590}
3591
3592#[derive(Clone, Debug)]
3593#[repr(C)]
3594pub struct Viewport {
3595    pub top_left_x: f32,
3596    pub top_left_y: f32,
3597    pub width: f32,
3598    pub height: f32,
3599    pub min_depth: f32,
3600    pub max_depth: f32,
3601}
3602impl Viewport {
3603    pub fn new() -> Self {
3604        Self {
3605            top_left_x: 0.0,
3606            top_left_y: 0.0,
3607            width: 0.0,
3608            height: 0.0,
3609            min_depth: 0.0,
3610            max_depth: 1.0,
3611        }
3612    }
3613    pub fn top_left_x(mut self, top_left_x: f32) -> Self {
3614        self.top_left_x = top_left_x;
3615        self
3616    }
3617    pub fn top_left_y(mut self, top_left_y: f32) -> Self {
3618        self.top_left_y = top_left_y;
3619        self
3620    }
3621    pub fn width(mut self, width: f32) -> Self {
3622        self.width = width;
3623        self
3624    }
3625    pub fn height(mut self, height: f32) -> Self {
3626        self.height = height;
3627        self
3628    }
3629    pub fn min_depth(mut self, min_depth: f32) -> Self {
3630        self.min_depth = min_depth;
3631        self
3632    }
3633    pub fn max_depth(mut self, max_depth: f32) -> Self {
3634        self.max_depth = max_depth;
3635        self
3636    }
3637}
3638impl From<D3D11_VIEWPORT> for Viewport {
3639    fn from(src: D3D11_VIEWPORT) -> Viewport {
3640        Viewport {
3641            top_left_x: src.TopLeftX,
3642            top_left_y: src.TopLeftY,
3643            width: src.Width,
3644            height: src.Height,
3645            min_depth: src.MinDepth,
3646            max_depth: src.MaxDepth,
3647        }
3648    }
3649}
3650
3651pub trait IDeviceChild: Interface {
3652    fn get_device(&self) -> Device;
3653    fn get_name(&self) -> Result<String, HResult>;
3654    fn set_name(&self, name: &str) -> Result<(), HResult>;
3655}
3656macro_rules! impl_devicechild {
3657    ($s: ident, $interface: ident) => {
3658        impl_interface!($s, $interface);
3659        impl IDeviceChild for $s {
3660            fn get_device(&self) -> Device {
3661                let mut obj = std::ptr::null_mut();
3662                unsafe {
3663                    self.0.GetDevice(&mut obj);
3664                    Device(ComPtr::from_raw(obj))
3665                }
3666            }
3667            fn get_name(&self) -> Result<String, HResult> {
3668                unsafe {
3669                    let mut sz = 0;
3670                    let res = self.0.GetPrivateData(
3671                        &WKPDID_D3DDebugObjectNameW,
3672                        &mut sz,
3673                        std::ptr::null_mut(),
3674                    );
3675                    let mut sz = hresult(sz, res)?;
3676                    let mut buf =
3677                        Vec::<u16>::with_capacity(sz as usize / std::mem::size_of::<u16>());
3678                    let res = self.0.GetPrivateData(
3679                        &WKPDID_D3DDebugObjectNameW,
3680                        &mut sz,
3681                        buf.as_mut_ptr() as *mut c_void,
3682                    );
3683                    let buf = hresult(buf, res)?;
3684                    Ok(OsString::from_wide(&buf).to_string_lossy().to_string())
3685                }
3686            }
3687            fn set_name(&self, name: &str) -> Result<(), HResult> {
3688                unsafe {
3689                    let wname = name.encode_utf16().chain(Some(0)).collect::<Vec<u16>>();
3690                    let res = self.0.SetPrivateData(
3691                        &WKPDID_D3DDebugObjectNameW,
3692                        (std::mem::size_of::<u16>() * wname.len()) as u32,
3693                        wname.as_ptr() as *const c_void,
3694                    );
3695                    hresult((), res)
3696                }
3697            }
3698        }
3699    };
3700}
3701
3702pub trait IResource: IDeviceChild {
3703    fn get_eviction_priority(&self) -> u32;
3704    fn get_type(&self) -> ResourceDimension;
3705    fn set_eviction_priority(&self, priority: u32);
3706}
3707#[derive(Clone, Debug)]
3708pub struct Resource(ComPtr<ID3D11Resource>);
3709macro_rules! impl_resource {
3710    ($s: ident, $interface: ident) => {
3711        impl_devicechild!($s, $interface);
3712        impl IResource for $s {
3713            fn get_eviction_priority(&self) -> u32 {
3714                unsafe { self.0.GetEvictionPriority() }
3715            }
3716            fn get_type(&self) -> ResourceDimension {
3717                let mut value = 0;
3718                unsafe {
3719                    self.0.GetType(&mut value);
3720                    std::mem::transmute(value)
3721                }
3722            }
3723            fn set_eviction_priority(&self, priority: u32) {
3724                unsafe { self.0.SetEvictionPriority(priority) }
3725            }
3726        }
3727    };
3728}
3729impl_resource!(Resource, ID3D11Resource);
3730
3731pub trait IView: IDeviceChild {
3732    fn get_resource(&self) -> Resource;
3733}
3734#[derive(Clone, Debug)]
3735pub struct View(ComPtr<ID3D11View>);
3736macro_rules! impl_view {
3737    ($s: ident, $interface: ident) => {
3738        impl_devicechild!($s, $interface);
3739        impl IView for $s {
3740            fn get_resource(&self) -> Resource {
3741                unsafe {
3742                    let mut r = std::ptr::null_mut();
3743                    self.0.GetResource(&mut r);
3744                    Resource(ComPtr::from_raw(r))
3745                }
3746            }
3747        }
3748    };
3749}
3750impl_view!(View, ID3D11View);
3751
3752pub trait IAsynchronous: IDeviceChild {
3753    fn get_data_size(&self) -> u32;
3754}
3755#[derive(Clone, Debug)]
3756pub struct Asynchronous(ComPtr<ID3D11Asynchronous>);
3757macro_rules! impl_asynchronous {
3758    ($s: ident, $interface: ident) => {
3759        impl_devicechild!($s, $interface);
3760        impl IAsynchronous for $s {
3761            fn get_data_size(&self) -> u32 {
3762                unsafe { self.0.GetDataSize() }
3763            }
3764        }
3765    };
3766}
3767impl_asynchronous!(Asynchronous, ID3D11Asynchronous);
3768
3769pub trait IAuthenticatedChannel: IDeviceChild {
3770    fn get_certificate(&self) -> Result<Vec<u8>, HResult>;
3771    fn get_channel_handle(&self) -> Handle;
3772}
3773#[derive(Clone, Debug)]
3774pub struct AuthenticatedChannel(ComPtr<ID3D11AuthenticatedChannel>);
3775impl_devicechild!(AuthenticatedChannel, ID3D11AuthenticatedChannel);
3776impl IAuthenticatedChannel for AuthenticatedChannel {
3777    fn get_certificate(&self) -> Result<Vec<u8>, HResult> {
3778        unsafe {
3779            let mut sz = 0;
3780            let res = self.0.GetCertificateSize(&mut sz);
3781            let sz = hresult(sz, res)?;
3782            let mut data = Vec::with_capacity(sz as usize);
3783            data.set_len(sz as usize);
3784            let res = self.0.GetCertificate(sz, data.as_mut_ptr());
3785            hresult(data, res)
3786        }
3787    }
3788    fn get_channel_handle(&self) -> Handle {
3789        unsafe {
3790            let mut handle = std::ptr::null_mut();
3791            self.0.GetChannelHandle(&mut handle);
3792            Handle::new(handle)
3793        }
3794    }
3795}
3796
3797pub trait IBlendState: IDeviceChild {
3798    fn get_desc(&self) -> BlendDesc;
3799}
3800#[derive(Clone, Debug)]
3801pub struct BlendState(ComPtr<ID3D11BlendState>);
3802macro_rules! impl_blendstate {
3803    ($s: ident, $interface: ident) => {
3804        impl_devicechild!($s, $interface);
3805        impl IBlendState for $s {
3806            fn get_desc(&self) -> BlendDesc {
3807                unsafe {
3808                    let mut desc = Default::default();
3809                    self.0.GetDesc(&mut desc);
3810                    desc.into()
3811                }
3812            }
3813        }
3814    };
3815}
3816impl_blendstate!(BlendState, ID3D11BlendState);
3817
3818pub trait IBuffer: IResource {
3819    fn get_desc(&self) -> BufferDesc<u32, Usage, BindFlags>;
3820}
3821#[derive(Clone, Debug)]
3822pub struct Buffer(ComPtr<ID3D11Buffer>);
3823macro_rules! impl_buffer {
3824    ($s: ident, $interface: ident) => {
3825        impl_resource!($s, $interface);
3826        impl IBuffer for $s {
3827            fn get_desc(&self) -> BufferDesc<u32, Usage, BindFlags> {
3828                unsafe {
3829                    let mut desc = Default::default();
3830                    self.0.GetDesc(&mut desc);
3831                    desc.into()
3832                }
3833            }
3834        }
3835    };
3836}
3837impl_buffer!(Buffer, ID3D11Buffer);
3838
3839pub trait IClassInstance: IDeviceChild {
3840    fn get_class_linkage(&self) -> ClassLinkage;
3841    fn get_desc(&self) -> ClassInstanceDesc;
3842    fn get_instance_name(&self) -> String;
3843    fn get_type_name(&self) -> String;
3844}
3845#[derive(Clone, Debug)]
3846pub struct ClassInstance(ComPtr<ID3D11ClassInstance>);
3847macro_rules! impl_classinstance {
3848    ($s: ident, $interface: ident) => {
3849        impl_devicechild!($s, $interface);
3850        impl IClassInstance for $s {
3851            fn get_class_linkage(&self) -> ClassLinkage {
3852                unsafe {
3853                    let mut linkage = std::ptr::null_mut();
3854                    self.0.GetClassLinkage(&mut linkage);
3855                    ClassLinkage(ComPtr::from_raw(linkage))
3856                }
3857            }
3858            fn get_desc(&self) -> ClassInstanceDesc {
3859                unsafe {
3860                    let mut desc = Default::default();
3861                    self.0.GetDesc(&mut desc);
3862                    desc.into()
3863                }
3864            }
3865            fn get_instance_name(&self) -> String {
3866                unsafe {
3867                    let mut buf = Vec::with_capacity(1024);
3868                    buf.set_len(1024);
3869                    let mut len = 0;
3870                    self.0.GetInstanceName(buf.as_mut_ptr(), &mut len);
3871                    String::from_raw_parts(buf.as_mut_ptr() as *mut u8, len, len)
3872                }
3873            }
3874            fn get_type_name(&self) -> String {
3875                unsafe {
3876                    let mut buf = Vec::with_capacity(1024);
3877                    buf.set_len(1024);
3878                    let mut len = 0;
3879                    self.0.GetTypeName(buf.as_mut_ptr(), &mut len);
3880                    String::from_raw_parts(buf.as_mut_ptr() as *mut u8, len, len)
3881                }
3882            }
3883        }
3884    };
3885}
3886impl_classinstance!(ClassInstance, ID3D11ClassInstance);
3887
3888pub trait IClassLinkage: IDeviceChild {
3889    fn create_class_instance(
3890        &self,
3891        class_type_name: &str,
3892        constant_buffer_offset: u32,
3893        constant_vector_offset: u32,
3894        texture_offset: u32,
3895        sampler_offset: u32,
3896    ) -> Result<ClassInstance, HResult>;
3897    fn get_class_instance(
3898        &self,
3899        class_name_instance: &str,
3900        instance_index: u32,
3901    ) -> Result<ClassInstance, HResult>;
3902}
3903#[derive(Clone, Debug)]
3904pub struct ClassLinkage(ComPtr<ID3D11ClassLinkage>);
3905macro_rules! impl_classlinkage {
3906    ($s: ident, $interface: ident) => {
3907        impl_devicechild!($s, $interface);
3908        impl IClassLinkage for $s {
3909            fn create_class_instance(
3910                &self,
3911                class_type_name: &str,
3912                constant_buffer_offset: u32,
3913                constant_vector_offset: u32,
3914                texture_offset: u32,
3915                sampler_offset: u32,
3916            ) -> Result<ClassInstance, HResult> {
3917                Ok(ClassInstance(ComPtr::new(|| {
3918                    let mut obj = std::ptr::null_mut();
3919                    let name = std::ffi::CString::new(class_type_name).unwrap();
3920                    let res = unsafe {
3921                        self.0.CreateClassInstance(
3922                            name.as_ptr(),
3923                            constant_buffer_offset,
3924                            constant_vector_offset,
3925                            texture_offset,
3926                            sampler_offset,
3927                            &mut obj,
3928                        )
3929                    };
3930                    hresult(obj, res)
3931                })?))
3932            }
3933            fn get_class_instance(
3934                &self,
3935                class_name_instance: &str,
3936                instance_index: u32,
3937            ) -> Result<ClassInstance, HResult> {
3938                Ok(ClassInstance(ComPtr::new(|| {
3939                    let mut obj = std::ptr::null_mut();
3940                    let name = std::ffi::CString::new(class_name_instance).unwrap();
3941                    let res = unsafe {
3942                        self.0
3943                            .GetClassInstance(name.as_ptr(), instance_index, &mut obj)
3944                    };
3945                    hresult(obj, res)
3946                })?))
3947            }
3948        }
3949    };
3950}
3951impl_classlinkage!(ClassLinkage, ID3D11ClassLinkage);
3952
3953pub trait ICommandList: IDeviceChild {
3954    fn get_context_flags(&self) -> u32;
3955}
3956#[derive(Clone, Debug)]
3957pub struct CommandList(ComPtr<ID3D11CommandList>);
3958macro_rules! impl_commandlist {
3959    ($s: ident, $interface: ident) => {
3960        impl_devicechild!($s, $interface);
3961        impl ICommandList for $s {
3962            fn get_context_flags(&self) -> u32 {
3963                unsafe { self.0.GetContextFlags() }
3964            }
3965        }
3966    };
3967}
3968impl_commandlist!(CommandList, ID3D11CommandList);
3969
3970pub trait IComputeShader: IDeviceChild {}
3971#[derive(Clone, Debug)]
3972pub struct ComputeShader(ComPtr<ID3D11ComputeShader>);
3973macro_rules! impl_computeshader {
3974    ($s: ident, $interface: ident) => {
3975        impl_devicechild!($s, $interface);
3976        impl IComputeShader for $s {}
3977    };
3978}
3979impl_computeshader!(ComputeShader, ID3D11ComputeShader);
3980
3981pub trait ICounter: IAsynchronous {
3982    fn get_desc(&self) -> CounterDesc;
3983}
3984#[derive(Clone, Debug)]
3985pub struct Counter(ComPtr<ID3D11Counter>);
3986macro_rules! impl_counter {
3987    ($s: ident, $interface: ident) => {
3988        impl_asynchronous!($s, $interface);
3989        impl ICounter for $s {
3990            fn get_desc(&self) -> CounterDesc {
3991                unsafe {
3992                    let mut desc = Default::default();
3993                    self.0.GetDesc(&mut desc);
3994                    desc.into()
3995                }
3996            }
3997        }
3998    };
3999}
4000impl_counter!(Counter, ID3D11Counter);
4001
4002pub trait ICryptoSession: IDeviceChild {
4003    fn get_certificate(&self) -> Result<Vec<u8>, HResult>;
4004    fn get_crypto_session_handle(&self) -> Handle;
4005    fn get_crypto_type(&self) -> Guid;
4006    fn get_decoder_profile(&self) -> Guid;
4007}
4008pub struct CryptoSession(ComPtr<ID3D11CryptoSession>);
4009macro_rules! impl_cryptosession {
4010    ($s: ident, $interface: ident) => {
4011        impl_devicechild!($s, $interface);
4012        impl ICryptoSession for $s {
4013            fn get_certificate(&self) -> Result<Vec<u8>, HResult> {
4014                unsafe {
4015                    let mut sz = 0;
4016                    let res = self.0.GetCertificateSize(&mut sz);
4017                    let sz = hresult(sz, res)?;
4018                    let mut data = Vec::with_capacity(sz as usize);
4019                    data.set_len(sz as usize);
4020                    let res = self.0.GetCertificate(sz, data.as_mut_ptr());
4021                    hresult(data, res)
4022                }
4023            }
4024            fn get_crypto_session_handle(&self) -> Handle {
4025                let mut handle = std::ptr::null_mut();
4026                unsafe { self.0.GetCryptoSessionHandle(&mut handle) };
4027                Handle::new(handle)
4028            }
4029            fn get_crypto_type(&self) -> Guid {
4030                let mut guid = Default::default();
4031                unsafe { self.0.GetCryptoType(&mut guid) };
4032                guid.into()
4033            }
4034            fn get_decoder_profile(&self) -> Guid {
4035                let mut guid = Default::default();
4036                unsafe { self.0.GetDecoderProfile(&mut guid) };
4037                guid.into()
4038            }
4039        }
4040    };
4041}
4042impl_cryptosession!(CryptoSession, ID3D11CryptoSession);
4043
4044pub trait IDepthStencilState: IDeviceChild {
4045    fn get_desc(&self) -> DepthStencilDesc;
4046}
4047#[derive(Clone, Debug)]
4048pub struct DepthStencilState(ComPtr<ID3D11DepthStencilState>);
4049macro_rules! impl_depthstencilstate {
4050    ($s: ident, $interface: ident) => {
4051        impl_devicechild!($s, $interface);
4052        impl IDepthStencilState for $s {
4053            fn get_desc(&self) -> DepthStencilDesc {
4054                let mut desc = Default::default();
4055                unsafe { self.0.GetDesc(&mut desc) };
4056                desc.into()
4057            }
4058        }
4059    };
4060}
4061impl_depthstencilstate!(DepthStencilState, ID3D11DepthStencilState);
4062
4063pub trait IDepthStencilView: IView {
4064    fn get_desc(&self) -> DepthStencilViewDesc;
4065}
4066#[derive(Clone, Debug)]
4067pub struct DepthStencilView(ComPtr<ID3D11DepthStencilView>);
4068macro_rules! impl_depthstencilview {
4069    ($s: ident, $interface: ident) => {
4070        impl_view!($s, $interface);
4071        impl IDepthStencilView for $s {
4072            fn get_desc(&self) -> DepthStencilViewDesc {
4073                let mut desc = Default::default();
4074                unsafe { self.0.GetDesc(&mut desc) };
4075                desc.into()
4076            }
4077        }
4078    };
4079}
4080impl_depthstencilview!(DepthStencilView, ID3D11DepthStencilView);
4081
4082#[derive(Clone, Debug)]
4083pub struct CheckCounterResult {
4084    pub ty: CounterType,
4085    pub active_counters: u32,
4086    pub name: Option<String>,
4087    pub units: Option<String>,
4088    pub description: Option<String>,
4089}
4090
4091pub trait IDevice: Interface {
4092    fn check_counter(&self, desc: &CounterDesc) -> Result<CheckCounterResult, HResult>;
4093    fn check_counter_info(&self) -> CounterInfo;
4094    fn check_feature_support<T: CheckFeatureSupport>(&self, args: T::Args) -> Result<T, HResult>;
4095    fn check_format_support(&self, format: dxgi::Format) -> Result<FormatSupport, HResult>;
4096    fn check_multisample_quality_levels(
4097        &self,
4098        format: dxgi::Format,
4099        sample_count: u32,
4100    ) -> Result<u32, HResult>;
4101    fn create_blend_state(&self, desc: &BlendDesc) -> Result<BlendState, HResult>;
4102    fn create_buffer(
4103        &self,
4104        desc: &BufferDesc<u32, Usage, BindFlags>,
4105        initial_data: Option<&SubresourceData<*const c_void, (), ()>>,
4106    ) -> Result<Buffer, HResult>;
4107    fn create_class_linkage(&self) -> Result<ClassLinkage, HResult>;
4108    fn create_compute_shader(
4109        &self,
4110        bytecode: &[u8],
4111        class_linkage: Option<&ClassLinkage>,
4112    ) -> Result<ComputeShader, HResult>;
4113    fn create_counter(&self, desc: &CounterDesc) -> Result<Counter, HResult>;
4114    fn create_deferred_context(&self) -> Result<DeviceContext, HResult>;
4115    fn create_depth_stencil_state(
4116        &self,
4117        desc: &DepthStencilDesc,
4118    ) -> Result<DepthStencilState, HResult>;
4119    fn create_depth_stencil_view(
4120        &self,
4121        resource: &impl IResource,
4122        desc: Option<&DepthStencilViewDesc>,
4123    ) -> Result<DepthStencilView, HResult>;
4124    fn create_domain_shader(
4125        &self,
4126        bytecode: &[u8],
4127        class_linkage: Option<&ClassLinkage>,
4128    ) -> Result<DomainShader, HResult>;
4129    fn create_geometry_shader(
4130        &self,
4131        bytecode: &[u8],
4132        class_linkage: Option<&ClassLinkage>,
4133    ) -> Result<GeometryShader, HResult>;
4134    fn create_geometry_shader_with_stream_output(
4135        &self,
4136        bytecode: &[u8],
4137        so_declaration: Option<&[&SODeclarationEntry]>,
4138        buffer_stride: &[u32],
4139        rasterized_stream: u32,
4140        class_linkage: Option<&ClassLinkage>,
4141    ) -> Result<GeometryShader, HResult>;
4142    fn create_hull_shader(
4143        &self,
4144        bytecode: &[u8],
4145        class_linkage: Option<&ClassLinkage>,
4146    ) -> Result<HullShader, HResult>;
4147    fn create_input_layout<'a>(
4148        &self,
4149        descs: &[InputElementDesc<'a>],
4150        bytecode: &[u8],
4151    ) -> Result<InputLayout, HResult>;
4152    fn create_pixel_shader(
4153        &self,
4154        bytecode: &[u8],
4155        class_linkage: Option<&ClassLinkage>,
4156    ) -> Result<PixelShader, HResult>;
4157    fn create_predicate(&self, desc: &QueryDesc) -> Result<Predicate, HResult>;
4158    fn create_query(&self, desc: &QueryDesc) -> Result<Query, HResult>;
4159    fn create_rasterizer_state(&self, desc: &RasterizerDesc) -> Result<RasterizerState, HResult>;
4160    fn create_render_target_view(
4161        &self,
4162        resource: &impl IResource,
4163        desc: Option<&RenderTargetViewDesc>,
4164    ) -> Result<RenderTargetView, HResult>;
4165    fn create_sampler_state(&self, desc: &SamplerDesc<Filter>) -> Result<SamplerState, HResult>;
4166    fn create_shader_resource_view(
4167        &self,
4168        resource: &impl IResource,
4169        desc: Option<&ShaderResourceViewDesc>,
4170    ) -> Result<ShaderResourceView, HResult>;
4171    fn create_texture1d(
4172        &self,
4173        desc: &Texture1DDesc<u32, dxgi::Format, Usage>,
4174        initial_data: Option<&SubresourceData<*const c_void, (), ()>>,
4175    ) -> Result<Texture1D, HResult>;
4176    fn create_texture2d(
4177        &self,
4178        desc: &Texture2DDesc<u32, u32, dxgi::Format, Usage>,
4179        initial_data: Option<&SubresourceData<*const c_void, u32, ()>>,
4180    ) -> Result<Texture2D, HResult>;
4181    fn create_texture3d(
4182        &self,
4183        desc: &Texture3DDesc<u32, u32, u32, dxgi::Format, Usage>,
4184        initial_data: Option<&SubresourceData<*const c_void, u32, u32>>,
4185    ) -> Result<Texture3D, HResult>;
4186    fn create_unordered_access_view(
4187        &self,
4188        resource: &impl IResource,
4189        desc: Option<&UnorderedAccessViewDesc>,
4190    ) -> Result<UnorderedAccessView, HResult>;
4191    fn create_vertex_shader(
4192        &self,
4193        bytecode: &[u8],
4194        class_linkage: Option<&ClassLinkage>,
4195    ) -> Result<VertexShader, HResult>;
4196    fn get_creation_flags(&self) -> Option<CreateDeviceFlags>;
4197    fn get_device_removed_reason(&self) -> HResult;
4198    fn get_exception_mode(&self) -> Option<RaiseFlags>;
4199    fn get_feature_level(&self) -> d3d::FeatureLevel;
4200    fn get_immediate_context(&self) -> DeviceContext;
4201    fn open_shared_resource<T: Interface>(&self, resource: &Handle) -> Result<T, HResult>;
4202    fn set_exception_mode(&self, flags: Option<RaiseFlags>) -> Result<(), HResult>;
4203    fn get_name(&self) -> Result<String, HResult>;
4204    fn set_name(&self, name: &str) -> Result<(), HResult>;
4205}
4206#[derive(Clone, Debug)]
4207pub struct Device(ComPtr<ID3D11Device>);
4208macro_rules! impl_device {
4209    ($s: ident, $interface: ident) => {
4210        impl_interface!($s, $interface);
4211        impl IDevice for $s {
4212            fn check_counter(&self, desc: &CounterDesc) -> Result<CheckCounterResult, HResult> {
4213                let c_desc = desc.to_c_struct();
4214                let mut ty = 0;
4215                let mut active_counters = 0;
4216                let mut name_len = 0;
4217                let mut units_len = 0;
4218                let mut description_len = 0;
4219                let res = unsafe {
4220                    self.0.CheckCounter(
4221                        &c_desc,
4222                        &mut ty,
4223                        &mut active_counters,
4224                        std::ptr::null_mut(),
4225                        &mut name_len,
4226                        std::ptr::null_mut(),
4227                        &mut units_len,
4228                        std::ptr::null_mut(),
4229                        &mut description_len,
4230                    )
4231                };
4232                hresult((), res)?;
4233                unsafe {
4234                    let mut name = Vec::<u8>::with_capacity(name_len as usize);
4235                    name.set_len(name_len as usize);
4236                    let mut units = Vec::<u8>::with_capacity(units_len as usize);
4237                    units.set_len(units_len as usize);
4238                    let mut description = Vec::<u8>::with_capacity(description_len as usize);
4239                    description.set_len(description_len as usize);
4240                    let res = self.0.CheckCounter(
4241                        &c_desc,
4242                        &mut ty,
4243                        &mut active_counters,
4244                        name.as_mut_ptr() as *mut i8,
4245                        &mut name_len,
4246                        units.as_mut_ptr() as *mut i8,
4247                        &mut units_len,
4248                        description.as_mut_ptr() as *mut i8,
4249                        &mut description_len,
4250                    );
4251                    let obj = CheckCounterResult {
4252                        ty: std::mem::transmute(ty),
4253                        active_counters,
4254                        name: String::from_utf8(name).ok(),
4255                        units: String::from_utf8(units).ok(),
4256                        description: String::from_utf8(description).ok(),
4257                    };
4258                    hresult(obj, res)
4259                }
4260            }
4261            fn check_counter_info(&self) -> CounterInfo {
4262                let mut obj = Default::default();
4263                unsafe { self.0.CheckCounterInfo(&mut obj) };
4264                obj.into()
4265            }
4266            fn check_feature_support<T: CheckFeatureSupport>(
4267                &self,
4268                args: T::Args,
4269            ) -> Result<T, HResult> {
4270                T::check_feature_support(self.0.as_ptr() as *mut ID3D11Device, args)
4271            }
4272            fn check_format_support(&self, format: dxgi::Format) -> Result<FormatSupport, HResult> {
4273                let mut val = 0;
4274                let res = unsafe { self.0.CheckFormatSupport(format as u32, &mut val) };
4275                hresult(FormatSupport(val), res)
4276            }
4277            fn check_multisample_quality_levels(
4278                &self,
4279                format: dxgi::Format,
4280                sample_count: u32,
4281            ) -> Result<u32, HResult> {
4282                let mut levels = 0;
4283                let res = unsafe {
4284                    self.0
4285                        .CheckMultisampleQualityLevels(format as u32, sample_count, &mut levels)
4286                };
4287                hresult(levels, res)
4288            }
4289            fn create_blend_state(&self, desc: &BlendDesc) -> Result<BlendState, HResult> {
4290                Ok(BlendState(ComPtr::new(|| {
4291                    let mut obj = std::ptr::null_mut();
4292                    let res = unsafe { self.0.CreateBlendState(&desc.to_c_struct(), &mut obj) };
4293                    hresult(obj, res)
4294                })?))
4295            }
4296            fn create_buffer(
4297                &self,
4298                desc: &BufferDesc<u32, Usage, BindFlags>,
4299                initial_data: Option<&SubresourceData<*const c_void, (), ()>>,
4300            ) -> Result<Buffer, HResult> {
4301                Ok(Buffer(ComPtr::new(|| {
4302                    let mut obj = std::ptr::null_mut();
4303                    let c_initial_data = initial_data.as_ref().map(|d| d.to_c_struct());
4304                    let res = unsafe {
4305                        self.0.CreateBuffer(
4306                            &desc.to_c_struct(),
4307                            c_initial_data.as_ref().map_or(std::ptr::null(), |d| d),
4308                            &mut obj,
4309                        )
4310                    };
4311                    hresult(obj, res)
4312                })?))
4313            }
4314            fn create_class_linkage(&self) -> Result<ClassLinkage, HResult> {
4315                Ok(ClassLinkage(ComPtr::new(|| {
4316                    let mut obj = std::ptr::null_mut();
4317                    let res = unsafe { self.0.CreateClassLinkage(&mut obj) };
4318                    hresult(obj, res)
4319                })?))
4320            }
4321            fn create_compute_shader(
4322                &self,
4323                bytecode: &[u8],
4324                class_linkage: Option<&ClassLinkage>,
4325            ) -> Result<ComputeShader, HResult> {
4326                Ok(ComputeShader(ComPtr::new(|| {
4327                    let mut obj = std::ptr::null_mut();
4328                    let res = unsafe {
4329                        self.0.CreateComputeShader(
4330                            bytecode.as_ptr() as *const c_void,
4331                            bytecode.len(),
4332                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4333                            &mut obj,
4334                        )
4335                    };
4336                    hresult(obj, res)
4337                })?))
4338            }
4339            fn create_counter(&self, desc: &CounterDesc) -> Result<Counter, HResult> {
4340                Ok(Counter(ComPtr::new(|| {
4341                    let mut obj = std::ptr::null_mut();
4342                    let res = unsafe { self.0.CreateCounter(&desc.to_c_struct(), &mut obj) };
4343                    hresult(obj, res)
4344                })?))
4345            }
4346            fn create_deferred_context(&self) -> Result<DeviceContext, HResult> {
4347                Ok(DeviceContext(ComPtr::new(|| {
4348                    let mut obj = std::ptr::null_mut();
4349                    let res = unsafe { self.0.CreateDeferredContext(0, &mut obj) };
4350                    hresult(obj, res)
4351                })?))
4352            }
4353            fn create_depth_stencil_state(
4354                &self,
4355                desc: &DepthStencilDesc,
4356            ) -> Result<DepthStencilState, HResult> {
4357                Ok(DepthStencilState(ComPtr::new(|| {
4358                    let mut obj = std::ptr::null_mut();
4359                    let res = unsafe {
4360                        self.0
4361                            .CreateDepthStencilState(&desc.to_c_struct(), &mut obj)
4362                    };
4363                    hresult(obj, res)
4364                })?))
4365            }
4366            fn create_depth_stencil_view(
4367                &self,
4368                resource: &impl IResource,
4369                desc: Option<&DepthStencilViewDesc>,
4370            ) -> Result<DepthStencilView, HResult> {
4371                Ok(DepthStencilView(ComPtr::new(|| {
4372                    let mut obj = std::ptr::null_mut();
4373                    let c_desc = desc.map(|d| d.to_c_struct());
4374                    let res = unsafe {
4375                        self.0.CreateDepthStencilView(
4376                            resource.as_ptr() as *mut _,
4377                            c_desc.as_ref().map_or(std::ptr::null(), |d| d),
4378                            &mut obj,
4379                        )
4380                    };
4381                    hresult(obj, res)
4382                })?))
4383            }
4384            fn create_domain_shader(
4385                &self,
4386                bytecode: &[u8],
4387                class_linkage: Option<&ClassLinkage>,
4388            ) -> Result<DomainShader, HResult> {
4389                Ok(DomainShader(ComPtr::new(|| {
4390                    let mut obj = std::ptr::null_mut();
4391                    let res = unsafe {
4392                        self.0.CreateDomainShader(
4393                            bytecode.as_ptr() as *const c_void,
4394                            bytecode.len(),
4395                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4396                            &mut obj,
4397                        )
4398                    };
4399                    hresult(obj, res)
4400                })?))
4401            }
4402            fn create_geometry_shader(
4403                &self,
4404                bytecode: &[u8],
4405                class_linkage: Option<&ClassLinkage>,
4406            ) -> Result<GeometryShader, HResult> {
4407                Ok(GeometryShader(ComPtr::new(|| {
4408                    let mut obj = std::ptr::null_mut();
4409                    let res = unsafe {
4410                        self.0.CreateGeometryShader(
4411                            bytecode.as_ptr() as *const c_void,
4412                            bytecode.len(),
4413                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4414                            &mut obj,
4415                        )
4416                    };
4417                    hresult(obj, res)
4418                })?))
4419            }
4420            fn create_geometry_shader_with_stream_output(
4421                &self,
4422                bytecode: &[u8],
4423                so_declaration: Option<&[&SODeclarationEntry]>,
4424                buffer_stride: &[u32],
4425                rasterized_stream: u32,
4426                class_linkage: Option<&ClassLinkage>,
4427            ) -> Result<GeometryShader, HResult> {
4428                Ok(GeometryShader(ComPtr::new(|| {
4429                    let mut obj = std::ptr::null_mut();
4430                    let (c_so, _tmp): (Vec<_>, Vec<_>) = so_declaration
4431                        .map_or((Vec::new(), Vec::new()), |d| {
4432                            d.iter().map(|entry| entry.to_c_struct()).unzip()
4433                        });
4434                    let res = unsafe {
4435                        self.0.CreateGeometryShaderWithStreamOutput(
4436                            bytecode.as_ptr() as *const c_void,
4437                            bytecode.len(),
4438                            if c_so.is_empty() {
4439                                std::ptr::null()
4440                            } else {
4441                                c_so.as_ptr()
4442                            },
4443                            c_so.len() as u32,
4444                            buffer_stride.as_ptr(),
4445                            buffer_stride.len() as u32,
4446                            rasterized_stream,
4447                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4448                            &mut obj,
4449                        )
4450                    };
4451                    hresult(obj, res)
4452                })?))
4453            }
4454            fn create_hull_shader(
4455                &self,
4456                bytecode: &[u8],
4457                class_linkage: Option<&ClassLinkage>,
4458            ) -> Result<HullShader, HResult> {
4459                Ok(HullShader(ComPtr::new(|| {
4460                    let mut obj = std::ptr::null_mut();
4461                    let res = unsafe {
4462                        self.0.CreateHullShader(
4463                            bytecode.as_ptr() as *const c_void,
4464                            bytecode.len(),
4465                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4466                            &mut obj,
4467                        )
4468                    };
4469                    hresult(obj, res)
4470                })?))
4471            }
4472            fn create_input_layout<'a>(
4473                &self,
4474                descs: &[InputElementDesc<'a>],
4475                bytecode: &[u8],
4476            ) -> Result<InputLayout, HResult> {
4477                Ok(InputLayout(ComPtr::new(|| {
4478                    let (c_descs, _tmp): (Vec<_>, Vec<_>) =
4479                        descs.iter().map(|d| d.to_c_struct()).unzip();
4480                    let mut obj = std::ptr::null_mut();
4481                    let res = unsafe {
4482                        self.0.CreateInputLayout(
4483                            c_descs.as_ptr(),
4484                            c_descs.len() as u32,
4485                            bytecode.as_ptr() as *const c_void,
4486                            bytecode.len(),
4487                            &mut obj,
4488                        )
4489                    };
4490                    hresult(obj, res)
4491                })?))
4492            }
4493            fn create_pixel_shader(
4494                &self,
4495                bytecode: &[u8],
4496                class_linkage: Option<&ClassLinkage>,
4497            ) -> Result<PixelShader, HResult> {
4498                Ok(PixelShader(ComPtr::new(|| {
4499                    let mut obj = std::ptr::null_mut();
4500                    let res = unsafe {
4501                        self.0.CreatePixelShader(
4502                            bytecode.as_ptr() as *const c_void,
4503                            bytecode.len(),
4504                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4505                            &mut obj,
4506                        )
4507                    };
4508                    hresult(obj, res)
4509                })?))
4510            }
4511            fn create_predicate(&self, desc: &QueryDesc) -> Result<Predicate, HResult> {
4512                Ok(Predicate(ComPtr::new(|| {
4513                    let mut obj = std::ptr::null_mut();
4514                    let res = unsafe { self.0.CreatePredicate(&desc.to_c_struct(), &mut obj) };
4515                    hresult(obj, res)
4516                })?))
4517            }
4518            fn create_query(&self, desc: &QueryDesc) -> Result<Query, HResult> {
4519                Ok(Query(ComPtr::new(|| {
4520                    let mut obj = std::ptr::null_mut();
4521                    let res = unsafe { self.0.CreateQuery(&desc.to_c_struct(), &mut obj) };
4522                    hresult(obj, res)
4523                })?))
4524            }
4525            fn create_rasterizer_state(
4526                &self,
4527                desc: &RasterizerDesc,
4528            ) -> Result<RasterizerState, HResult> {
4529                Ok(RasterizerState(ComPtr::new(|| {
4530                    let mut obj = std::ptr::null_mut();
4531                    let res =
4532                        unsafe { self.0.CreateRasterizerState(&desc.to_c_struct(), &mut obj) };
4533                    hresult(obj, res)
4534                })?))
4535            }
4536            fn create_render_target_view(
4537                &self,
4538                resource: &impl IResource,
4539                desc: Option<&RenderTargetViewDesc>,
4540            ) -> Result<RenderTargetView, HResult> {
4541                Ok(RenderTargetView(ComPtr::new(|| {
4542                    let mut obj = std::ptr::null_mut();
4543                    let c_desc = desc.map(|d| d.to_c_struct());
4544                    let res = unsafe {
4545                        self.0.CreateRenderTargetView(
4546                            resource.as_ptr() as *mut _,
4547                            c_desc.as_ref().map_or(std::ptr::null(), |d| d),
4548                            &mut obj,
4549                        )
4550                    };
4551                    hresult(obj, res)
4552                })?))
4553            }
4554            fn create_sampler_state(
4555                &self,
4556                desc: &SamplerDesc<Filter>,
4557            ) -> Result<SamplerState, HResult> {
4558                Ok(SamplerState(ComPtr::new(|| {
4559                    let mut obj = std::ptr::null_mut();
4560                    let res = unsafe { self.0.CreateSamplerState(&desc.to_c_struct(), &mut obj) };
4561                    hresult(obj, res)
4562                })?))
4563            }
4564            fn create_shader_resource_view(
4565                &self,
4566                resource: &impl IResource,
4567                desc: Option<&ShaderResourceViewDesc>,
4568            ) -> Result<ShaderResourceView, HResult> {
4569                Ok(ShaderResourceView(ComPtr::new(|| {
4570                    let mut obj = std::ptr::null_mut();
4571                    let c_desc = desc.map(|d| d.to_c_struct());
4572                    let res = unsafe {
4573                        self.0.CreateShaderResourceView(
4574                            resource.as_ptr() as *mut _,
4575                            c_desc.as_ref().map_or(std::ptr::null(), |d| d),
4576                            &mut obj,
4577                        )
4578                    };
4579                    hresult(obj, res)
4580                })?))
4581            }
4582            fn create_texture1d(
4583                &self,
4584                desc: &Texture1DDesc<u32, dxgi::Format, Usage>,
4585                initial_data: Option<&SubresourceData<*const c_void, (), ()>>,
4586            ) -> Result<Texture1D, HResult> {
4587                let c_data = initial_data
4588                    .as_ref()
4589                    .map_or(None, |d| Some(d.to_c_struct()));
4590                Ok(Texture1D(ComPtr::new(|| {
4591                    let mut obj = std::ptr::null_mut();
4592                    let res = unsafe {
4593                        self.0.CreateTexture1D(
4594                            &desc.to_c_struct(),
4595                            c_data.as_ref().map_or(std::ptr::null(), |d| d),
4596                            &mut obj,
4597                        )
4598                    };
4599                    hresult(obj, res)
4600                })?))
4601            }
4602            fn create_texture2d(
4603                &self,
4604                desc: &Texture2DDesc<u32, u32, dxgi::Format, Usage>,
4605                initial_data: Option<&SubresourceData<*const c_void, u32, ()>>,
4606            ) -> Result<Texture2D, HResult> {
4607                let c_data = initial_data
4608                    .as_ref()
4609                    .map_or(None, |d| Some(d.to_c_struct()));
4610                Ok(Texture2D(ComPtr::new(|| {
4611                    let mut obj = std::ptr::null_mut();
4612                    let res = unsafe {
4613                        self.0.CreateTexture2D(
4614                            &desc.to_c_struct(),
4615                            c_data.as_ref().map_or(std::ptr::null(), |d| d),
4616                            &mut obj,
4617                        )
4618                    };
4619                    hresult(obj, res)
4620                })?))
4621            }
4622            fn create_texture3d(
4623                &self,
4624                desc: &Texture3DDesc<u32, u32, u32, dxgi::Format, Usage>,
4625                initial_data: Option<&SubresourceData<*const c_void, u32, u32>>,
4626            ) -> Result<Texture3D, HResult> {
4627                let c_data = initial_data
4628                    .as_ref()
4629                    .map_or(None, |d| Some(d.to_c_struct()));
4630                Ok(Texture3D(ComPtr::new(|| {
4631                    let mut obj = std::ptr::null_mut();
4632                    let res = unsafe {
4633                        self.0.CreateTexture3D(
4634                            &desc.to_c_struct(),
4635                            c_data.as_ref().map_or(std::ptr::null(), |d| d),
4636                            &mut obj,
4637                        )
4638                    };
4639                    hresult(obj, res)
4640                })?))
4641            }
4642            fn create_unordered_access_view(
4643                &self,
4644                resource: &impl IResource,
4645                desc: Option<&UnorderedAccessViewDesc>,
4646            ) -> Result<UnorderedAccessView, HResult> {
4647                Ok(UnorderedAccessView(ComPtr::new(|| {
4648                    let mut obj = std::ptr::null_mut();
4649                    let c_desc = desc.map(|d| d.to_c_struct());
4650                    let res = unsafe {
4651                        self.0.CreateUnorderedAccessView(
4652                            resource.as_ptr() as *mut _,
4653                            c_desc.as_ref().map_or(std::ptr::null(), |d| d),
4654                            &mut obj,
4655                        )
4656                    };
4657                    hresult(obj, res)
4658                })?))
4659            }
4660            fn create_vertex_shader(
4661                &self,
4662                bytecode: &[u8],
4663                class_linkage: Option<&ClassLinkage>,
4664            ) -> Result<VertexShader, HResult> {
4665                Ok(VertexShader(ComPtr::new(|| {
4666                    let mut obj = std::ptr::null_mut();
4667                    let res = unsafe {
4668                        self.0.CreateVertexShader(
4669                            bytecode.as_ptr() as *const c_void,
4670                            bytecode.len(),
4671                            class_linkage.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
4672                            &mut obj,
4673                        )
4674                    };
4675                    hresult(obj, res)
4676                })?))
4677            }
4678            fn get_creation_flags(&self) -> Option<CreateDeviceFlags> {
4679                let value = unsafe { self.0.GetCreationFlags() };
4680                if value == 0 {
4681                    None
4682                } else {
4683                    Some(CreateDeviceFlags(value))
4684                }
4685            }
4686            fn get_device_removed_reason(&self) -> HResult {
4687                unsafe { self.0.GetDeviceRemovedReason().into() }
4688            }
4689            fn get_exception_mode(&self) -> Option<RaiseFlags> {
4690                let value = unsafe { self.0.GetExceptionMode() };
4691                if value == 0 {
4692                    None
4693                } else {
4694                    Some(RaiseFlags(value))
4695                }
4696            }
4697            fn get_feature_level(&self) -> d3d::FeatureLevel {
4698                let level = unsafe { self.0.GetFeatureLevel() };
4699                level.into()
4700            }
4701            fn get_immediate_context(&self) -> DeviceContext {
4702                unsafe {
4703                    let mut obj = std::ptr::null_mut();
4704                    self.0.GetImmediateContext(&mut obj);
4705                    DeviceContext(ComPtr::from_raw(obj))
4706                }
4707            }
4708            fn open_shared_resource<T: Interface>(&self, resource: &Handle) -> Result<T, HResult> {
4709                Ok(T::new(ComPtr::new(|| {
4710                    let mut obj = std::ptr::null_mut();
4711                    let res = unsafe {
4712                        self.0.OpenSharedResource(
4713                            resource.as_raw_handle(),
4714                            &T::uuidof().into(),
4715                            &mut obj,
4716                        )
4717                    };
4718                    hresult(obj as *mut <T as Interface>::APIType, res)
4719                })?))
4720            }
4721            fn set_exception_mode(&self, flags: Option<RaiseFlags>) -> Result<(), HResult> {
4722                let res = unsafe { self.0.SetExceptionMode(flags.map_or(0, |f| f.0)) };
4723                hresult((), res)
4724            }
4725            fn get_name(&self) -> Result<String, HResult> {
4726                unsafe {
4727                    let mut sz = 0;
4728                    let res = self.0.GetPrivateData(
4729                        &WKPDID_D3DDebugObjectNameW,
4730                        &mut sz,
4731                        std::ptr::null_mut(),
4732                    );
4733                    let mut sz = hresult(sz, res)?;
4734                    let mut buf =
4735                        Vec::<u16>::with_capacity(sz as usize / std::mem::size_of::<u16>());
4736                    let res = self.0.GetPrivateData(
4737                        &WKPDID_D3DDebugObjectNameW,
4738                        &mut sz,
4739                        buf.as_mut_ptr() as *mut c_void,
4740                    );
4741                    let buf = hresult(buf, res)?;
4742                    Ok(OsString::from_wide(&buf).to_string_lossy().to_string())
4743                }
4744            }
4745            fn set_name(&self, name: &str) -> Result<(), HResult> {
4746                unsafe {
4747                    let wname = name.encode_utf16().chain(Some(0)).collect::<Vec<u16>>();
4748                    let res = self.0.SetPrivateData(
4749                        &WKPDID_D3DDebugObjectNameW,
4750                        (std::mem::size_of::<u16>() * wname.len()) as u32,
4751                        wname.as_ptr() as *const c_void,
4752                    );
4753                    hresult((), res)
4754                }
4755            }
4756        }
4757    };
4758}
4759impl_device!(Device, ID3D11Device);
4760
4761fn shader_get_objects<F, T: Interface>(f: F, start_slot: u32, num: u32) -> Vec<Option<T>>
4762where
4763    F: FnOnce(u32, u32, *mut *mut T::APIType),
4764{
4765    unsafe {
4766        let mut objs = Vec::with_capacity(num as usize);
4767        objs.set_len(num as usize);
4768        f(start_slot, num, objs.as_mut_ptr());
4769        objs.into_iter()
4770            .map(|p| {
4771                if p == std::ptr::null_mut() {
4772                    None
4773                } else {
4774                    Some(T::new(ComPtr::from_raw(p)))
4775                }
4776            })
4777            .collect::<Vec<_>>()
4778    }
4779}
4780
4781fn get_shader<F, T: Interface>(f: F) -> (Option<T>, Option<Vec<ClassInstance>>)
4782where
4783    F: FnOnce(*mut *mut T::APIType, *mut *mut ID3D11ClassInstance, &mut u32),
4784{
4785    unsafe {
4786        let mut shader = std::ptr::null_mut();
4787        let mut instances = std::ptr::null_mut();
4788        let mut instances_num = 0;
4789        f(&mut shader, &mut instances, &mut instances_num);
4790        let shader = if shader == std::ptr::null_mut() {
4791            None
4792        } else {
4793            Some(T::new(ComPtr::from_raw(shader)))
4794        };
4795        let instances = if instances == std::ptr::null_mut() {
4796            None
4797        } else {
4798            let c_instances = Vec::from_raw_parts(
4799                &mut instances,
4800                instances_num as usize,
4801                instances_num as usize,
4802            );
4803            Some(
4804                c_instances
4805                    .into_iter()
4806                    .map(|p| ClassInstance(ComPtr::from_raw(p)))
4807                    .collect::<Vec<_>>(),
4808            )
4809        };
4810        (shader, instances)
4811    }
4812}
4813
4814fn shader_set_objects<F, T: Interface>(f: F, start_slot: u32, objs: &[&T])
4815where
4816    F: FnOnce(u32, u32, *const *mut T::APIType),
4817{
4818    let c_objs = objs.iter().map(|o| o.as_ptr()).collect::<Vec<_>>();
4819    f(start_slot, c_objs.len() as u32, c_objs.as_ptr());
4820}
4821
4822fn set_shader<F, T: Interface>(f: F, shader: &T, instances: Option<&[&ClassInstance]>)
4823where
4824    F: FnOnce(*mut T::APIType, *const *mut ID3D11ClassInstance, u32),
4825{
4826    let c_instances = instances.map(|a| a.iter().map(|i| i.as_ptr()).collect::<Vec<_>>());
4827    f(
4828        shader.as_ptr(),
4829        c_instances
4830            .as_ref()
4831            .map_or(std::ptr::null(), |ci| ci.as_ptr()),
4832        c_instances.as_ref().map_or(0, |ci| ci.len() as u32),
4833    );
4834}
4835
4836pub trait IDeviceContext: IDeviceChild {
4837    fn begin(&self, obj: &impl IAsynchronous);
4838    fn clear_depth_stencil_view(
4839        &self,
4840        view: &DepthStencilView,
4841        clear_flags: ClearFlags,
4842        depth: f32,
4843        stencil: u8,
4844    );
4845    fn clear_render_target_view(&self, view: &RenderTargetView, color: dxgi::RGBA);
4846    fn clear_state(&self);
4847    fn clear_unordered_access_view_float(&self, view: &UnorderedAccessView, values: [f32; 4]);
4848    fn clear_unordered_access_view_uint(&self, view: &UnorderedAccessView, values: [u32; 4]);
4849    fn copy_resource(&self, dest: &impl IResource, src: &impl IResource);
4850    fn copy_structure_count(
4851        &self,
4852        buffer: &impl IBuffer,
4853        dest_aligned_byte_offset: u32,
4854        src_view: &UnorderedAccessView,
4855    );
4856    fn copy_subresource_region(
4857        &self,
4858        dest: &impl IResource,
4859        dest_subresource: u32,
4860        dest_x: u32,
4861        dest_y: u32,
4862        dest_z: u32,
4863        src: &impl IResource,
4864        src_subresource: u32,
4865        src_box: Option<&Box3D>,
4866    );
4867    fn cs_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
4868    fn cs_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
4869    fn cs_get_shader(&self) -> (Option<ComputeShader>, Option<Vec<ClassInstance>>);
4870    fn cs_get_shader_resources(
4871        &self,
4872        start_slot: u32,
4873        num_views: u32,
4874    ) -> Vec<Option<ShaderResourceView>>;
4875    fn cs_get_unordered_access_views(
4876        &self,
4877        start_slot: u32,
4878        num_uavs: u32,
4879    ) -> Vec<Option<UnorderedAccessView>>;
4880    fn cs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
4881    fn cs_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]);
4882    fn cs_set_shader(&self, shader: &ComputeShader, instances: Option<&[&ClassInstance]>);
4883    fn cs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
4884    fn cs_set_unordered_access_views(
4885        &self,
4886        start_slot: u32,
4887        vies: &[&UnorderedAccessView],
4888        initial_counts: &[u32],
4889    );
4890    fn dispatch(
4891        &self,
4892        thread_group_count_x: u32,
4893        thread_group_count_y: u32,
4894        thraed_group_count_z: u32,
4895    );
4896    fn dispatch_indirect(&self, args: &Buffer, byte_offset: u32);
4897    fn draw(&self, vertex_count: u32, start_vertex_location: u32);
4898    fn draw_auto(&self);
4899    fn draw_indexed(&self, index_count: u32, start_index_location: u32, base_vertex_location: i32);
4900    fn draw_indexed_instanced(
4901        &self,
4902        index_count_per_instance: u32,
4903        instance_count: u32,
4904        start_index_location: u32,
4905        base_vertex_location: i32,
4906        start_instance_location: u32,
4907    );
4908    fn draw_indexed_instanced_indirect(&self, args: &impl IBuffer, byte_offset: u32);
4909    fn draw_instanced(
4910        &self,
4911        vertex_count_per_instance: u32,
4912        instance_count: u32,
4913        start_vertex_location: u32,
4914        start_instance_location: u32,
4915    );
4916    fn draw_instanced_indirect(&self, args: &impl IBuffer, byte_offset: u32);
4917    fn ds_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
4918    fn ds_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
4919    fn ds_get_shader(&self) -> (Option<DomainShader>, Option<Vec<ClassInstance>>);
4920    fn ds_get_shader_resources(
4921        &self,
4922        start_slot: u32,
4923        num_views: u32,
4924    ) -> Vec<Option<ShaderResourceView>>;
4925    fn ds_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
4926    fn ds_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]);
4927    fn ds_set_shader(&self, shader: &DomainShader, instances: Option<&[&ClassInstance]>);
4928    fn ds_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
4929    fn end(&self, obj: &impl IAsynchronous);
4930    fn execute_command_list(&self, cmd_list: &impl ICommandList, restore_context_state: bool);
4931    fn finish_command_list(
4932        &self,
4933        restore_deferred_context_state: bool,
4934    ) -> Result<CommandList, HResult>;
4935    fn flush(&self);
4936    fn generate_mips(&self, view: &impl IShaderResourceView);
4937    fn get_context_flags(&self) -> u32;
4938    fn get_data(
4939        &self,
4940        async_obj: &impl IAsynchronous,
4941        flags: Option<AsyncGetDataFlag>,
4942    ) -> Result<Vec<u8>, HResult>;
4943    fn get_predication(&self) -> Option<(Predicate, bool)>;
4944    fn get_resource_min_lod(&self, resource: &impl IResource) -> f32;
4945    fn get_type(&self) -> DeviceContextType;
4946    fn gs_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
4947    fn gs_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
4948    fn gs_get_shader(&self) -> (Option<GeometryShader>, Option<Vec<ClassInstance>>);
4949    fn gs_get_shader_resources(
4950        &self,
4951        start_slot: u32,
4952        num_views: u32,
4953    ) -> Vec<Option<ShaderResourceView>>;
4954    fn gs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
4955    fn gs_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]);
4956    fn gs_set_shader(&self, shader: &GeometryShader, instances: Option<&[&ClassInstance]>);
4957    fn gs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
4958    fn hs_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
4959    fn hs_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
4960    fn hs_get_shader(&self) -> (Option<HullShader>, Option<Vec<ClassInstance>>);
4961    fn hs_get_shader_resources(
4962        &self,
4963        start_slot: u32,
4964        num_views: u32,
4965    ) -> Vec<Option<ShaderResourceView>>;
4966    fn hs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
4967    fn hs_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]);
4968    fn hs_set_shader(&self, shader: &HullShader, instances: Option<&[&ClassInstance]>);
4969    fn hs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
4970    fn ia_get_index_buffer(&self) -> Option<(Buffer, dxgi::Format, u32)>;
4971    fn ia_get_input_layout(&self) -> Option<InputLayout>;
4972    fn ia_get_primitive_topology(&self) -> Option<PrimitiveTopology>;
4973    fn ia_get_vertex_buffers(
4974        &self,
4975        start_slot: u32,
4976        num_buffers: u32,
4977    ) -> Vec<Option<(Buffer, u32, u32)>>;
4978    fn ia_set_index_buffer(&self, buffer: &impl IBuffer, format: dxgi::Format, offset: u32);
4979    fn ia_set_input_layout(&self, input_layout: &impl IInputLayout);
4980    fn ia_set_primitive_topology(&self, topology: PrimitiveTopology);
4981    fn ia_set_vertex_buffers(
4982        &self,
4983        start_slot: u32,
4984        buffers: &[&impl IBuffer],
4985        strides: &[u32],
4986        offset: &[u32],
4987    );
4988    fn map(
4989        &self,
4990        resource: &impl IResource,
4991        subresource: u32,
4992        map_type: MapType,
4993        map_flags: Option<MapFlag>,
4994    ) -> Result<MappedSubresource, HResult>;
4995    fn om_get_blend_state(&self) -> Option<(BlendState, [f32; 4], u32)>;
4996    fn om_get_depth_stencil_state(&self) -> (Option<DepthStencilState>, u32);
4997    fn om_get_render_targets(
4998        &self,
4999        num_views: u32,
5000    ) -> (Vec<Option<RenderTargetView>>, Option<DepthStencilView>);
5001    // fn om_get_render_targets_and_unordered_access_views(&self, num_rtvs: u32, uav_start_slot: u32, num_uavs: u32) -> (Vec<Option<RenderTargetView>>, Option<DepthStencilView>, Vec<Option<(UnorderedAccessView, u32)>>);
5002    fn om_set_blend_state(&self, state: &BlendState, factor: &[f32; 4], mask: u32);
5003    fn om_set_depth_stencil_state(&self, state: &DepthStencilState, stencil_ref: u32);
5004    fn om_set_render_targets(
5005        &self,
5006        rtvs: Option<&[&RenderTargetView]>,
5007        dsv: Option<&DepthStencilView>,
5008    );
5009    fn om_set_render_targets_and_unordered_access_views(
5010        &self,
5011        rtvs: Option<&[&RenderTargetView]>,
5012        dsv: Option<&DepthStencilView>,
5013        uav_start_slot: u32,
5014        uavs: Option<&[&UnorderedAccessView]>,
5015        initial_counts: Option<&[u32]>,
5016    );
5017    fn ps_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
5018    fn ps_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
5019    fn ps_get_shader(&self) -> (Option<PixelShader>, Option<Vec<ClassInstance>>);
5020    fn ps_get_shader_resources(
5021        &self,
5022        start_slot: u32,
5023        num_views: u32,
5024    ) -> Vec<Option<ShaderResourceView>>;
5025    fn ps_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
5026    fn ps_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]);
5027    fn ps_set_shader(&self, shader: &PixelShader, instances: Option<&[&ClassInstance]>);
5028    fn ps_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
5029    fn resolve_subresource(
5030        &self,
5031        dest: &impl IResource,
5032        dest_subresource: u32,
5033        src: &impl IResource,
5034        src_subresource: u32,
5035        format: dxgi::Format,
5036    );
5037    fn rs_get_scissor_rects(&self) -> Vec<Rect<i32>>;
5038    fn rs_get_state(&self) -> Option<RasterizerState>;
5039    fn rs_get_viewports(&self) -> Vec<Viewport>;
5040    fn rs_set_scissor_rects(&self, rects: &[Rect<i32>]);
5041    fn rs_set_state(&self, rasterizer_state: &RasterizerState);
5042    fn rs_set_viewports(&self, viewports: &[Viewport]);
5043    fn set_predication(&self, predicate: Option<&Predicate>, value: bool);
5044    fn set_resource_min_lod(&self, resource: &impl IResource, min_lod: f32);
5045    fn so_get_targets(&self, num: u32) -> Vec<Option<Buffer>>;
5046    fn so_set_targets(&self, targets: &[&impl IBuffer], offset: &[u32]);
5047    fn unmap(&self, resource: &impl IResource, subresource: u32);
5048    fn update_subresource(
5049        &self,
5050        dest: &impl IResource,
5051        dest_subresource: u32,
5052        dest_box: Option<&Box3D>,
5053        src: &[u8],
5054        src_row_pitch: u32,
5055        src_depth_pitch: u32,
5056    );
5057    fn vs_get_constant_buffers(&self, start_slot: u32, num_buffers: u32) -> Vec<Option<Buffer>>;
5058    fn vs_get_samplers(&self, start_slot: u32, num_samplers: u32) -> Vec<Option<SamplerState>>;
5059    fn vs_get_shader(&self) -> (Option<VertexShader>, Option<Vec<ClassInstance>>);
5060    fn vs_get_shader_resources(
5061        &self,
5062        start_slot: u32,
5063        num_views: u32,
5064    ) -> Vec<Option<ShaderResourceView>>;
5065    fn vs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]);
5066    fn vs_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]);
5067    fn vs_set_shader(&self, shader: &VertexShader, instances: Option<&[&ClassInstance]>);
5068    fn vs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]);
5069}
5070#[derive(Clone, Debug)]
5071pub struct DeviceContext(ComPtr<ID3D11DeviceContext>);
5072macro_rules! impl_devicecontext {
5073    ($s: ident, $interface: ident) => {
5074        impl_devicechild!($s, $interface);
5075        impl IDeviceContext for $s {
5076            fn begin(&self, obj: &impl IAsynchronous) {
5077                unsafe {
5078                    self.0.Begin(obj.as_ptr() as *mut _);
5079                }
5080            }
5081            fn clear_depth_stencil_view(
5082                &self,
5083                view: &DepthStencilView,
5084                clear_flags: ClearFlags,
5085                depth: f32,
5086                stencil: u8,
5087            ) {
5088                unsafe {
5089                    self.0
5090                        .ClearDepthStencilView(view.as_ptr(), clear_flags.0, depth, stencil);
5091                }
5092            }
5093            fn clear_render_target_view(&self, view: &RenderTargetView, color: dxgi::RGBA) {
5094                unsafe {
5095                    self.0.ClearRenderTargetView(
5096                        view.as_ptr(),
5097                        &[color.r, color.g, color.b, color.a],
5098                    );
5099                }
5100            }
5101            fn clear_state(&self) {
5102                unsafe {
5103                    self.0.ClearState();
5104                }
5105            }
5106            fn clear_unordered_access_view_float(
5107                &self,
5108                view: &UnorderedAccessView,
5109                values: [f32; 4],
5110            ) {
5111                unsafe {
5112                    self.0.ClearUnorderedAccessViewFloat(view.as_ptr(), &values);
5113                }
5114            }
5115            fn clear_unordered_access_view_uint(
5116                &self,
5117                view: &UnorderedAccessView,
5118                values: [u32; 4],
5119            ) {
5120                unsafe {
5121                    self.0.ClearUnorderedAccessViewUint(view.as_ptr(), &values);
5122                }
5123            }
5124            fn copy_resource(&self, dest: &impl IResource, src: &impl IResource) {
5125                unsafe {
5126                    self.0
5127                        .CopyResource(dest.as_ptr() as *mut _, src.as_ptr() as *mut _);
5128                }
5129            }
5130            fn copy_structure_count(
5131                &self,
5132                dest: &impl IBuffer,
5133                byte_offset: u32,
5134                src_view: &UnorderedAccessView,
5135            ) {
5136                unsafe {
5137                    self.0.CopyStructureCount(
5138                        dest.as_ptr() as *mut _,
5139                        byte_offset,
5140                        src_view.as_ptr(),
5141                    );
5142                }
5143            }
5144            fn copy_subresource_region(
5145                &self,
5146                dest: &impl IResource,
5147                dest_resource: u32,
5148                dest_x: u32,
5149                dest_y: u32,
5150                dest_z: u32,
5151                src: &impl IResource,
5152                src_subresource: u32,
5153                src_box: Option<&Box3D>,
5154            ) {
5155                unsafe {
5156                    self.0.CopySubresourceRegion(
5157                        dest.as_ptr() as *mut _,
5158                        dest_resource,
5159                        dest_x,
5160                        dest_y,
5161                        dest_z,
5162                        src.as_ptr() as *mut _,
5163                        src_subresource,
5164                        src_box.map_or(std::ptr::null(), |b| b.as_c_ptr()),
5165                    );
5166                }
5167            }
5168            fn cs_get_constant_buffers(
5169                &self,
5170                start_slot: u32,
5171                num_buffers: u32,
5172            ) -> Vec<Option<Buffer>> {
5173                shader_get_objects(
5174                    |s, n, p| unsafe { self.0.CSGetConstantBuffers(s, n, p) },
5175                    start_slot,
5176                    num_buffers,
5177                )
5178            }
5179            fn cs_get_samplers(
5180                &self,
5181                start_slot: u32,
5182                num_samplers: u32,
5183            ) -> Vec<Option<SamplerState>> {
5184                shader_get_objects(
5185                    |s, n, p| unsafe { self.0.CSGetSamplers(s, n, p) },
5186                    start_slot,
5187                    num_samplers,
5188                )
5189            }
5190            fn cs_get_shader(&self) -> (Option<ComputeShader>, Option<Vec<ClassInstance>>) {
5191                get_shader(|p, c, n| unsafe { self.0.CSGetShader(p, c, n) })
5192            }
5193            fn cs_get_shader_resources(
5194                &self,
5195                start_slot: u32,
5196                num_views: u32,
5197            ) -> Vec<Option<ShaderResourceView>> {
5198                shader_get_objects(
5199                    |s, n, p| unsafe { self.0.CSGetShaderResources(s, n, p) },
5200                    start_slot,
5201                    num_views,
5202                )
5203            }
5204            fn cs_get_unordered_access_views(
5205                &self,
5206                start_slot: u32,
5207                num_uavs: u32,
5208            ) -> Vec<Option<UnorderedAccessView>> {
5209                shader_get_objects(
5210                    |s, n, p| unsafe { self.0.CSGetUnorderedAccessViews(s, n, p) },
5211                    start_slot,
5212                    num_uavs,
5213                )
5214            }
5215            fn cs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
5216                shader_set_objects(
5217                    |s, n, p| unsafe { self.0.CSSetConstantBuffers(s, n, p as *mut _) },
5218                    start_slot,
5219                    buffers,
5220                )
5221            }
5222            fn cs_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]) {
5223                shader_set_objects(
5224                    |s, n, p| unsafe { self.0.CSSetSamplers(s, n, p as *mut _) },
5225                    start_slot,
5226                    samplers,
5227                )
5228            }
5229            fn cs_set_shader(&self, shader: &ComputeShader, instances: Option<&[&ClassInstance]>) {
5230                set_shader(
5231                    |p, c, n| unsafe { self.0.CSSetShader(p, c, n) },
5232                    shader,
5233                    instances,
5234                )
5235            }
5236            fn cs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
5237                shader_set_objects(
5238                    |s, n, p| unsafe { self.0.CSSetShaderResources(s, n, p) },
5239                    start_slot,
5240                    views,
5241                )
5242            }
5243            fn cs_set_unordered_access_views(
5244                &self,
5245                start_slot: u32,
5246                views: &[&UnorderedAccessView],
5247                initial_data: &[u32],
5248            ) {
5249                let c_views = views.iter().map(|o| o.as_ptr()).collect::<Vec<_>>();
5250                unsafe {
5251                    self.0.CSSetUnorderedAccessViews(
5252                        start_slot,
5253                        c_views.len() as u32,
5254                        c_views.as_ptr(),
5255                        initial_data.as_ptr(),
5256                    );
5257                }
5258            }
5259            fn dispatch(
5260                &self,
5261                thread_group_count_x: u32,
5262                thread_group_count_y: u32,
5263                thraed_group_count_z: u32,
5264            ) {
5265                unsafe {
5266                    self.0.Dispatch(
5267                        thread_group_count_x,
5268                        thread_group_count_y,
5269                        thraed_group_count_z,
5270                    );
5271                }
5272            }
5273            fn dispatch_indirect(&self, buffer: &Buffer, byte_offset: u32) {
5274                unsafe {
5275                    self.0.DispatchIndirect(buffer.as_ptr(), byte_offset);
5276                }
5277            }
5278            fn draw(&self, vertex_count: u32, start_vertex_location: u32) {
5279                unsafe {
5280                    self.0.Draw(vertex_count, start_vertex_location);
5281                }
5282            }
5283            fn draw_auto(&self) {
5284                unsafe { self.0.DrawAuto() };
5285            }
5286            fn draw_indexed(
5287                &self,
5288                index_count: u32,
5289                start_index_location: u32,
5290                base_vertex_location: i32,
5291            ) {
5292                unsafe {
5293                    self.0
5294                        .DrawIndexed(index_count, start_index_location, base_vertex_location);
5295                }
5296            }
5297            fn draw_indexed_instanced(
5298                &self,
5299                index_count_per_instance: u32,
5300                instance_count: u32,
5301                start_index_location: u32,
5302                base_vertex_location: i32,
5303                start_instance_location: u32,
5304            ) {
5305                unsafe {
5306                    self.0.DrawIndexedInstanced(
5307                        index_count_per_instance,
5308                        instance_count,
5309                        start_index_location,
5310                        base_vertex_location,
5311                        start_instance_location,
5312                    );
5313                }
5314            }
5315            fn draw_indexed_instanced_indirect(&self, args: &impl IBuffer, byte_offset: u32) {
5316                unsafe {
5317                    self.0
5318                        .DrawIndexedInstancedIndirect(args.as_ptr() as *mut _, byte_offset);
5319                }
5320            }
5321            fn draw_instanced(
5322                &self,
5323                vertex_count_per_instance: u32,
5324                instance_count: u32,
5325                start_vertex_location: u32,
5326                start_instance_location: u32,
5327            ) {
5328                unsafe {
5329                    self.0.DrawInstanced(
5330                        vertex_count_per_instance,
5331                        instance_count,
5332                        start_vertex_location,
5333                        start_instance_location,
5334                    );
5335                }
5336            }
5337            fn draw_instanced_indirect(&self, args: &impl IBuffer, byte_offset: u32) {
5338                unsafe {
5339                    self.0
5340                        .DrawInstancedIndirect(args.as_ptr() as *mut _, byte_offset);
5341                }
5342            }
5343            fn ds_get_constant_buffers(
5344                &self,
5345                start_slot: u32,
5346                num_buffers: u32,
5347            ) -> Vec<Option<Buffer>> {
5348                shader_get_objects(
5349                    |s, n, p| unsafe { self.0.DSGetConstantBuffers(s, n, p) },
5350                    start_slot,
5351                    num_buffers,
5352                )
5353            }
5354            fn ds_get_samplers(
5355                &self,
5356                start_slot: u32,
5357                num_samplers: u32,
5358            ) -> Vec<Option<SamplerState>> {
5359                shader_get_objects(
5360                    |s, n, p| unsafe { self.0.DSGetSamplers(s, n, p) },
5361                    start_slot,
5362                    num_samplers,
5363                )
5364            }
5365            fn ds_get_shader(&self) -> (Option<DomainShader>, Option<Vec<ClassInstance>>) {
5366                get_shader(|p, c, n| unsafe { self.0.DSGetShader(p, c, n) })
5367            }
5368            fn ds_get_shader_resources(
5369                &self,
5370                start_slot: u32,
5371                num_views: u32,
5372            ) -> Vec<Option<ShaderResourceView>> {
5373                shader_get_objects(
5374                    |s, n, p| unsafe { self.0.DSGetShaderResources(s, n, p) },
5375                    start_slot,
5376                    num_views,
5377                )
5378            }
5379            fn ds_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
5380                shader_set_objects(
5381                    |s, n, p| unsafe { self.0.DSSetConstantBuffers(s, n, p as *mut _) },
5382                    start_slot,
5383                    buffers,
5384                )
5385            }
5386            fn ds_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]) {
5387                shader_set_objects(
5388                    |s, n, p| unsafe { self.0.DSSetSamplers(s, n, p as *mut _) },
5389                    start_slot,
5390                    samplers,
5391                )
5392            }
5393            fn ds_set_shader(&self, shader: &DomainShader, instances: Option<&[&ClassInstance]>) {
5394                set_shader(
5395                    |p, c, n| unsafe { self.0.DSSetShader(p, c, n) },
5396                    shader,
5397                    instances,
5398                )
5399            }
5400            fn ds_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
5401                shader_set_objects(
5402                    |s, n, p| unsafe { self.0.DSSetShaderResources(s, n, p) },
5403                    start_slot,
5404                    views,
5405                )
5406            }
5407            fn end(&self, obj: &impl IAsynchronous) {
5408                unsafe {
5409                    self.0.End(obj.as_ptr() as *mut _);
5410                }
5411            }
5412            fn execute_command_list(
5413                &self,
5414                cmd_list: &impl ICommandList,
5415                restore_context_state: bool,
5416            ) {
5417                unsafe {
5418                    self.0.ExecuteCommandList(
5419                        cmd_list.as_ptr() as *mut _,
5420                        to_BOOL(restore_context_state),
5421                    );
5422                }
5423            }
5424            fn finish_command_list(
5425                &self,
5426                restore_deferred_context_state: bool,
5427            ) -> Result<CommandList, HResult> {
5428                Ok(CommandList(ComPtr::new(|| {
5429                    let mut obj = std::ptr::null_mut();
5430                    let res = unsafe {
5431                        self.0
5432                            .FinishCommandList(to_BOOL(restore_deferred_context_state), &mut obj)
5433                    };
5434                    hresult(obj, res)
5435                })?))
5436            }
5437            fn flush(&self) {
5438                unsafe {
5439                    self.0.Flush();
5440                }
5441            }
5442            fn generate_mips(&self, view: &impl IShaderResourceView) {
5443                unsafe {
5444                    self.0.GenerateMips(view.as_ptr() as *mut _);
5445                }
5446            }
5447            fn get_context_flags(&self) -> u32 {
5448                unsafe { self.0.GetContextFlags() }
5449            }
5450            fn get_data(
5451                &self,
5452                async_obj: &impl IAsynchronous,
5453                flags: Option<AsyncGetDataFlag>,
5454            ) -> Result<Vec<u8>, HResult> {
5455                unsafe {
5456                    let mut data = Vec::new();
5457                    data.resize(async_obj.get_data_size() as usize, 0);
5458                    let res = self.0.GetData(
5459                        async_obj.as_ptr() as *mut _,
5460                        data.as_mut_ptr() as *mut c_void,
5461                        data.len() as u32,
5462                        flags.map_or(0, |f| f.0),
5463                    );
5464                    hresult(data, res)
5465                }
5466            }
5467            fn get_predication(&self) -> Option<(Predicate, bool)> {
5468                unsafe {
5469                    let mut obj = std::ptr::null_mut();
5470                    let mut value = 0;
5471                    self.0.GetPredication(&mut obj, &mut value);
5472                    if obj == std::ptr::null_mut() {
5473                        None
5474                    } else {
5475                        Some((Predicate(ComPtr::from_raw(obj)), value != 0))
5476                    }
5477                }
5478            }
5479            fn get_resource_min_lod(&self, resource: &impl IResource) -> f32 {
5480                unsafe { self.0.GetResourceMinLOD(resource.as_ptr() as *mut _) }
5481            }
5482            fn get_type(&self) -> DeviceContextType {
5483                unsafe {
5484                    let t = self.0.GetType();
5485                    std::mem::transmute(t)
5486                }
5487            }
5488            fn gs_get_constant_buffers(
5489                &self,
5490                start_slot: u32,
5491                num_buffers: u32,
5492            ) -> Vec<Option<Buffer>> {
5493                shader_get_objects(
5494                    |s, n, p| unsafe { self.0.GSGetConstantBuffers(s, n, p) },
5495                    start_slot,
5496                    num_buffers,
5497                )
5498            }
5499            fn gs_get_samplers(
5500                &self,
5501                start_slot: u32,
5502                num_samplers: u32,
5503            ) -> Vec<Option<SamplerState>> {
5504                shader_get_objects(
5505                    |s, n, p| unsafe { self.0.GSGetSamplers(s, n, p) },
5506                    start_slot,
5507                    num_samplers,
5508                )
5509            }
5510            fn gs_get_shader(&self) -> (Option<GeometryShader>, Option<Vec<ClassInstance>>) {
5511                get_shader(|p, c, n| unsafe { self.0.GSGetShader(p, c, n) })
5512            }
5513            fn gs_get_shader_resources(
5514                &self,
5515                start_slot: u32,
5516                num_views: u32,
5517            ) -> Vec<Option<ShaderResourceView>> {
5518                shader_get_objects(
5519                    |s, n, p| unsafe { self.0.GSGetShaderResources(s, n, p) },
5520                    start_slot,
5521                    num_views,
5522                )
5523            }
5524            fn gs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
5525                shader_set_objects(
5526                    |s, n, p| unsafe { self.0.GSSetConstantBuffers(s, n, p as *mut _) },
5527                    start_slot,
5528                    buffers,
5529                )
5530            }
5531            fn gs_set_samplers(&self, start_slot: u32, samplers: &[&impl ISamplerState]) {
5532                shader_set_objects(
5533                    |s, n, p| unsafe { self.0.GSSetSamplers(s, n, p as *mut _) },
5534                    start_slot,
5535                    samplers,
5536                )
5537            }
5538            fn gs_set_shader(&self, shader: &GeometryShader, instances: Option<&[&ClassInstance]>) {
5539                set_shader(
5540                    |p, c, n| unsafe { self.0.GSSetShader(p, c, n) },
5541                    shader,
5542                    instances,
5543                )
5544            }
5545            fn gs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
5546                shader_set_objects(
5547                    |s, n, p| unsafe { self.0.GSSetShaderResources(s, n, p) },
5548                    start_slot,
5549                    views,
5550                )
5551            }
5552            fn hs_get_constant_buffers(
5553                &self,
5554                start_slot: u32,
5555                num_buffers: u32,
5556            ) -> Vec<Option<Buffer>> {
5557                shader_get_objects(
5558                    |s, n, p| unsafe { self.0.HSGetConstantBuffers(s, n, p) },
5559                    start_slot,
5560                    num_buffers,
5561                )
5562            }
5563            fn hs_get_samplers(
5564                &self,
5565                start_slot: u32,
5566                num_samplers: u32,
5567            ) -> Vec<Option<SamplerState>> {
5568                shader_get_objects(
5569                    |s, n, p| unsafe { self.0.HSGetSamplers(s, n, p) },
5570                    start_slot,
5571                    num_samplers,
5572                )
5573            }
5574            fn hs_get_shader(&self) -> (Option<HullShader>, Option<Vec<ClassInstance>>) {
5575                get_shader(|p, c, n| unsafe { self.0.HSGetShader(p, c, n) })
5576            }
5577            fn hs_get_shader_resources(
5578                &self,
5579                start_slot: u32,
5580                num_views: u32,
5581            ) -> Vec<Option<ShaderResourceView>> {
5582                shader_get_objects(
5583                    |s, n, p| unsafe { self.0.HSGetShaderResources(s, n, p) },
5584                    start_slot,
5585                    num_views,
5586                )
5587            }
5588            fn hs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
5589                shader_set_objects(
5590                    |s, n, p| unsafe { self.0.HSSetConstantBuffers(s, n, p as *mut _) },
5591                    start_slot,
5592                    buffers,
5593                )
5594            }
5595            fn hs_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]) {
5596                shader_set_objects(
5597                    |s, n, p| unsafe { self.0.HSSetSamplers(s, n, p) },
5598                    start_slot,
5599                    samplers,
5600                )
5601            }
5602            fn hs_set_shader(&self, shader: &HullShader, instances: Option<&[&ClassInstance]>) {
5603                set_shader(
5604                    |p, c, n| unsafe { self.0.HSSetShader(p, c, n) },
5605                    shader,
5606                    instances,
5607                )
5608            }
5609            fn hs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
5610                shader_set_objects(
5611                    |s, n, p| unsafe { self.0.HSSetShaderResources(s, n, p) },
5612                    start_slot,
5613                    views,
5614                )
5615            }
5616            fn ia_get_index_buffer(&self) -> Option<(Buffer, dxgi::Format, u32)> {
5617                unsafe {
5618                    let mut obj = std::ptr::null_mut();
5619                    let mut format = 0;
5620                    let mut offset = 0;
5621                    self.0.IAGetIndexBuffer(&mut obj, &mut format, &mut offset);
5622                    if obj == std::ptr::null_mut() {
5623                        None
5624                    } else {
5625                        Some((
5626                            Buffer(ComPtr::from_raw(obj)),
5627                            std::mem::transmute(format),
5628                            offset,
5629                        ))
5630                    }
5631                }
5632            }
5633            fn ia_get_input_layout(&self) -> Option<InputLayout> {
5634                unsafe {
5635                    let mut obj = std::ptr::null_mut();
5636                    self.0.IAGetInputLayout(&mut obj);
5637                    if obj == std::ptr::null_mut() {
5638                        None
5639                    } else {
5640                        Some(InputLayout(ComPtr::from_raw(obj)))
5641                    }
5642                }
5643            }
5644            fn ia_get_primitive_topology(&self) -> Option<PrimitiveTopology> {
5645                unsafe {
5646                    let mut topology = 0;
5647                    self.0.IAGetPrimitiveTopology(&mut topology);
5648                    if topology == 0 {
5649                        None
5650                    } else {
5651                        Some(std::mem::transmute(topology))
5652                    }
5653                }
5654            }
5655            fn ia_get_vertex_buffers(
5656                &self,
5657                start_slot: u32,
5658                num_buffers: u32,
5659            ) -> Vec<Option<(Buffer, u32, u32)>> {
5660                unsafe {
5661                    let mut buffers = Vec::with_capacity(num_buffers as usize);
5662                    buffers.set_len(num_buffers as usize);
5663                    let mut strides = Vec::with_capacity(num_buffers as usize);
5664                    strides.set_len(num_buffers as usize);
5665                    let mut offsets = Vec::with_capacity(num_buffers as usize);
5666                    offsets.set_len(num_buffers as usize);
5667                    self.0.IAGetVertexBuffers(
5668                        start_slot,
5669                        num_buffers,
5670                        buffers.as_mut_ptr(),
5671                        strides.as_mut_ptr(),
5672                        offsets.as_mut_ptr(),
5673                    );
5674                    let mut data: Vec<Option<(Buffer, u32, u32)>> =
5675                        Vec::with_capacity(num_buffers as usize);
5676                    for i in 0..num_buffers as usize {
5677                        if buffers[i] == std::ptr::null_mut() {
5678                            data.push(None)
5679                        } else {
5680                            data.push(Some((
5681                                Buffer(ComPtr::from_raw(buffers[i])),
5682                                strides[i],
5683                                offsets[i],
5684                            )))
5685                        }
5686                    }
5687                    data
5688                }
5689            }
5690            fn ia_set_index_buffer(
5691                &self,
5692                buffer: &impl IBuffer,
5693                format: dxgi::Format,
5694                offset: u32,
5695            ) {
5696                unsafe {
5697                    self.0
5698                        .IASetIndexBuffer(buffer.as_ptr() as *mut _, format as u32, offset);
5699                }
5700            }
5701            fn ia_set_input_layout(&self, input_layout: &impl IInputLayout) {
5702                unsafe {
5703                    self.0.IASetInputLayout(input_layout.as_ptr() as *mut _);
5704                }
5705            }
5706            fn ia_set_primitive_topology(&self, topology: PrimitiveTopology) {
5707                unsafe {
5708                    self.0.IASetPrimitiveTopology(topology as u32);
5709                }
5710            }
5711            fn ia_set_vertex_buffers(
5712                &self,
5713                start_slot: u32,
5714                buffers: &[&impl IBuffer],
5715                strides: &[u32],
5716                offsets: &[u32],
5717            ) {
5718                unsafe {
5719                    let bufs = buffers
5720                        .iter()
5721                        .map(|b| b.as_ptr() as *mut _)
5722                        .collect::<Vec<_>>();
5723                    assert!(bufs.len() == strides.len());
5724                    assert!(bufs.len() == offsets.len());
5725                    self.0.IASetVertexBuffers(
5726                        start_slot,
5727                        bufs.len() as u32,
5728                        bufs.as_ptr(),
5729                        strides.as_ptr(),
5730                        offsets.as_ptr(),
5731                    );
5732                }
5733            }
5734            fn map(
5735                &self,
5736                resource: &impl IResource,
5737                subresource: u32,
5738                map_type: MapType,
5739                map_flags: Option<MapFlag>,
5740            ) -> Result<MappedSubresource, HResult> {
5741                unsafe {
5742                    let mut mapped_subresource = Default::default();
5743                    let res = self.0.Map(
5744                        resource.as_ptr() as *mut _,
5745                        subresource,
5746                        map_type as u32,
5747                        map_flags.map_or(0, |f| f.0),
5748                        &mut mapped_subresource,
5749                    );
5750                    hresult(mapped_subresource.into(), res)
5751                }
5752            }
5753            fn om_get_blend_state(&self) -> Option<(BlendState, [f32; 4], u32)> {
5754                let mut blend_state = std::ptr::null_mut();
5755                let mut factor = [0.0f32; 4];
5756                let mut mask = 0;
5757                unsafe {
5758                    self.0
5759                        .OMGetBlendState(&mut blend_state, &mut factor, &mut mask);
5760                    if blend_state == std::ptr::null_mut() {
5761                        None
5762                    } else {
5763                        Some((BlendState(ComPtr::from_raw(blend_state)), factor, mask))
5764                    }
5765                }
5766            }
5767            fn om_get_depth_stencil_state(&self) -> (Option<DepthStencilState>, u32) {
5768                let mut state = std::ptr::null_mut();
5769                let mut stencil = 0;
5770                unsafe {
5771                    self.0.OMGetDepthStencilState(&mut state, &mut stencil);
5772                    let state = if state == std::ptr::null_mut() {
5773                        None
5774                    } else {
5775                        Some(DepthStencilState(ComPtr::from_raw(state)))
5776                    };
5777                    (state, stencil)
5778                }
5779            }
5780            fn om_get_render_targets(
5781                &self,
5782                num_views: u32,
5783            ) -> (Vec<Option<RenderTargetView>>, Option<DepthStencilView>) {
5784                unsafe {
5785                    let mut rtvs = Vec::with_capacity(num_views as usize);
5786                    rtvs.set_len(num_views as usize);
5787                    let mut dsv = std::ptr::null_mut();
5788                    self.0
5789                        .OMGetRenderTargets(num_views, rtvs.as_mut_ptr(), &mut dsv);
5790                    let rtvs = rtvs
5791                        .into_iter()
5792                        .map(|rtv| {
5793                            if rtv == std::ptr::null_mut() {
5794                                None
5795                            } else {
5796                                Some(RenderTargetView(ComPtr::from_raw(rtv)))
5797                            }
5798                        })
5799                        .collect::<Vec<_>>();
5800                    let dsv = if dsv == std::ptr::null_mut() {
5801                        None
5802                    } else {
5803                        Some(DepthStencilView(ComPtr::from_raw(dsv)))
5804                    };
5805                    (rtvs, dsv)
5806                }
5807            }
5808            // The argument of OMGetRenderTargetsAndUnorderedAccessViews is missing.
5809            /*
5810            fn om_get_render_targets_and_unordered_access_views(&self, num_rtvs: u32, uav_start_slot: u32, num_uavs: u32) -> (Vec<Option<RenderTargetView>>, Option<DepthStencilView>, Vec<Option<UnorderedAccessView>>) {
5811                unsafe {
5812                    let mut rtvs = Vec::with_capacity(num_rtvs as usize);
5813                    rtvs.set_len(num_rtvs as usize);
5814                    let mut dsv = std::ptr::null_mut();
5815                    let mut uavs = Vec::with_capacity(num_uavs as usize);
5816                    uavs.set_len(num_uavs as usize);
5817                    self.0.OMGetRenderTargetsAndUnorderedAccessViews(num_rtvs, rtvs.as_mut_ptr(), &mut dsv, uav_start_slot, num_uavs, uavs.as_mut_ptr());
5818                    let rtvs = rtvs.into_iter().map(|rtv| {
5819                        if rtv == std::ptr::null_mut() {
5820                            None
5821                        } else {
5822                            Some(RenderTargetView(ComPtr::from_raw(rtv)))
5823                        }
5824                    }).collect::<Vec<_>>();
5825                    let dsv = if dsv == std::ptr::null_mut() {
5826                        None
5827                    } else {
5828                        Some(DepthStencilView(ComPtr::from_raw(dsv)))
5829                    };
5830                    let uavs = uavs.into_iter().map(|uav| {
5831                        if uav == std::ptr::null_mut() {
5832                            None
5833                        } else {
5834                            Some(UnorderedAccessView(ComPtr::from_raw(uav)))
5835                        }
5836                    }).collect::<Vec<_>>();
5837                    (rtvs, dsv, uavs)
5838                }
5839            }
5840            */
5841            fn om_set_blend_state(&self, blend_state: &BlendState, factor: &[f32; 4], mask: u32) {
5842                unsafe {
5843                    self.0.OMSetBlendState(blend_state.as_ptr(), factor, mask);
5844                }
5845            }
5846            fn om_set_depth_stencil_state(&self, dss: &DepthStencilState, stencil_ref: u32) {
5847                unsafe {
5848                    self.0.OMSetDepthStencilState(dss.as_ptr(), stencil_ref);
5849                }
5850            }
5851            fn om_set_render_targets(
5852                &self,
5853                rtvs: Option<&[&RenderTargetView]>,
5854                dsv: Option<&DepthStencilView>,
5855            ) {
5856                let c_rtvs = rtvs.map(|r| r.iter().map(|rtv| rtv.as_ptr()).collect::<Vec<_>>());
5857                unsafe {
5858                    self.0.OMSetRenderTargets(
5859                        c_rtvs.as_ref().map_or(0, |r| r.len() as u32),
5860                        c_rtvs.as_ref().map_or(std::ptr::null(), |r| r.as_ptr()),
5861                        dsv.map_or(std::ptr::null_mut(), |d| d.as_ptr()),
5862                    );
5863                }
5864            }
5865            fn om_set_render_targets_and_unordered_access_views(
5866                &self,
5867                rtvs: Option<&[&RenderTargetView]>,
5868                dsv: Option<&DepthStencilView>,
5869                uav_start_slot: u32,
5870                uavs: Option<&[&UnorderedAccessView]>,
5871                initial_counts: Option<&[u32]>,
5872            ) {
5873                let c_rtvs = rtvs.map(|r| r.iter().map(|rtv| rtv.as_ptr()).collect::<Vec<_>>());
5874                let c_uavs = uavs.map(|r| r.iter().map(|uav| uav.as_ptr()).collect::<Vec<_>>());
5875                unsafe {
5876                    self.0.OMSetRenderTargetsAndUnorderedAccessViews(
5877                        c_rtvs.as_ref().map_or(0, |r| r.len() as u32),
5878                        c_rtvs.as_ref().map_or(std::ptr::null(), |r| r.as_ptr()),
5879                        dsv.map_or(std::ptr::null_mut(), |d| d.as_ptr()),
5880                        uav_start_slot,
5881                        c_uavs.as_ref().map_or(0, |u| u.len() as u32),
5882                        c_uavs.as_ref().map_or(std::ptr::null(), |u| u.as_ptr()),
5883                        initial_counts.map_or(std::ptr::null(), |ic| ic.as_ptr()),
5884                    );
5885                }
5886            }
5887            fn ps_get_constant_buffers(
5888                &self,
5889                start_slot: u32,
5890                num_buffers: u32,
5891            ) -> Vec<Option<Buffer>> {
5892                shader_get_objects(
5893                    |s, n, p| unsafe { self.0.PSGetConstantBuffers(s, n, p) },
5894                    start_slot,
5895                    num_buffers,
5896                )
5897            }
5898            fn ps_get_samplers(
5899                &self,
5900                start_slot: u32,
5901                num_samplers: u32,
5902            ) -> Vec<Option<SamplerState>> {
5903                shader_get_objects(
5904                    |s, n, p| unsafe { self.0.PSGetSamplers(s, n, p) },
5905                    start_slot,
5906                    num_samplers,
5907                )
5908            }
5909            fn ps_get_shader(&self) -> (Option<PixelShader>, Option<Vec<ClassInstance>>) {
5910                get_shader(|p, c, n| unsafe { self.0.PSGetShader(p, c, n) })
5911            }
5912            fn ps_get_shader_resources(
5913                &self,
5914                start_slot: u32,
5915                num_views: u32,
5916            ) -> Vec<Option<ShaderResourceView>> {
5917                shader_get_objects(
5918                    |s, n, p| unsafe { self.0.PSGetShaderResources(s, n, p) },
5919                    start_slot,
5920                    num_views,
5921                )
5922            }
5923            fn ps_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
5924                shader_set_objects(
5925                    |s, n, p| unsafe { self.0.PSSetConstantBuffers(s, n, p as *mut _) },
5926                    start_slot,
5927                    buffers,
5928                )
5929            }
5930            fn ps_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]) {
5931                shader_set_objects(
5932                    |s, n, p| unsafe { self.0.PSSetSamplers(s, n, p) },
5933                    start_slot,
5934                    samplers,
5935                )
5936            }
5937            fn ps_set_shader(&self, shader: &PixelShader, instances: Option<&[&ClassInstance]>) {
5938                set_shader(
5939                    |p, c, n| unsafe { self.0.PSSetShader(p, c, n) },
5940                    shader,
5941                    instances,
5942                )
5943            }
5944            fn ps_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
5945                shader_set_objects(
5946                    |s, n, p| unsafe { self.0.PSSetShaderResources(s, n, p) },
5947                    start_slot,
5948                    views,
5949                )
5950            }
5951            fn resolve_subresource(
5952                &self,
5953                dest: &impl IResource,
5954                dest_subresource: u32,
5955                src: &impl IResource,
5956                src_subresource: u32,
5957                format: dxgi::Format,
5958            ) {
5959                unsafe {
5960                    self.0.ResolveSubresource(
5961                        dest.as_ptr() as *mut _,
5962                        dest_subresource,
5963                        src.as_ptr() as *mut _,
5964                        src_subresource,
5965                        format as u32,
5966                    );
5967                }
5968            }
5969            fn rs_get_scissor_rects(&self) -> Vec<Rect<i32>> {
5970                unsafe {
5971                    let mut sz = 0;
5972                    self.0.RSGetScissorRects(&mut sz, std::ptr::null_mut());
5973                    if sz == 0 {
5974                        return Vec::new();
5975                    }
5976                    let mut rcs = Vec::with_capacity(sz as usize);
5977                    rcs.set_len(sz as usize);
5978                    self.0.RSGetScissorRects(&mut sz, rcs.as_mut_ptr());
5979                    rcs.into_iter().map(|rc| rc.into()).collect::<Vec<_>>()
5980                }
5981            }
5982            fn rs_get_state(&self) -> Option<RasterizerState> {
5983                unsafe {
5984                    let mut obj = std::ptr::null_mut();
5985                    self.0.RSGetState(&mut obj);
5986                    if obj == std::ptr::null_mut() {
5987                        None
5988                    } else {
5989                        Some(RasterizerState(ComPtr::from_raw(obj)))
5990                    }
5991                }
5992            }
5993            fn rs_get_viewports(&self) -> Vec<Viewport> {
5994                unsafe {
5995                    let mut sz = 0;
5996                    self.0.RSGetViewports(&mut sz, std::ptr::null_mut());
5997                    if sz == 0 {
5998                        return Vec::new();
5999                    }
6000                    let mut vps = Vec::with_capacity(sz as usize);
6001                    vps.set_len(sz as usize);
6002                    self.0.RSGetViewports(&mut sz, vps.as_mut_ptr());
6003                    vps.into_iter().map(|vp| vp.into()).collect::<Vec<_>>()
6004                }
6005            }
6006            fn rs_set_scissor_rects(&self, rects: &[Rect<i32>]) {
6007                unsafe {
6008                    self.0
6009                        .RSSetScissorRects(rects.len() as u32, rects.as_ptr() as *const RECT);
6010                }
6011            }
6012            fn rs_set_state(&self, rasterizer_state: &RasterizerState) {
6013                unsafe {
6014                    self.0.RSSetState(rasterizer_state.as_ptr());
6015                }
6016            }
6017            fn rs_set_viewports(&self, viewports: &[Viewport]) {
6018                unsafe {
6019                    self.0.RSSetViewports(
6020                        viewports.len() as u32,
6021                        viewports.as_ptr() as *const D3D11_VIEWPORT,
6022                    );
6023                }
6024            }
6025            fn set_predication(&self, predicate: Option<&Predicate>, value: bool) {
6026                unsafe {
6027                    self.0.SetPredication(
6028                        predicate.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
6029                        to_BOOL(value),
6030                    );
6031                }
6032            }
6033            fn set_resource_min_lod(&self, resource: &impl IResource, min_lod: f32) {
6034                unsafe {
6035                    self.0
6036                        .SetResourceMinLOD(resource.as_ptr() as *mut _, min_lod);
6037                }
6038            }
6039            fn so_get_targets(&self, num: u32) -> Vec<Option<Buffer>> {
6040                unsafe {
6041                    let mut bufs = Vec::with_capacity(num as usize);
6042                    bufs.set_len(num as usize);
6043                    self.0.SOGetTargets(num, bufs.as_mut_ptr());
6044                    bufs.into_iter()
6045                        .map(|p| {
6046                            if p == std::ptr::null_mut() {
6047                                None
6048                            } else {
6049                                Some(Buffer(ComPtr::from_raw(p)))
6050                            }
6051                        })
6052                        .collect::<Vec<_>>()
6053                }
6054            }
6055            fn so_set_targets(&self, targets: &[&impl IBuffer], offset: &[u32]) {
6056                let c_targets = targets
6057                    .iter()
6058                    .map(|t| t.as_ptr() as *mut _)
6059                    .collect::<Vec<_>>();
6060                unsafe {
6061                    self.0.SOSetTargets(
6062                        c_targets.len() as u32,
6063                        c_targets.as_ptr(),
6064                        offset.as_ptr(),
6065                    );
6066                }
6067            }
6068            fn unmap(&self, resource: &impl IResource, subresource: u32) {
6069                unsafe {
6070                    self.0.Unmap(resource.as_ptr() as *mut _, subresource);
6071                }
6072            }
6073            fn update_subresource(
6074                &self,
6075                dest: &impl IResource,
6076                dest_subresource: u32,
6077                dest_box: Option<&Box3D>,
6078                src: &[u8],
6079                src_row_pitch: u32,
6080                src_depth_pitch: u32,
6081            ) {
6082                unsafe {
6083                    self.0.UpdateSubresource(
6084                        dest.as_ptr() as *mut _,
6085                        dest_subresource,
6086                        dest_box.map_or(std::ptr::null(), |b| b.as_c_ptr()),
6087                        src.as_ptr() as *const c_void,
6088                        src_row_pitch,
6089                        src_depth_pitch,
6090                    );
6091                }
6092            }
6093            fn vs_get_constant_buffers(
6094                &self,
6095                start_slot: u32,
6096                num_buffers: u32,
6097            ) -> Vec<Option<Buffer>> {
6098                shader_get_objects(
6099                    |s, n, p| unsafe { self.0.VSGetConstantBuffers(s, n, p) },
6100                    start_slot,
6101                    num_buffers,
6102                )
6103            }
6104            fn vs_get_samplers(
6105                &self,
6106                start_slot: u32,
6107                num_samplers: u32,
6108            ) -> Vec<Option<SamplerState>> {
6109                shader_get_objects(
6110                    |s, n, p| unsafe { self.0.VSGetSamplers(s, n, p) },
6111                    start_slot,
6112                    num_samplers,
6113                )
6114            }
6115            fn vs_get_shader(&self) -> (Option<VertexShader>, Option<Vec<ClassInstance>>) {
6116                get_shader(|p, c, n| unsafe { self.0.VSGetShader(p, c, n) })
6117            }
6118            fn vs_get_shader_resources(
6119                &self,
6120                start_slot: u32,
6121                num_views: u32,
6122            ) -> Vec<Option<ShaderResourceView>> {
6123                shader_get_objects(
6124                    |s, n, p| unsafe { self.0.VSGetShaderResources(s, n, p) },
6125                    start_slot,
6126                    num_views,
6127                )
6128            }
6129            fn vs_set_constant_buffers(&self, start_slot: u32, buffers: &[&impl IBuffer]) {
6130                shader_set_objects(
6131                    |s, n, p| unsafe { self.0.VSSetConstantBuffers(s, n, p as *mut _) },
6132                    start_slot,
6133                    buffers,
6134                )
6135            }
6136            fn vs_set_samplers(&self, start_slot: u32, samplers: &[&SamplerState]) {
6137                shader_set_objects(
6138                    |s, n, p| unsafe { self.0.VSSetSamplers(s, n, p) },
6139                    start_slot,
6140                    samplers,
6141                )
6142            }
6143            fn vs_set_shader(&self, shader: &VertexShader, instances: Option<&[&ClassInstance]>) {
6144                set_shader(
6145                    |p, c, n| unsafe { self.0.VSSetShader(p, c, n) },
6146                    shader,
6147                    instances,
6148                )
6149            }
6150            fn vs_set_shader_resources(&self, start_slot: u32, views: &[&ShaderResourceView]) {
6151                shader_set_objects(
6152                    |s, n, p| unsafe { self.0.VSSetShaderResources(s, n, p) },
6153                    start_slot,
6154                    views,
6155                )
6156            }
6157        }
6158    };
6159}
6160impl_devicecontext!(DeviceContext, ID3D11DeviceContext);
6161
6162pub trait IDomainShader: IDeviceChild {}
6163#[derive(Clone, Debug)]
6164pub struct DomainShader(ComPtr<ID3D11DomainShader>);
6165macro_rules! impl_domainshader {
6166    ($s: ident, $interface: ident) => {
6167        impl_devicechild!($s, $interface);
6168        impl IDomainShader for $s {}
6169    };
6170}
6171impl_domainshader!(DomainShader, ID3D11DomainShader);
6172
6173pub trait IGeometryShader: IDeviceChild {}
6174#[derive(Clone, Debug)]
6175pub struct GeometryShader(ComPtr<ID3D11GeometryShader>);
6176macro_rules! impl_geometryshader {
6177    ($s: ident, $interface: ident) => {
6178        impl_devicechild!($s, $interface);
6179        impl IGeometryShader for $s {}
6180    };
6181}
6182impl_geometryshader!(GeometryShader, ID3D11GeometryShader);
6183
6184pub trait IHullShader: IDeviceChild {}
6185#[derive(Clone, Debug)]
6186pub struct HullShader(ComPtr<ID3D11HullShader>);
6187macro_rules! impl_hullshader {
6188    ($s: ident, $interface: ident) => {
6189        impl_devicechild!($s, $interface);
6190        impl IHullShader for $s {}
6191    };
6192}
6193impl_hullshader!(HullShader, ID3D11HullShader);
6194
6195pub trait IInputLayout: IDeviceChild {}
6196#[derive(Clone, Debug)]
6197pub struct InputLayout(ComPtr<ID3D11InputLayout>);
6198macro_rules! impl_inputlayout {
6199    ($s: ident, $interface: ident) => {
6200        impl_devicechild!($s, $interface);
6201        impl IInputLayout for $s {}
6202    };
6203}
6204impl_inputlayout!(InputLayout, ID3D11InputLayout);
6205
6206pub trait IPixelShader: IDeviceChild {}
6207#[derive(Clone, Debug)]
6208pub struct PixelShader(ComPtr<ID3D11PixelShader>);
6209macro_rules! impl_pixelshader {
6210    ($s: ident, $interface: ident) => {
6211        impl_devicechild!($s, $interface);
6212        impl IPixelShader for $s {}
6213    };
6214}
6215impl_pixelshader!(PixelShader, ID3D11PixelShader);
6216
6217pub trait IQuery: IAsynchronous {
6218    fn get_desc(&self) -> QueryDesc;
6219}
6220#[derive(Clone, Debug)]
6221pub struct Query(ComPtr<ID3D11Query>);
6222macro_rules! impl_query {
6223    ($s: ident, $interface: ident) => {
6224        impl_asynchronous!($s, $interface);
6225        impl IQuery for $s {
6226            fn get_desc(&self) -> QueryDesc {
6227                let mut desc = Default::default();
6228                unsafe { self.0.GetDesc(&mut desc) };
6229                desc.into()
6230            }
6231        }
6232    };
6233}
6234impl_query!(Query, ID3D11Query);
6235
6236pub trait IPredicate: IQuery {}
6237#[derive(Clone, Debug)]
6238pub struct Predicate(ComPtr<ID3D11Predicate>);
6239macro_rules! impl_predicate {
6240    ($s: ident, $interface: ident) => {
6241        impl_query!($s, $interface);
6242        impl IPredicate for $s {}
6243    };
6244}
6245impl_predicate!(Predicate, ID3D11Predicate);
6246
6247pub trait IRasterizerState: IDeviceChild {
6248    fn get_desc(&self) -> RasterizerDesc;
6249}
6250#[derive(Clone, Debug)]
6251pub struct RasterizerState(ComPtr<ID3D11RasterizerState>);
6252macro_rules! impl_rasterizerState {
6253    ($s: ident, $interface: ident) => {
6254        impl_devicechild!($s, $interface);
6255        impl IRasterizerState for $s {
6256            fn get_desc(&self) -> RasterizerDesc {
6257                let mut desc = Default::default();
6258                unsafe { self.0.GetDesc(&mut desc) };
6259                desc.into()
6260            }
6261        }
6262    };
6263}
6264impl_rasterizerState!(RasterizerState, ID3D11RasterizerState);
6265
6266pub trait IRenderTargetView: IView {
6267    fn get_desc(&self) -> RenderTargetViewDesc;
6268}
6269#[derive(Clone, Debug)]
6270pub struct RenderTargetView(ComPtr<ID3D11RenderTargetView>);
6271macro_rules! impl_rendertargetview {
6272    ($s: ident, $interface: ident) => {
6273        impl_view!($s, $interface);
6274        impl IRenderTargetView for $s {
6275            fn get_desc(&self) -> RenderTargetViewDesc {
6276                let mut desc = Default::default();
6277                unsafe { self.0.GetDesc(&mut desc) };
6278                desc.into()
6279            }
6280        }
6281    };
6282}
6283impl_rendertargetview!(RenderTargetView, ID3D11RenderTargetView);
6284
6285pub trait ISamplerState: IDeviceChild {
6286    fn get_desc(&self) -> SamplerDesc<Filter>;
6287}
6288#[derive(Clone, Debug)]
6289pub struct SamplerState(ComPtr<ID3D11SamplerState>);
6290macro_rules! impl_samplerstate {
6291    ($s: ident, $interface: ident) => {
6292        impl_devicechild!($s, $interface);
6293        impl ISamplerState for $s {
6294            fn get_desc(&self) -> SamplerDesc<Filter> {
6295                let mut desc = Default::default();
6296                unsafe { self.0.GetDesc(&mut desc) };
6297                desc.into()
6298            }
6299        }
6300    };
6301}
6302impl_samplerstate!(SamplerState, ID3D11SamplerState);
6303
6304pub trait IShaderResourceView: IView {
6305    fn get_desc(&self) -> ShaderResourceViewDesc;
6306}
6307#[derive(Clone, Debug)]
6308pub struct ShaderResourceView(ComPtr<ID3D11ShaderResourceView>);
6309macro_rules! impl_shader_resource_view {
6310    ($s: ident, $interface: ident) => {
6311        impl_view!($s, $interface);
6312        impl IShaderResourceView for $s {
6313            fn get_desc(&self) -> ShaderResourceViewDesc {
6314                let mut desc = Default::default();
6315                unsafe { self.0.GetDesc(&mut desc) };
6316                desc.into()
6317            }
6318        }
6319    };
6320}
6321impl_shader_resource_view!(ShaderResourceView, ID3D11ShaderResourceView);
6322
6323pub trait ITexture1D: IResource {
6324    fn get_desc(&self) -> Texture1DDesc<u32, dxgi::Format, Usage>;
6325}
6326#[derive(Clone, Debug)]
6327pub struct Texture1D(ComPtr<ID3D11Texture1D>);
6328macro_rules! impl_texture1d {
6329    ($s: ident, $interface: ident) => {
6330        impl_resource!($s, $interface);
6331        impl ITexture1D for $s {
6332            fn get_desc(&self) -> Texture1DDesc<u32, dxgi::Format, Usage> {
6333                let mut desc = Default::default();
6334                unsafe { self.0.GetDesc(&mut desc) };
6335                desc.into()
6336            }
6337        }
6338    };
6339}
6340impl_texture1d!(Texture1D, ID3D11Texture1D);
6341
6342pub trait ITexture2D: IResource {
6343    fn get_desc(&self) -> Texture2DDesc<u32, u32, dxgi::Format, Usage>;
6344}
6345#[derive(Clone, Debug)]
6346pub struct Texture2D(ComPtr<ID3D11Texture2D>);
6347macro_rules! impl_texture2d {
6348    ($s: ident, $interface: ident) => {
6349        impl_resource!($s, $interface);
6350        impl ITexture2D for $s {
6351            fn get_desc(&self) -> Texture2DDesc<u32, u32, dxgi::Format, Usage> {
6352                let mut desc = Default::default();
6353                unsafe { self.0.GetDesc(&mut desc) };
6354                desc.into()
6355            }
6356        }
6357    };
6358}
6359impl_texture2d!(Texture2D, ID3D11Texture2D);
6360
6361pub trait ITexture3D: IResource {
6362    fn get_desc(&self) -> Texture3DDesc<u32, u32, u32, dxgi::Format, Usage>;
6363}
6364#[derive(Clone, Debug)]
6365pub struct Texture3D(ComPtr<ID3D11Texture3D>);
6366macro_rules! impl_texture3d {
6367    ($s: ident, $interface: ident) => {
6368        impl_resource!($s, $interface);
6369        impl ITexture3D for $s {
6370            fn get_desc(&self) -> Texture3DDesc<u32, u32, u32, dxgi::Format, Usage> {
6371                let mut desc = Default::default();
6372                unsafe { self.0.GetDesc(&mut desc) };
6373                desc.into()
6374            }
6375        }
6376    };
6377}
6378impl_texture3d!(Texture3D, ID3D11Texture3D);
6379
6380pub trait IUnorderedAccessView: IView {
6381    fn get_desc(&self) -> UnorderedAccessViewDesc;
6382}
6383#[derive(Clone, Debug)]
6384pub struct UnorderedAccessView(ComPtr<ID3D11UnorderedAccessView>);
6385macro_rules! impl_unordered_access_view {
6386    ($s: ident, $interface: ident) => {
6387        impl_view!($s, $interface);
6388        impl IUnorderedAccessView for $s {
6389            fn get_desc(&self) -> UnorderedAccessViewDesc {
6390                let mut desc = Default::default();
6391                unsafe { self.0.GetDesc(&mut desc) };
6392                desc.into()
6393            }
6394        }
6395    };
6396}
6397impl_unordered_access_view!(UnorderedAccessView, ID3D11UnorderedAccessView);
6398
6399pub trait IVertexShader: IDeviceChild {}
6400#[derive(Clone, Debug)]
6401pub struct VertexShader(ComPtr<ID3D11VertexShader>);
6402macro_rules! impl_vertexshader {
6403    ($s: ident, $interface: ident) => {
6404        impl_devicechild!($s, $interface);
6405        impl IVertexShader for $s {}
6406    };
6407}
6408impl_vertexshader!(VertexShader, ID3D11VertexShader);
6409
6410pub fn calc_subresource(mip_slice: u32, array_slice: u32, mip_levels: u32) -> u32 {
6411    D3D11CalcSubresource(mip_slice, array_slice, mip_levels)
6412}
6413
6414pub fn create_device(
6415    adapter: Option<&dxgi::Adapter>,
6416    driver_type: d3d::DriverType,
6417    software: Option<winapi::shared::minwindef::HMODULE>,
6418    flags: Option<CreateDeviceFlags>,
6419    feature_levels: &[d3d::FeatureLevel],
6420) -> Result<(Device, d3d::FeatureLevel, DeviceContext), HResult> {
6421    unsafe {
6422        let mut device = std::ptr::null_mut();
6423        let mut level = 0;
6424        let mut device_context = std::ptr::null_mut();
6425        let c_feature_levels = feature_levels.iter().map(|&l| l.into()).collect::<Vec<_>>();
6426        let res = D3D11CreateDevice(
6427            adapter.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
6428            driver_type as u32,
6429            software.unwrap_or(std::ptr::null_mut()),
6430            flags.map_or(0, |f| f.0 as u32),
6431            c_feature_levels.as_ptr(),
6432            c_feature_levels.len() as u32,
6433            D3D11_SDK_VERSION,
6434            &mut device,
6435            &mut level,
6436            &mut device_context,
6437        );
6438        if res < 0 {
6439            return Err(res.into());
6440        }
6441        Ok((
6442            Device(ComPtr::from_raw(device)),
6443            level.into(),
6444            DeviceContext(ComPtr::from_raw(device_context)),
6445        ))
6446    }
6447}
6448
6449pub fn create_device_and_swap_chain(
6450    adapter: Option<&dxgi::Adapter>,
6451    driver_type: d3d::DriverType,
6452    software: Option<winapi::shared::minwindef::HMODULE>,
6453    flags: Option<CreateDeviceFlags>,
6454    feature_levels: &[d3d::FeatureLevel],
6455    swap_chain_desc: &dxgi::SwapChainDesc<
6456        dxgi::ModeDesc<u32, u32, dxgi::Rational, dxgi::Format>,
6457        dxgi::Usage,
6458        u32,
6459        *const std::ffi::c_void,
6460        bool,
6461        dxgi::SwapEffect,
6462    >,
6463) -> Result<(dxgi::SwapChain, Device, d3d::FeatureLevel, DeviceContext), HResult> {
6464    unsafe {
6465        let mut swap_chain = std::ptr::null_mut();
6466        let mut device = std::ptr::null_mut();
6467        let mut level = 0;
6468        let mut device_context = std::ptr::null_mut();
6469        let c_feature_levels = feature_levels.iter().map(|&l| l.into()).collect::<Vec<_>>();
6470        let res = D3D11CreateDeviceAndSwapChain(
6471            adapter.map_or(std::ptr::null_mut(), |p| p.as_ptr()),
6472            driver_type as u32,
6473            software.unwrap_or(std::ptr::null_mut()),
6474            flags.map_or(0, |f| f.0 as u32),
6475            c_feature_levels.as_ptr(),
6476            c_feature_levels.len() as u32,
6477            D3D11_SDK_VERSION,
6478            &swap_chain_desc.to_c_struct(),
6479            &mut swap_chain,
6480            &mut device,
6481            &mut level,
6482            &mut device_context,
6483        );
6484        if res < 0 {
6485            return Err(res.into());
6486        }
6487        Ok((
6488            dxgi::SwapChain(ComPtr::from_raw(swap_chain)),
6489            Device(ComPtr::from_raw(device)),
6490            level.into(),
6491            DeviceContext(ComPtr::from_raw(device_context)),
6492        ))
6493    }
6494}