mirror of
https://github.com/italicsjenga/spirv-to-dxil-rs.git
synced 2024-12-23 11:31:31 +11:00
rs: initial implementation of safe wrapper
This commit is contained in:
parent
9afe6b30ca
commit
463a584917
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -30,6 +30,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
|
@ -202,6 +208,11 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
|||
[[package]]
|
||||
name = "spirv-to-dxil"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
"spirv-to-dxil-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirv-to-dxil-sys"
|
||||
|
|
|
@ -4,8 +4,6 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.63.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::{fs::File, env, path::PathBuf};
|
||||
use cmake::Config;
|
||||
use std::{env, fs::File, path::PathBuf};
|
||||
|
||||
fn main() {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
@ -9,9 +9,7 @@ fn main() {
|
|||
return;
|
||||
}
|
||||
|
||||
let cmake_dst = Config::new("native")
|
||||
.build_target("mesa")
|
||||
.build();
|
||||
let cmake_dst = Config::new("native").build_target("mesa").build();
|
||||
|
||||
let object_dst = cmake_dst.join("build/mesa/lib");
|
||||
|
||||
|
@ -36,5 +34,4 @@ fn main() {
|
|||
bindings
|
||||
.write_to_file(out_dir.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
|
||||
}
|
|
@ -5,4 +5,11 @@ edition = "2021"
|
|||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
|
||||
[dependencies]
|
||||
spirv-to-dxil-sys = { version = "0.1.0", path = "../spirv-to-dxil-sys" }
|
||||
bitflags = "1.3.2"
|
||||
|
||||
[dev-dependencies]
|
||||
bytemuck = "1.13.0"
|
80
spirv-to-dxil/src/config.rs
Normal file
80
spirv-to-dxil/src/config.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
/// Configuration options for CBVs
|
||||
#[derive(Default)]
|
||||
pub struct ConstantBufferConfig {
|
||||
pub register_space: u32,
|
||||
pub base_shader_register: u32,
|
||||
}
|
||||
|
||||
/// Configuration options for SPIR-V YZ flip mode.
|
||||
#[derive(Default)]
|
||||
pub struct FlipConfig {
|
||||
pub mode: crate::FlipMode,
|
||||
pub y_mask: u16,
|
||||
pub z_mask: u16,
|
||||
}
|
||||
|
||||
/// 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,
|
||||
}
|
||||
}
|
||||
}
|
130
spirv-to-dxil/src/enums.rs
Normal file
130
spirv-to-dxil/src/enums.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
use bitflags::bitflags;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,134 @@
|
|||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
mod config;
|
||||
mod enums;
|
||||
mod object;
|
||||
mod specialization;
|
||||
mod logger;
|
||||
|
||||
pub use config::*;
|
||||
pub use enums::*;
|
||||
pub use object::*;
|
||||
pub use specialization::*;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
fn spirv_to_dxil_inner(
|
||||
spirv_words: &[u32],
|
||||
specializations: Option<&[Specialization]>,
|
||||
entry_point: &[u8],
|
||||
stage: ShaderStage,
|
||||
shader_model_max: ShaderModel,
|
||||
validator_version_max: ValidatorVersion,
|
||||
runtime_conf: RuntimeConfig,
|
||||
dump_nir: bool,
|
||||
logger: &spirv_to_dxil_sys::dxil_spirv_logger,
|
||||
out: &mut MaybeUninit<dxil_spirv_object>,
|
||||
) -> bool {
|
||||
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(
|
||||
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(),
|
||||
entry_point.as_ptr().cast(),
|
||||
shader_model_max.into(),
|
||||
validator_version_max.into(),
|
||||
&debug,
|
||||
&runtime_conf,
|
||||
logger,
|
||||
out.as_mut_ptr(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Dump NIR to stdout.
|
||||
pub fn dump_nir(
|
||||
spirv_words: &[u32],
|
||||
specializations: Option<&[Specialization]>,
|
||||
entry_point: impl AsRef<str>,
|
||||
stage: ShaderStage,
|
||||
shader_model_max: ShaderModel,
|
||||
validator_version_max: ValidatorVersion,
|
||||
runtime_conf: RuntimeConfig,
|
||||
) -> bool {
|
||||
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,
|
||||
specializations,
|
||||
&entry_point,
|
||||
stage,
|
||||
shader_model_max,
|
||||
validator_version_max,
|
||||
runtime_conf,
|
||||
true,
|
||||
&logger::DEBUG_LOGGER,
|
||||
&mut out,
|
||||
)
|
||||
}
|
||||
|
||||
/// Compile SPIR-V words to a DXIL blob.
|
||||
pub fn spirv_to_dxil(
|
||||
spirv_words: &[u32],
|
||||
specializations: Option<&[Specialization]>,
|
||||
entry_point: impl AsRef<str>,
|
||||
stage: ShaderStage,
|
||||
shader_model_max: ShaderModel,
|
||||
validator_version_max: ValidatorVersion,
|
||||
runtime_conf: RuntimeConfig,
|
||||
) -> Result<DxilObject, String> {
|
||||
let entry_point = entry_point.as_ref();
|
||||
let mut entry_point = String::from(entry_point).into_bytes();
|
||||
entry_point.push(0);
|
||||
|
||||
let logger = Logger::new();
|
||||
let logger = logger.into_logger();
|
||||
let mut out = MaybeUninit::uninit();
|
||||
|
||||
let result = spirv_to_dxil_inner(
|
||||
spirv_words,
|
||||
specializations,
|
||||
&entry_point,
|
||||
stage,
|
||||
shader_model_max,
|
||||
validator_version_max,
|
||||
runtime_conf,
|
||||
false,
|
||||
&logger,
|
||||
&mut out,
|
||||
);
|
||||
|
||||
let logger = unsafe {
|
||||
Logger::finalize(logger)
|
||||
};
|
||||
|
||||
if result {
|
||||
let out = unsafe { out.assume_init() };
|
||||
|
||||
Ok(DxilObject::new(out))
|
||||
} else {
|
||||
Err(logger)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -7,8 +136,29 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
fn dump_nir() {
|
||||
let fragment: &[u8] = include_bytes!("../test/fragment.spv");
|
||||
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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compile() {
|
||||
let fragment: &[u8] = include_bytes!("../test/fragment.spv");
|
||||
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::default())
|
||||
.expect("failed to compile");
|
||||
}
|
||||
}
|
||||
|
|
56
spirv-to-dxil/src/logger.rs
Normal file
56
spirv-to-dxil/src/logger.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
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)
|
||||
};
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
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 msg = unsafe {
|
||||
CStr::from_ptr(msg)
|
||||
};
|
||||
|
||||
str.push_str(msg.to_string_lossy().as_ref())
|
||||
}
|
||||
|
||||
pub(crate) struct Logger {
|
||||
msg: String
|
||||
}
|
||||
|
||||
impl Logger {
|
||||
pub fn new() -> Logger {
|
||||
Logger {
|
||||
msg: String::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_logger(self) -> spirv_to_dxil_sys::dxil_spirv_logger {
|
||||
spirv_to_dxil_sys::dxil_spirv_logger {
|
||||
priv_: Box::into_raw(Box::new(self)).cast(),
|
||||
log: Some(string_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())
|
||||
};
|
||||
|
||||
logger.msg
|
||||
}
|
||||
}
|
33
spirv-to-dxil/src/object.rs
Normal file
33
spirv-to-dxil/src/object.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
/// A compiled DXIL artifact.
|
||||
pub struct DxilObject {
|
||||
inner: spirv_to_dxil_sys::dxil_spirv_object,
|
||||
}
|
||||
|
||||
impl Drop for DxilObject {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// SAFETY:
|
||||
// spirv_to_dxil_free frees only the interior buffer.
|
||||
// https://gitlab.freedesktop.org/mesa/mesa/-/blob/7b0d00034201f8284a41370c0c3326736ae1134c/src/microsoft/spirv_to_dxil/spirv_to_dxil.c#L118
|
||||
spirv_to_dxil_sys::spirv_to_dxil_free(&mut self.inner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DxilObject {
|
||||
pub(crate) fn new(raw: spirv_to_dxil_sys::dxil_spirv_object) -> Self {
|
||||
Self { inner: raw }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for DxilObject {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(self.inner.binary.buffer.cast(), self.inner.binary.size)
|
||||
}
|
||||
}
|
||||
}
|
49
spirv-to-dxil/src/specialization.rs
Normal file
49
spirv-to-dxil/src/specialization.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ConstValue {
|
||||
Bool(bool),
|
||||
Float32(f32),
|
||||
Float64(f64),
|
||||
Int8(i8),
|
||||
Uint8(u8),
|
||||
Int16(i16),
|
||||
Uint16(u16),
|
||||
Int32(i32),
|
||||
Uint32(u32),
|
||||
Int64(i64),
|
||||
Uint64(u64),
|
||||
}
|
||||
|
||||
impl From<ConstValue> for spirv_to_dxil_sys::dxil_spirv_const_value {
|
||||
fn from(value: ConstValue) -> Self {
|
||||
match value {
|
||||
ConstValue::Bool(b) => spirv_to_dxil_sys::dxil_spirv_const_value { b },
|
||||
ConstValue::Float32(f32_) => spirv_to_dxil_sys::dxil_spirv_const_value { f32_ },
|
||||
ConstValue::Float64(f64_) => spirv_to_dxil_sys::dxil_spirv_const_value { f64_ },
|
||||
ConstValue::Int8(i8_) => spirv_to_dxil_sys::dxil_spirv_const_value { i8_ },
|
||||
ConstValue::Uint8(u8_) => spirv_to_dxil_sys::dxil_spirv_const_value { u8_ },
|
||||
ConstValue::Int16(i16_) => spirv_to_dxil_sys::dxil_spirv_const_value { i16_ },
|
||||
ConstValue::Uint16(u16_) => spirv_to_dxil_sys::dxil_spirv_const_value { u16_ },
|
||||
ConstValue::Int32(i32_) => spirv_to_dxil_sys::dxil_spirv_const_value { i32_ },
|
||||
ConstValue::Uint32(u32_) => spirv_to_dxil_sys::dxil_spirv_const_value { u32_ },
|
||||
ConstValue::Int64(i64_) => spirv_to_dxil_sys::dxil_spirv_const_value { i64_ },
|
||||
ConstValue::Uint64(u64_) => spirv_to_dxil_sys::dxil_spirv_const_value { u64_ },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Specialization {
|
||||
pub id: u32,
|
||||
pub value: ConstValue,
|
||||
pub defined_on_module: bool,
|
||||
}
|
||||
|
||||
impl From<Specialization> for spirv_to_dxil_sys::dxil_spirv_specialization {
|
||||
fn from(value: Specialization) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
defined_on_module: value.defined_on_module,
|
||||
value: value.value.into(),
|
||||
}
|
||||
}
|
||||
}
|
BIN
spirv-to-dxil/test/fragment.spv
Normal file
BIN
spirv-to-dxil/test/fragment.spv
Normal file
Binary file not shown.
BIN
spirv-to-dxil/test/vertex.spv
Normal file
BIN
spirv-to-dxil/test/vertex.spv
Normal file
Binary file not shown.
Loading…
Reference in a new issue