rt(gl): remove need for explicit external FBO object
Replaced with an internal FBO that is state tracked so as to not recreate it every frame, but will update if necessary
This commit is contained in:
parent
4d790e7a7b
commit
41353ac9c4
|
@ -194,33 +194,17 @@ typedef struct _filter_chain_gl *libra_gl_filter_chain_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_OPENGL)
|
#if defined(LIBRA_RUNTIME_OPENGL)
|
||||||
/// OpenGL parameters for the source image.
|
/// OpenGL parameters for an image.
|
||||||
typedef struct libra_source_image_gl_t {
|
typedef struct libra_image_gl_t {
|
||||||
/// A texture GLuint to the source image.
|
/// A texture GLuint to the texture.
|
||||||
uint32_t handle;
|
uint32_t handle;
|
||||||
/// The format of the source image.
|
/// The format of the texture.
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
/// The width of the source image.
|
/// The width of the texture.
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
/// The height of the source image.
|
/// The height of the texture.
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
} libra_source_image_gl_t;
|
} libra_image_gl_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_OPENGL)
|
|
||||||
/// OpenGL parameters for the output framebuffer.
|
|
||||||
typedef struct libra_output_framebuffer_gl_t {
|
|
||||||
/// A framebuffer GLuint to the output framebuffer.
|
|
||||||
uint32_t fbo;
|
|
||||||
/// A texture GLuint to the logical buffer of the output framebuffer.
|
|
||||||
uint32_t texture;
|
|
||||||
/// The format of the output framebuffer.
|
|
||||||
uint32_t format;
|
|
||||||
/// The width of the output image.
|
|
||||||
uint32_t width;
|
|
||||||
/// The height of the output image.
|
|
||||||
uint32_t height;
|
|
||||||
} libra_output_framebuffer_gl_t;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Defines the output origin for a rendered frame.
|
/// Defines the output origin for a rendered frame.
|
||||||
|
@ -269,7 +253,7 @@ typedef struct libra_device_vk_t {
|
||||||
/// for the device attached to the instance that will perform rendering.
|
/// for the device attached to the instance that will perform rendering.
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
/// The queue to use, if this is `NULL`, then
|
/// The queue to use, if this is `NULL`, then
|
||||||
/// a suitable queue will be chosen.
|
/// a suitable queue will be chosen. This must be a graphics queue.
|
||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
/// The entry loader for the Vulkan library.
|
/// The entry loader for the Vulkan library.
|
||||||
PFN_vkGetInstanceProcAddr entry;
|
PFN_vkGetInstanceProcAddr entry;
|
||||||
|
@ -642,8 +626,8 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_create)(libra_shader_preset_t
|
||||||
///libra_gl_filter_chain_frame
|
///libra_gl_filter_chain_frame
|
||||||
typedef libra_error_t (*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t *chain,
|
||||||
size_t frame_count,
|
size_t frame_count,
|
||||||
struct libra_source_image_gl_t image,
|
struct libra_image_gl_t image,
|
||||||
struct libra_output_framebuffer_gl_t out,
|
struct libra_image_gl_t out,
|
||||||
const struct libra_viewport_t *viewport,
|
const struct libra_viewport_t *viewport,
|
||||||
const float *mvp,
|
const float *mvp,
|
||||||
const struct frame_gl_opt_t *opt);
|
const struct frame_gl_opt_t *opt);
|
||||||
|
@ -660,7 +644,7 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_set_param)(libra_gl_filter_cha
|
||||||
#if defined(LIBRA_RUNTIME_OPENGL)
|
#if defined(LIBRA_RUNTIME_OPENGL)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_gl_filter_chain_get_param
|
///libra_gl_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_gl_filter_chain_get_param)(libra_gl_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_gl_filter_chain_get_param)(const libra_gl_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -728,7 +712,7 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_set_param)(libra_vk_filter_cha
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_vk_filter_chain_get_param
|
///libra_vk_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_vk_filter_chain_get_param)(libra_vk_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_vk_filter_chain_get_param)(const libra_vk_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -743,7 +727,7 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_set_active_pass_count)(libra_v
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_vk_filter_chain_get_active_pass_count
|
///libra_vk_filter_chain_get_active_pass_count
|
||||||
typedef libra_error_t (*PFN_libra_vk_filter_chain_get_active_pass_count)(libra_vk_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_vk_filter_chain_get_active_pass_count)(const libra_vk_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -796,7 +780,7 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_set_param)(libra_d3d11_filt
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d11_filter_chain_get_param
|
///libra_d3d11_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_param)(libra_d3d11_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_param)(const libra_d3d11_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -811,7 +795,7 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_set_active_pass_count)(libr
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d11_filter_chain_get_active_pass_count
|
///libra_d3d11_filter_chain_get_active_pass_count
|
||||||
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_active_pass_count)(libra_d3d11_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_active_pass_count)(const libra_d3d11_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -853,7 +837,7 @@ typedef libra_error_t (*PFN_libra_d3d9_filter_chain_set_param)(libra_d3d9_filter
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D9))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D9))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d9_filter_chain_get_param
|
///libra_d3d9_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_d3d9_filter_chain_get_param)(libra_d3d9_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d9_filter_chain_get_param)(const libra_d3d9_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -868,7 +852,7 @@ typedef libra_error_t (*PFN_libra_d3d9_filter_chain_set_active_pass_count)(libra
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D9))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D9))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d9_filter_chain_get_active_pass_count
|
///libra_d3d9_filter_chain_get_active_pass_count
|
||||||
typedef libra_error_t (*PFN_libra_d3d9_filter_chain_get_active_pass_count)(libra_d3d9_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d9_filter_chain_get_active_pass_count)(const libra_d3d9_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -921,7 +905,7 @@ typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_param)(libra_d3d12_filt
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d12_filter_chain_get_param
|
///libra_d3d12_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_param)(libra_d3d12_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_param)(const libra_d3d12_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -936,7 +920,7 @@ typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_active_pass_count)(libr
|
||||||
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12))
|
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d12_filter_chain_get_active_pass_count
|
///libra_d3d12_filter_chain_get_active_pass_count
|
||||||
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_active_pass_count)(libra_d3d12_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_active_pass_count)(const libra_d3d12_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -989,7 +973,7 @@ typedef libra_error_t (*PFN_libra_mtl_filter_chain_set_param)(libra_mtl_filter_c
|
||||||
#if (defined(__APPLE__) && defined(LIBRA_RUNTIME_METAL) && defined(__OBJC__))
|
#if (defined(__APPLE__) && defined(LIBRA_RUNTIME_METAL) && defined(__OBJC__))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_mtl_filter_chain_get_param
|
///libra_mtl_filter_chain_get_param
|
||||||
typedef libra_error_t (*PFN_libra_mtl_filter_chain_get_param)(libra_mtl_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_mtl_filter_chain_get_param)(const libra_mtl_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1004,7 +988,7 @@ typedef libra_error_t (*PFN_libra_mtl_filter_chain_set_active_pass_count)(libra_
|
||||||
#if (defined(__APPLE__) && defined(LIBRA_RUNTIME_METAL) && defined(__OBJC__))
|
#if (defined(__APPLE__) && defined(LIBRA_RUNTIME_METAL) && defined(__OBJC__))
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_mtl_filter_chain_get_active_pass_count
|
///libra_mtl_filter_chain_get_active_pass_count
|
||||||
typedef libra_error_t (*PFN_libra_mtl_filter_chain_get_active_pass_count)(libra_mtl_filter_chain_t *chain,
|
typedef libra_error_t (*PFN_libra_mtl_filter_chain_get_active_pass_count)(const libra_mtl_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1037,6 +1021,7 @@ typedef libra_error_t (*PFN_libra_mtl_filter_chain_free)(libra_mtl_filter_chain_
|
||||||
/// ABI versions are not backwards compatible. It is not
|
/// ABI versions are not backwards compatible. It is not
|
||||||
/// valid to load a librashader C API instance for any ABI
|
/// valid to load a librashader C API instance for any ABI
|
||||||
/// version not equal to LIBRASHADER_CURRENT_ABI.
|
/// version not equal to LIBRASHADER_CURRENT_ABI.
|
||||||
|
///
|
||||||
/// ## ABI Versions
|
/// ## ABI Versions
|
||||||
/// - ABI version 0: null instance (unloaded)
|
/// - ABI version 0: null instance (unloaded)
|
||||||
/// - ABI version 1: 0.1.0
|
/// - ABI version 1: 0.1.0
|
||||||
|
@ -1205,7 +1190,7 @@ libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
///
|
///
|
||||||
/// - `chain` is a handle to the filter chain.
|
/// - `chain` is a handle to the filter chain.
|
||||||
/// - `frame_count` is the number of frames passed to the shader
|
/// - `frame_count` is the number of frames passed to the shader
|
||||||
/// - `image` is a `libra_source_image_gl_t`, containing the name of a Texture, format, and size information to
|
/// - `image` is a `libra_image_gl_t`, containing the name of a Texture, format, and size information to
|
||||||
/// to an image that will serve as the source image for the frame.
|
/// to an image that will serve as the source image for the frame.
|
||||||
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
|
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
|
||||||
/// and size information for the render target of the frame.
|
/// and size information for the render target of the frame.
|
||||||
|
@ -1231,8 +1216,8 @@ libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
/// the filter chain.
|
/// the filter chain.
|
||||||
libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
||||||
size_t frame_count,
|
size_t frame_count,
|
||||||
struct libra_source_image_gl_t image,
|
struct libra_image_gl_t image,
|
||||||
struct libra_output_framebuffer_gl_t out,
|
struct libra_image_gl_t out,
|
||||||
const struct libra_viewport_t *viewport,
|
const struct libra_viewport_t *viewport,
|
||||||
const float *mvp,
|
const float *mvp,
|
||||||
const struct frame_gl_opt_t *opt);
|
const struct frame_gl_opt_t *opt);
|
||||||
|
@ -1257,7 +1242,7 @@ libra_error_t libra_gl_filter_chain_set_param(libra_gl_filter_chain_t *chain,
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_gl_filter_chain_get_param(libra_gl_filter_chain_t *chain,
|
libra_error_t libra_gl_filter_chain_get_param(const libra_gl_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1402,7 +1387,7 @@ libra_error_t libra_vk_filter_chain_set_param(libra_vk_filter_chain_t *chain,
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_vk_filter_chain_get_param(libra_vk_filter_chain_t *chain,
|
libra_error_t libra_vk_filter_chain_get_param(const libra_vk_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1421,7 +1406,7 @@ libra_error_t libra_vk_filter_chain_set_active_pass_count(libra_vk_filter_chain_
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`.
|
||||||
libra_error_t libra_vk_filter_chain_get_active_pass_count(libra_vk_filter_chain_t *chain,
|
libra_error_t libra_vk_filter_chain_get_active_pass_count(const libra_vk_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1550,7 +1535,7 @@ libra_error_t libra_d3d11_filter_chain_set_param(libra_d3d11_filter_chain_t *cha
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_d3d11_filter_chain_get_param(libra_d3d11_filter_chain_t *chain,
|
libra_error_t libra_d3d11_filter_chain_get_param(const libra_d3d11_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1569,7 +1554,7 @@ libra_error_t libra_d3d11_filter_chain_set_active_pass_count(libra_d3d11_filter_
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
|
||||||
libra_error_t libra_d3d11_filter_chain_get_active_pass_count(libra_d3d11_filter_chain_t *chain,
|
libra_error_t libra_d3d11_filter_chain_get_active_pass_count(const libra_d3d11_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1656,7 +1641,7 @@ libra_error_t libra_d3d9_filter_chain_set_param(libra_d3d9_filter_chain_t *chain
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d9_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d9_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_d3d9_filter_chain_get_param(libra_d3d9_filter_chain_t *chain,
|
libra_error_t libra_d3d9_filter_chain_get_param(const libra_d3d9_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1675,7 +1660,7 @@ libra_error_t libra_d3d9_filter_chain_set_active_pass_count(libra_d3d9_filter_ch
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d9_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d9_filter_chain_t`.
|
||||||
libra_error_t libra_d3d9_filter_chain_get_active_pass_count(libra_d3d9_filter_chain_t *chain,
|
libra_error_t libra_d3d9_filter_chain_get_active_pass_count(const libra_d3d9_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1800,7 +1785,7 @@ libra_error_t libra_d3d12_filter_chain_set_param(libra_d3d12_filter_chain_t *cha
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d12_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d12_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_d3d12_filter_chain_get_param(libra_d3d12_filter_chain_t *chain,
|
libra_error_t libra_d3d12_filter_chain_get_param(const libra_d3d12_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1819,7 +1804,7 @@ libra_error_t libra_d3d12_filter_chain_set_active_pass_count(libra_d3d12_filter_
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d12_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d12_filter_chain_t`.
|
||||||
libra_error_t libra_d3d12_filter_chain_get_active_pass_count(libra_d3d12_filter_chain_t *chain,
|
libra_error_t libra_d3d12_filter_chain_get_active_pass_count(const libra_d3d12_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1936,7 +1921,7 @@ libra_error_t libra_mtl_filter_chain_set_param(libra_mtl_filter_chain_t *chain,
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_mtl_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_mtl_filter_chain_t`.
|
||||||
/// - `param_name` must be either null or a null terminated string.
|
/// - `param_name` must be either null or a null terminated string.
|
||||||
libra_error_t libra_mtl_filter_chain_get_param(libra_mtl_filter_chain_t *chain,
|
libra_error_t libra_mtl_filter_chain_get_param(const libra_mtl_filter_chain_t *chain,
|
||||||
const char *param_name,
|
const char *param_name,
|
||||||
float *out);
|
float *out);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1955,7 +1940,7 @@ libra_error_t libra_mtl_filter_chain_set_active_pass_count(libra_mtl_filter_chai
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_mtl_filter_chain_t`.
|
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_mtl_filter_chain_t`.
|
||||||
libra_error_t libra_mtl_filter_chain_get_active_pass_count(libra_mtl_filter_chain_t *chain,
|
libra_error_t libra_mtl_filter_chain_get_active_pass_count(const libra_mtl_filter_chain_t *chain,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1984,7 +1969,7 @@ LIBRASHADER_API_VERSION libra_instance_api_version(void);
|
||||||
///
|
///
|
||||||
/// These automatically inferred variables, as well as all other variables can be overridden with
|
/// These automatically inferred variables, as well as all other variables can be overridden with
|
||||||
/// `libra_preset_ctx_set_param`, but the expected string values must be provided.
|
/// `libra_preset_ctx_set_param`, but the expected string values must be provided.
|
||||||
/// See https://github.com/libretro/RetroArch/pull/15023 for a list of expected string values.
|
/// See <https://github.com/libretro/RetroArch/pull/15023> for a list of expected string values.
|
||||||
///
|
///
|
||||||
/// No variables can be removed once added to the context, however subsequent calls to set the same
|
/// No variables can be removed once added to the context, however subsequent calls to set the same
|
||||||
/// variable will overwrite the expected variable.
|
/// variable will overwrite the expected variable.
|
||||||
|
|
|
@ -204,7 +204,7 @@ libra_error_t __librashader__noop_gl_filter_chain_create(
|
||||||
|
|
||||||
libra_error_t __librashader__noop_gl_filter_chain_frame(
|
libra_error_t __librashader__noop_gl_filter_chain_frame(
|
||||||
libra_gl_filter_chain_t *chain, size_t frame_count,
|
libra_gl_filter_chain_t *chain, size_t frame_count,
|
||||||
struct libra_source_image_gl_t image, struct libra_output_framebuffer_gl_t out,
|
struct libra_image_gl_t image, struct libra_image_gl_t out,
|
||||||
const struct libra_viewport_t *viewport, const float *mvp,
|
const struct libra_viewport_t *viewport, const float *mvp,
|
||||||
const struct frame_gl_opt_t *opt) {
|
const struct frame_gl_opt_t *opt) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -4,9 +4,8 @@ use crate::ctypes::{
|
||||||
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
|
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
|
||||||
use crate::ffi::extern_fn;
|
use crate::ffi::extern_fn;
|
||||||
use crate::LIBRASHADER_API_VERSION;
|
use crate::LIBRASHADER_API_VERSION;
|
||||||
use librashader::runtime::gl::error::FilterChainError;
|
|
||||||
use librashader::runtime::gl::{
|
use librashader::runtime::gl::{
|
||||||
FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage,
|
FilterChain, FilterChainOptions, FrameOptions, GLImage,
|
||||||
};
|
};
|
||||||
use librashader::runtime::FilterChainParameters;
|
use librashader::runtime::FilterChainParameters;
|
||||||
use librashader::runtime::{Size, Viewport};
|
use librashader::runtime::{Size, Viewport};
|
||||||
|
@ -21,36 +20,21 @@ use std::sync::Arc;
|
||||||
/// A GL function loader that librashader needs to be initialized with.
|
/// A GL function loader that librashader needs to be initialized with.
|
||||||
pub type libra_gl_loader_t = unsafe extern "system" 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 an image.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct libra_source_image_gl_t {
|
pub struct libra_image_gl_t {
|
||||||
/// A texture GLuint to the source image.
|
/// A texture GLuint to the texture.
|
||||||
pub handle: u32,
|
pub handle: u32,
|
||||||
/// The format of the source image.
|
/// The format of the texture.
|
||||||
pub format: u32,
|
pub format: u32,
|
||||||
/// The width of the source image.
|
/// The width of the texture.
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
/// The height of the source image.
|
/// The height of the texture.
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OpenGL parameters for the output framebuffer.
|
impl From<libra_image_gl_t> for GLImage {
|
||||||
#[repr(C)]
|
fn from(value: libra_image_gl_t) -> Self {
|
||||||
pub struct libra_output_framebuffer_gl_t {
|
|
||||||
/// A framebuffer GLuint to the output framebuffer.
|
|
||||||
pub fbo: u32,
|
|
||||||
/// A texture GLuint to the logical buffer of the output framebuffer.
|
|
||||||
pub texture: u32,
|
|
||||||
/// The format of the output framebuffer.
|
|
||||||
pub format: u32,
|
|
||||||
/// The width of the output image.
|
|
||||||
pub width: u32,
|
|
||||||
/// The height of the output image.
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<libra_source_image_gl_t> for GLImage {
|
|
||||||
fn from(value: libra_source_image_gl_t) -> Self {
|
|
||||||
let handle = NonZeroU32::try_from(value.handle)
|
let handle = NonZeroU32::try_from(value.handle)
|
||||||
.ok()
|
.ok()
|
||||||
.map(glow::NativeTexture);
|
.map(glow::NativeTexture);
|
||||||
|
@ -166,7 +150,7 @@ extern_fn! {
|
||||||
///
|
///
|
||||||
/// - `chain` is a handle to the filter chain.
|
/// - `chain` is a handle to the filter chain.
|
||||||
/// - `frame_count` is the number of frames passed to the shader
|
/// - `frame_count` is the number of frames passed to the shader
|
||||||
/// - `image` is a `libra_source_image_gl_t`, containing the name of a Texture, format, and size information to
|
/// - `image` is a `libra_image_gl_t`, containing the name of a Texture, format, and size information to
|
||||||
/// to an image that will serve as the source image for the frame.
|
/// to an image that will serve as the source image for the frame.
|
||||||
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
|
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
|
||||||
/// and size information for the render target of the frame.
|
/// and size information for the render target of the frame.
|
||||||
|
@ -193,14 +177,16 @@ extern_fn! {
|
||||||
nopanic fn libra_gl_filter_chain_frame(
|
nopanic fn libra_gl_filter_chain_frame(
|
||||||
chain: *mut libra_gl_filter_chain_t,
|
chain: *mut libra_gl_filter_chain_t,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
image: libra_source_image_gl_t,
|
image: libra_image_gl_t,
|
||||||
out: libra_output_framebuffer_gl_t,
|
out: libra_image_gl_t,
|
||||||
viewport: *const libra_viewport_t,
|
viewport: *const libra_viewport_t,
|
||||||
mvp: *const f32,
|
mvp: *const f32,
|
||||||
opt: *const MaybeUninit<frame_gl_opt_t>,
|
opt: *const MaybeUninit<frame_gl_opt_t>,
|
||||||
) mut |chain| {
|
) mut |chain| {
|
||||||
assert_some_ptr!(mut chain);
|
assert_some_ptr!(mut chain);
|
||||||
let image: GLImage = image.into();
|
let image: GLImage = image.into();
|
||||||
|
let out: GLImage = out.into();
|
||||||
|
|
||||||
let mvp = if mvp.is_null() {
|
let mvp = if mvp.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,26 +200,14 @@ extern_fn! {
|
||||||
|
|
||||||
let opt = opt.map(FromUninit::from_uninit);
|
let opt = opt.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let texture = NonZeroU32::try_from(out.texture)
|
|
||||||
.ok()
|
|
||||||
.map(glow::NativeTexture);
|
|
||||||
|
|
||||||
let fbo = NonZeroU32::try_from(out.fbo)
|
|
||||||
.ok()
|
|
||||||
.map(glow::NativeFramebuffer)
|
|
||||||
.ok_or(FilterChainError::GlInvalidFramebuffer)?;
|
|
||||||
|
|
||||||
let framebuffer = GLFramebuffer::new_from_raw(Arc::clone(chain.get_context()),
|
|
||||||
texture, fbo, out.format, Size::new(out.width, out.height), 1);
|
|
||||||
|
|
||||||
let viewport = if viewport.is_null() {
|
let viewport = if viewport.is_null() {
|
||||||
Viewport::new_render_target_sized_origin(&framebuffer, mvp)?
|
Viewport::new_render_target_sized_origin(&out, mvp)?
|
||||||
} else {
|
} else {
|
||||||
let viewport = unsafe { viewport.read() };
|
let viewport = unsafe { viewport.read() };
|
||||||
Viewport {
|
Viewport {
|
||||||
x: viewport.x,
|
x: viewport.x,
|
||||||
y: viewport.y,
|
y: viewport.y,
|
||||||
output: &framebuffer,
|
output: &out,
|
||||||
size: Size {
|
size: Size {
|
||||||
height: viewport.height,
|
height: viewport.height,
|
||||||
width: viewport.width
|
width: viewport.width
|
||||||
|
|
|
@ -2,7 +2,8 @@ use crate::binding::{GlUniformStorage, UniformLocation, VariableLocation};
|
||||||
use crate::error::FilterChainError;
|
use crate::error::FilterChainError;
|
||||||
use crate::filter_pass::{FilterPass, UniformOffset};
|
use crate::filter_pass::{FilterPass, UniformOffset};
|
||||||
use crate::gl::{
|
use crate::gl::{
|
||||||
CompileProgram, DrawQuad, FramebufferInterface, GLFramebuffer, GLInterface, LoadLut, UboRing,
|
CompileProgram, DrawQuad, FramebufferInterface, GLFramebuffer, GLInterface, LoadLut,
|
||||||
|
OutputFramebuffer, UboRing,
|
||||||
};
|
};
|
||||||
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
@ -39,6 +40,7 @@ pub(crate) struct FilterChainImpl<T: GLInterface> {
|
||||||
output_framebuffers: Box<[GLFramebuffer]>,
|
output_framebuffers: Box<[GLFramebuffer]>,
|
||||||
feedback_framebuffers: Box<[GLFramebuffer]>,
|
feedback_framebuffers: Box<[GLFramebuffer]>,
|
||||||
history_framebuffers: VecDeque<GLFramebuffer>,
|
history_framebuffers: VecDeque<GLFramebuffer>,
|
||||||
|
render_target: OutputFramebuffer,
|
||||||
default_options: FrameOptionsGL,
|
default_options: FrameOptionsGL,
|
||||||
draw_last_pass_feedback: bool,
|
draw_last_pass_feedback: bool,
|
||||||
}
|
}
|
||||||
|
@ -183,6 +185,8 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
// create vertex objects
|
// create vertex objects
|
||||||
let draw_quad = T::DrawQuad::new(&context)?;
|
let draw_quad = T::DrawQuad::new(&context)?;
|
||||||
|
|
||||||
|
let output = OutputFramebuffer::new(&context);
|
||||||
|
|
||||||
Ok(FilterChainImpl {
|
Ok(FilterChainImpl {
|
||||||
draw_last_pass_feedback: framebuffer_init.uses_final_pass_as_feedback(),
|
draw_last_pass_feedback: framebuffer_init.uses_final_pass_as_feedback(),
|
||||||
passes: filters,
|
passes: filters,
|
||||||
|
@ -201,6 +205,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
context,
|
context,
|
||||||
},
|
},
|
||||||
default_options: Default::default(),
|
default_options: Default::default(),
|
||||||
|
render_target: output,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +283,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
pub unsafe fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLImage>,
|
||||||
input: &GLImage,
|
input: &GLImage,
|
||||||
options: Option<&FrameOptionsGL>,
|
options: Option<&FrameOptionsGL>,
|
||||||
) -> error::Result<()> {
|
) -> error::Result<()> {
|
||||||
|
@ -385,6 +390,10 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
assert_eq!(last.len(), 1);
|
assert_eq!(last.len(), 1);
|
||||||
if let Some(pass) = last.iter_mut().next() {
|
if let Some(pass) = last.iter_mut().next() {
|
||||||
let index = passes_len - 1;
|
let index = passes_len - 1;
|
||||||
|
let final_viewport = self
|
||||||
|
.render_target
|
||||||
|
.ensure::<T::FramebufferInterface>(viewport.output)?;
|
||||||
|
|
||||||
source.filter = pass.config.filter;
|
source.filter = pass.config.filter;
|
||||||
source.mip_filter = pass.config.filter;
|
source.mip_filter = pass.config.filter;
|
||||||
source.wrap_mode = pass.config.wrap_mode;
|
source.wrap_mode = pass.config.wrap_mode;
|
||||||
|
@ -411,7 +420,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
RenderTarget::viewport(viewport),
|
RenderTarget::viewport_with_output(final_viewport, viewport),
|
||||||
);
|
);
|
||||||
self.common.output_textures[passes_len - 1] = viewport
|
self.common.output_textures[passes_len - 1] = viewport
|
||||||
.output
|
.output
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::{FilterChainError, Result};
|
||||||
use crate::filter_chain::chain::FilterChainImpl;
|
use crate::filter_chain::chain::FilterChainImpl;
|
||||||
use crate::filter_chain::inner::FilterChainDispatch;
|
use crate::filter_chain::inner::FilterChainDispatch;
|
||||||
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
||||||
use crate::{GLFramebuffer, GLImage};
|
use crate::GLImage;
|
||||||
use librashader_presets::ShaderPreset;
|
use librashader_presets::ShaderPreset;
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -63,7 +63,7 @@ impl FilterChainGL {
|
||||||
pub unsafe fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &GLImage,
|
input: &GLImage,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLImage>,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
options: Option<&FrameOptionsGL>,
|
options: Option<&FrameOptionsGL>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
|
|
@ -12,10 +12,10 @@ use librashader_runtime::render_target::RenderTarget;
|
||||||
|
|
||||||
use crate::binding::{GlUniformBinder, GlUniformStorage, UniformLocation, VariableLocation};
|
use crate::binding::{GlUniformBinder, GlUniformStorage, UniformLocation, VariableLocation};
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::gl::{BindTexture, GLInterface, UboRing};
|
use crate::gl::{BindTexture, GLFramebuffer, GLInterface, UboRing};
|
||||||
use crate::options::FrameOptionsGL;
|
use crate::options::FrameOptionsGL;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::GLFramebuffer;
|
use crate::GLImage;
|
||||||
|
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ impl<T: GLInterface> FilterPass<T> {
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
options: &FrameOptionsGL,
|
options: &FrameOptionsGL,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLImage>,
|
||||||
original: &InputTexture,
|
original: &InputTexture,
|
||||||
source: &InputTexture,
|
source: &InputTexture,
|
||||||
output: RenderTarget<GLFramebuffer, i32>,
|
output: RenderTarget<GLFramebuffer, i32>,
|
||||||
|
@ -177,7 +177,7 @@ impl<T: GLInterface> FilterPass<T> {
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
options: &FrameOptionsGL,
|
options: &FrameOptionsGL,
|
||||||
fb_size: Size<u32>,
|
fb_size: Size<u32>,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLImage>,
|
||||||
original: &InputTexture,
|
original: &InputTexture,
|
||||||
source: &InputTexture,
|
source: &InputTexture,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use librashader_common::{GetSize, Size};
|
use crate::texture::InputTexture;
|
||||||
|
use librashader_common::{FilterMode, GetSize, Size, WrapMode};
|
||||||
|
|
||||||
/// A handle to an OpenGL texture with format and size information.
|
/// A handle to an OpenGL texture with format and size information.
|
||||||
///
|
///
|
||||||
|
@ -13,6 +14,17 @@ pub struct GLImage {
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GLImage {
|
||||||
|
pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> InputTexture {
|
||||||
|
InputTexture {
|
||||||
|
image: *self,
|
||||||
|
filter,
|
||||||
|
mip_filter: filter,
|
||||||
|
wrap_mode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GetSize<u32> for GLImage {
|
impl GetSize<u32> for GLImage {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
|
@ -20,3 +32,11 @@ impl GetSize<u32> for GLImage {
|
||||||
Ok(self.size)
|
Ok(self.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetSize<u32> for &GLImage {
|
||||||
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
|
fn size(&self) -> Result<Size<u32>, Self::Error> {
|
||||||
|
Ok(self.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct GLFramebuffer {
|
||||||
pub(crate) format: u32,
|
pub(crate) format: u32,
|
||||||
pub(crate) max_levels: u32,
|
pub(crate) max_levels: u32,
|
||||||
pub(crate) mip_levels: u32,
|
pub(crate) mip_levels: u32,
|
||||||
pub(crate) is_raw: bool,
|
pub(crate) is_extern_image: bool,
|
||||||
pub(crate) ctx: Arc<glow::Context>,
|
pub(crate) ctx: Arc<glow::Context>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ impl GLFramebuffer {
|
||||||
max_levels: miplevels,
|
max_levels: miplevels,
|
||||||
mip_levels: miplevels,
|
mip_levels: miplevels,
|
||||||
fbo,
|
fbo,
|
||||||
is_raw: true,
|
is_extern_image: true,
|
||||||
ctx,
|
ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,14 +89,58 @@ impl GLFramebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A state-checked wrapper around a raw framebuffer, used exclusively for output images.
|
||||||
|
pub struct OutputFramebuffer {
|
||||||
|
framebuffer: Option<GLFramebuffer>,
|
||||||
|
ctx: Arc<glow::Context>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputFramebuffer {
|
||||||
|
pub fn new(ctx: &Arc<glow::Context>) -> Self {
|
||||||
|
OutputFramebuffer {
|
||||||
|
ctx: Arc::clone(ctx),
|
||||||
|
framebuffer: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensure that the renderbuffer is up to date.
|
||||||
|
pub fn ensure<T: FramebufferInterface>(&mut self, image: &GLImage) -> Result<&GLFramebuffer> {
|
||||||
|
let texture = image.handle;
|
||||||
|
let size = image.size;
|
||||||
|
let format = image.format;
|
||||||
|
|
||||||
|
let Some(framebuffer) = self.framebuffer.as_mut() else {
|
||||||
|
self.framebuffer = Some(T::new_raw(&self.ctx, texture, size, format, 1)?);
|
||||||
|
return Ok(self.framebuffer.as_ref().unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
framebuffer.is_extern_image,
|
||||||
|
"Somehow an internal image got into the renderbuffer!"
|
||||||
|
);
|
||||||
|
|
||||||
|
if framebuffer.image == texture && framebuffer.size == size && framebuffer.format == format
|
||||||
|
{
|
||||||
|
// Problem Case #3 :cry:
|
||||||
|
return Ok(self.framebuffer.as_ref().unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Replace with a new framebuffer.
|
||||||
|
let new = T::new_raw(&self.ctx, texture, size, format, 1)?;
|
||||||
|
std::mem::swap(&mut self.framebuffer, &mut Some(new));
|
||||||
|
Ok(self.framebuffer.as_ref().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for GLFramebuffer {
|
impl Drop for GLFramebuffer {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.is_raw {
|
unsafe {
|
||||||
|
self.ctx.delete_framebuffer(self.fbo);
|
||||||
|
|
||||||
|
if self.is_extern_image {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
self.ctx.delete_framebuffer(self.fbo);
|
|
||||||
if let Some(image) = self.image {
|
if let Some(image) = self.image {
|
||||||
self.ctx.delete_texture(image);
|
self.ctx.delete_texture(image);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,69 @@ impl FramebufferInterface for Gl3Framebuffer {
|
||||||
max_levels,
|
max_levels,
|
||||||
mip_levels: 0,
|
mip_levels: 0,
|
||||||
fbo: framebuffer,
|
fbo: framebuffer,
|
||||||
is_raw: false,
|
is_extern_image: false,
|
||||||
ctx: Arc::clone(&ctx),
|
ctx: Arc::clone(&ctx),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_raw(
|
||||||
|
ctx: &Arc<glow::Context>,
|
||||||
|
image: Option<glow::Texture>,
|
||||||
|
mut size: Size<u32>,
|
||||||
|
format: u32,
|
||||||
|
miplevels: u32,
|
||||||
|
) -> Result<GLFramebuffer> {
|
||||||
|
let framebuffer = unsafe {
|
||||||
|
ctx.create_framebuffer()
|
||||||
|
.map_err(FilterChainError::GlError)?
|
||||||
|
};
|
||||||
|
|
||||||
|
if size.width == 0 {
|
||||||
|
size.width = 1;
|
||||||
|
}
|
||||||
|
if size.height == 0 {
|
||||||
|
size.height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if size.width > librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 {
|
||||||
|
size.width = librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if size.height > librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 {
|
||||||
|
size.height = librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let status = unsafe {
|
||||||
|
ctx.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer));
|
||||||
|
|
||||||
|
ctx.framebuffer_texture_2d(
|
||||||
|
glow::FRAMEBUFFER,
|
||||||
|
glow::COLOR_ATTACHMENT0,
|
||||||
|
glow::TEXTURE_2D,
|
||||||
|
image,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.check_framebuffer_status(glow::FRAMEBUFFER)
|
||||||
|
};
|
||||||
|
|
||||||
|
if status != glow::FRAMEBUFFER_COMPLETE {
|
||||||
|
return Err(FilterChainError::FramebufferInit(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(GLFramebuffer {
|
||||||
|
image,
|
||||||
|
size,
|
||||||
|
format,
|
||||||
|
max_levels: miplevels,
|
||||||
|
mip_levels: miplevels,
|
||||||
|
fbo: framebuffer,
|
||||||
|
is_extern_image: true,
|
||||||
|
ctx: Arc::clone(&ctx),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn clear<const REBIND: bool>(fb: &GLFramebuffer) {
|
fn clear<const REBIND: bool>(fb: &GLFramebuffer) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if REBIND {
|
if REBIND {
|
||||||
|
@ -120,7 +177,7 @@ impl FramebufferInterface for Gl3Framebuffer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn init(fb: &mut GLFramebuffer, mut size: Size<u32>, format: impl Into<u32>) -> Result<()> {
|
fn init(fb: &mut GLFramebuffer, mut size: Size<u32>, format: impl Into<u32>) -> Result<()> {
|
||||||
if fb.is_raw {
|
if fb.is_extern_image {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
fb.format = format.into();
|
fb.format = format.into();
|
||||||
|
|
|
@ -29,11 +29,60 @@ impl FramebufferInterface for Gl46Framebuffer {
|
||||||
max_levels,
|
max_levels,
|
||||||
mip_levels: 0,
|
mip_levels: 0,
|
||||||
fbo: framebuffer,
|
fbo: framebuffer,
|
||||||
is_raw: false,
|
is_extern_image: false,
|
||||||
ctx: Arc::clone(&context),
|
ctx: Arc::clone(&context),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_raw(
|
||||||
|
ctx: &Arc<glow::Context>,
|
||||||
|
image: Option<glow::Texture>,
|
||||||
|
mut size: Size<u32>,
|
||||||
|
format: u32,
|
||||||
|
miplevels: u32,
|
||||||
|
) -> Result<GLFramebuffer> {
|
||||||
|
let framebuffer = unsafe {
|
||||||
|
ctx.create_named_framebuffer()
|
||||||
|
.map_err(FilterChainError::GlError)?
|
||||||
|
};
|
||||||
|
|
||||||
|
if size.width == 0 {
|
||||||
|
size.width = 1;
|
||||||
|
}
|
||||||
|
if size.height == 0 {
|
||||||
|
size.height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if size.width > librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 {
|
||||||
|
size.width = librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if size.height > librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 {
|
||||||
|
size.height = librashader_runtime::scaling::MAX_TEXEL_SIZE as u32 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let status = unsafe {
|
||||||
|
ctx.named_framebuffer_texture(Some(framebuffer), glow::COLOR_ATTACHMENT0, image, 0);
|
||||||
|
|
||||||
|
ctx.check_named_framebuffer_status(Some(framebuffer), glow::FRAMEBUFFER)
|
||||||
|
};
|
||||||
|
|
||||||
|
if status != glow::FRAMEBUFFER_COMPLETE {
|
||||||
|
return Err(FilterChainError::FramebufferInit(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(GLFramebuffer {
|
||||||
|
image,
|
||||||
|
size,
|
||||||
|
format,
|
||||||
|
max_levels: miplevels,
|
||||||
|
mip_levels: miplevels,
|
||||||
|
fbo: framebuffer,
|
||||||
|
is_extern_image: true,
|
||||||
|
ctx: Arc::clone(&ctx),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn clear<const REBIND: bool>(fb: &GLFramebuffer) {
|
fn clear<const REBIND: bool>(fb: &GLFramebuffer) {
|
||||||
unsafe {
|
unsafe {
|
||||||
fb.ctx.clear_named_framebuffer_f32_slice(
|
fb.ctx.clear_named_framebuffer_f32_slice(
|
||||||
|
@ -90,7 +139,7 @@ impl FramebufferInterface for Gl46Framebuffer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn init(fb: &mut GLFramebuffer, mut size: Size<u32>, format: impl Into<u32>) -> Result<()> {
|
fn init(fb: &mut GLFramebuffer, mut size: Size<u32>, format: impl Into<u32>) -> Result<()> {
|
||||||
if fb.is_raw {
|
if fb.is_extern_image {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
fb.format = format.into();
|
fb.format = format.into();
|
||||||
|
|
|
@ -95,6 +95,16 @@ pub(crate) trait UboRing<const SIZE: usize> {
|
||||||
|
|
||||||
pub(crate) trait FramebufferInterface {
|
pub(crate) trait FramebufferInterface {
|
||||||
fn new(context: &Arc<glow::Context>, max_levels: u32) -> Result<GLFramebuffer>;
|
fn new(context: &Arc<glow::Context>, max_levels: u32) -> Result<GLFramebuffer>;
|
||||||
|
|
||||||
|
/// Create a new raw framebuffer for the given image, size, format, and miplevels.
|
||||||
|
fn new_raw(
|
||||||
|
context: &Arc<glow::Context>,
|
||||||
|
image: Option<glow::Texture>,
|
||||||
|
size: Size<u32>,
|
||||||
|
format: u32,
|
||||||
|
miplevels: u32,
|
||||||
|
) -> Result<GLFramebuffer>;
|
||||||
|
|
||||||
fn scale(
|
fn scale(
|
||||||
fb: &mut GLFramebuffer,
|
fb: &mut GLFramebuffer,
|
||||||
scaling: Scale2D,
|
scaling: Scale2D,
|
||||||
|
@ -104,7 +114,7 @@ pub(crate) trait FramebufferInterface {
|
||||||
original_size: &Size<u32>,
|
original_size: &Size<u32>,
|
||||||
mipmap: bool,
|
mipmap: bool,
|
||||||
) -> Result<Size<u32>> {
|
) -> Result<Size<u32>> {
|
||||||
if fb.is_raw {
|
if fb.is_extern_image {
|
||||||
return Ok(fb.size);
|
return Ok(fb.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,3 +165,5 @@ pub(crate) trait GLInterface {
|
||||||
type BindTexture: BindTexture;
|
type BindTexture: BindTexture;
|
||||||
type CompileShader: CompileProgram;
|
type CompileShader: CompileProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use framebuffer::OutputFramebuffer;
|
||||||
|
|
|
@ -18,6 +18,5 @@ mod texture;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
|
|
||||||
pub use crate::gl::GLFramebuffer;
|
|
||||||
pub use filter_chain::FilterChainGL;
|
pub use filter_chain::FilterChainGL;
|
||||||
pub use framebuffer::GLImage;
|
pub use framebuffer::GLImage;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use librashader_common::{GetSize, Size, Viewport};
|
use librashader_common::{GetSize, Size, Viewport};
|
||||||
|
|
||||||
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
|
use librashader_runtime_gl::{FilterChainGL, GLImage};
|
||||||
|
|
||||||
const WIDTH: u32 = 800;
|
const WIDTH: u32 = 800;
|
||||||
const HEIGHT: u32 = 600;
|
const HEIGHT: u32 = 600;
|
||||||
|
@ -385,14 +385,11 @@ void main()
|
||||||
let (fb_width, fb_height) = window.get_framebuffer_size();
|
let (fb_width, fb_height) = window.get_framebuffer_size();
|
||||||
let (vp_width, vp_height) = window.get_size();
|
let (vp_width, vp_height) = window.get_size();
|
||||||
|
|
||||||
let output = GLFramebuffer::new_from_raw(
|
let output = GLImage {
|
||||||
Arc::clone(gl),
|
handle: Some(output_texture),
|
||||||
Some(output_texture),
|
format: glow::RGBA8,
|
||||||
output_framebuffer_handle,
|
size: Size::new(vp_width as u32, vp_height as u32),
|
||||||
glow::RGBA8,
|
};
|
||||||
Size::new(vp_width as u32, vp_height as u32),
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
while !window.should_close() {
|
while !window.should_close() {
|
||||||
glfw.poll_events();
|
glfw.poll_events();
|
||||||
|
|
|
@ -6,7 +6,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use librashader_common::{GetSize, Size, Viewport};
|
use librashader_common::{GetSize, Size, Viewport};
|
||||||
|
|
||||||
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
|
use librashader_runtime_gl::{FilterChainGL, GLImage};
|
||||||
|
|
||||||
const WIDTH: u32 = 800;
|
const WIDTH: u32 = 800;
|
||||||
const HEIGHT: u32 = 600;
|
const HEIGHT: u32 = 600;
|
||||||
|
@ -348,14 +348,11 @@ void main()
|
||||||
let (fb_width, fb_height) = window.get_framebuffer_size();
|
let (fb_width, fb_height) = window.get_framebuffer_size();
|
||||||
let (vp_width, vp_height) = window.get_size();
|
let (vp_width, vp_height) = window.get_size();
|
||||||
|
|
||||||
let output = GLFramebuffer::new_from_raw(
|
let output = GLImage {
|
||||||
Arc::clone(gl),
|
handle: Some(output_texture),
|
||||||
Some(output_texture),
|
format: glow::RGBA8,
|
||||||
output_framebuffer_handle,
|
size: Size::new(vp_width as u32, vp_height as u32),
|
||||||
glow::RGBA8,
|
};
|
||||||
Size::new(vp_width as u32, vp_height as u32),
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
while !window.should_close() {
|
while !window.should_close() {
|
||||||
glfw.poll_events();
|
glfw.poll_events();
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn triangle_gl() {
|
||||||
let mut filter = FilterChainGL::load_from_path(
|
let mut filter = FilterChainGL::load_from_path(
|
||||||
Arc::clone(&context),
|
Arc::clone(&context),
|
||||||
// "../test/basic.slangp",
|
// "../test/basic.slangp",
|
||||||
"../test/shaders_slang/crt/crt-royale.slangp",
|
"../test/shaders_slang/test/feedback.slangp",
|
||||||
Some(&FilterChainOptionsGL {
|
Some(&FilterChainOptionsGL {
|
||||||
glsl_version: 0,
|
glsl_version: 0,
|
||||||
use_dsa: false,
|
use_dsa: false,
|
||||||
|
@ -35,8 +35,8 @@ fn triangle_gl46() {
|
||||||
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
||||||
// "../test/slang-shaders/test/history.slangp",
|
// "../test/slang-shaders/test/history.slangp",
|
||||||
// "../test/basic.slangp",
|
// "../test/basic.slangp",
|
||||||
"../test/shaders_slang/crt/crt-royale.slangp",
|
// "../test/shaders_slang/crt/crt-royale.slangp",
|
||||||
// "../test/shadersslang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
Some(&FilterChainOptionsGL {
|
Some(&FilterChainOptionsGL {
|
||||||
glsl_version: 330,
|
glsl_version: 330,
|
||||||
use_dsa: true,
|
use_dsa: true,
|
||||||
|
|
|
@ -263,7 +263,7 @@ pub mod runtime {
|
||||||
pub use librashader_runtime_gl::{
|
pub use librashader_runtime_gl::{
|
||||||
error,
|
error,
|
||||||
options::{FilterChainOptionsGL as FilterChainOptions, FrameOptionsGL as FrameOptions},
|
options::{FilterChainOptionsGL as FilterChainOptions, FrameOptionsGL as FrameOptions},
|
||||||
FilterChainGL as FilterChain, GLFramebuffer, GLImage,
|
FilterChainGL as FilterChain, GLImage,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue