Merge branch 'SnowflakePowered:master' into master
This commit is contained in:
commit
9f6e5aaac2
24 changed files with 719 additions and 584 deletions
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -38,6 +38,9 @@ jobs:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- run: pip install meson ninja mako
|
- run: pip install meson ninja mako
|
||||||
name: Install Meson for spirv-to-dxil-sys
|
name: Install Meson for spirv-to-dxil-sys
|
||||||
|
- if: runner.os == 'Windows'
|
||||||
|
name: Install winflexbison
|
||||||
|
run: choco install winflexbison3
|
||||||
- name: Build dynamic library
|
- name: Build dynamic library
|
||||||
run: cargo run -p librashader-build-script -- --profile ${{ matrix.profile }}
|
run: cargo run -p librashader-build-script -- --profile ${{ matrix.profile }}
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
|
|
913
Cargo.lock
generated
913
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -14,6 +14,7 @@ members = [
|
||||||
"librashader-capi",
|
"librashader-capi",
|
||||||
"librashader-build-script"
|
"librashader-build-script"
|
||||||
]
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.metadata.release]
|
[workspace.metadata.release]
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ impl<T: ShaderCompilation + for<'de> serde::Deserialize<'de> + serde::Serialize
|
||||||
|
|
||||||
let Ok(cache) = cache else {
|
let Ok(cache) = cache else {
|
||||||
return Ok(CachedCompilation {
|
return Ok(CachedCompilation {
|
||||||
compilation: T::compile(source)?
|
compilation: T::compile(source)?,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = {
|
let key = {
|
||||||
|
|
|
@ -18,7 +18,9 @@ impl CacheKey for windows::Win32::Graphics::Direct3D::Dxc::IDxcBlob {
|
||||||
|
|
||||||
impl Cacheable for windows::Win32::Graphics::Direct3D::ID3DBlob {
|
impl Cacheable for windows::Win32::Graphics::Direct3D::ID3DBlob {
|
||||||
fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
||||||
let Some(blob) = (unsafe { windows::Win32::Graphics::Direct3D::Fxc::D3DCreateBlob(bytes.len()).ok() }) else {
|
let Some(blob) =
|
||||||
|
(unsafe { windows::Win32::Graphics::Direct3D::Fxc::D3DCreateBlob(bytes.len()).ok() })
|
||||||
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,11 +46,18 @@ impl Cacheable for windows::Win32::Graphics::Direct3D::Dxc::IDxcBlob {
|
||||||
fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
||||||
let Some(blob) = (unsafe {
|
let Some(blob) = (unsafe {
|
||||||
windows::Win32::Graphics::Direct3D::Dxc::DxcCreateInstance(
|
windows::Win32::Graphics::Direct3D::Dxc::DxcCreateInstance(
|
||||||
&windows::Win32::Graphics::Direct3D::Dxc::CLSID_DxcLibrary)
|
&windows::Win32::Graphics::Direct3D::Dxc::CLSID_DxcLibrary,
|
||||||
.and_then(|library: windows::Win32::Graphics::Direct3D::Dxc::IDxcUtils| {
|
)
|
||||||
library.CreateBlob(bytes.as_ptr().cast(), bytes.len() as u32,
|
.and_then(
|
||||||
windows::Win32::Graphics::Direct3D::Dxc::DXC_CP(0))
|
|library: windows::Win32::Graphics::Direct3D::Dxc::IDxcUtils| {
|
||||||
}).ok()
|
library.CreateBlob(
|
||||||
|
bytes.as_ptr().cast(),
|
||||||
|
bytes.len() as u32,
|
||||||
|
windows::Win32::Graphics::Direct3D::Dxc::DXC_CP(0),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
}) else {
|
}) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub type PFN_libra_error_errno = extern "C" fn(error: libra_error_t) -> LIBRA_ER
|
||||||
/// - `error` must be valid and initialized.
|
/// - `error` must be valid and initialized.
|
||||||
pub unsafe extern "C" fn libra_error_errno(error: libra_error_t) -> LIBRA_ERRNO {
|
pub unsafe extern "C" fn libra_error_errno(error: libra_error_t) -> LIBRA_ERRNO {
|
||||||
let Some(error) = error else {
|
let Some(error) = error else {
|
||||||
return LIBRA_ERRNO::UNKNOWN_ERROR
|
return LIBRA_ERRNO::UNKNOWN_ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe { error.as_ref().get_code() }
|
unsafe { error.as_ref().get_code() }
|
||||||
|
@ -82,9 +82,7 @@ pub type PFN_libra_error_print = extern "C" fn(error: libra_error_t) -> i32;
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `error` must be a valid and initialized instance of `libra_error_t`.
|
/// - `error` must be a valid and initialized instance of `libra_error_t`.
|
||||||
pub unsafe extern "C" fn libra_error_print(error: libra_error_t) -> i32 {
|
pub unsafe extern "C" fn libra_error_print(error: libra_error_t) -> i32 {
|
||||||
let Some(error) = error else {
|
let Some(error) = error else { return 1 };
|
||||||
return 1
|
|
||||||
};
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let error = error.as_ref();
|
let error = error.as_ref();
|
||||||
println!("{error:?}: {error}");
|
println!("{error:?}: {error}");
|
||||||
|
@ -130,9 +128,7 @@ pub unsafe extern "C" fn libra_error_write(
|
||||||
error: libra_error_t,
|
error: libra_error_t,
|
||||||
out: *mut MaybeUninit<*mut c_char>,
|
out: *mut MaybeUninit<*mut c_char>,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let Some(error) = error else {
|
let Some(error) = error else { return 1 };
|
||||||
return 1
|
|
||||||
};
|
|
||||||
if out.is_null() {
|
if out.is_null() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +136,7 @@ pub unsafe extern "C" fn libra_error_write(
|
||||||
unsafe {
|
unsafe {
|
||||||
let error = error.as_ref();
|
let error = error.as_ref();
|
||||||
let Ok(cstring) = CString::new(format!("{error:?}: {error}")) else {
|
let Ok(cstring) = CString::new(format!("{error:?}: {error}")) else {
|
||||||
return 1
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
out.write(MaybeUninit::new(cstring.into_raw()))
|
out.write(MaybeUninit::new(cstring.into_raw()))
|
||||||
|
|
|
@ -25,7 +25,7 @@ fn read_file(path: impl AsRef<Path>) -> Result<String, PreprocessError> {
|
||||||
let buf = e.into_bytes();
|
let buf = e.into_bytes();
|
||||||
let decoder = WINDOWS_1252.new_decoder();
|
let decoder = WINDOWS_1252.new_decoder();
|
||||||
let Some(len) = decoder.max_utf8_buffer_length_without_replacement(buf.len()) else {
|
let Some(len) = decoder.max_utf8_buffer_length_without_replacement(buf.len()) else {
|
||||||
return Err(PreprocessError::EncodingError(path.to_path_buf()))
|
return Err(PreprocessError::EncodingError(path.to_path_buf()));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut latin1_string = String::with_capacity(len);
|
let mut latin1_string = String::with_capacity(len);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! as input to create a filter chain.
|
//! as input to create a filter chain.
|
||||||
//!
|
//!
|
||||||
//! Re-exported as [`librashader::presets`](https://docs.rs/librashader/latest/librashader/presets/index.html).
|
//! Re-exported as [`librashader::presets`](https://docs.rs/librashader/latest/librashader/presets/index.html).
|
||||||
#![feature(drain_filter)]
|
#![feature(extract_if)]
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod parse;
|
mod parse;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{ParameterConfig, Scale2D, Scaling, ShaderPassConfig, ShaderPreset, T
|
||||||
|
|
||||||
pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
let textures: Vec<TextureConfig> = values
|
let textures: Vec<TextureConfig> = values
|
||||||
.drain_filter(|f| matches!(*f, Value::Texture { .. }))
|
.extract_if(|f| matches!(*f, Value::Texture { .. }))
|
||||||
.map(|value| {
|
.map(|value| {
|
||||||
if let Value::Texture {
|
if let Value::Texture {
|
||||||
name,
|
name,
|
||||||
|
@ -27,7 +27,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let parameters: Vec<ParameterConfig> = values
|
let parameters: Vec<ParameterConfig> = values
|
||||||
.drain_filter(|f| matches!(*f, Value::Parameter { .. }))
|
.extract_if(|f| matches!(*f, Value::Parameter { .. }))
|
||||||
.map(|value| {
|
.map(|value| {
|
||||||
if let Value::Parameter(name, value) = value {
|
if let Value::Parameter(name, value) = value {
|
||||||
ParameterConfig { name, value }
|
ParameterConfig { name, value }
|
||||||
|
@ -64,7 +64,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
|v| matches!(*v, Value::Shader(shader_index, _) if shader_index == shader),
|
|v| matches!(*v, Value::Shader(shader_index, _) if shader_index == shader),
|
||||||
) {
|
) {
|
||||||
let shader_values: Vec<Value> = values
|
let shader_values: Vec<Value> = values
|
||||||
.drain_filter(|v| v.shader_index() == Some(shader))
|
.extract_if(|v| v.shader_index() == Some(shader))
|
||||||
.collect();
|
.collect();
|
||||||
let scale_type = shader_values.iter().find_map(|f| match f {
|
let scale_type = shader_values.iter().find_map(|f| match f {
|
||||||
Value::ScaleType(_, value) => Some(*value),
|
Value::ScaleType(_, value) => Some(*value),
|
||||||
|
|
|
@ -187,7 +187,7 @@ fn load_child_reference_strings(
|
||||||
|
|
||||||
let mut new_tokens = do_lex(&reference_contents)?;
|
let mut new_tokens = do_lex(&reference_contents)?;
|
||||||
let new_references: Vec<PathBuf> = new_tokens
|
let new_references: Vec<PathBuf> = new_tokens
|
||||||
.drain_filter(|token| *token.key.fragment() == "#reference")
|
.extract_if(|token| *token.key.fragment() == "#reference")
|
||||||
.map(|value| PathBuf::from(*value.value.fragment()))
|
.map(|value| PathBuf::from(*value.value.fragment()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ pub fn parse_values(
|
||||||
}
|
}
|
||||||
|
|
||||||
let references: Vec<PathBuf> = tokens
|
let references: Vec<PathBuf> = tokens
|
||||||
.drain_filter(|token| *token.key.fragment() == "#reference")
|
.extract_if(|token| *token.key.fragment() == "#reference")
|
||||||
.map(|value| PathBuf::from(*value.value.fragment()))
|
.map(|value| PathBuf::from(*value.value.fragment()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ pub fn parse_values(
|
||||||
// collect all possible parameter names.
|
// collect all possible parameter names.
|
||||||
let mut parameter_names: Vec<&str> = Vec::new();
|
let mut parameter_names: Vec<&str> = Vec::new();
|
||||||
for (_, tokens) in all_tokens.iter_mut() {
|
for (_, tokens) in all_tokens.iter_mut() {
|
||||||
for token in tokens.drain_filter(|token| *token.key.fragment() == "parameters") {
|
for token in tokens.extract_if(|token| *token.key.fragment() == "parameters") {
|
||||||
let parameter_name_string: &str = token.value.fragment();
|
let parameter_name_string: &str = token.value.fragment();
|
||||||
for parameter_name in parameter_name_string.split(';') {
|
for parameter_name in parameter_name_string.split(';') {
|
||||||
parameter_names.push(parameter_name);
|
parameter_names.push(parameter_name);
|
||||||
|
@ -265,7 +265,7 @@ pub fn parse_values(
|
||||||
// collect all possible texture names.
|
// collect all possible texture names.
|
||||||
let mut texture_names: Vec<&str> = Vec::new();
|
let mut texture_names: Vec<&str> = Vec::new();
|
||||||
for (_, tokens) in all_tokens.iter_mut() {
|
for (_, tokens) in all_tokens.iter_mut() {
|
||||||
for token in tokens.drain_filter(|token| *token.key.fragment() == "textures") {
|
for token in tokens.extract_if(|token| *token.key.fragment() == "textures") {
|
||||||
let texture_name_string: &str = token.value.fragment();
|
let texture_name_string: &str = token.value.fragment();
|
||||||
for texture_name in texture_name_string.split(';') {
|
for texture_name in texture_name_string.split(';') {
|
||||||
texture_names.push(texture_name);
|
texture_names.push(texture_name);
|
||||||
|
@ -276,7 +276,7 @@ pub fn parse_values(
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
// resolve shader paths.
|
// resolve shader paths.
|
||||||
for (path, tokens) in all_tokens.iter_mut() {
|
for (path, tokens) in all_tokens.iter_mut() {
|
||||||
for token in tokens.drain_filter(|token| parse_indexed_key("shader", token.key).is_ok()) {
|
for token in tokens.extract_if(|token| parse_indexed_key("shader", token.key).is_ok()) {
|
||||||
let (_, index) = parse_indexed_key("shader", token.key).map_err(|e| match e {
|
let (_, index) = parse_indexed_key("shader", token.key).map_err(|e| match e {
|
||||||
nom::Err::Error(e) | nom::Err::Failure(e) => {
|
nom::Err::Error(e) | nom::Err::Failure(e) => {
|
||||||
let input: Span = e.input;
|
let input: Span = e.input;
|
||||||
|
@ -307,7 +307,7 @@ pub fn parse_values(
|
||||||
// resolve texture paths
|
// resolve texture paths
|
||||||
let mut textures = Vec::new();
|
let mut textures = Vec::new();
|
||||||
for (path, tokens) in all_tokens.iter_mut() {
|
for (path, tokens) in all_tokens.iter_mut() {
|
||||||
for token in tokens.drain_filter(|token| texture_names.contains(token.key.fragment())) {
|
for token in tokens.extract_if(|token| texture_names.contains(token.key.fragment())) {
|
||||||
let mut relative_path = path.to_path_buf();
|
let mut relative_path = path.to_path_buf();
|
||||||
relative_path.push(*token.value.fragment());
|
relative_path.push(*token.value.fragment());
|
||||||
relative_path
|
relative_path
|
||||||
|
|
|
@ -24,7 +24,7 @@ librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.4"
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.1.4" }
|
librashader-presets = { path = "../librashader-presets", version = "0.1.4" }
|
||||||
|
|
||||||
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true }
|
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true }
|
||||||
spirv-to-dxil = { version = "0.3", optional = true }
|
spirv-to-dxil = { version = "0.4", optional = true }
|
||||||
naga = { version = "0.11.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
|
naga = { version = "0.11.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
|
||||||
|
|
||||||
rspirv = { version = "0.11.0+1.5.4", optional = true }
|
rspirv = { version = "0.11.0+1.5.4", optional = true }
|
||||||
|
|
|
@ -59,6 +59,7 @@ impl CompileShader<DXIL> for WriteSpirV {
|
||||||
register_space: 0,
|
register_space: 0,
|
||||||
base_shader_register: 1,
|
base_shader_register: 1,
|
||||||
},
|
},
|
||||||
|
shader_model_max: sm,
|
||||||
..RuntimeConfig::default()
|
..RuntimeConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,7 +69,6 @@ impl CompileShader<DXIL> for WriteSpirV {
|
||||||
None,
|
None,
|
||||||
"main",
|
"main",
|
||||||
ShaderStage::Vertex,
|
ShaderStage::Vertex,
|
||||||
sm,
|
|
||||||
ValidatorVersion::None,
|
ValidatorVersion::None,
|
||||||
&config,
|
&config,
|
||||||
)
|
)
|
||||||
|
@ -79,7 +79,6 @@ impl CompileShader<DXIL> for WriteSpirV {
|
||||||
None,
|
None,
|
||||||
"main",
|
"main",
|
||||||
ShaderStage::Fragment,
|
ShaderStage::Fragment,
|
||||||
sm,
|
|
||||||
ValidatorVersion::None,
|
ValidatorVersion::None,
|
||||||
&config,
|
&config,
|
||||||
)
|
)
|
||||||
|
|
|
@ -54,10 +54,26 @@ pub(crate) type GlslReflect = CrossReflect<glsl::Target>;
|
||||||
|
|
||||||
impl ValidateTypeSemantics<Type> for UniqueSemantics {
|
impl ValidateTypeSemantics<Type> for UniqueSemantics {
|
||||||
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
|
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
|
||||||
let (Type::Float { ref array, vecsize, columns, .. }
|
let (Type::Float {
|
||||||
| Type::Int { ref array, vecsize, columns, .. }
|
ref array,
|
||||||
| Type::UInt { ref array, vecsize, columns, .. }) = *ty else {
|
vecsize,
|
||||||
return None
|
columns,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| Type::Int {
|
||||||
|
ref array,
|
||||||
|
vecsize,
|
||||||
|
columns,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| Type::UInt {
|
||||||
|
ref array,
|
||||||
|
vecsize,
|
||||||
|
columns,
|
||||||
|
..
|
||||||
|
}) = *ty
|
||||||
|
else {
|
||||||
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !array.is_empty() {
|
if !array.is_empty() {
|
||||||
|
@ -93,8 +109,14 @@ impl ValidateTypeSemantics<Type> for UniqueSemantics {
|
||||||
|
|
||||||
impl ValidateTypeSemantics<Type> for TextureSemantics {
|
impl ValidateTypeSemantics<Type> for TextureSemantics {
|
||||||
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
|
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
|
||||||
let Type::Float { ref array, vecsize, columns, .. } = *ty else {
|
let Type::Float {
|
||||||
return None
|
ref array,
|
||||||
|
vecsize,
|
||||||
|
columns,
|
||||||
|
..
|
||||||
|
} = *ty
|
||||||
|
else {
|
||||||
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !array.is_empty() {
|
if !array.is_empty() {
|
||||||
|
@ -295,7 +317,7 @@ where
|
||||||
|
|
||||||
if let Some(parameter) = semantics.uniform_semantics.get_unique_semantic(&name) {
|
if let Some(parameter) = semantics.uniform_semantics.get_unique_semantic(&name) {
|
||||||
let Some(typeinfo) = parameter.semantics.validate_type(&range_type) else {
|
let Some(typeinfo) = parameter.semantics.validate_type(&range_type) else {
|
||||||
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)))
|
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)));
|
||||||
};
|
};
|
||||||
|
|
||||||
match ¶meter.semantics {
|
match ¶meter.semantics {
|
||||||
|
@ -372,7 +394,7 @@ where
|
||||||
}
|
}
|
||||||
} else if let Some(texture) = semantics.uniform_semantics.get_texture_semantic(&name) {
|
} else if let Some(texture) = semantics.uniform_semantics.get_texture_semantic(&name) {
|
||||||
let Some(_typeinfo) = texture.semantics.validate_type(&range_type) else {
|
let Some(_typeinfo) = texture.semantics.validate_type(&range_type) else {
|
||||||
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)))
|
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)));
|
||||||
};
|
};
|
||||||
|
|
||||||
if let TextureSemantics::PassOutput = texture.semantics {
|
if let TextureSemantics::PassOutput = texture.semantics {
|
||||||
|
@ -488,8 +510,15 @@ where
|
||||||
semantics: &ShaderSemantics,
|
semantics: &ShaderSemantics,
|
||||||
meta: &mut BindingMeta,
|
meta: &mut BindingMeta,
|
||||||
) -> Result<(), ShaderReflectError> {
|
) -> Result<(), ShaderReflectError> {
|
||||||
let Some(semantic) = semantics.texture_semantics.get_texture_semantic(texture.name) else {
|
let Some(semantic) = semantics
|
||||||
return Err(SemanticErrorBlame::Fragment.error(SemanticsErrorKind::UnknownSemantics(texture.name.to_string())))
|
.texture_semantics
|
||||||
|
.get_texture_semantic(texture.name)
|
||||||
|
else {
|
||||||
|
return Err(
|
||||||
|
SemanticErrorBlame::Fragment.error(SemanticsErrorKind::UnknownSemantics(
|
||||||
|
texture.name.to_string(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if semantic.semantics == TextureSemantics::PassOutput && semantic.index >= pass_number {
|
if semantic.semantics == TextureSemantics::PassOutput && semantic.index >= pass_number {
|
||||||
|
|
|
@ -361,7 +361,9 @@ impl TextureSemanticMap for FxHashMap<String, Semantic<TextureSemantics>> {
|
||||||
{
|
{
|
||||||
if semantics.is_indexed() {
|
if semantics.is_indexed() {
|
||||||
let index = &name[semantics.texture_name().len()..];
|
let index = &name[semantics.texture_name().len()..];
|
||||||
let Ok(index) = usize::from_str(index) else {return None};
|
let Ok(index) = usize::from_str(index) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
return Some(Semantic {
|
return Some(Semantic {
|
||||||
semantics: *semantics,
|
semantics: *semantics,
|
||||||
index,
|
index,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::texture::{D3D11InputView, InputTexture, LutTexture};
|
use crate::texture::{D3D11InputView, InputTexture, LutTexture};
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
|
|
||||||
use librashader_presets::{ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::GlslangCompilation;
|
use librashader_reflect::front::GlslangCompilation;
|
||||||
|
@ -45,9 +45,6 @@ pub struct FilterMutable {
|
||||||
pub(crate) parameters: FxHashMap<String, f32>,
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta =
|
|
||||||
ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation> + Send>;
|
|
||||||
|
|
||||||
/// A Direct3D 11 filter chain.
|
/// A Direct3D 11 filter chain.
|
||||||
pub struct FilterChainD3D11 {
|
pub struct FilterChainD3D11 {
|
||||||
pub(crate) common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
|
@ -75,6 +72,24 @@ pub(crate) struct FilterCommon {
|
||||||
pub(crate) draw_quad: DrawQuad,
|
pub(crate) draw_quad: DrawQuad,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShaderPassMeta =
|
||||||
|
ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation> + Send>;
|
||||||
|
fn compile_passes(
|
||||||
|
shaders: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
disable_cache: bool,
|
||||||
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
HLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
||||||
|
shaders, &textures,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
HLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(shaders, &textures)?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
|
||||||
impl FilterChainD3D11 {
|
impl FilterChainD3D11 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub unsafe fn load_from_path(
|
pub unsafe fn load_from_path(
|
||||||
|
@ -121,17 +136,7 @@ impl FilterChainD3D11 {
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures, disable_cache)?;
|
||||||
HLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
HLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let samplers = SamplerSet::new(device)?;
|
let samplers = SamplerSet::new(device)?;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::samplers::SamplerSet;
|
||||||
use crate::texture::{D3D12InputImage, D3D12OutputView, InputTexture, OutputDescriptor};
|
use crate::texture::{D3D12InputImage, D3D12OutputView, InputTexture, OutputDescriptor};
|
||||||
use crate::{error, util};
|
use crate::{error, util};
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_presets::{ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::{DXIL, HLSL};
|
use librashader_reflect::back::targets::{DXIL, HLSL};
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::GlslangCompilation;
|
use librashader_reflect::front::GlslangCompilation;
|
||||||
|
@ -54,11 +54,6 @@ use rayon::prelude::*;
|
||||||
|
|
||||||
const MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS: usize = 4096;
|
const MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS: usize = 4096;
|
||||||
|
|
||||||
type DxilShaderPassMeta =
|
|
||||||
ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation> + Send>;
|
|
||||||
type HlslShaderPassMeta =
|
|
||||||
ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation> + Send>;
|
|
||||||
|
|
||||||
pub struct FilterMutable {
|
pub struct FilterMutable {
|
||||||
pub(crate) passes_enabled: usize,
|
pub(crate) passes_enabled: usize,
|
||||||
pub(crate) parameters: FxHashMap<String, f32>,
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
|
@ -148,6 +143,41 @@ impl Drop for FrameResiduals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DxilShaderPassMeta =
|
||||||
|
ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation> + Send>;
|
||||||
|
fn compile_passes_dxil(
|
||||||
|
shaders: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
disable_cache: bool,
|
||||||
|
) -> Result<(Vec<DxilShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
DXIL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
||||||
|
shaders, &textures,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
DXIL::compile_preset_passes::<GlslangCompilation, FilterChainError>(shaders, &textures)?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
type HlslShaderPassMeta =
|
||||||
|
ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation> + Send>;
|
||||||
|
fn compile_passes_hlsl(
|
||||||
|
shaders: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
disable_cache: bool,
|
||||||
|
) -> Result<(Vec<HlslShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
HLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
||||||
|
shaders, &textures,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
HLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(shaders, &textures)?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
|
||||||
impl FilterChainD3D12 {
|
impl FilterChainD3D12 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub unsafe fn load_from_path(
|
pub unsafe fn load_from_path(
|
||||||
|
@ -219,29 +249,9 @@ impl FilterChainD3D12 {
|
||||||
let shader_copy = preset.shaders.clone();
|
let shader_copy = preset.shaders.clone();
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) =
|
||||||
DXIL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
compile_passes_dxil(preset.shaders, &preset.textures, disable_cache)?;
|
||||||
preset.shaders,
|
let (hlsl_passes, _) = compile_passes_hlsl(shader_copy, &preset.textures, disable_cache)?;
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
DXIL::compile_preset_passes::<GlslangCompilation, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let (hlsl_passes, _) = if !disable_cache {
|
|
||||||
HLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
|
||||||
shader_copy,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
HLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(
|
|
||||||
shader_copy,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let samplers = SamplerSet::new(device)?;
|
let samplers = SamplerSet::new(device)?;
|
||||||
let mipmap_gen = D3D12MipmapGen::new(device, false)?;
|
let mipmap_gen = D3D12MipmapGen::new(device, false)?;
|
||||||
|
@ -368,7 +378,7 @@ impl FilterChainD3D12 {
|
||||||
texture.filter_mode,
|
texture.filter_mode,
|
||||||
texture.wrap_mode,
|
texture.wrap_mode,
|
||||||
texture.mipmap,
|
texture.mipmap,
|
||||||
gc
|
gc,
|
||||||
)?;
|
)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
|
@ -424,40 +434,50 @@ impl FilterChainD3D12 {
|
||||||
let (sampler_work_heaps, _, sampler_heap_handle) =
|
let (sampler_work_heaps, _, sampler_heap_handle) =
|
||||||
unsafe { sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize, 0) };
|
unsafe { sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize, 0) };
|
||||||
|
|
||||||
let filters: Vec<error::Result<_>> = passes.into_par_iter()
|
let filters: Vec<error::Result<_>> = passes
|
||||||
|
.into_par_iter()
|
||||||
.zip(hlsl_passes)
|
.zip(hlsl_passes)
|
||||||
.zip(work_heaps)
|
.zip(work_heaps)
|
||||||
.zip(sampler_work_heaps)
|
.zip(sampler_work_heaps)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map_init(
|
.map_init(
|
||||||
|| {
|
|| {
|
||||||
let validator: IDxcValidator = unsafe { DxcCreateInstance(&CLSID_DxcValidator)? };
|
let validator: IDxcValidator =
|
||||||
|
unsafe { DxcCreateInstance(&CLSID_DxcValidator)? };
|
||||||
let library: IDxcUtils = unsafe { DxcCreateInstance(&CLSID_DxcLibrary)? };
|
let library: IDxcUtils = unsafe { DxcCreateInstance(&CLSID_DxcLibrary)? };
|
||||||
let compiler: IDxcCompiler = unsafe { DxcCreateInstance(&CLSID_DxcCompiler)? };
|
let compiler: IDxcCompiler = unsafe { DxcCreateInstance(&CLSID_DxcCompiler)? };
|
||||||
Ok::<_, FilterChainError>((validator, library, compiler))
|
Ok::<_, FilterChainError>((validator, library, compiler))
|
||||||
},
|
},
|
||||||
|dxc, (index, ((((config, source, mut dxil),
|
|dxc,
|
||||||
(_, _, mut hlsl)), mut texture_heap), mut sampler_heap))| {
|
(
|
||||||
let Ok((validator, library, compiler)) = dxc else {
|
index,
|
||||||
return Err(FilterChainError::Direct3DOperationError("Could not initialize DXC for thread"));
|
(
|
||||||
};
|
(((config, source, mut dxil), (_, _, mut hlsl)), mut texture_heap),
|
||||||
|
mut sampler_heap,
|
||||||
|
),
|
||||||
|
)| {
|
||||||
|
let Ok((validator, library, compiler)) = dxc else {
|
||||||
|
return Err(FilterChainError::Direct3DOperationError(
|
||||||
|
"Could not initialize DXC for thread",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
let dxil_reflection = dxil.reflect(index, semantics)?;
|
let dxil_reflection = dxil.reflect(index, semantics)?;
|
||||||
let dxil = dxil.compile(Some(
|
let dxil = dxil.compile(Some(
|
||||||
librashader_reflect::back::dxil::ShaderModel::ShaderModel6_0,
|
librashader_reflect::back::dxil::ShaderModel::ShaderModel6_0,
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let render_format = if let Some(format) = config.get_format_override() {
|
let render_format = if let Some(format) = config.get_format_override() {
|
||||||
format
|
format
|
||||||
} else if source.format != ImageFormat::Unknown {
|
} else if source.format != ImageFormat::Unknown {
|
||||||
source.format
|
source.format
|
||||||
} else {
|
} else {
|
||||||
ImageFormat::R8G8B8A8Unorm
|
ImageFormat::R8G8B8A8Unorm
|
||||||
}.into();
|
}
|
||||||
|
.into();
|
||||||
|
|
||||||
|
// incredibly cursed.
|
||||||
// incredibly cursed.
|
let (reflection, graphics_pipeline) = if !force_hlsl &&
|
||||||
let (reflection, graphics_pipeline) = if !force_hlsl &&
|
|
||||||
let Ok(graphics_pipeline) =
|
let Ok(graphics_pipeline) =
|
||||||
D3D12GraphicsPipeline::new_from_dxil(
|
D3D12GraphicsPipeline::new_from_dxil(
|
||||||
device,
|
device,
|
||||||
|
@ -494,11 +514,11 @@ impl FilterChainD3D12 {
|
||||||
|
|
||||||
let uniform_storage = UniformStorage::new_with_storage(
|
let uniform_storage = UniformStorage::new_with_storage(
|
||||||
RawD3D12Buffer::new(D3D12Buffer::new(device, ubo_size)?)?,
|
RawD3D12Buffer::new(D3D12Buffer::new(device, ubo_size)?)?,
|
||||||
RawD3D12Buffer::new(D3D12Buffer::new(device, push_size)?)?
|
RawD3D12Buffer::new(D3D12Buffer::new(device, push_size)?)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let uniform_bindings =
|
||||||
let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset());
|
reflection.meta.create_binding_map(|param| param.offset());
|
||||||
|
|
||||||
let texture_heap = texture_heap.alloc_range()?;
|
let texture_heap = texture_heap.alloc_range()?;
|
||||||
let sampler_heap = sampler_heap.alloc_range()?;
|
let sampler_heap = sampler_heap.alloc_range()?;
|
||||||
|
@ -513,8 +533,9 @@ impl FilterChainD3D12 {
|
||||||
sampler_heap,
|
sampler_heap,
|
||||||
source,
|
source,
|
||||||
})
|
})
|
||||||
|
},
|
||||||
}).collect();
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
let filters: error::Result<Vec<_>> = filters.into_iter().collect();
|
let filters: error::Result<Vec<_>> = filters.into_iter().collect();
|
||||||
let filters = filters?;
|
let filters = filters?;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::error::assume_d3d12_init;
|
use crate::error::assume_d3d12_init;
|
||||||
|
use crate::filter_chain::FrameResiduals;
|
||||||
use crate::mipmap::MipmapGenContext;
|
use crate::mipmap::MipmapGenContext;
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
|
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
|
||||||
|
@ -22,7 +23,6 @@ use windows::Win32::Graphics::Direct3D12::{
|
||||||
D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||||
use crate::filter_chain::FrameResiduals;
|
|
||||||
|
|
||||||
pub struct LutTexture {
|
pub struct LutTexture {
|
||||||
resource: ID3D12Resource,
|
resource: ID3D12Resource,
|
||||||
|
|
|
@ -10,6 +10,7 @@ use windows::Win32::Graphics::Direct3D::Dxc::{
|
||||||
DXC_CP_UTF8,
|
DXC_CP_UTF8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::filter_chain::FrameResiduals;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
|
||||||
D3D12_FEATURE_FORMAT_SUPPORT, D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT,
|
D3D12_FEATURE_FORMAT_SUPPORT, D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT,
|
||||||
|
@ -20,7 +21,6 @@ use windows::Win32::Graphics::Direct3D12::{
|
||||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::*;
|
use windows::Win32::Graphics::Dxgi::Common::*;
|
||||||
use crate::filter_chain::FrameResiduals;
|
|
||||||
|
|
||||||
/// wtf retroarch?
|
/// wtf retroarch?
|
||||||
const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000);
|
const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000);
|
||||||
|
@ -273,7 +273,7 @@ pub(crate) fn d3d12_update_subresources(
|
||||||
&num_rows,
|
&num_rows,
|
||||||
&row_sizes_in_bytes,
|
&row_sizes_in_bytes,
|
||||||
source,
|
source,
|
||||||
gc
|
gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,11 +228,11 @@ unsafe extern "system" fn debug_log(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod d3d12_hello_triangle {
|
pub mod d3d12_hello_triangle {
|
||||||
use std::mem::ManuallyDrop;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::hello_triangle::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
use crate::hello_triangle::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
||||||
use librashader_common::{Size, Viewport};
|
use librashader_common::{Size, Viewport};
|
||||||
use librashader_runtime_d3d12::{D3D12InputImage, D3D12OutputView, FilterChainD3D12};
|
use librashader_runtime_d3d12::{D3D12InputImage, D3D12OutputView, FilterChainD3D12};
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
@ -571,7 +571,11 @@ pub mod d3d12_hello_triangle {
|
||||||
// Record commands.
|
// Record commands.
|
||||||
unsafe {
|
unsafe {
|
||||||
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1006
|
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1006
|
||||||
command_list.ClearRenderTargetView(rtv_handle, &*[0.3, 0.4, 0.6, 1.0].as_ptr(), Some(&[]));
|
command_list.ClearRenderTargetView(
|
||||||
|
rtv_handle,
|
||||||
|
&*[0.3, 0.4, 0.6, 1.0].as_ptr(),
|
||||||
|
Some(&[]),
|
||||||
|
);
|
||||||
command_list.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
command_list.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
command_list.IASetVertexBuffers(0, Some(&[resources.vbv]));
|
command_list.IASetVertexBuffers(0, Some(&[resources.vbv]));
|
||||||
command_list.DrawInstanced(3, 1, 0, 0);
|
command_list.DrawInstanced(3, 1, 0, 0);
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn triangle_d3d12() {
|
||||||
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
|
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
|
||||||
//"../test/shaders_slang/crt/crt-lottes.slangp",
|
//"../test/shaders_slang/crt/crt-lottes.slangp",
|
||||||
// "../test/basic.slangp",
|
// "../test/basic.slangp",
|
||||||
"../test/shaders_slang/handheld/console-border/gbc-lcd-grid-v2.slangp",
|
"../test/shaders_slang/handheld/console-border/gbc-lcd-grid-v2.slangp",
|
||||||
// "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_GBA_SP/GBA_SP-[ADV]-[LCD-GRID]-[Night].slangp",
|
// "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_GBA_SP/GBA_SP-[ADV]-[LCD-GRID]-[Night].slangp",
|
||||||
// "../test/slang-shaders/test/feedback.slangp",
|
// "../test/slang-shaders/test/feedback.slangp",
|
||||||
// "../test/slang-shaders/test/history.slangp",
|
// "../test/slang-shaders/test/history.slangp",
|
||||||
|
@ -17,6 +17,6 @@ fn triangle_d3d12() {
|
||||||
use_warp_device: false,
|
use_warp_device: false,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::main(sample).unwrap()
|
hello_triangle::main(sample).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{error, GLImage};
|
||||||
use gl::types::GLuint;
|
use gl::types::GLuint;
|
||||||
use librashader_common::Viewport;
|
use librashader_common::Viewport;
|
||||||
|
|
||||||
use librashader_presets::ShaderPreset;
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::cross::GlslVersion;
|
use librashader_reflect::back::cross::GlslVersion;
|
||||||
use librashader_reflect::back::targets::GLSL;
|
use librashader_reflect::back::targets::GLSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
|
@ -98,6 +98,21 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<GLSL, GlslangCompilation>>;
|
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<GLSL, GlslangCompilation>>;
|
||||||
|
fn compile_passes(
|
||||||
|
shaders: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
disable_cache: bool,
|
||||||
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
GLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
||||||
|
shaders, &textures,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
GLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(shaders, &textures)?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChainImpl<T> {
|
impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
@ -106,19 +121,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures, disable_cache)?;
|
||||||
let (passes, semantics) = if !disable_cache {
|
|
||||||
GLSL::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
GLSL::compile_preset_passes::<GlslangCompilation, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let version = options.map_or_else(gl_get_version, |o| gl_u16_to_version(o.glsl_version));
|
let version = options.map_or_else(gl_get_version, |o| gl_u16_to_version(o.glsl_version));
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
//! See [`librashader::runtime::gl`](https://docs.rs/librashader/latest/librashader/runtime/gl/index.html) instead.
|
//! See [`librashader::runtime::gl`](https://docs.rs/librashader/latest/librashader/runtime/gl/index.html) instead.
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
#![feature(type_alias_impl_trait)]
|
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
mod binding;
|
mod binding;
|
||||||
mod filter_chain;
|
mod filter_chain;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ash::vk;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
|
|
||||||
use gpu_allocator::vulkan::Allocator;
|
use gpu_allocator::vulkan::Allocator;
|
||||||
use librashader_presets::{ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::SPIRV;
|
use librashader_reflect::back::targets::SPIRV;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::GlslangCompilation;
|
use librashader_reflect::front::GlslangCompilation;
|
||||||
|
@ -46,9 +46,6 @@ pub struct VulkanObjects {
|
||||||
// pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
// pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta =
|
|
||||||
ShaderPassArtifact<impl CompileReflectShader<SPIRV, GlslangCompilation> + Send>;
|
|
||||||
|
|
||||||
/// A collection of handles needed to access the Vulkan instance.
|
/// A collection of handles needed to access the Vulkan instance.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VulkanInstance {
|
pub struct VulkanInstance {
|
||||||
|
@ -208,6 +205,24 @@ impl Drop for FrameResiduals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShaderPassMeta =
|
||||||
|
ShaderPassArtifact<impl CompileReflectShader<SPIRV, GlslangCompilation> + Send>;
|
||||||
|
fn compile_passes(
|
||||||
|
shaders: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
disable_cache: bool,
|
||||||
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
SPIRV::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
||||||
|
shaders, &textures,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
SPIRV::compile_preset_passes::<GlslangCompilation, FilterChainError>(shaders, &textures)?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
|
||||||
impl FilterChainVulkan {
|
impl FilterChainVulkan {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub unsafe fn load_from_path<V, E>(
|
pub unsafe fn load_from_path<V, E>(
|
||||||
|
@ -307,18 +322,7 @@ impl FilterChainVulkan {
|
||||||
FilterChainError: From<E>,
|
FilterChainError: From<E>,
|
||||||
{
|
{
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures, disable_cache)?;
|
||||||
let (passes, semantics) = if !disable_cache {
|
|
||||||
SPIRV::compile_preset_passes::<CachedCompilation<GlslangCompilation>, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
SPIRV::compile_preset_passes::<GlslangCompilation, FilterChainError>(
|
|
||||||
preset.shaders,
|
|
||||||
&preset.textures,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let device = vulkan.try_into().map_err(From::from)?;
|
let device = vulkan.try_into().map_err(From::from)?;
|
||||||
|
|
||||||
|
|
|
@ -100,10 +100,10 @@ impl VulkanBuffer {
|
||||||
|
|
||||||
pub fn as_mut_slice(&mut self) -> error::Result<&mut [u8]> {
|
pub fn as_mut_slice(&mut self) -> error::Result<&mut [u8]> {
|
||||||
let Some(allocation) = self.memory.as_mut() else {
|
let Some(allocation) = self.memory.as_mut() else {
|
||||||
return Err(FilterChainError::AllocationDoesNotExist)
|
return Err(FilterChainError::AllocationDoesNotExist);
|
||||||
};
|
};
|
||||||
let Some(allocation) = allocation.mapped_slice_mut() else {
|
let Some(allocation) = allocation.mapped_slice_mut() else {
|
||||||
return Err(FilterChainError::AllocationDoesNotExist)
|
return Err(FilterChainError::AllocationDoesNotExist);
|
||||||
};
|
};
|
||||||
Ok(allocation)
|
Ok(allocation)
|
||||||
}
|
}
|
||||||
|
@ -147,11 +147,8 @@ impl RawVulkanBuffer {
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
let buffer = ManuallyDrop::new(VulkanBuffer::new(device, allocator, usage, size)?);
|
let buffer = ManuallyDrop::new(VulkanBuffer::new(device, allocator, usage, size)?);
|
||||||
|
|
||||||
let Some(ptr) = buffer.memory
|
let Some(ptr) = buffer.memory.as_ref().map(|m| m.mapped_ptr()).flatten() else {
|
||||||
.as_ref()
|
return Err(FilterChainError::AllocationDoesNotExist);
|
||||||
.map(|m| m.mapped_ptr())
|
|
||||||
.flatten() else {
|
|
||||||
return Err(FilterChainError::AllocationDoesNotExist)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(RawVulkanBuffer { buffer, ptr })
|
Ok(RawVulkanBuffer { buffer, ptr })
|
||||||
|
|
Loading…
Add table
Reference in a new issue