mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
347 lines
9.6 KiB
Rust
347 lines
9.6 KiB
Rust
//! Device
|
|
|
|
use com::WeakPtr;
|
|
use command_list::{CmdListType, CommandSignature, IndirectArgument};
|
|
use descriptor::{CpuDescriptor, DescriptorHeapFlags, DescriptorHeapType, RenderTargetViewDesc};
|
|
use heap::{Heap, HeapFlags, HeapProperties};
|
|
use std::ops::Range;
|
|
use winapi::um::d3d12;
|
|
use winapi::Interface;
|
|
use {pso, query, queue};
|
|
use {
|
|
Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, Fence,
|
|
GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature, Shader,
|
|
TextureAddressMode,
|
|
};
|
|
|
|
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)
|
|
}
|
|
}
|