api: fix feature flags to allow building a proper subset of librashader

This commit is contained in:
chyyran 2023-02-07 18:50:26 -05:00
parent 07b20fecdc
commit d1771a8b25
10 changed files with 115 additions and 73 deletions

5
Cargo.lock generated
View file

@ -751,7 +751,6 @@ dependencies = [
"librashader-runtime-d3d12",
"librashader-runtime-gl",
"librashader-runtime-vk",
"librashader-spirv-cross",
"windows",
]
@ -1014,9 +1013,9 @@ dependencies = [
[[package]]
name = "naga"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707"
checksum = "5eafe22a23b797c9bc227c6c896419b26b5bb88fa903417a3adaed08778850d5"
dependencies = [
"bit-set",
"bitflags",

View file

@ -33,7 +33,7 @@ librashader provides both a Rust API under the `librashader` crate, and a C API.
The C API is geared more towards integration with existing projects. The Rust `librashader` crate exposes more
of the internals if you wish to use parts of librashader piecemeal.
The librashader C API is best used by linking statically with `librashader_ld`, which implements a loader that dynamically
The librashader C API is best used by including `librashader_ld.h` in your project, which implements a loader that dynamically
loads the librashader (`librashader.so` or `librashader.dll`) implementation in the search path.
### Building
@ -106,35 +106,62 @@ Please report an issue if you run into a shader that works in RetroArch, but not
* Unlike RetroArch, librashader does not have full knowledge of the entire rendering state and is designed to be pluggable
at any point in your render pipeline. Instead, filter chains terminate at a caller-provided output surface and viewport.
It is the caller's responsibility to blit the surface back to the backbuffer.
* Shaders are compiled in parallel where possible. This should noticeably decrease preset compile times. Note that parallel compilation
is not available to OpenGL.
* Runtime-specific differences
* OpenGL
* Copying of in-flight framebuffer contents to history is done via `glBlitFramebuffer` rather than drawing a quad into an intermediate FBO.
* Sampler objects are used rather than `glTexParameter`.
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
* OpenGL 4.6+
* All caveats from the OpenGL 3.3+ section should be considered.
* Should work on OpenGL 4.5 but this is not guaranteed. The OpenGL 4.6 runtime may eventually switch to using `ARB_spirv_extensions` for loading shaders, and this will not be marked as a breaking change.
* The OpenGL 4.6 runtime uses Direct State Access to minimize changes to the OpenGL state. For GPUs released within the last 5 years, this may improve performance.
* Vulkan
* The Vulkan runtime uses [`VK_KHR_dynamic_rendering`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dynamic_rendering.html) by default.
This extension must be enabled at device creation. Explicit render passes can be used by configuring filter chain options, but may have reduced performance
compared to dynamic rendering.
* UBOs use multiple discontiguous buffers. This may be improved in the future by switching to VMA rather than manually handling allocations.
* Direct3D 11
* Framebuffer copies are done via `ID3D11DeviceContext::CopySubresourceRegion` rather than a CPU conversion + copy.
* HDR10 support is not part of the shader runtime and is not supported.
* Direct3D 12
* The Direct3D 12 runtime uses [render passes](https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-render-passes). This feature has been available since Windows 10 version 1809,
which was released in late 2018.
* For maximum compatibility with shaders, a shader compile pipeline based on [`spirv-to-dxil`](https://github.com/SnowflakePowered/spirv-to-dxil-rs) is used, with the SPIRV-Cross HLSL pipeline used as a fallback.
This brings shader compatibility beyond what the RetroArch Direct3D 12 runtime provides. The HLSL pipeline fallback may be removed in the future as `spirv-to-dxil` improves.
* Shaders are compiled in parallel where possible. This should noticeably decrease preset compile times.
Parallel shader compilation is not available to OpenGL.
* HDR10 support is not part of any shader runtime and is not supported by librashader.
### Runtime specific differences
* OpenGL
* Copying of in-flight framebuffer contents to history is done via `glBlitFramebuffer` rather than drawing a quad into an intermediate FBO.
* Sampler objects are used rather than `glTexParameter`.
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
* OpenGL 4.6+
* All caveats from the OpenGL 3.3+ section should be considered.
* Should work on OpenGL 4.5 but this is not guaranteed. The OpenGL 4.6 runtime may eventually switch to using `ARB_spirv_extensions` for loading shaders, and this will not be marked as a breaking change.
* The OpenGL 4.6 runtime uses Direct State Access to minimize changes to the OpenGL state. For GPUs released within the last 5 years, this may improve performance.
* Vulkan
* The Vulkan runtime uses [`VK_KHR_dynamic_rendering`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dynamic_rendering.html) by default.
This extension must be enabled at device creation. Explicit render passes can be used by configuring filter chain options, but may have reduced performance
compared to dynamic rendering.
* UBOs use multiple discontiguous buffers. This may be improved in the future by switching to VMA rather than manually handling allocations.
* Direct3D 11
* Framebuffer copies are done via `ID3D11DeviceContext::CopySubresourceRegion` rather than a CPU conversion + copy.
* Direct3D 12
* The Direct3D 12 runtime uses [render passes](https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-render-passes). This feature has been available since Windows 10 version 1809,
which was released in late 2018.
* For maximum compatibility with shaders, a shader compile pipeline based on [`spirv-to-dxil`](https://github.com/SnowflakePowered/spirv-to-dxil-rs) is used, with the SPIRV-Cross HLSL pipeline used as a fallback.
This brings shader compatibility beyond what the RetroArch Direct3D 12 runtime provides. The HLSL pipeline fallback may be removed in the future as `spirv-to-dxil` improves.
Most, if not all shader presets should work fine on librashader. The runtime specific differences should not affect the output,
and are more a heads-up for integrating librashader into your project.
### Quad vertices and rotations
All runtimes except OpenGL render with an identity matrix MVP and a VBO for with range `[-1, 1]`. The final pass uses a
Quad VBO with range `[0, 1]` and the following projection matrix by default.
```rust
static DEFAULT_MVP: &[f32; 16] = &[
2.0, 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
-1.0, -1.0, 0.0, 1.0,
];
```
As with RetroArch, a rotation on this MVP will be applied only on the final pass for these runtimes. This is the only way to
pass orientation information to shaders.
The OpenGL runtime uses a VBO for range `[0, 1]` for all passes and the following MVP for all passes.
```rust
static GL_DEFAULT_MVP: &[f32; 16] = &[
2.0, 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 2.0, 0.0,
-1.0, -1.0, 0.0, 1.0,
];
```
### Writing a librashader Runtime
If you wish to contribute a runtime implementation not already available, see the [librashader-runtime](https://docs.rs/librashader-runtime/latest/librashader_runtime/)

View file

@ -16,10 +16,10 @@ crate-type = [ "cdylib", "staticlib" ]
[features]
default = ["runtime-opengl", "runtime-d3d11", "runtime-d3d12", "runtime-vulkan"]
runtime-opengl = ["gl", "librashader/gl"]
runtime-d3d11 = ["windows", "librashader/d3d11", "windows/Win32_Graphics_Direct3D11"]
runtime-d3d12 = ["windows", "librashader/d3d12", "windows/Win32_Graphics_Direct3D12"]
runtime-vulkan = ["ash", "librashader/vk"]
runtime-opengl = ["gl", "librashader/runtime-gl"]
runtime-d3d11 = ["windows", "librashader/runtime-d3d11", "windows/Win32_Graphics_Direct3D11"]
runtime-d3d12 = ["windows", "librashader/runtime-d3d12", "windows/Win32_Graphics_Direct3D12"]
runtime-vulkan = ["ash", "librashader/runtime-vk"]
[dependencies]
librashader = { path = "../librashader", version = "0.1.0-beta.14", features = ["internal"] }

View file

@ -13,7 +13,7 @@ description = "RetroArch shaders for all."
[dependencies]
shaderc = { version = "0.8.2", features = [] }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", features = [ "glsl", "hlsl" ] }
bytemuck = "1.13.0"
thiserror = "1.0.37"
bitflags = "1.3.2"
@ -23,14 +23,15 @@ librashader-common = { path = "../librashader-common", version = "0.1.0-beta.14"
librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.0-beta.14" }
librashader-presets = { path = "../librashader-presets", version = "0.1.0-beta.14" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true }
spirv-to-dxil = { version = "0.3", optional = true }
naga = { version = "0.10.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 }
bytemuck = "1.13.0"
rspirv = { version = "0.11.0+1.5.4", optional = true }
[features]
default = ["dxil"]
default = ["cross", "dxil"]
unstable-naga = [ "naga", "rspirv" ]
standalone = ["shaderc/build-from-source"]
dxil = ["spirv-to-dxil"]
cross = [ "spirv_cross", "spirv_cross/glsl", "spirv_cross/hlsl" ]

View file

@ -5,11 +5,11 @@ use crate::front::GlslangCompilation;
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect};
use crate::reflect::ReflectShader;
/// The GLSL version to use.
pub type GlslVersion = spirv_cross::glsl::Version;
/// The GLSL version to target.
pub use spirv_cross::glsl::Version as GlslVersion;
/// The HLSL shader model version to use
pub type HlslVersion = spirv_cross::hlsl::ShaderModel;
/// The HLSL shader model version to target.
pub use spirv_cross::hlsl::ShaderModel as HlslShaderModel;
/// The context for a GLSL compilation via spirv-cross.
pub struct CrossGlslContext {
@ -43,7 +43,7 @@ pub struct CrossHlslContext {
impl FromCompilation<GlslangCompilation> for HLSL {
type Target = HLSL;
type Options = Option<HlslVersion>;
type Options = Option<HlslShaderModel>;
type Context = CrossHlslContext;
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
+ ReflectShader;

View file

@ -9,11 +9,10 @@ use crate::reflect::semantics::{
use crate::reflect::{align_uniform_size, ReflectShader};
use std::ops::Deref;
use spirv_cross::hlsl::ShaderModel;
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
use spirv_cross::{glsl, hlsl, ErrorCode};
use crate::back::cross::{CrossGlslContext, CrossHlslContext, HlslVersion};
use crate::back::cross::{CrossGlslContext, CrossHlslContext, HlslShaderModel};
use crate::back::targets::{GLSL, HLSL};
use crate::back::{CompileShader, ShaderCompilerOutput};
use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData};
@ -826,14 +825,14 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
}
impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
type Options = Option<HlslVersion>;
type Options = Option<HlslShaderModel>;
type Context = CrossHlslContext;
fn compile(
mut self,
options: Self::Options,
) -> Result<ShaderCompilerOutput<String, CrossHlslContext>, ShaderCompileError> {
let sm = options.unwrap_or(ShaderModel::V5_0);
let sm = options.unwrap_or(HlslShaderModel::V5_0);
let mut options = hlsl::CompilerOptions::default();
options.shader_model = sm;

View file

@ -3,10 +3,10 @@ use gl::types::{GLsizei, GLsizeiptr, GLuint};
#[rustfmt::skip]
static QUAD_VBO_DATA: &[f32; 16] = &[
0.0f32, 0.0f32, 0.0f32, 0.0f32,
1.0f32, 0.0f32, 1.0f32, 0.0f32,
0.0f32, 1.0f32, 0.0f32, 1.0f32,
1.0f32, 1.0f32, 1.0f32, 1.0f32,
0.0, 0.0, 0.0, 0.0,
1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 1.0,
];
pub struct Gl3DrawQuad {

View file

@ -3,10 +3,10 @@ use gl::types::{GLint, GLsizeiptr, GLuint};
#[rustfmt::skip]
static QUAD_VBO_DATA: &[f32; 16] = &[
0.0f32, 0.0f32, 0.0f32, 0.0f32,
1.0f32, 0.0f32, 1.0f32, 0.0f32,
0.0f32, 1.0f32, 0.0f32, 1.0f32,
1.0f32, 1.0f32, 1.0f32, 1.0f32,
0.0, 0.0, 0.0, 0.0,
1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 1.0,
];
pub struct Gl46DrawQuad {

View file

@ -24,23 +24,33 @@ librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.1.0-
librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.1.0-beta.14", optional = true }
ash = { version = "0.37.1+1.3.235", optional = true }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", features = ["glsl", "hlsl"], optional = true }
[target.'cfg(windows)'.dependencies.windows]
version = "0.44.0"
optional = true
[features]
default = ["gl", "d3d11", "d3d12", "vk", "reflect", "preprocess", "presets" ]
gl = [ "runtime", "librashader-common/opengl", "librashader-runtime-gl", "spirv_cross" ]
d3d11 = [ "runtime", "librashader-common/d3d11", "librashader-runtime-d3d11", "windows/Win32_Graphics_Direct3D11" ]
d3d12 = [ "runtime", "librashader-reflect/dxil", "librashader-common/d3d12", "librashader-runtime-d3d12", "windows/Win32_Graphics_Direct3D12" ]
vk = ["runtime", "librashader-common/vulkan", "librashader-runtime-vk", "ash" ]
# core features and definitions
runtime = []
reflect = []
preprocess = []
presets = []
# runtimes
runtime-gl = [ "runtime", "reflect-cross", "librashader-common/opengl", "librashader-runtime-gl" ]
runtime-d3d11 = [ "runtime", "reflect-cross","librashader-common/d3d11", "librashader-runtime-d3d11", "windows/Win32_Graphics_Direct3D11" ]
runtime-d3d12 = [ "runtime", "reflect-cross", "reflect-dxil", "librashader-common/d3d12", "librashader-runtime-d3d12", "windows/Win32_Graphics_Direct3D12" ]
runtime-vk = ["runtime", "reflect-cross", "librashader-common/vulkan", "librashader-runtime-vk", "ash" ]
# reflection
reflect-cross = ["reflect", "librashader-reflect/cross"]
reflect-dxil = ["reflect", "librashader-reflect/dxil"]
runtime-all = ["runtime-gl", "runtime-d3d11", "runtime-d3d12", "runtime-vk"]
reflect-all = ["reflect-cross", "reflect-dxil"]
# enable all features by default
default = [ "runtime-all", "reflect-all", "preprocess", "presets" ]
internal = []
[package.metadata.docs.rs]

View file

@ -145,14 +145,18 @@ pub mod reflect {
};
/// Reflection via SPIRV-Cross.
#[cfg(feature = "reflect-cross")]
#[doc(cfg(feature = "reflect-cross"))]
pub mod cross {
pub use librashader_reflect::front::GlslangCompilation;
/// The version of GLSL to target.
pub use spirv_cross::glsl::Version as GlslVersion;
///
pub use librashader_reflect::back::cross::GlslVersion;
/// The HLSL Shader Model to target.
pub use spirv_cross::hlsl::ShaderModel as HlslVersion;
///
pub use librashader_reflect::back::cross::HlslShaderModel;
pub use librashader_reflect::back::cross::CrossGlslContext;
@ -164,6 +168,8 @@ pub mod reflect {
}
/// DXIL reflection via spirv-to-dxil.
#[cfg(feature = "reflect-dxil")]
#[doc(cfg(feature = "reflect-dxil"))]
pub mod dxil {
/// The maximum shader model to use when compiling the DXIL blob.
pub use librashader_reflect::back::dxil::ShaderModel;
@ -194,13 +200,13 @@ pub mod runtime {
pub use librashader_common::{Size, Viewport};
pub use librashader_runtime::parameters::FilterChainParameters;
#[cfg(feature = "gl")]
#[doc(cfg(feature = "gl"))]
#[cfg(feature = "runtime-gl")]
#[doc(cfg(feature = "runtime-gl"))]
/// Shader runtime for OpenGL 3.3+.
///
/// DSA support requires OpenGL 4.6.
///
/// Note that the OpenGL runtime requires `gl` to be
/// The OpenGL runtime requires `gl` to be
/// initialized with [`gl::load_with`](https://docs.rs/gl/0.14.0/gl/fn.load_with.html).
pub mod gl {
pub use librashader_runtime_gl::{
@ -219,8 +225,8 @@ pub mod runtime {
}
}
#[cfg(all(target_os = "windows", feature = "d3d11"))]
#[doc(cfg(all(target_os = "windows", feature = "d3d11")))]
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
/// Shader runtime for Direct3D 11.
pub mod d3d11 {
pub use librashader_runtime_d3d11::{
@ -241,8 +247,8 @@ pub mod runtime {
}
}
#[cfg(all(target_os = "windows", feature = "d3d12"))]
#[doc(cfg(all(target_os = "windows", feature = "d3d12")))]
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
/// Shader runtime for Direct3D 12.
pub mod d3d12 {
pub use librashader_runtime_d3d12::{
@ -263,8 +269,8 @@ pub mod runtime {
}
}
#[cfg(feature = "vk")]
#[doc(cfg(feature = "vk"))]
#[cfg(feature = "runtime-vk")]
#[doc(cfg(feature = "runtime-vk"))]
/// Shader runtime for Vulkan.
pub mod vk {
pub use librashader_runtime_vk::{