release(0.3): substantially improve API ergonomics and remove build-time bindgen

This commit is contained in:
chyyran 2023-02-06 19:13:42 -05:00
parent 70b57831d3
commit e0fe82716e
18 changed files with 546 additions and 423 deletions

36
Cargo.lock generated
View file

@ -24,6 +24,14 @@ dependencies = [
"which",
]
[[package]]
name = "bindings_generator"
version = "0.1.0"
dependencies = [
"bindgen",
"cmake",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -207,18 +215,18 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "spirv-to-dxil"
version = "0.2.5"
version = "0.3.0"
dependencies = [
"bitflags",
"bytemuck",
"spirv-to-dxil-sys",
"thiserror",
]
[[package]]
name = "spirv-to-dxil-sys"
version = "0.2.3"
version = "0.3.0"
dependencies = [
"bindgen",
"bytemuck",
"cmake",
]
@ -233,6 +241,26 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.6"

View file

@ -3,4 +3,5 @@
members = [
"spirv-to-dxil",
"spirv-to-dxil-sys",
"bindings_generator"
]

View file

@ -0,0 +1,11 @@
fn main() {
println!(
"cargo:rustc-env=TARGET={}",
std::env::var("TARGET").unwrap()
);
println!("cargo:rustc-env=HOST={}", std::env::var("HOST").unwrap());
println!(
"cargo:rustc-env=OUT_DIR={}",
std::env::var("OUT_DIR").unwrap()
);
}

View file

@ -0,0 +1,72 @@
use bindgen::callbacks::{EnumVariantValue, ParseCallbacks};
#[derive(Debug)]
pub struct SpirvToDxilCallbacks;
impl SpirvToDxilCallbacks {
pub fn rename_shader_stage(variant: &str) -> Option<String> {
match variant {
"DXIL_SPIRV_SHADER_NONE" => Some("None".into()),
"DXIL_SPIRV_SHADER_VERTEX" => Some("Vertex".into()),
"DXIL_SPIRV_SHADER_TESS_CTRL" => Some("TesselationControl".into()),
"DXIL_SPIRV_SHADER_TESS_EVAL" => Some("TesselationEvaluation".into()),
"DXIL_SPIRV_SHADER_GEOMETRY" => Some("Geometry".into()),
"DXIL_SPIRV_SHADER_FRAGMENT" => Some("Fragment".into()),
"DXIL_SPIRV_SHADER_COMPUTE" => Some("Compute".into()),
"DXIL_SPIRV_SHADER_KERNEL" => Some("Kernel".into()),
_ => None
}
}
pub fn rename_shader_model(variant: &str) -> Option<String> {
Some(variant.replace("SHADER_MODEL_", "ShaderModel"))
}
pub fn rename_flip_mode(variant: &str) -> Option<String> {
Some(variant.replace("DXIL_SPIRV_", ""))
}
pub fn rename_validator_version(variant: &str, value: EnumVariantValue) -> Option<String> {
match value {
EnumVariantValue::Unsigned(0)
| EnumVariantValue::Signed(0) => Some("None".into()),
_ => Some(variant.replace("DXIL_VALIDATOR_", "Validator"))
}
}
}
impl ParseCallbacks for SpirvToDxilCallbacks {
fn enum_variant_name(
&self,
enum_name: Option<&str>,
original_variant_name: &str,
variant_value: EnumVariantValue,
) -> Option<String> {
match enum_name {
Some("dxil_spirv_shader_stage") => {
SpirvToDxilCallbacks::rename_shader_stage(original_variant_name)
}
Some("enum dxil_shader_model") => {
SpirvToDxilCallbacks::rename_shader_model(original_variant_name)
}
Some("enum dxil_validator_version") => {
SpirvToDxilCallbacks::rename_validator_version(original_variant_name, variant_value)
}
Some("enum dxil_spirv_yz_flip_mode") => {
SpirvToDxilCallbacks::rename_flip_mode(original_variant_name)
}
_ => {
eprintln!("skipping {:?}", enum_name);
None
},
}
}
fn item_name(&self, original_item_name: &str) -> Option<String> {
match original_item_name {
"dxil_spirv_runtime_conf__bindgen_ty_1" => Some("dxil_spirv_runtime_conf_runtime_cbv".into()),
"dxil_spirv_runtime_conf__bindgen_ty_2" => Some("dxil_spirv_runtime_conf_push_cbv".into()),
"dxil_spirv_runtime_conf__bindgen_ty_3" => Some("dxil_spirv_runtime_conf_flip_conf".into()),
_ => None
}
}
}

View file

@ -1,6 +1,6 @@
[package]
name = "spirv-to-dxil-sys"
version = "0.2.6"
version = "0.3.0"
edition = "2021"
description = "Raw bindings to spirv-to-dxil"
license = "MIT"
@ -10,12 +10,8 @@ readme = "../README.md"
[lib]
[dependencies]
bytemuck = "1.13.0"
[build-dependencies]
bindgen = "0.63.0"
cmake = "0.1"
[features]
included-bindings = []
[package.metadata.docs.rs]
features = ["included-bindings"]

View file

@ -1,11 +1,12 @@
use cmake::Config;
use std::{env, fs::File, path::{Path, PathBuf}};
use std::{
env,
path::Path
};
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
if env::var("DOCS_RS").is_ok() {
println!("cargo:warning=Skipping spirv-to-dxil native build for docs.rs.");
File::create(out_dir.join("bindings.rs")).unwrap();
return;
}
@ -16,9 +17,6 @@ fn main() {
let object_dst = cmake_dst.join("build/mesa/lib");
let header_dst = cmake_dst.join("build/mesa/src/mesa/src/microsoft/spirv_to_dxil");
let header_compiler_dst = cmake_dst.join("build/mesa/src/mesa/src/microsoft/compiler");
println!("cargo:rustc-link-search=native={}", object_dst.display());
println!("cargo:rustc-link-lib=static=spirv_to_dxil");
@ -51,19 +49,4 @@ fn main() {
println!("cargo:rustc-link-search=native={}", search_dir);
println!("cargo:rustc-link-lib=dylib=stdc++");
}
let bindings = bindgen::Builder::default()
.header("native/wrapper.h")
.clang_arg(format!("-F{}", header_dst.display()))
.clang_arg(format!("-F{}", header_compiler_dst.display()))
.clang_arg(format!("-I{}", header_dst.display()))
.clang_arg(format!("-I{}", header_compiler_dst.display()))
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_dir.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

View file

@ -20,25 +20,33 @@ pub const WCHAR_MAX: u32 = 65535;
pub const WINT_MIN: u32 = 0;
pub const WINT_MAX: u32 = 65535;
pub const DXIL_SPIRV_MAX_VIEWPORT: u32 = 16;
pub const dxil_shader_model_SHADER_MODEL_6_0: dxil_shader_model = 393216;
pub const dxil_shader_model_SHADER_MODEL_6_1: dxil_shader_model = 393217;
pub const dxil_shader_model_SHADER_MODEL_6_2: dxil_shader_model = 393218;
pub const dxil_shader_model_SHADER_MODEL_6_3: dxil_shader_model = 393219;
pub const dxil_shader_model_SHADER_MODEL_6_4: dxil_shader_model = 393220;
pub const dxil_shader_model_SHADER_MODEL_6_5: dxil_shader_model = 393221;
pub const dxil_shader_model_SHADER_MODEL_6_6: dxil_shader_model = 393222;
pub const dxil_shader_model_SHADER_MODEL_6_7: dxil_shader_model = 393223;
pub type dxil_shader_model = ::std::os::raw::c_int;
pub const dxil_validator_version_NO_DXIL_VALIDATION: dxil_validator_version = 0;
pub const dxil_validator_version_DXIL_VALIDATOR_1_0: dxil_validator_version = 65536;
pub const dxil_validator_version_DXIL_VALIDATOR_1_1: dxil_validator_version = 65537;
pub const dxil_validator_version_DXIL_VALIDATOR_1_2: dxil_validator_version = 65538;
pub const dxil_validator_version_DXIL_VALIDATOR_1_3: dxil_validator_version = 65539;
pub const dxil_validator_version_DXIL_VALIDATOR_1_4: dxil_validator_version = 65540;
pub const dxil_validator_version_DXIL_VALIDATOR_1_5: dxil_validator_version = 65541;
pub const dxil_validator_version_DXIL_VALIDATOR_1_6: dxil_validator_version = 65542;
pub const dxil_validator_version_DXIL_VALIDATOR_1_7: dxil_validator_version = 65543;
pub type dxil_validator_version = ::std::os::raw::c_int;
#[repr(i32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum dxil_shader_model {
ShaderModel6_0 = 393216,
ShaderModel6_1 = 393217,
ShaderModel6_2 = 393218,
ShaderModel6_3 = 393219,
ShaderModel6_4 = 393220,
ShaderModel6_5 = 393221,
ShaderModel6_6 = 393222,
ShaderModel6_7 = 393223,
}
#[repr(i32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum dxil_validator_version {
None = 0,
Validator1_0 = 65536,
Validator1_1 = 65537,
Validator1_2 = 65538,
Validator1_3 = 65539,
Validator1_4 = 65540,
Validator1_5 = 65541,
Validator1_6 = 65542,
Validator1_7 = 65543,
}
pub type wchar_t = ::std::os::raw::c_ushort;
pub type max_align_t = f64;
pub type va_list = *mut ::std::os::raw::c_char;
@ -76,15 +84,18 @@ pub type uint_fast32_t = ::std::os::raw::c_uint;
pub type uint_fast64_t = ::std::os::raw::c_ulonglong;
pub type intmax_t = ::std::os::raw::c_longlong;
pub type uintmax_t = ::std::os::raw::c_ulonglong;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_NONE: dxil_spirv_shader_stage = -1;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_VERTEX: dxil_spirv_shader_stage = 0;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_TESS_CTRL: dxil_spirv_shader_stage = 1;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_TESS_EVAL: dxil_spirv_shader_stage = 2;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_GEOMETRY: dxil_spirv_shader_stage = 3;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_FRAGMENT: dxil_spirv_shader_stage = 4;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_COMPUTE: dxil_spirv_shader_stage = 5;
pub const dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_KERNEL: dxil_spirv_shader_stage = 14;
pub type dxil_spirv_shader_stage = ::std::os::raw::c_int;
#[repr(i32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum dxil_spirv_shader_stage {
None = -1,
Vertex = 0,
TesselationControl = 1,
TesselationEvaluation = 2,
Geometry = 3,
Fragment = 4,
Compute = 5,
Kernel = 14,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union dxil_spirv_const_value {
@ -495,7 +506,7 @@ pub struct dxil_spirv_vertex_runtime_data {
pub first_vertex: u32,
pub base_instance: u32,
pub is_indexed_draw: bool,
pub __bindgen_anon_1: dxil_spirv_vertex_runtime_data__bindgen_ty_1,
pub _dxil_spirv_anon1: dxil_spirv_vertex_runtime_data__bindgen_ty_1,
pub draw_id: u32,
pub viewport_width: f32,
pub viewport_height: f32,
@ -505,7 +516,7 @@ pub struct dxil_spirv_vertex_runtime_data {
#[derive(Copy, Clone)]
pub union dxil_spirv_vertex_runtime_data__bindgen_ty_1 {
pub yz_flip_mask: u32,
pub __bindgen_anon_1: dxil_spirv_vertex_runtime_data__bindgen_ty_1__bindgen_ty_1,
pub _dxil_spirv_anon1: dxil_spirv_vertex_runtime_data__bindgen_ty_1__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -674,22 +685,64 @@ fn bindgen_test_layout_dxil_spirv_vertex_runtime_data() {
)
);
}
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_NONE: dxil_spirv_yz_flip_mode = 0;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_Y_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = 1;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_Z_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = 2;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = 3;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_Y_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = 4;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_Z_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = 8;
pub const dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = 12;
pub type dxil_spirv_yz_flip_mode = ::std::os::raw::c_int;
impl dxil_spirv_yz_flip_mode {
pub const YZ_FLIP_NONE: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(0);
}
impl dxil_spirv_yz_flip_mode {
pub const Y_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(1);
}
impl dxil_spirv_yz_flip_mode {
pub const Z_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(2);
}
impl dxil_spirv_yz_flip_mode {
pub const YZ_FLIP_UNCONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(3);
}
impl dxil_spirv_yz_flip_mode {
pub const Y_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(4);
}
impl dxil_spirv_yz_flip_mode {
pub const Z_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(8);
}
impl dxil_spirv_yz_flip_mode {
pub const YZ_FLIP_CONDITIONAL: dxil_spirv_yz_flip_mode = dxil_spirv_yz_flip_mode(12);
}
impl ::std::ops::BitOr<dxil_spirv_yz_flip_mode> for dxil_spirv_yz_flip_mode {
type Output = Self;
#[inline]
fn bitor(self, other: Self) -> Self {
dxil_spirv_yz_flip_mode(self.0 | other.0)
}
}
impl ::std::ops::BitOrAssign for dxil_spirv_yz_flip_mode {
#[inline]
fn bitor_assign(&mut self, rhs: dxil_spirv_yz_flip_mode) {
self.0 |= rhs.0;
}
}
impl ::std::ops::BitAnd<dxil_spirv_yz_flip_mode> for dxil_spirv_yz_flip_mode {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self {
dxil_spirv_yz_flip_mode(self.0 & other.0)
}
}
impl ::std::ops::BitAndAssign for dxil_spirv_yz_flip_mode {
#[inline]
fn bitand_assign(&mut self, rhs: dxil_spirv_yz_flip_mode) {
self.0 &= rhs.0;
}
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct dxil_spirv_yz_flip_mode(pub ::std::os::raw::c_int);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dxil_spirv_runtime_conf {
pub runtime_data_cbv: dxil_spirv_runtime_conf__bindgen_ty_1,
pub push_constant_cbv: dxil_spirv_runtime_conf__bindgen_ty_2,
pub runtime_data_cbv: dxil_spirv_runtime_conf_runtime_cbv,
pub push_constant_cbv: dxil_spirv_runtime_conf_push_cbv,
pub zero_based_vertex_instance_id: bool,
pub zero_based_compute_workgroup_id: bool,
pub yz_flip: dxil_spirv_runtime_conf__bindgen_ty_3,
pub yz_flip: dxil_spirv_runtime_conf_flip_conf,
pub read_only_images_as_srvs: bool,
pub force_sample_rate_shading: bool,
pub lower_view_index: bool,
@ -697,29 +750,26 @@ pub struct dxil_spirv_runtime_conf {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dxil_spirv_runtime_conf__bindgen_ty_1 {
pub struct dxil_spirv_runtime_conf_runtime_cbv {
pub register_space: u32,
pub base_shader_register: u32,
}
#[test]
fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_1() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf__bindgen_ty_1> =
fn bindgen_test_layout_dxil_spirv_runtime_conf_runtime_cbv() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf_runtime_cbv> =
::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<dxil_spirv_runtime_conf__bindgen_ty_1>(),
::std::mem::size_of::<dxil_spirv_runtime_conf_runtime_cbv>(),
8usize,
concat!(
"Size of: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_1)
)
concat!("Size of: ", stringify!(dxil_spirv_runtime_conf_runtime_cbv))
);
assert_eq!(
::std::mem::align_of::<dxil_spirv_runtime_conf__bindgen_ty_1>(),
::std::mem::align_of::<dxil_spirv_runtime_conf_runtime_cbv>(),
4usize,
concat!(
"Alignment of ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_1)
stringify!(dxil_spirv_runtime_conf_runtime_cbv)
)
);
assert_eq!(
@ -727,7 +777,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_1() {
0usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_1),
stringify!(dxil_spirv_runtime_conf_runtime_cbv),
"::",
stringify!(register_space)
)
@ -737,7 +787,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_1() {
4usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_1),
stringify!(dxil_spirv_runtime_conf_runtime_cbv),
"::",
stringify!(base_shader_register)
)
@ -745,29 +795,26 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_1() {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dxil_spirv_runtime_conf__bindgen_ty_2 {
pub struct dxil_spirv_runtime_conf_push_cbv {
pub register_space: u32,
pub base_shader_register: u32,
}
#[test]
fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_2() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf__bindgen_ty_2> =
fn bindgen_test_layout_dxil_spirv_runtime_conf_push_cbv() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf_push_cbv> =
::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<dxil_spirv_runtime_conf__bindgen_ty_2>(),
::std::mem::size_of::<dxil_spirv_runtime_conf_push_cbv>(),
8usize,
concat!(
"Size of: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_2)
)
concat!("Size of: ", stringify!(dxil_spirv_runtime_conf_push_cbv))
);
assert_eq!(
::std::mem::align_of::<dxil_spirv_runtime_conf__bindgen_ty_2>(),
::std::mem::align_of::<dxil_spirv_runtime_conf_push_cbv>(),
4usize,
concat!(
"Alignment of ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_2)
stringify!(dxil_spirv_runtime_conf_push_cbv)
)
);
assert_eq!(
@ -775,7 +822,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_2() {
0usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_2),
stringify!(dxil_spirv_runtime_conf_push_cbv),
"::",
stringify!(register_space)
)
@ -785,7 +832,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_2() {
4usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_2),
stringify!(dxil_spirv_runtime_conf_push_cbv),
"::",
stringify!(base_shader_register)
)
@ -793,30 +840,27 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_2() {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dxil_spirv_runtime_conf__bindgen_ty_3 {
pub struct dxil_spirv_runtime_conf_flip_conf {
pub mode: dxil_spirv_yz_flip_mode,
pub y_mask: u16,
pub z_mask: u16,
}
#[test]
fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_3() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf__bindgen_ty_3> =
fn bindgen_test_layout_dxil_spirv_runtime_conf_flip_conf() {
const UNINIT: ::std::mem::MaybeUninit<dxil_spirv_runtime_conf_flip_conf> =
::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<dxil_spirv_runtime_conf__bindgen_ty_3>(),
::std::mem::size_of::<dxil_spirv_runtime_conf_flip_conf>(),
8usize,
concat!(
"Size of: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_3)
)
concat!("Size of: ", stringify!(dxil_spirv_runtime_conf_flip_conf))
);
assert_eq!(
::std::mem::align_of::<dxil_spirv_runtime_conf__bindgen_ty_3>(),
::std::mem::align_of::<dxil_spirv_runtime_conf_flip_conf>(),
4usize,
concat!(
"Alignment of ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_3)
stringify!(dxil_spirv_runtime_conf_flip_conf)
)
);
assert_eq!(
@ -824,7 +868,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_3() {
0usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_3),
stringify!(dxil_spirv_runtime_conf_flip_conf),
"::",
stringify!(mode)
)
@ -834,7 +878,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_3() {
4usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_3),
stringify!(dxil_spirv_runtime_conf_flip_conf),
"::",
stringify!(y_mask)
)
@ -844,7 +888,7 @@ fn bindgen_test_layout_dxil_spirv_runtime_conf__bindgen_ty_3() {
6usize,
concat!(
"Offset of field: ",
stringify!(dxil_spirv_runtime_conf__bindgen_ty_3),
stringify!(dxil_spirv_runtime_conf_flip_conf),
"::",
stringify!(z_mask)
)

View file

@ -2,22 +2,65 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
#[cfg(feature = "included-bindings")]
mod bindings;
#[cfg(feature = "included-bindings")]
use bytemuck::NoUninit;
pub use bindings::*;
#[cfg(test)]
mod tests {
use super::*;
impl Default for dxil_spirv_yz_flip_mode {
fn default() -> Self {
dxil_spirv_yz_flip_mode::YZ_FLIP_NONE
}
}
#[test]
fn it_works() {
unsafe {
eprintln!("{:x?}", spirv_to_dxil_get_version());
// runtime cbv
impl Default for dxil_spirv_runtime_conf_runtime_cbv {
fn default() -> Self {
Self {
register_space: 0,
base_shader_register: 0,
}
}
}
// push cbv
impl Default for dxil_spirv_runtime_conf_push_cbv {
fn default() -> Self {
Self {
register_space: 0,
base_shader_register: 0,
}
}
}
// flip options
impl Default for dxil_spirv_runtime_conf_flip_conf {
fn default() -> Self {
Self {
mode: Default::default(),
y_mask: 0,
z_mask: 0,
}
}
}
impl Default for dxil_spirv_runtime_conf {
fn default() -> Self {
Self {
runtime_data_cbv: Default::default(),
push_constant_cbv: Default::default(),
zero_based_vertex_instance_id: true,
zero_based_compute_workgroup_id: false,
yz_flip: Default::default(),
read_only_images_as_srvs: false,
force_sample_rate_shading: false,
lower_view_index: false,
lower_view_index_to_rt_layer: false,
}
}
}
unsafe impl NoUninit for dxil_spirv_vertex_runtime_data { }
unsafe impl NoUninit for dxil_spirv_vertex_runtime_data__bindgen_ty_1 { }
unsafe impl NoUninit for dxil_spirv_vertex_runtime_data__bindgen_ty_1__bindgen_ty_1 { }
unsafe impl NoUninit for dxil_spirv_compute_runtime_data { }

View file

@ -1,17 +1,16 @@
[package]
name = "spirv-to-dxil"
version = "0.2.6"
version = "0.3.0"
edition = "2021"
description = "Rust bindings to spirv-to-dxil"
license = "MIT"
repository = "https://github.com/SnowflakePowered/spirv-to-dxil-rs"
keywords = ["SPIR-V", "DXIL"]
readme = "../README.md"
[lib]
[dependencies]
spirv-to-dxil-sys = { version = "0.2", path = "../spirv-to-dxil-sys" }
bitflags = "1.3.2"
[dev-dependencies]
spirv-to-dxil-sys = { version = "0.3", path = "../spirv-to-dxil-sys" }
thiserror = "1.0.38"
bytemuck = "1.13.0"

View file

@ -1,81 +0,0 @@
/// Configuration options for CBVs
#[derive(Default, Debug, Clone)]
pub struct ConstantBufferConfig {
pub register_space: u32,
pub base_shader_register: u32,
}
/// Configuration options for SPIR-V YZ flip mode.
#[derive(Default, Debug, Clone)]
pub struct FlipConfig {
pub mode: crate::FlipMode,
pub y_mask: u16,
pub z_mask: u16,
}
#[derive(Debug, Clone)]
/// Runtime configuration options for the SPIR-V compilation.
pub struct RuntimeConfig {
pub runtime_data_cbv: ConstantBufferConfig,
pub push_constant_cbv: ConstantBufferConfig,
/// Set true if vertex and instance ids have already been converted to
/// zero-based. Otherwise, runtime_data will be required to lower them.
pub zero_based_vertex_instance_id: bool,
/// Set true if workgroup base is known to be zero
pub zero_based_compute_workgroup_id: bool,
pub yz_flip: FlipConfig,
/// The caller supports read-only images to be turned into SRV accesses,
/// which allows us to run the nir_opt_access() pass
pub read_only_images_as_srvs: bool,
/// Force sample rate shading on a fragment shader
pub force_sample_rate_shading: bool,
/// View index needs to be lowered to a UBO lookup
pub lower_view_index: bool,
/// View index also needs to be forwarded to RT layer output
pub lower_view_index_to_rt_layer: bool,
}
impl Default for RuntimeConfig {
fn default() -> Self {
RuntimeConfig {
runtime_data_cbv: ConstantBufferConfig {
register_space: 31,
base_shader_register: 0,
},
push_constant_cbv: Default::default(),
zero_based_vertex_instance_id: true,
zero_based_compute_workgroup_id: false,
yz_flip: Default::default(),
read_only_images_as_srvs: false,
force_sample_rate_shading: false,
lower_view_index: false,
lower_view_index_to_rt_layer: false,
}
}
}
impl From<RuntimeConfig> for spirv_to_dxil_sys::dxil_spirv_runtime_conf {
fn from(value: RuntimeConfig) -> Self {
spirv_to_dxil_sys::dxil_spirv_runtime_conf {
runtime_data_cbv: spirv_to_dxil_sys::dxil_spirv_runtime_conf__bindgen_ty_1 {
register_space: value.runtime_data_cbv.register_space,
base_shader_register: value.runtime_data_cbv.base_shader_register,
},
push_constant_cbv: spirv_to_dxil_sys::dxil_spirv_runtime_conf__bindgen_ty_2 {
register_space: value.push_constant_cbv.register_space,
base_shader_register: value.push_constant_cbv.base_shader_register,
},
zero_based_vertex_instance_id: value.zero_based_vertex_instance_id,
zero_based_compute_workgroup_id: value.zero_based_compute_workgroup_id,
yz_flip: spirv_to_dxil_sys::dxil_spirv_runtime_conf__bindgen_ty_3 {
mode: value.yz_flip.mode.bits(),
y_mask: value.yz_flip.y_mask,
z_mask: value.yz_flip.z_mask,
},
read_only_images_as_srvs: value.read_only_images_as_srvs,
force_sample_rate_shading: value.force_sample_rate_shading,
lower_view_index: value.lower_view_index,
lower_view_index_to_rt_layer: value.lower_view_index_to_rt_layer,
}
}
}

View file

@ -0,0 +1,23 @@
/// Configuration options for the runtime data constant buffer if required.
pub use spirv_to_dxil_sys::dxil_spirv_runtime_conf_runtime_cbv as RuntimeDataBufferConfig;
/// Configuration options for the push constant buffer if required
pub use spirv_to_dxil_sys::dxil_spirv_runtime_conf_push_cbv as PushConstantBufferConfig;
/// Configuration options for SPIR-V YZ flip mode.
pub use spirv_to_dxil_sys::dxil_spirv_runtime_conf_flip_conf as FlipConfig;
/// Runtime configuration options for the SPIR-V compilation.
pub use spirv_to_dxil_sys::dxil_spirv_runtime_conf as RuntimeConfig;
/// The DXIL shader model to target.
pub use spirv_to_dxil_sys::dxil_shader_model as ShaderModel;
/// The validator version to target. Requires `dxil.dll` in path.
pub use spirv_to_dxil_sys::dxil_validator_version as ValidatorVersion;
/// The shader stage of the input.
pub use spirv_to_dxil_sys::dxil_spirv_shader_stage as ShaderStage;
/// The flip mode to use when compiling the shader.
pub use spirv_to_dxil_sys::dxil_spirv_yz_flip_mode as FlipMode;

View file

@ -1,133 +0,0 @@
use bitflags::bitflags;
#[derive(Copy, Clone, Debug)]
pub enum ShaderStage {
None,
Vertex,
TesselationControl,
TesselationEvaluation,
Geometry,
Fragment,
Compute,
Kernel,
}
impl From<ShaderStage> for spirv_to_dxil_sys::dxil_spirv_shader_stage {
fn from(value: ShaderStage) -> Self {
match value {
ShaderStage::None => spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_NONE,
ShaderStage::Vertex => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_VERTEX
}
ShaderStage::TesselationControl => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_TESS_CTRL
}
ShaderStage::TesselationEvaluation => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_TESS_EVAL
}
ShaderStage::Geometry => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_GEOMETRY
}
ShaderStage::Fragment => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_FRAGMENT
}
ShaderStage::Compute => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_COMPUTE
}
ShaderStage::Kernel => {
spirv_to_dxil_sys::dxil_spirv_shader_stage_DXIL_SPIRV_SHADER_KERNEL
}
}
}
}
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum ShaderModel {
ShaderModel6_0,
ShaderModel6_1,
ShaderModel6_2,
ShaderModel6_3,
ShaderModel6_4,
ShaderModel6_5,
ShaderModel6_6,
ShaderModel6_7,
}
impl From<ShaderModel> for spirv_to_dxil_sys::dxil_shader_model {
fn from(value: ShaderModel) -> Self {
match value {
ShaderModel::ShaderModel6_0 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_0,
ShaderModel::ShaderModel6_1 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_1,
ShaderModel::ShaderModel6_2 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_2,
ShaderModel::ShaderModel6_3 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_3,
ShaderModel::ShaderModel6_4 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_4,
ShaderModel::ShaderModel6_5 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_5,
ShaderModel::ShaderModel6_6 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_6,
ShaderModel::ShaderModel6_7 => spirv_to_dxil_sys::dxil_shader_model_SHADER_MODEL_6_7,
}
}
}
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum ValidatorVersion {
None,
Validator1_0,
Validator1_1,
Validator1_2,
Validator1_3,
Validator1_4,
Validator1_5,
Validator1_6,
Validator1_7,
}
impl From<ValidatorVersion> for spirv_to_dxil_sys::dxil_validator_version {
fn from(value: ValidatorVersion) -> Self {
match value {
ValidatorVersion::None => spirv_to_dxil_sys::dxil_validator_version_NO_DXIL_VALIDATION,
ValidatorVersion::Validator1_0 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_0
}
ValidatorVersion::Validator1_1 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_1
}
ValidatorVersion::Validator1_2 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_2
}
ValidatorVersion::Validator1_3 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_3
}
ValidatorVersion::Validator1_4 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_4
}
ValidatorVersion::Validator1_5 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_5
}
ValidatorVersion::Validator1_6 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_6
}
ValidatorVersion::Validator1_7 => {
spirv_to_dxil_sys::dxil_validator_version_DXIL_VALIDATOR_1_7
}
}
}
}
bitflags! {
#[derive(Default)]
pub struct FlipMode: spirv_to_dxil_sys::dxil_spirv_yz_flip_mode {
/// No YZ flip
const NONE = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_NONE;
/// Y-flip is unconditional: pos.y = -pos.y
const Y_FLIP_UNCONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_Y_FLIP_UNCONDITIONAL;
/// Z-flip is unconditional: pos.z = -pos.z + 1.0f
const Z_FLIP_UNCONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_Z_FLIP_UNCONDITIONAL;
const YZ_FLIP_UNCONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_UNCONDITIONAL;
const Y_FLIP_CONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_Y_FLIP_CONDITIONAL;
/// Z-flip is unconditional: pos.z = -pos.z + 1.0f
const Z_FLIP_CONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_Z_FLIP_CONDITIONAL;
const YZ_FLIP_CONDITIONAL = spirv_to_dxil_sys::dxil_spirv_yz_flip_mode_DXIL_SPIRV_YZ_FLIP_CONDITIONAL;
}
}

View file

@ -1,4 +1,13 @@
use thiserror::Error;
#[derive(Debug, Error)]
/// Error type for spirv-to-dxil.
pub enum SpirvToDxilError {
/// An error occurred when compiling SPIR-V to DXIL.
#[error("An error occurred when compiled to DXIL: {0}.")]
CompilerError(String),
RegisterSpaceOverflow(usize)
/// The requested register space for a push or runtime constant block is beyond
/// the limit of 31.
#[error("Register space {0} is beyond the limit of 31.")]
RegisterSpaceOverflow(u32)
}

View file

@ -1,20 +1,37 @@
mod config;
mod enums;
//! Rust bindings for [spirv-to-dxil](https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/microsoft/spirv_to_dxil).
//!
//! For the lower-level C interface, see the [spirv-to-dxil-sys](https://docs.rs/spirv-to-dxil-sys/) crate.
//!
//! ## Push Constant Buffers
//! SPIR-V shaders that use Push Constants must choose register assignments that correspond with the Root Descriptor that the compiled shader will
//! use for a constant buffer to store push constants with [PushConstantBufferConfig](crate::PushConstantBufferConfig).
//!
//! ## Runtime Data
//! For some vertex and compute shaders, a constant buffer provided at runtime is required to be bound.
//!
//! You can check if the compiled shader requires runtime data with
//! [`DxilObject::requires_runtime_data`](crate::DxilObject::requires_runtime_data).
//!
//! If your shader requires runtime data, then register assignments must be chosen in
//! [RuntimeDataBufferConfig](crate::RuntimeDataBufferConfig).
//!
//! See the [`runtime`](crate::runtime) module for how to construct the expected runtime data to be bound in a constant buffer.
mod ctypes;
mod logger;
mod object;
mod specialization;
mod logger;
mod error;
pub mod runtime;
pub use config::*;
pub use enums::*;
pub use ctypes::*;
pub use object::*;
pub use specialization::*;
pub use crate::error::SpirvToDxilError;
pub use spirv_to_dxil_sys::DXIL_SPIRV_MAX_VIEWPORT;
use std::mem::MaybeUninit;
use spirv_to_dxil_sys::dxil_spirv_object;
pub use spirv_to_dxil_sys::DXIL_SPIRV_MAX_VIEWPORT;
use crate::logger::Logger;
use spirv_to_dxil_sys::dxil_spirv_object;
fn spirv_to_dxil_inner(
spirv_words: &[u32],
@ -23,45 +40,43 @@ fn spirv_to_dxil_inner(
stage: ShaderStage,
shader_model_max: ShaderModel,
validator_version_max: ValidatorVersion,
runtime_conf: RuntimeConfig,
runtime_conf: &RuntimeConfig,
dump_nir: bool,
logger: &spirv_to_dxil_sys::dxil_spirv_logger,
out: &mut MaybeUninit<dxil_spirv_object>,
) -> bool {
) -> Result<bool, SpirvToDxilError> {
if runtime_conf.push_constant_cbv.register_space > 31
|| runtime_conf.runtime_data_cbv.register_space > 31 {
panic!("register space can not be greater than 31")
|| runtime_conf.runtime_data_cbv.register_space > 31
{
return Err(SpirvToDxilError::RegisterSpaceOverflow(std::cmp::max(runtime_conf.push_constant_cbv.register_space, runtime_conf.runtime_data_cbv.register_space)))
}
let num_specializations = specializations.map(|o| o.len()).unwrap_or(0) as u32;
let mut specializations: Option<Vec<spirv_to_dxil_sys::dxil_spirv_specialization>> =
specializations.map(|o| o.into_iter().map(|o| (*o).into()).collect());
let runtime_conf: spirv_to_dxil_sys::dxil_spirv_runtime_conf =
runtime_conf.into();
let debug = spirv_to_dxil_sys::dxil_spirv_debug_options { dump_nir };
unsafe {
spirv_to_dxil_sys::spirv_to_dxil(
Ok(spirv_to_dxil_sys::spirv_to_dxil(
spirv_words.as_ptr(),
spirv_words.len(),
specializations
.as_mut()
.map_or(std::ptr::null_mut(), |x| x.as_mut_ptr()),
num_specializations,
stage.into(),
stage,
entry_point.as_ptr().cast(),
shader_model_max.into(),
validator_version_max.into(),
shader_model_max,
validator_version_max,
&debug,
&runtime_conf,
runtime_conf,
logger,
out.as_mut_ptr(),
)
))
}
}
/// Dump NIR to stdout.
/// Dump the parsed NIR output of the SPIR-V to stdout.
pub fn dump_nir(
spirv_words: &[u32],
specializations: Option<&[Specialization]>,
@ -69,13 +84,12 @@ pub fn dump_nir(
stage: ShaderStage,
shader_model_max: ShaderModel,
validator_version_max: ValidatorVersion,
runtime_conf: RuntimeConfig,
) -> bool {
runtime_conf: &RuntimeConfig,
) -> Result<bool, SpirvToDxilError> {
let entry_point = entry_point.as_ref();
let mut entry_point = String::from(entry_point).into_bytes();
entry_point.push(0);
let mut out = MaybeUninit::uninit();
spirv_to_dxil_inner(
spirv_words,
@ -99,8 +113,8 @@ pub fn spirv_to_dxil(
stage: ShaderStage,
shader_model_max: ShaderModel,
validator_version_max: ValidatorVersion,
runtime_conf: RuntimeConfig,
) -> Result<DxilObject, String> {
runtime_conf: &RuntimeConfig,
) -> Result<DxilObject, SpirvToDxilError> {
let entry_point = entry_point.as_ref();
let mut entry_point = String::from(entry_point).into_bytes();
entry_point.push(0);
@ -120,18 +134,16 @@ pub fn spirv_to_dxil(
false,
&logger,
&mut out,
);
)?;
let logger = unsafe {
Logger::finalize(logger)
};
let logger = unsafe { Logger::finalize(logger) };
if result {
let out = unsafe { out.assume_init() };
Ok(DxilObject::new(out))
} else {
Err(logger)
Err(SpirvToDxilError::CompilerError(logger))
}
}
@ -145,11 +157,15 @@ mod tests {
let fragment = Vec::from(fragment);
let fragment = bytemuck::cast_slice(&fragment);
super::dump_nir(&fragment,
None, "main",
ShaderStage::Fragment,
ShaderModel::ShaderModel6_0, ValidatorVersion::None,
RuntimeConfig::default());
super::dump_nir(
&fragment,
None,
"main",
ShaderStage::Fragment,
ShaderModel::ShaderModel6_0,
ValidatorVersion::None,
&RuntimeConfig::default(),
).expect("failed to compile");
}
#[test]
@ -158,22 +174,26 @@ mod tests {
let fragment = Vec::from(fragment);
let fragment = bytemuck::cast_slice(&fragment);
super::spirv_to_dxil(&fragment,
None, "main",
ShaderStage::Fragment,
ShaderModel::ShaderModel6_0, ValidatorVersion::None,
RuntimeConfig {
runtime_data_cbv: ConstantBufferConfig {
register_space: 0,
base_shader_register: 0,
super::spirv_to_dxil(
&fragment,
None,
"main",
ShaderStage::Fragment,
ShaderModel::ShaderModel6_0,
ValidatorVersion::None,
&RuntimeConfig {
runtime_data_cbv: RuntimeDataBufferConfig {
register_space: 0,
base_shader_register: 0,
},
push_constant_cbv: PushConstantBufferConfig {
register_space: 31,
base_shader_register: 1,
},
..RuntimeConfig::default()
},
push_constant_cbv: ConstantBufferConfig {
register_space: 128,
base_shader_register: 1,
},
..RuntimeConfig::default()
})
.expect("failed to compile");
)
.expect("failed to compile");
}
#[test]
@ -182,11 +202,15 @@ mod tests {
let fragment = Vec::from(fragment);
let fragment = bytemuck::cast_slice(&fragment);
super::spirv_to_dxil(&fragment,
None, "main",
ShaderStage::Vertex,
ShaderModel::ShaderModel6_0, ValidatorVersion::None,
RuntimeConfig::default())
.expect("failed to compile");
super::spirv_to_dxil(
&fragment,
None,
"main",
ShaderStage::Vertex,
ShaderModel::ShaderModel6_0,
ValidatorVersion::None,
&RuntimeConfig::default(),
)
.expect("failed to compile");
}
}

View file

@ -2,41 +2,33 @@ use std::ffi::CStr;
use std::os::raw::{c_char, c_void};
extern "C" fn stdout_logger(_: *mut c_void, msg: *const c_char) {
let msg = unsafe {
CStr::from_ptr(msg)
};
let msg = unsafe { CStr::from_ptr(msg) };
println!("[spirv-to-dxil] {:?}", msg)
}
pub(crate) const DEBUG_LOGGER: spirv_to_dxil_sys::dxil_spirv_logger = spirv_to_dxil_sys::dxil_spirv_logger {
priv_: std::ptr::null_mut(),
log: Some(stdout_logger),
};
pub(crate) const DEBUG_LOGGER: spirv_to_dxil_sys::dxil_spirv_logger =
spirv_to_dxil_sys::dxil_spirv_logger {
priv_: std::ptr::null_mut(),
log: Some(stdout_logger),
};
extern "C" fn string_logger(out: *mut c_void, msg: *const c_char) {
let logger = out.cast::<Logger>();
let str = unsafe {
std::ptr::addr_of_mut!((*logger).msg)
.as_mut().unwrap()
};
let str = unsafe { std::ptr::addr_of_mut!((*logger).msg).as_mut().unwrap() };
let msg = unsafe {
CStr::from_ptr(msg)
};
let msg = unsafe { CStr::from_ptr(msg) };
str.push_str(msg.to_string_lossy().as_ref())
}
pub(crate) struct Logger {
msg: String
msg: String,
}
impl Logger {
pub fn new() -> Logger {
Logger {
msg: String::new()
}
Logger { msg: String::new() }
}
pub fn into_logger(self) -> spirv_to_dxil_sys::dxil_spirv_logger {
@ -47,9 +39,7 @@ impl Logger {
}
pub unsafe fn finalize(logger: spirv_to_dxil_sys::dxil_spirv_logger) -> String {
let logger: Box<Logger> = unsafe {
Box::from_raw(logger.priv_.cast())
};
let logger: Box<Logger> = unsafe { Box::from_raw(logger.priv_.cast()) };
logger.msg
}

View file

@ -21,6 +21,7 @@ impl DxilObject {
Self { inner: raw }
}
/// Returns if the compiled shader requires runtime data to be bound.
pub fn requires_runtime_data(&self) -> bool {
self.inner.metadata.requires_runtime_data
}

View file

@ -0,0 +1,111 @@
//! Higher level helpers for runtime data.
//!
//! Builder structs should not be used directly. Instead, call [`build`](RuntimeDataBuilder::build) to consume
//! the builder and yield an object referenceable as a byte buffer that can be uploaded to a mapped constant buffer.
use spirv_to_dxil_sys::{dxil_spirv_vertex_runtime_data__bindgen_ty_1, dxil_spirv_vertex_runtime_data__bindgen_ty_1__bindgen_ty_1};
/// A vector of three items.
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Vec3<T> {
pub x: T,
pub y: T,
pub z: T
}
/// Trait for runtime data builders.
pub trait RuntimeDataBuilder<T> {
/// Consumes the builder and finalizes the bytes.
fn build(self) -> T;
}
/// Runtime data builder for compute shaders.
#[derive(Debug, Clone)]
pub struct ComputeRuntimeDataBuilder {
pub group_count: Vec3<u32>,
pub base_group: Vec3<u32>
}
/// Runtime data buffer for compute shaders.
pub struct ComputeRuntimeData(spirv_to_dxil_sys::dxil_spirv_compute_runtime_data);
impl RuntimeDataBuilder<ComputeRuntimeData> for ComputeRuntimeDataBuilder {
fn build(self) -> ComputeRuntimeData {
let data = spirv_to_dxil_sys::dxil_spirv_compute_runtime_data {
group_count_x: self.group_count.x,
group_count_y: self.group_count.y,
group_count_z: self.group_count.z,
padding0: 0,
base_group_x: self.base_group.x,
base_group_y: self.base_group.y,
base_group_z: self.base_group.z,
};
ComputeRuntimeData(data)
}
}
impl From<ComputeRuntimeDataBuilder> for ComputeRuntimeData {
fn from(value: ComputeRuntimeDataBuilder) -> Self {
value.build()
}
}
impl AsRef<[u8]> for ComputeRuntimeData {
fn as_ref(&self) -> &[u8] {
bytemuck::bytes_of(&self.0)
}
}
/// Runtime data builder for vertex shaders.
#[derive(Debug, Clone)]
pub struct VertexRuntimeDataBuilder {
pub first_vertex: u32,
pub base_instance: u32,
pub is_indexed_draw: bool,
pub y_flip_mask: u16,
pub z_flip_mask: u16,
pub draw_id: u32,
pub viewport_width: f32,
pub viewport_height: f32,
pub view_index: u32,
}
/// Runtime data buffer for vertex shaders.
pub struct VertexRuntimeData(spirv_to_dxil_sys::dxil_spirv_vertex_runtime_data);
impl RuntimeDataBuilder<VertexRuntimeData> for VertexRuntimeDataBuilder {
fn build(self) -> VertexRuntimeData {
let data = spirv_to_dxil_sys::dxil_spirv_vertex_runtime_data {
first_vertex: self.first_vertex,
base_instance: self.base_instance,
is_indexed_draw: self.is_indexed_draw,
_dxil_spirv_anon1: dxil_spirv_vertex_runtime_data__bindgen_ty_1 {
_dxil_spirv_anon1: dxil_spirv_vertex_runtime_data__bindgen_ty_1__bindgen_ty_1 {
y_flip_mask: self.y_flip_mask,
z_flip_mask: self.z_flip_mask,
}
},
draw_id: self.draw_id,
viewport_width: self.viewport_width,
viewport_height: self.viewport_height,
view_index: self.view_index,
};
VertexRuntimeData(data)
}
}
impl From<VertexRuntimeDataBuilder> for VertexRuntimeData {
fn from(value: VertexRuntimeDataBuilder) -> Self {
value.build()
}
}
impl AsRef<[u8]> for VertexRuntimeData {
fn as_ref(&self) -> &[u8] {
bytemuck::bytes_of(&self.0)
}
}

View file

@ -1,3 +1,4 @@
/// The value of a SPIR-V specialization constant.
#[derive(Debug, Copy, Clone)]
pub enum ConstValue {
Bool(bool),
@ -31,6 +32,7 @@ impl From<ConstValue> for spirv_to_dxil_sys::dxil_spirv_const_value {
}
}
/// SPIR-V specialization constant definition.
#[derive(Debug, Copy, Clone)]
pub struct Specialization {
pub id: u32,