summaryrefslogtreecommitdiffstats
path: root/third_party/rust/d3d12/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/d3d12/src/device.rs344
1 files changed, 344 insertions, 0 deletions
diff --git a/third_party/rust/d3d12/src/device.rs b/third_party/rust/d3d12/src/device.rs
new file mode 100644
index 0000000000..188eb40b1d
--- /dev/null
+++ b/third_party/rust/d3d12/src/device.rs
@@ -0,0 +1,344 @@
+//! Device
+
+use crate::{
+ com::WeakPtr,
+ command_list::{CmdListType, CommandSignature, IndirectArgument},
+ descriptor::{CpuDescriptor, DescriptorHeapFlags, DescriptorHeapType, RenderTargetViewDesc},
+ heap::{Heap, HeapFlags, HeapProperties},
+ pso, query, queue, Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap,
+ Fence, GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature,
+ Shader, TextureAddressMode,
+};
+use std::ops::Range;
+use winapi::{um::d3d12, Interface};
+
+pub type Device = WeakPtr<d3d12::ID3D12Device>;
+
+#[cfg(feature = "libloading")]
+impl crate::D3D12Lib {
+ pub fn create_device<I: Interface>(
+ &self,
+ adapter: WeakPtr<I>,
+ feature_level: crate::FeatureLevel,
+ ) -> Result<D3DResult<Device>, libloading::Error> {
+ type Fun = extern "system" fn(
+ *mut winapi::um::unknwnbase::IUnknown,
+ winapi::um::d3dcommon::D3D_FEATURE_LEVEL,
+ winapi::shared::guiddef::REFGUID,
+ *mut *mut winapi::ctypes::c_void,
+ ) -> crate::HRESULT;
+
+ let mut device = Device::null();
+ let hr = unsafe {
+ let func: libloading::Symbol<Fun> = self.lib.get(b"D3D12CreateDevice")?;
+ func(
+ adapter.as_unknown() as *const _ as *mut _,
+ feature_level as _,
+ &d3d12::ID3D12Device::uuidof(),
+ device.mut_void(),
+ )
+ };
+
+ Ok((device, hr))
+ }
+}
+
+impl Device {
+ #[cfg(feature = "implicit-link")]
+ pub fn create<I: Interface>(
+ adapter: WeakPtr<I>,
+ feature_level: crate::FeatureLevel,
+ ) -> D3DResult<Self> {
+ let mut device = Device::null();
+ let hr = unsafe {
+ d3d12::D3D12CreateDevice(
+ adapter.as_unknown() as *const _ as *mut _,
+ feature_level as _,
+ &d3d12::ID3D12Device::uuidof(),
+ device.mut_void(),
+ )
+ };
+
+ (device, hr)
+ }
+
+ pub fn create_heap(
+ &self,
+ size_in_bytes: u64,
+ properties: HeapProperties,
+ alignment: u64,
+ flags: HeapFlags,
+ ) -> D3DResult<Heap> {
+ let mut heap = Heap::null();
+
+ let desc = d3d12::D3D12_HEAP_DESC {
+ SizeInBytes: size_in_bytes,
+ Properties: properties.0,
+ Alignment: alignment,
+ Flags: flags.bits(),
+ };
+
+ let hr = unsafe { self.CreateHeap(&desc, &d3d12::ID3D12Heap::uuidof(), heap.mut_void()) };
+
+ (heap, hr)
+ }
+
+ pub fn create_command_allocator(&self, list_type: CmdListType) -> D3DResult<CommandAllocator> {
+ let mut allocator = CommandAllocator::null();
+ let hr = unsafe {
+ self.CreateCommandAllocator(
+ list_type as _,
+ &d3d12::ID3D12CommandAllocator::uuidof(),
+ allocator.mut_void(),
+ )
+ };
+
+ (allocator, hr)
+ }
+
+ pub fn create_command_queue(
+ &self,
+ list_type: CmdListType,
+ priority: queue::Priority,
+ flags: queue::CommandQueueFlags,
+ node_mask: NodeMask,
+ ) -> D3DResult<CommandQueue> {
+ let desc = d3d12::D3D12_COMMAND_QUEUE_DESC {
+ Type: list_type as _,
+ Priority: priority as _,
+ Flags: flags.bits(),
+ NodeMask: node_mask,
+ };
+
+ let mut queue = CommandQueue::null();
+ let hr = unsafe {
+ self.CreateCommandQueue(
+ &desc,
+ &d3d12::ID3D12CommandQueue::uuidof(),
+ queue.mut_void(),
+ )
+ };
+
+ (queue, hr)
+ }
+
+ pub fn create_descriptor_heap(
+ &self,
+ num_descriptors: u32,
+ heap_type: DescriptorHeapType,
+ flags: DescriptorHeapFlags,
+ node_mask: NodeMask,
+ ) -> D3DResult<DescriptorHeap> {
+ let desc = d3d12::D3D12_DESCRIPTOR_HEAP_DESC {
+ Type: heap_type as _,
+ NumDescriptors: num_descriptors,
+ Flags: flags.bits(),
+ NodeMask: node_mask,
+ };
+
+ let mut heap = DescriptorHeap::null();
+ let hr = unsafe {
+ self.CreateDescriptorHeap(
+ &desc,
+ &d3d12::ID3D12DescriptorHeap::uuidof(),
+ heap.mut_void(),
+ )
+ };
+
+ (heap, hr)
+ }
+
+ pub fn get_descriptor_increment_size(&self, heap_type: DescriptorHeapType) -> u32 {
+ unsafe { self.GetDescriptorHandleIncrementSize(heap_type as _) }
+ }
+
+ pub fn create_graphics_command_list(
+ &self,
+ list_type: CmdListType,
+ allocator: CommandAllocator,
+ initial: PipelineState,
+ node_mask: NodeMask,
+ ) -> D3DResult<GraphicsCommandList> {
+ let mut command_list = GraphicsCommandList::null();
+ let hr = unsafe {
+ self.CreateCommandList(
+ node_mask,
+ list_type as _,
+ allocator.as_mut_ptr(),
+ initial.as_mut_ptr(),
+ &d3d12::ID3D12GraphicsCommandList::uuidof(),
+ command_list.mut_void(),
+ )
+ };
+
+ (command_list, hr)
+ }
+
+ pub fn create_query_heap(
+ &self,
+ heap_ty: query::QueryHeapType,
+ count: u32,
+ node_mask: NodeMask,
+ ) -> D3DResult<QueryHeap> {
+ let desc = d3d12::D3D12_QUERY_HEAP_DESC {
+ Type: heap_ty as _,
+ Count: count,
+ NodeMask: node_mask,
+ };
+
+ let mut query_heap = QueryHeap::null();
+ let hr = unsafe {
+ self.CreateQueryHeap(
+ &desc,
+ &d3d12::ID3D12QueryHeap::uuidof(),
+ query_heap.mut_void(),
+ )
+ };
+
+ (query_heap, hr)
+ }
+
+ pub fn create_graphics_pipeline_state(
+ &self,
+ _root_signature: RootSignature,
+ _vs: Shader,
+ _ps: Shader,
+ _gs: Shader,
+ _hs: Shader,
+ _ds: Shader,
+ _node_mask: NodeMask,
+ _cached_pso: CachedPSO,
+ _flags: pso::PipelineStateFlags,
+ ) -> D3DResult<PipelineState> {
+ unimplemented!()
+ }
+
+ pub fn create_compute_pipeline_state(
+ &self,
+ root_signature: RootSignature,
+ cs: Shader,
+ node_mask: NodeMask,
+ cached_pso: CachedPSO,
+ flags: pso::PipelineStateFlags,
+ ) -> D3DResult<PipelineState> {
+ let mut pipeline = PipelineState::null();
+ let desc = d3d12::D3D12_COMPUTE_PIPELINE_STATE_DESC {
+ pRootSignature: root_signature.as_mut_ptr(),
+ CS: *cs,
+ NodeMask: node_mask,
+ CachedPSO: *cached_pso,
+ Flags: flags.bits(),
+ };
+
+ let hr = unsafe {
+ self.CreateComputePipelineState(
+ &desc,
+ &d3d12::ID3D12PipelineState::uuidof(),
+ pipeline.mut_void(),
+ )
+ };
+
+ (pipeline, hr)
+ }
+
+ pub fn create_sampler(
+ &self,
+ sampler: CpuDescriptor,
+ filter: d3d12::D3D12_FILTER,
+ address_mode: TextureAddressMode,
+ mip_lod_bias: f32,
+ max_anisotropy: u32,
+ comparison_op: d3d12::D3D12_COMPARISON_FUNC,
+ border_color: [f32; 4],
+ lod: Range<f32>,
+ ) {
+ let desc = d3d12::D3D12_SAMPLER_DESC {
+ Filter: filter,
+ AddressU: address_mode[0],
+ AddressV: address_mode[1],
+ AddressW: address_mode[2],
+ MipLODBias: mip_lod_bias,
+ MaxAnisotropy: max_anisotropy,
+ ComparisonFunc: comparison_op,
+ BorderColor: border_color,
+ MinLOD: lod.start,
+ MaxLOD: lod.end,
+ };
+
+ unsafe {
+ self.CreateSampler(&desc, sampler);
+ }
+ }
+
+ pub fn create_root_signature(
+ &self,
+ blob: Blob,
+ node_mask: NodeMask,
+ ) -> D3DResult<RootSignature> {
+ let mut signature = RootSignature::null();
+ let hr = unsafe {
+ self.CreateRootSignature(
+ node_mask,
+ blob.GetBufferPointer(),
+ blob.GetBufferSize(),
+ &d3d12::ID3D12RootSignature::uuidof(),
+ signature.mut_void(),
+ )
+ };
+
+ (signature, hr)
+ }
+
+ pub fn create_command_signature(
+ &self,
+ root_signature: RootSignature,
+ arguments: &[IndirectArgument],
+ stride: u32,
+ node_mask: NodeMask,
+ ) -> D3DResult<CommandSignature> {
+ let mut signature = CommandSignature::null();
+ let desc = d3d12::D3D12_COMMAND_SIGNATURE_DESC {
+ ByteStride: stride,
+ NumArgumentDescs: arguments.len() as _,
+ pArgumentDescs: arguments.as_ptr() as *const _,
+ NodeMask: node_mask,
+ };
+
+ let hr = unsafe {
+ self.CreateCommandSignature(
+ &desc,
+ root_signature.as_mut_ptr(),
+ &d3d12::ID3D12CommandSignature::uuidof(),
+ signature.mut_void(),
+ )
+ };
+
+ (signature, hr)
+ }
+
+ pub fn create_render_target_view(
+ &self,
+ resource: Resource,
+ desc: &RenderTargetViewDesc,
+ descriptor: CpuDescriptor,
+ ) {
+ unsafe {
+ self.CreateRenderTargetView(resource.as_mut_ptr(), &desc.0 as *const _, descriptor);
+ }
+ }
+
+ // TODO: interface not complete
+ pub fn create_fence(&self, initial: u64) -> D3DResult<Fence> {
+ let mut fence = Fence::null();
+ let hr = unsafe {
+ self.CreateFence(
+ initial,
+ d3d12::D3D12_FENCE_FLAG_NONE,
+ &d3d12::ID3D12Fence::uuidof(),
+ fence.mut_void(),
+ )
+ };
+
+ (fence, hr)
+ }
+}