capi: finish capi for vulkan

This commit is contained in:
chyyran 2023-01-13 17:59:22 -05:00
parent 45d03fbfb8
commit 3e628093ae
27 changed files with 444 additions and 80 deletions

5
Cargo.lock generated
View file

@ -22,9 +22,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "ash" name = "ash"
version = "0.37.1+1.3.235" version = "0.37.2+1.3.238"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "911015c962d56e2e4052f40182ca5462ba60a3d2ff04e827c365a0ab3d65726d" checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03"
dependencies = [ dependencies = [
"libloading", "libloading",
] ]
@ -787,6 +787,7 @@ dependencies = [
name = "librashader-capi" name = "librashader-capi"
version = "0.1.0-alpha.5" version = "0.1.0-alpha.5"
dependencies = [ dependencies = [
"ash",
"gl", "gl",
"librashader", "librashader",
"paste", "paste",

View file

@ -6,7 +6,8 @@
librashader (*/ˈli:brəʃeɪdɚ/*) is a preprocessor, compiler, and runtime for RetroArch 'slang' shaders, rewritten in pure Rust. librashader (*/ˈli:brəʃeɪdɚ/*) is a preprocessor, compiler, and runtime for RetroArch 'slang' shaders, rewritten in pure Rust.
Heavily WIP. [![Latest Version](https://img.shields.io/crates/v/librashader.svg)](https://crates.io/crates/librashader) [![Docs](https://docs.rs/librashader/badge.svg)](https://docs.rs/librashader) ![License](https://img.shields.io/crates/l/librashader)
![Nightly rust](https://img.shields.io/badge/rust-nightly-orange.svg)
## Supported Render APIs ## Supported Render APIs
librashader supports OpenGL 3, OpenGL 4.6, Vulkan, DirectX 11, and DirectX 12. Older versions librashader supports OpenGL 3, OpenGL 4.6, Vulkan, DirectX 11, and DirectX 12. Older versions

View file

@ -15,9 +15,10 @@ description = "RetroArch shaders for all."
crate-type = [ "cdylib", "staticlib" ] crate-type = [ "cdylib", "staticlib" ]
[features] [features]
default = ["runtime-opengl", "runtime-d3d11"] default = ["runtime-opengl", "runtime-d3d11", "runtime-vulkan"]
runtime-opengl = ["gl", "librashader/gl"] runtime-opengl = ["gl", "librashader/gl"]
runtime-d3d11 = ["windows", "librashader/d3d11"] runtime-d3d11 = ["windows", "librashader/d3d11"]
runtime-vulkan = ["ash", "librashader/vk"]
[dependencies] [dependencies]
librashader = { path = "../librashader", version = "0.1.0-alpha.5" } librashader = { path = "../librashader", version = "0.1.0-alpha.5" }
@ -25,6 +26,7 @@ thiserror = "1.0.37"
paste = "1.0.9" paste = "1.0.9"
gl = { version = "0.14.0", optional = true } gl = { version = "0.14.0", optional = true }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
ash = { version = "0.37.2+1.3.238", optional = true }
[dependencies.windows] [dependencies.windows]
version = "0.43.0" version = "0.43.0"

View file

@ -4,13 +4,14 @@ include_guard = "__LIBRASHADER_H__"
pragma_once = true pragma_once = true
usize_is_size_t = true usize_is_size_t = true
documentation_style = "c++" documentation_style = "c++"
after_includes = "#ifdef _WIN32 && RUNTIME_D3D11 \n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif" after_includes = "#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)\n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif\n#if defined(LIBRA_RUNTIME_VULKAN)\n#include <vulkan\\vulkan.h>\n#endif"
[defines] [defines]
"feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL" "feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL"
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11" "feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
"feature = runtime-vulkan" = "LIBRA_RUNTIME_VULKAN"
[parse] [parse]
parse_deps = true parse_deps = true
@ -19,7 +20,8 @@ include = ["librashader",
"librashader-preprocess", "librashader-preprocess",
"librashader-reflect", "librashader-reflect",
"librashader-runtime-gl", "librashader-runtime-gl",
"librashader-runtime-d3d11" "librashader-runtime-d3d11",
"librashader-runtime-vk",
] ]
expand = ["librashader-capi"] expand = ["librashader-capi"]
@ -66,4 +68,15 @@ include = [
"FrameOptionsGL" = "frame_gl_opt_t" "FrameOptionsGL" = "frame_gl_opt_t"
"FilterChainD3D11" = "_filter_chain_d3d11" "FilterChainD3D11" = "_filter_chain_d3d11"
"FilterChainOptionsD3D11" = "filter_chain_d3d11_opt_t" "FilterChainOptionsD3D11" = "filter_chain_d3d11_opt_t"
"FrameOptionsD3D11" = "frame_d3d11_opt_t" "FrameOptionsD3D11" = "frame_vk_opt_t"
"FilterChainVulkan" = "_filter_chain_vk"
"FilterChainOptionsVulkan" = "filter_chain_vk_opt_t"
"FrameOptionsVullam" = "frame_vk_opt_t"
# vulkan renames
"PhysicalDevice" = "VkPhysicalDevice"
"Instance" = "VkInstance"
"Device" = "VkDevice"
"CommandBuffer" = "VkCommandBuffer"
"Format" = "VkFormat"
"Image" = "VkImage"

View file

@ -8,11 +8,14 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32 && RUNTIME_D3D11 #if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
#include <d3d11.h> #include <d3d11.h>
#else #else
typedef void ID3D11Device; typedef void ID3D11RenderTargetView; typedef void ID3D1ShaderResourceView; typedef void ID3D11Device; typedef void ID3D11RenderTargetView; typedef void ID3D1ShaderResourceView;
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN)
#include <vulkan\vulkan.h>
#endif
/// Error codes for librashader error types. /// Error codes for librashader error types.
enum LIBRA_ERRNO enum LIBRA_ERRNO
@ -32,7 +35,13 @@ typedef int32_t LIBRA_ERRNO;
#endif // __cplusplus #endif // __cplusplus
/// A Direct3D 11 filter chain. /// A Direct3D 11 filter chain.
typedef struct FilterChain FilterChain; typedef struct _filter_chain_d3d11 _filter_chain_d3d11;
/// An OpenGL filter chain.
typedef struct _filter_chain_gl _filter_chain_gl;
/// A Vulkan filter chain.
typedef struct _filter_chain_vk _filter_chain_vk;
/// The error type for librashader. /// The error type for librashader.
typedef struct _libra_error _libra_error; typedef struct _libra_error _libra_error;
@ -49,23 +58,21 @@ typedef struct _shader_preset* libra_shader_preset_t;
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// A GL function loader that librashader needs to be initialized with. /// A GL function loader that librashader needs to be initialized with.
typedef const void* (*gl_loader_t)(const char*); typedef const void* (*libra_gl_loader_t)(const char*);
#endif #endif
/// Options for Direct3D11 filter chain creation. /// Options for filter chain creation.
typedef struct FilterChainOptions { typedef struct filter_chain_gl_opt_t {
/// Use a deferred context to record shader rendering state. /// The GLSL version. Should be at least `330`.
/// uint16_t gl_version;
/// The deferred context will be executed on the immediate context /// Whether or not to use the Direct State Access APIs. Only available on OpenGL 4.5+.
/// with `RenderContextState = true`. bool use_dsa;
bool use_deferred_context; /// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
/// Whether or not to explicitly disable mipmap
/// generation regardless of shader preset settings.
bool force_no_mipmaps; bool force_no_mipmaps;
} FilterChainOptions; } filter_chain_gl_opt_t;
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
typedef struct FilterChain* libra_gl_filter_chain_t; typedef struct _filter_chain_gl* libra_gl_filter_chain_t;
#endif #endif
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
@ -102,16 +109,28 @@ typedef struct libra_draw_framebuffer_gl_t {
} libra_draw_framebuffer_gl_t; } libra_draw_framebuffer_gl_t;
#endif #endif
/// Options for each Direct3D11 shader frame. /// Options for each OpenGL shader frame.
typedef struct FrameOptions { typedef struct frame_gl_opt_t {
/// Whether or not to clear the history buffers. /// Whether or not to clear the history buffers.
bool clear_history; bool clear_history;
/// The direction of the frame. 1 should be vertical. /// The direction of the frame. 1 should be vertical.
int32_t frame_direction; int32_t frame_direction;
} FrameOptions; } frame_gl_opt_t;
/// Options for Direct3D11 filter chain creation.
typedef struct filter_chain_d3d11_opt_t {
/// Use a deferred context to record shader rendering state.
///
/// The deferred context will be executed on the immediate context
/// with `RenderContextState = true`.
bool use_deferred_context;
/// Whether or not to explicitly disable mipmap
/// generation regardless of shader preset settings.
bool force_no_mipmaps;
} filter_chain_d3d11_opt_t;
#if defined(LIBRA_RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
typedef struct FilterChain* libra_d3d11_filter_chain_t; typedef struct _filter_chain_d3d11* libra_d3d11_filter_chain_t;
#endif #endif
#if defined(LIBRA_RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
@ -126,6 +145,65 @@ typedef struct libra_source_image_d3d11_t {
} libra_source_image_d3d11_t; } libra_source_image_d3d11_t;
#endif #endif
/// Options for each Direct3D11 shader frame.
typedef struct frame_vk_opt_t {
/// Whether or not to clear the history buffers.
bool clear_history;
/// The direction of the frame. 1 should be vertical.
int32_t frame_direction;
} frame_vk_opt_t;
#if defined(LIBRA_RUNTIME_VULKAN)
/// Handles required to instantiate vulkan
typedef struct libra_device_vk_t {
/// A raw `VkPhysicalDevice` handle
/// for the physical device that will perform rendering.
VkPhysicalDevice physical_device;
/// A raw `VkInstance` handle
/// for the Vulkan instance that will perform rendering.
VkInstance instance;
/// A raw `VkDevice` handle
/// for the device attached to the instance that will perform rendering.
VkDevice device;
/// The entry loader for the Vulkan library.
PFN_vkGetInstanceProcAddr entry;
} libra_device_vk_t;
#endif
/// Options for filter chain creation.
typedef struct filter_chain_vk_opt_t {
/// The number of frames in flight to keep. If zero, defaults to three.
uint32_t frames_in_flight;
/// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
bool force_no_mipmaps;
} filter_chain_vk_opt_t;
#if defined(LIBRA_RUNTIME_VULKAN)
typedef struct _filter_chain_vk* libra_vk_filter_chain_t;
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Vulkan parameters for the source image.
typedef struct libra_image_vk_t {
/// A raw `VkImage` handle to the source image.
VkImage handle;
/// The `VkFormat` of the source image.
VkFormat format;
/// The width of the source image.
uint32_t width;
/// The height of the source image.
uint32_t height;
} libra_image_vk_t;
#endif
/// Options for each Vulkan shader frame.
typedef struct FrameOptionsVulkan {
/// Whether or not to clear the history buffers.
bool clear_history;
/// The direction of the frame. 1 should be vertical.
int32_t frame_direction;
} FrameOptionsVulkan;
typedef libra_error_t(*PFN_libra_preset_free)(libra_shader_preset_t* preset); typedef libra_error_t(*PFN_libra_preset_free)(libra_shader_preset_t* preset);
typedef libra_error_t(*PFN_libra_preset_set_param)(libra_shader_preset_t* preset, typedef libra_error_t(*PFN_libra_preset_set_param)(libra_shader_preset_t* preset,
@ -152,12 +230,12 @@ typedef int32_t(*PFN_libra_error_write)(libra_error_t error, char** out);
typedef int32_t(*PFN_libra_error_free_string)(char** out); typedef int32_t(*PFN_libra_error_free_string)(char** out);
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
typedef libra_error_t(*PFN_libra_gl_init_context)(gl_loader_t loader); typedef libra_error_t(*PFN_libra_gl_init_context)(libra_gl_loader_t loader);
#endif #endif
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
typedef libra_error_t(*PFN_libra_gl_filter_chain_create)(libra_shader_preset_t* preset, typedef libra_error_t(*PFN_libra_gl_filter_chain_create)(libra_shader_preset_t* preset,
const struct FilterChainOptions* options, const struct filter_chain_gl_opt_t* options,
libra_gl_filter_chain_t* out); libra_gl_filter_chain_t* out);
#endif #endif
@ -168,7 +246,7 @@ typedef libra_error_t(*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t*
struct libra_viewport_t viewport, struct libra_viewport_t viewport,
struct libra_draw_framebuffer_gl_t out, struct libra_draw_framebuffer_gl_t out,
const float* mvp, const float* mvp,
const struct FrameOptions* opt); const struct frame_gl_opt_t* opt);
#endif #endif
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
@ -177,7 +255,7 @@ typedef libra_error_t(*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t*
#if defined(LIBRA_RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_create)(libra_shader_preset_t* preset, typedef libra_error_t(*PFN_libra_d3d11_filter_chain_create)(libra_shader_preset_t* preset,
const struct FilterChainOptions* options, const struct filter_chain_d3d11_opt_t* options,
const ID3D11Device* device, const ID3D11Device* device,
libra_d3d11_filter_chain_t* out); libra_d3d11_filter_chain_t* out);
#endif #endif
@ -189,7 +267,7 @@ typedef libra_error_t(*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_ch
struct libra_viewport_t viewport, struct libra_viewport_t viewport,
const ID3D11RenderTargetView* out, const ID3D11RenderTargetView* out,
const float* mvp, const float* mvp,
const struct FrameOptions* opt); const struct frame_vk_opt_t* opt);
#endif #endif
#if defined(LIBRA_RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
@ -294,7 +372,7 @@ extern "C" {
/// ///
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter /// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
/// chain objects, and drawing with them causes immediate undefined behaviour. /// chain objects, and drawing with them causes immediate undefined behaviour.
libra_error_t libra_gl_init_context(gl_loader_t loader); libra_error_t libra_gl_init_context(libra_gl_loader_t loader);
#endif #endif
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
@ -308,7 +386,7 @@ extern "C" {
/// - `options` must be either null, or valid and aligned. /// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized. /// - `out` must be aligned, but may be null, invalid, or uninitialized.
libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t* preset, libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t* preset,
const struct FilterChainOptions* options, const struct filter_chain_gl_opt_t* options,
libra_gl_filter_chain_t* out); libra_gl_filter_chain_t* out);
#endif #endif
@ -328,7 +406,7 @@ extern "C" {
struct libra_viewport_t viewport, struct libra_viewport_t viewport,
struct libra_draw_framebuffer_gl_t out, struct libra_draw_framebuffer_gl_t out,
const float* mvp, const float* mvp,
const struct FrameOptions* opt); const struct frame_gl_opt_t* opt);
#endif #endif
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
@ -351,7 +429,7 @@ extern "C" {
/// - `options` must be either null, or valid and aligned. /// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized. /// - `out` must be aligned, but may be null, invalid, or uninitialized.
libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t* preset, libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t* preset,
const struct FilterChainOptions* options, const struct filter_chain_d3d11_opt_t* options,
const ID3D11Device* device, const ID3D11Device* device,
libra_d3d11_filter_chain_t* out); libra_d3d11_filter_chain_t* out);
#endif #endif
@ -372,7 +450,7 @@ extern "C" {
struct libra_viewport_t viewport, struct libra_viewport_t viewport,
const ID3D11RenderTargetView* out, const ID3D11RenderTargetView* out,
const float* mvp, const float* mvp,
const struct FrameOptions* opt); const struct frame_vk_opt_t* opt);
#endif #endif
#if defined(LIBRA_RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
@ -384,6 +462,59 @@ extern "C" {
libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t* chain); libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t* chain);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Create the filter chain given the shader preset.
///
/// The shader preset is immediately invalidated and must be recreated after
/// the filter chain is created.
///
/// ## Safety:
/// - The handles provided in `vulkan` must be valid for the command buffers that
/// `libra_vk_filter_chain_frame` will write to. Namely, the VkDevice must have been
/// created with the `VK_KHR_dynamic_rendering` extension.
/// - `preset` must be either null, or valid and aligned.
/// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
libra_error_t libra_vk_filter_chain_create(struct libra_device_vk_t vulkan,
libra_shader_preset_t* preset,
const struct filter_chain_vk_opt_t* options,
libra_vk_filter_chain_t* out);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
///
/// librashader will not do any queue submissions.
///
/// ## Safety
/// - `libra_vk_filter_chain_frame` **must not be called within a RenderPass**.
/// - `command_buffer` must be a valid handle to a `VkCommandBuffer` that is ready for recording.
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
/// values for the model view projection matrix.
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
/// struct.
libra_error_t libra_vk_filter_chain_frame(libra_vk_filter_chain_t* chain,
VkCommandBuffer command_buffer,
size_t frame_count,
struct libra_image_vk_t image,
struct libra_viewport_t viewport,
struct libra_image_vk_t out,
const float* mvp,
const struct FrameOptionsVulkan* opt);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Free a GL filter chain.
///
/// The resulting value in `chain` then becomes null.
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
libra_error_t libra_vk_filter_chain_free(libra_vk_filter_chain_t* chain);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif // __cplusplus #endif // __cplusplus

View file

@ -13,6 +13,10 @@ pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::capi
pub type libra_d3d11_filter_chain_t = pub type libra_d3d11_filter_chain_t =
Option<NonNull<librashader::runtime::d3d11::capi::FilterChainD3D11>>; Option<NonNull<librashader::runtime::d3d11::capi::FilterChainD3D11>>;
#[cfg(feature = "runtime-vulkan")]
pub type libra_vk_filter_chain_t =
Option<NonNull<librashader::runtime::vk::capi::FilterChainVulkan>>;
/// Parameters for the output viewport. /// Parameters for the output viewport.
#[repr(C)] #[repr(C)]
pub struct libra_viewport_t { pub struct libra_viewport_t {

View file

@ -29,6 +29,9 @@ pub enum LibrashaderError {
#[cfg(feature = "runtime-d3d11")] #[cfg(feature = "runtime-d3d11")]
#[error("There was an error in the D3D11 filter chain.")] #[error("There was an error in the D3D11 filter chain.")]
D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError), D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError),
#[cfg(feature = "runtime-vulkan")]
#[error("There was an error in the Vulkan filter chain.")]
VulkanFilterError(#[from] librashader::runtime::vk::error::FilterChainError),
} }
/// Error codes for librashader error types. /// Error codes for librashader error types.
@ -167,6 +170,8 @@ impl LibrashaderError {
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-d3d11")] #[cfg(feature = "runtime-d3d11")]
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-vulkan")]
LibrashaderError::VulkanFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
} }
} }
pub(crate) const fn ok() -> libra_error_t { pub(crate) const fn ok() -> libra_error_t {

View file

@ -4,9 +4,9 @@
//! possible by linking against `librashader.h` as well as any static libraries used by `librashader`. //! possible by linking against `librashader.h` as well as any static libraries used by `librashader`.
//! //!
//! ## Usage //! ## Usage
//! ⚠ Rust consumers should take a look at [librashader](https://docs.rs/librashader/) //! ⚠ Rust consumers use [librashader](https://docs.rs/librashader/) directly instead.
//! //!
//! The C API is designed to be easy to use and safe. Most objects are only accessible behind an opaque pointer. //! The librashader C API is designed to be easy to use and safe. Most objects are only accessible behind an opaque pointer.
//! Every allocated object can be freed with a corresponding `free` function **for that specific object type**. //! Every allocated object can be freed with a corresponding `free` function **for that specific object type**.
//! //!
//! Once an object is freed, the input pointer is always set to null. Attempting to free an object that was not //! Once an object is freed, the input pointer is always set to null. Attempting to free an object that was not
@ -44,6 +44,7 @@ mod ffi;
pub mod presets; pub mod presets;
#[cfg(feature = "reflect")] #[cfg(feature = "reflect")]
#[doc(hidden)]
pub mod reflect; pub mod reflect;
pub mod runtime; pub mod runtime;

View file

@ -7,11 +7,6 @@ use std::ffi::{c_char, CStr, CString};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr::NonNull; use std::ptr::NonNull;
pub type PFN_lbr_preset_create = unsafe extern "C" fn(
filename: *const c_char,
out: *mut MaybeUninit<libra_shader_preset_t>,
) -> libra_error_t;
extern_fn! { extern_fn! {
/// Load a preset. /// Load a preset.
/// ///

View file

@ -14,7 +14,7 @@ pub use librashader::runtime::gl::capi::options::FrameOptionsGL;
use librashader::runtime::{Size, Viewport}; use librashader::runtime::{Size, Viewport};
/// A GL function loader that librashader needs to be initialized with. /// A GL function loader that librashader needs to be initialized with.
pub type gl_loader_t = unsafe extern "C" fn(*const c_char) -> *const c_void; pub type libra_gl_loader_t = unsafe extern "system" fn(*const c_char) -> *const c_void;
/// OpenGL parameters for the source image. /// OpenGL parameters for the source image.
#[repr(C)] #[repr(C)]
@ -59,7 +59,7 @@ extern_fn! {
/// ///
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter /// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
/// chain objects, and drawing with them causes immediate undefined behaviour. /// chain objects, and drawing with them causes immediate undefined behaviour.
raw fn libra_gl_init_context(loader: gl_loader_t) { raw fn libra_gl_init_context(loader: libra_gl_loader_t) {
gl::load_with(|s| unsafe { gl::load_with(|s| unsafe {
let proc_name = CString::new(s).unwrap_unchecked(); let proc_name = CString::new(s).unwrap_unchecked();
loader(proc_name.as_ptr()) loader(proc_name.as_ptr())

View file

@ -4,3 +4,6 @@ pub mod gl;
#[cfg(feature = "runtime-d3d11")] #[cfg(feature = "runtime-d3d11")]
pub mod d3d11; pub mod d3d11;
#[cfg(feature = "runtime-vulkan")]
pub mod vk;

View file

@ -0,0 +1,183 @@
use std::ffi::{c_char, c_void};
use crate::ctypes::{
libra_vk_filter_chain_t, libra_shader_preset_t, libra_viewport_t,
};
use crate::error::{assert_non_null, assert_some_ptr};
use crate::ffi::extern_fn;
use librashader::runtime::vk::{VulkanImage, VulkanInstance};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use std::slice;
pub use librashader::runtime::vk::capi::options::FilterChainOptionsVulkan;
pub use librashader::runtime::vk::capi::options::FrameOptionsVulkan;
use librashader::runtime::{Size, Viewport};
use ash::vk;
use ash::vk::Handle;
pub use ash::vk::PFN_vkGetInstanceProcAddr;
/// A Vulkan instance function loader that the Vulkan filter chain needs to be initialized with.
pub type libra_PFN_vkGetInstanceProcAddr = unsafe extern "system" fn(instance: *mut c_void, p_name: *const c_char);
/// Vulkan parameters for the source image.
#[repr(C)]
pub struct libra_image_vk_t {
/// A raw `VkImage` handle to the source image.
pub handle: vk::Image,
/// The `VkFormat` of the source image.
pub format: vk::Format,
/// The width of the source image.
pub width: u32,
/// The height of the source image.
pub height: u32,
}
/// Handles required to instantiate vulkan
#[repr(C)]
pub struct libra_device_vk_t {
/// A raw `VkPhysicalDevice` handle
/// for the physical device that will perform rendering.
pub physical_device: vk::PhysicalDevice,
/// A raw `VkInstance` handle
/// for the Vulkan instance that will perform rendering.
pub instance: vk::Instance,
/// A raw `VkDevice` handle
/// for the device attached to the instance that will perform rendering.
pub device: vk::Device,
/// The entry loader for the Vulkan library.
pub entry: vk::PFN_vkGetInstanceProcAddr
}
impl From<libra_image_vk_t> for VulkanImage {
fn from(value: libra_image_vk_t) -> Self {
VulkanImage {
size: Size::new(value.width, value.height),
image: value.handle,
format: value.format,
}
}
}
impl From<libra_device_vk_t> for VulkanInstance {
fn from(value: libra_device_vk_t) -> Self {
VulkanInstance {
device: value.device,
instance: value.instance,
physical_device: value.physical_device,
get_instance_proc_addr: value.entry,
}
}
}
extern_fn! {
/// Create the filter chain given the shader preset.
///
/// The shader preset is immediately invalidated and must be recreated after
/// the filter chain is created.
///
/// ## Safety:
/// - The handles provided in `vulkan` must be valid for the command buffers that
/// `libra_vk_filter_chain_frame` will write to. Namely, the VkDevice must have been
/// created with the `VK_KHR_dynamic_rendering` extension.
/// - `preset` must be either null, or valid and aligned.
/// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
fn libra_vk_filter_chain_create(
vulkan: libra_device_vk_t,
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsVulkan,
out: *mut MaybeUninit<libra_vk_filter_chain_t>
) {
assert_non_null!(preset);
let preset = unsafe {
let preset_ptr = &mut *preset;
let preset = preset_ptr.take();
Box::from_raw(preset.unwrap().as_ptr())
};
let options = if options.is_null() {
None
} else {
Some(unsafe { &*options })
};
let vulkan: VulkanInstance = vulkan.into();
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(vulkan, *preset, options)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain,
)))))
}
}
}
extern_fn! {
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
///
/// librashader will not do any queue submissions.
///
/// ## Safety
/// - `libra_vk_filter_chain_frame` **must not be called within a RenderPass**.
/// - `command_buffer` must be a valid handle to a `VkCommandBuffer` that is ready for recording.
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
/// values for the model view projection matrix.
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
/// struct.
fn libra_vk_filter_chain_frame(
chain: *mut libra_vk_filter_chain_t,
command_buffer: vk::CommandBuffer,
frame_count: usize,
image: libra_image_vk_t,
viewport: libra_viewport_t,
out: libra_image_vk_t,
mvp: *const f32,
opt: *const FrameOptionsVulkan
) mut |chain| {
assert_some_ptr!(mut chain);
let image: VulkanImage = image.into();
let output = out.into();
let mvp = if mvp.is_null() {
None
} else {
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
};
let opt = if opt.is_null() {
None
} else {
Some(unsafe { opt.read() })
};
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
output,
mvp,
};
chain.frame(&image, &viewport, command_buffer, frame_count, opt.as_ref())?;
}
}
extern_fn! {
/// Free a GL filter chain.
///
/// The resulting value in `chain` then becomes null.
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
fn libra_vk_filter_chain_free(
chain: *mut libra_vk_filter_chain_t
) {
assert_non_null!(chain);
unsafe {
let chain_ptr = &mut *chain;
let chain = chain_ptr.take();
drop(Box::from_raw(chain.unwrap().as_ptr()))
};
}
}

View file

@ -0,0 +1,4 @@
//! C API for the librashader OpenGL Runtime (`libra_gl_*`)
mod filter_chain;
pub use filter_chain::*;

View file

@ -53,7 +53,7 @@ const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] = &[
// slang_process.cpp 229 // slang_process.cpp 229
impl FilterPass { impl FilterPass {
pub fn get_format(&self) -> ImageFormat { pub fn get_format(&self) -> ImageFormat {
let mut fb_format = self.source.format; let fb_format = self.source.format;
if let Some(format) = self.config.get_format_override() { if let Some(format) = self.config.get_format_override() {
format format
} else if fb_format == ImageFormat::Unknown { } else if fb_format == ImageFormat::Unknown {

View file

@ -104,7 +104,7 @@ impl<T: GLInterface> FilterPass<T> {
impl<T: GLInterface> FilterPass<T> { impl<T: GLInterface> FilterPass<T> {
pub fn get_format(&self) -> ImageFormat { pub fn get_format(&self) -> ImageFormat {
let mut fb_format = self.source.format; let fb_format = self.source.format;
if let Some(format) = self.config.get_format_override() { if let Some(format) = self.config.get_format_override() {
format format
} else if fb_format == ImageFormat::Unknown { } else if fb_format == ImageFormat::Unknown {

View file

@ -3,7 +3,7 @@ use crate::framebuffer::GLImage;
use crate::gl::framebuffer::Framebuffer; use crate::gl::framebuffer::Framebuffer;
use crate::gl::FramebufferInterface; use crate::gl::FramebufferInterface;
use crate::texture::Texture; use crate::texture::Texture;
use gl::types::{GLenum, GLint, GLsizei, GLuint}; use gl::types::{GLenum, GLint, GLsizei};
use librashader_common::{ImageFormat, Size, Viewport}; use librashader_common::{ImageFormat, Size, Viewport};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ViewportSize};

View file

@ -3,7 +3,7 @@ use crate::framebuffer::GLImage;
use crate::gl::framebuffer::Framebuffer; use crate::gl::framebuffer::Framebuffer;
use crate::gl::FramebufferInterface; use crate::gl::FramebufferInterface;
use crate::texture::Texture; use crate::texture::Texture;
use gl::types::{GLenum, GLint, GLsizei, GLuint}; use gl::types::{GLenum, GLint, GLsizei};
use librashader_common::{ImageFormat, Size, Viewport}; use librashader_common::{ImageFormat, Size, Viewport};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ViewportSize};

View file

@ -29,7 +29,7 @@ use std::path::Path;
use crate::options::{FilterChainOptionsVulkan, FrameOptionsVulkan}; use crate::options::{FilterChainOptionsVulkan, FrameOptionsVulkan};
/// A Vulkan device and metadata that is required by the shader runtime. /// A Vulkan device and metadata that is required by the shader runtime.
pub struct VulkanDevice { pub struct VulkanObjects {
pub(crate) device: ash::Device, pub(crate) device: ash::Device,
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties, pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
queue: vk::Queue, queue: vk::Queue,
@ -55,7 +55,7 @@ pub struct VulkanInstance {
pub get_instance_proc_addr: vk::PFN_vkGetInstanceProcAddr, pub get_instance_proc_addr: vk::PFN_vkGetInstanceProcAddr,
} }
impl TryFrom<VulkanInstance> for VulkanDevice { impl TryFrom<VulkanInstance> for VulkanObjects {
type Error = FilterChainError; type Error = FilterChainError;
fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> { fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> {
@ -76,7 +76,7 @@ impl TryFrom<VulkanInstance> for VulkanDevice {
let memory_properties = let memory_properties =
instance.get_physical_device_memory_properties(vulkan.physical_device); instance.get_physical_device_memory_properties(vulkan.physical_device);
Ok(VulkanDevice { Ok(VulkanObjects {
device, device,
queue, queue,
pipeline_cache, pipeline_cache,
@ -87,7 +87,7 @@ impl TryFrom<VulkanInstance> for VulkanDevice {
} }
} }
impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanDevice { impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanObjects {
type Error = FilterChainError; type Error = FilterChainError;
fn try_from(value: (vk::PhysicalDevice, ash::Instance, ash::Device)) -> error::Result<Self> { fn try_from(value: (vk::PhysicalDevice, ash::Instance, ash::Device)) -> error::Result<Self> {
@ -100,7 +100,7 @@ impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanDevice
let memory_properties = value.1.get_physical_device_memory_properties(value.0); let memory_properties = value.1.get_physical_device_memory_properties(value.0);
Ok(VulkanDevice { Ok(VulkanObjects {
device, device,
queue, queue,
pipeline_cache, pipeline_cache,
@ -115,7 +115,7 @@ impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanDevice
pub struct FilterChainVulkan { pub struct FilterChainVulkan {
pub(crate) common: FilterCommon, pub(crate) common: FilterCommon,
passes: Box<[FilterPass]>, passes: Box<[FilterPass]>,
vulkan: VulkanDevice, vulkan: VulkanObjects,
output_framebuffers: Box<[OwnedImage]>, output_framebuffers: Box<[OwnedImage]>,
feedback_framebuffers: Box<[OwnedImage]>, feedback_framebuffers: Box<[OwnedImage]>,
history_framebuffers: VecDeque<OwnedImage>, history_framebuffers: VecDeque<OwnedImage>,
@ -191,7 +191,7 @@ impl Drop for FrameResiduals {
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 fn load_from_path( pub fn load_from_path(
vulkan: impl TryInto<VulkanDevice, Error = FilterChainError>, vulkan: impl TryInto<VulkanObjects, Error = FilterChainError>,
path: impl AsRef<Path>, path: impl AsRef<Path>,
options: Option<&FilterChainOptionsVulkan>, options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> { ) -> error::Result<FilterChainVulkan> {
@ -202,7 +202,7 @@ impl FilterChainVulkan {
/// Load a filter chain from a pre-parsed `ShaderPreset`. /// Load a filter chain from a pre-parsed `ShaderPreset`.
pub fn load_from_preset( pub fn load_from_preset(
vulkan: impl TryInto<VulkanDevice, Error = FilterChainError>, vulkan: impl TryInto<VulkanObjects, Error = FilterChainError>,
preset: ShaderPreset, preset: ShaderPreset,
options: Option<&FilterChainOptionsVulkan>, options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> { ) -> error::Result<FilterChainVulkan> {
@ -328,7 +328,7 @@ impl FilterChainVulkan {
} }
fn init_passes( fn init_passes(
vulkan: &VulkanDevice, vulkan: &VulkanObjects,
passes: Vec<ShaderPassMeta>, passes: Vec<ShaderPassMeta>,
semantics: &ShaderSemantics, semantics: &ShaderSemantics,
frames_in_flight: u32, frames_in_flight: u32,
@ -402,7 +402,7 @@ impl FilterChainVulkan {
} }
fn load_luts( fn load_luts(
vulkan: &VulkanDevice, vulkan: &VulkanObjects,
textures: &[TextureConfig], textures: &[TextureConfig],
) -> error::Result<FxHashMap<usize, LutTexture>> { ) -> error::Result<FxHashMap<usize, LutTexture>> {
let mut luts = FxHashMap::default(); let mut luts = FxHashMap::default();
@ -462,7 +462,7 @@ impl FilterChainVulkan {
} }
fn init_history( fn init_history(
vulkan: &VulkanDevice, vulkan: &VulkanObjects,
filters: &[FilterPass], filters: &[FilterPass],
) -> error::Result<(VecDeque<OwnedImage>, Box<[Option<InputImage>]>)> { ) -> error::Result<(VecDeque<OwnedImage>, Box<[Option<InputImage>]>)> {
let mut required_images = 0; let mut required_images = 0;
@ -580,11 +580,11 @@ impl FilterChainVulkan {
/// the output image to the final layout. /// the output image to the final layout.
pub fn frame( pub fn frame(
&mut self, &mut self,
count: usize,
viewport: &Viewport<VulkanImage>,
input: &VulkanImage, input: &VulkanImage,
viewport: &Viewport<VulkanImage>,
cmd: vk::CommandBuffer, cmd: vk::CommandBuffer,
options: Option<FrameOptionsVulkan>, count: usize,
options: Option<&FrameOptionsVulkan>,
) -> error::Result<()> { ) -> error::Result<()> {
let intermediates = &mut self.residuals[count % self.residuals.len()]; let intermediates = &mut self.residuals[count % self.residuals.len()];
intermediates.dispose(); intermediates.dispose();

View file

@ -1,4 +1,4 @@
use crate::filter_chain::VulkanDevice; use crate::filter_chain::VulkanObjects;
use crate::texture::VulkanImage; use crate::texture::VulkanImage;
use crate::{error, util}; use crate::{error, util};
use ash::vk; use ash::vk;
@ -13,7 +13,7 @@ pub(crate) struct OutputImage {
} }
impl OutputImage { impl OutputImage {
pub fn new(vulkan: &VulkanDevice, image: VulkanImage) -> error::Result<OutputImage> { pub fn new(vulkan: &VulkanObjects, image: VulkanImage) -> error::Result<OutputImage> {
let image_subresource = vk::ImageSubresourceRange::builder() let image_subresource = vk::ImageSubresourceRange::builder()
.base_mip_level(0) .base_mip_level(0)
.base_array_layer(0) .base_array_layer(0)

View file

@ -8,7 +8,7 @@ mod swapchain;
mod syncobjects; mod syncobjects;
pub mod vulkan_base; pub mod vulkan_base;
use crate::filter_chain::{FilterChainVulkan, VulkanDevice}; use crate::filter_chain::{FilterChainVulkan, VulkanObjects};
use crate::hello_triangle::command::VulkanCommandPool; use crate::hello_triangle::command::VulkanCommandPool;
use crate::hello_triangle::framebuffer::VulkanFramebuffer; use crate::hello_triangle::framebuffer::VulkanFramebuffer;
use crate::hello_triangle::pipeline::VulkanPipeline; use crate::hello_triangle::pipeline::VulkanPipeline;
@ -212,7 +212,11 @@ impl VulkanWindow {
filter filter
.frame( .frame(
frame, &VulkanImage {
size: vulkan.swapchain.extent.into(),
image: framebuffer_image,
format: vulkan.swapchain.format.format,
},
&Viewport { &Viewport {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
@ -223,12 +227,8 @@ impl VulkanWindow {
}, },
mvp: None, mvp: None,
}, },
&VulkanImage {
size: vulkan.swapchain.extent.into(),
image: framebuffer_image,
format: vulkan.swapchain.format.format,
},
cmd, cmd,
frame,
None, None,
) )
.unwrap(); .unwrap();

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use std::error::Error; use std::error::Error;
use crate::error::FilterChainError; use crate::error::FilterChainError;
use crate::filter_chain::VulkanDevice; use crate::filter_chain::VulkanObjects;
use crate::hello_triangle::debug::VulkanDebug; use crate::hello_triangle::debug::VulkanDebug;
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device}; use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
use crate::hello_triangle::surface::VulkanSurface; use crate::hello_triangle::surface::VulkanSurface;
@ -158,11 +158,11 @@ impl Drop for VulkanBase {
} }
} }
impl TryFrom<&VulkanBase> for VulkanDevice { impl TryFrom<&VulkanBase> for VulkanObjects {
type Error = FilterChainError; type Error = FilterChainError;
fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> { fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> {
VulkanDevice::try_from(( VulkanObjects::try_from((
value.physical_device, value.physical_device,
value.instance.clone(), value.instance.clone(),
value.device.clone(), value.device.clone(),

View file

@ -20,7 +20,7 @@ mod vulkan_primitives;
mod vulkan_state; mod vulkan_state;
pub use filter_chain::FilterChainVulkan; pub use filter_chain::FilterChainVulkan;
pub use filter_chain::VulkanDevice; pub use filter_chain::VulkanObjects;
pub use filter_chain::VulkanInstance; pub use filter_chain::VulkanInstance;
pub use texture::VulkanImage; pub use texture::VulkanImage;

View file

@ -1,4 +1,4 @@
use crate::filter_chain::VulkanDevice; use crate::filter_chain::VulkanObjects;
use crate::texture::{InputImage, VulkanImage}; use crate::texture::{InputImage, VulkanImage};
use crate::vulkan_primitives::{VulkanBuffer, VulkanImageMemory}; use crate::vulkan_primitives::{VulkanBuffer, VulkanImageMemory};
use crate::{error, util}; use crate::{error, util};
@ -15,7 +15,7 @@ pub struct LutTexture {
impl LutTexture { impl LutTexture {
pub fn new( pub fn new(
vulkan: &VulkanDevice, vulkan: &VulkanObjects,
cmd: vk::CommandBuffer, cmd: vk::CommandBuffer,
image: Image<BGRA8>, image: Image<BGRA8>,
config: &TextureConfig, config: &TextureConfig,

View file

@ -1,4 +1,4 @@
use crate::filter_chain::VulkanDevice; use crate::filter_chain::VulkanObjects;
use crate::util::find_vulkan_memory_type; use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory; use crate::vulkan_primitives::VulkanImageMemory;
use crate::{error, util}; use crate::{error, util};
@ -114,7 +114,7 @@ impl OwnedImage {
} }
pub fn new( pub fn new(
vulkan: &VulkanDevice, vulkan: &VulkanObjects,
size: Size<u32>, size: Size<u32>,
format: ImageFormat, format: ImageFormat,
max_miplevels: u32, max_miplevels: u32,

View file

@ -28,6 +28,9 @@
//! | DirectX 9 | ❌ | | //! | DirectX 9 | ❌ | |
//! | Metal | ❌ | | //! | Metal | ❌ | |
//! //!
//! ## C API
//! For documentation on the librashader C API, see [librashader_capi](https://docs.rs/librashader-capi/latest/librashader_capi/),
//! or [`librashader.h`](https://github.com/SnowflakePowered/librashader/blob/master/librashader-capi/librashader.h).
#[cfg(feature = "presets")] #[cfg(feature = "presets")]
/// Parsing and usage of shader presets. /// Parsing and usage of shader presets.
@ -150,7 +153,7 @@ pub mod runtime {
FrameOptionsVulkan as FrameOptions, FrameOptionsVulkan as FrameOptions,
}, },
FilterChainVulkan as FilterChain, FilterChainVulkan as FilterChain,
VulkanImage, VulkanDevice, VulkanInstance, VulkanImage, VulkanObjects, VulkanInstance,
error error
}; };

View file

@ -4,7 +4,15 @@
#include <iostream> #include <iostream>
#include <filesystem> #include <filesystem>
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
VK_DEFINE_HANDLE(VkInstance)
typedef void (*PFN_vkVoidFunction)(void);
typedef PFN_vkVoidFunction(*PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);
#define LIBRA_RUNTIME_OPENGL #define LIBRA_RUNTIME_OPENGL
#define LIBRA_RUNTIME_VULKAN
#include "../../../../librashader-capi/librashader.h" #include "../../../../librashader-capi/librashader.h"
int main() int main()
{ {
@ -16,8 +24,12 @@ int main()
std::cout << "error happened\n"; std::cout << "error happened\n";
} }
libra_preset_print(&preset); libra_preset_print(&preset);
libra_gl_filter_chain_t chain; libra_gl_filter_chain_t chain;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
libra_PFN_vkGetInstanceProcAddr entry = reinterpret_cast<libra_PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr);
error = libra_gl_filter_chain_create(NULL, NULL, &chain); error = libra_gl_filter_chain_create(NULL, NULL, &chain);
if (error != NULL) { if (error != NULL) {
libra_error_print(error); libra_error_print(error);

View file

@ -110,10 +110,13 @@
<TreatAngleIncludeAsExternal>false</TreatAngleIncludeAsExternal> <TreatAngleIncludeAsExternal>false</TreatAngleIncludeAsExternal>
<LanguageStandard>stdcpplatest</LanguageStandard> <LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<AdditionalIncludeDirectories>D:\Runtime\Vulkan\1.3.224.1\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>D:\Runtime\Vulkan\1.3.224.1\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -124,12 +127,15 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>D:\Runtime\Vulkan\1.3.224.1\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>D:\Runtime\Vulkan\1.3.224.1\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>