Home

Awesome

Documentation Crates.io

rusty-d3d12

This project provides low-level bindings for D3D12 API. It utilizes rust-bindgen for generating raw bindings (unlike d3d12-rs crate), but aims for providing idiomatic APIs (unlike the raw D3D12 wrappers from winapi or windows-rs crates).

Features

Examples

let debug_controller = Debug::new().expect("cannot create debug controller");
debug_controller.enable_debug_layer();
debug_controller.enable_gpu_based_validation();
debug_controller.enable_object_auto_name();
let rtv_heap = device
    .create_descriptor_heap(
        &DescriptorHeapDesc::default()
            .with_heap_type(DescriptorHeapType::Rtv)
            .with_num_descriptors(FRAMES_IN_FLIGHT),
    )
    .expect("Cannot create RTV heap");
rtv_heap
    .set_name("RTV heap")
    .expect("Cannot set RTV heap name");
let mut feature_data = FeatureDataOptions::default();
device
    .check_feature_support(Feature::D3D12Options, &mut feature_data)
    .expect("Cannot check feature support");

let cross_adapter_textures_supported = feature_data.cross_adapter_row_major_texture_supported();
let ms_bytecode = ShaderBytecode::new(&mesh_shader);
let ps_bytecode = ShaderBytecode::new(&pixel_shader);

let pso_subobjects_desc = MeshShaderPipelineStateDesc::default()
    .with_root_signature(root_signature)
    .with_ms_bytecode(&ms_bytecode)
    .with_ps_bytecode(&ps_bytecode)
    .with_rasterizer_state(
        RasterizerDesc::default().with_depth_clip_enable(false),
    )
    .with_blend_state(BlendDesc::default())
    .with_depth_stencil_state(
        DepthStencilDesc::default().with_depth_enable(false),
    )
    .with_primitive_topology_type(PrimitiveTopologyType::Triangle)
    .with_rtv_formats(&[Format::R8G8B8A8Unorm]);

let pso_desc = PipelineStateStreamDesc::default()
    .with_pipeline_state_subobject_stream(
        pso_subobjects_desc.as_byte_stream(),
    );

let pso = device
    .create_pipeline_state(&pso_desc)
    .expect("Cannot create PSO");

Several runnable samples can be found in examples directory. Please note their code can be dirty and contains some (non-critical) bugs, so they should not be treated as sane D3D12 tutorials or high-quality Rust code examples since their purpose is just to showcase the API.

Currently implemented examples include:

The next planned goal for this project is to cover DXR APIs and provide the corresponding samples.

API stability

Currently the library is under active development, so breaking changes can happen between minor releases (but should not happen between patch releases). After publishing version 1.0 standard semantic versioning will be applied.

Making changes

As mentioned above, the library is still a work-in-progress, so all contributions are welcome :)

How to add a struct or enum that is missing

If the type in question is already present in the pre-generated d3d12.rs, you can use conversion_assist.py script to generate most (or sometimes all) of the code for you.

How to add a missing function

Unfortunately conversion_assist.py doesn't support generating function definitions yet, so it should be done manually :( Please refer to lib.rs for examples.

Running rust-bindgen

If the required function or type is not yet present in the shipped d3d12.rs (i.e. the new Agility SDK has come out but has not been integrated into rusty-d3d12 yet), then running rust-bindgen on the workspace is required after updating Agility SDK.

When used as a Cargo dependency, rusty-d3d12 does not generate bindings during build process by default (besides increasing build times, running rust-bindgen requires libclang.dll, which can be absent on some systems, and cannot be vendored via crates.io due to its large size). So as a prerequisite, Cargo should be able to find this DLL under the path set in LIBCLANG_PATH environment variable. After this requirement is met, Cargo feature devel can be activated, and d3d12_bindings.rs and pix_bindings.rs files will be generated from scratch, and included into src/raw_bindings/mod.rs instead of the shipped ones. Of course, enabling this feature and copying libclang.dll is not required if one doesn't need to update Agility SDK headers and just wants to wrap some APIs that are already present in the shipped d3d12.rs but not yet covered by this library.

After generating the new raw bindings file (d3d12_bindings.rs, please see the build script for details) using rust-bindgen it should be copied from $OUT_DIR to src/raw_bindings directory and renamed into d3d12.rs.