capi: remove potential panics

This commit is contained in:
chyyran 2023-01-13 16:10:54 -05:00
parent f25693815b
commit 9b7d6fc014
6 changed files with 36 additions and 30 deletions

View file

@ -47,7 +47,7 @@ typedef struct _libra_error* libra_error_t;
typedef struct _shader_preset* libra_shader_preset_t; typedef struct _shader_preset* libra_shader_preset_t;
#if defined(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* (*gl_loader_t)(const char*);
#endif #endif
@ -64,11 +64,11 @@ typedef struct FilterChainOptions {
bool force_no_mipmaps; bool force_no_mipmaps;
} FilterChainOptions; } FilterChainOptions;
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
typedef struct FilterChain* libra_gl_filter_chain_t; typedef struct FilterChain* libra_gl_filter_chain_t;
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// OpenGL parameters for the source image. /// OpenGL parameters for the source image.
typedef struct libra_source_image_gl_t { typedef struct libra_source_image_gl_t {
/// A texture GLuint to the source image. /// A texture GLuint to the source image.
@ -90,7 +90,7 @@ typedef struct libra_viewport_t {
uint32_t height; uint32_t height;
} libra_viewport_t; } libra_viewport_t;
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// OpenGL parameters for the output framebuffer. /// OpenGL parameters for the output framebuffer.
typedef struct libra_draw_framebuffer_gl_t { typedef struct libra_draw_framebuffer_gl_t {
/// A framebuffer GLuint to the output framebuffer. /// A framebuffer GLuint to the output framebuffer.
@ -110,11 +110,11 @@ typedef struct FrameOptions {
int32_t frame_direction; int32_t frame_direction;
} FrameOptions; } FrameOptions;
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
typedef struct FilterChain* libra_d3d11_filter_chain_t; typedef struct FilterChain* libra_d3d11_filter_chain_t;
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
/// OpenGL parameters for the source image. /// OpenGL parameters for the source image.
typedef struct libra_source_image_d3d11_t { typedef struct libra_source_image_d3d11_t {
/// A shader resource view into the source image /// A shader resource view into the source image
@ -151,17 +151,17 @@ 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(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)(gl_loader_t loader);
#endif #endif
#if defined(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 FilterChainOptions* options,
libra_gl_filter_chain_t* out); libra_gl_filter_chain_t* out);
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
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_source_image_gl_t image,
@ -171,18 +171,18 @@ typedef libra_error_t(*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t*
const struct FrameOptions* opt); const struct FrameOptions* opt);
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
typedef libra_error_t(*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t* chain); typedef libra_error_t(*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t* chain);
#endif #endif
#if defined(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 FilterChainOptions* options,
const ID3D11Device* device, const ID3D11Device* device,
libra_d3d11_filter_chain_t* out); libra_d3d11_filter_chain_t* out);
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_chain_t* chain, typedef libra_error_t(*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_chain_t* chain,
size_t frame_count, size_t frame_count,
struct libra_source_image_d3d11_t image, struct libra_source_image_d3d11_t image,
@ -192,7 +192,7 @@ typedef libra_error_t(*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_ch
const struct FrameOptions* opt); const struct FrameOptions* opt);
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t* chain); typedef libra_error_t(*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t* chain);
#endif #endif
@ -286,7 +286,7 @@ extern "C" {
libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t* preset, libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t* preset,
const char** value); const char** value);
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// Initialize the OpenGL Context for librashader. /// Initialize the OpenGL Context for librashader.
/// ///
/// ## Safety /// ## Safety
@ -297,7 +297,7 @@ extern "C" {
libra_error_t libra_gl_init_context(gl_loader_t loader); libra_error_t libra_gl_init_context(gl_loader_t loader);
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// Create the filter chain given the shader preset. /// Create the filter chain given the shader preset.
/// ///
/// The shader preset is immediately invalidated and must be recreated after /// The shader preset is immediately invalidated and must be recreated after
@ -312,7 +312,7 @@ extern "C" {
libra_gl_filter_chain_t* out); libra_gl_filter_chain_t* out);
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// Draw a frame with the given parameters for the given filter chain. /// Draw a frame with the given parameters for the given filter chain.
/// ///
/// ## Safety /// ## Safety
@ -331,7 +331,7 @@ extern "C" {
const struct FrameOptions* opt); const struct FrameOptions* opt);
#endif #endif
#if defined(RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
/// Free a GL filter chain. /// Free a GL filter chain.
/// ///
/// The resulting value in `chain` then becomes null. /// The resulting value in `chain` then becomes null.
@ -340,7 +340,7 @@ extern "C" {
libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t* chain); libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t* chain);
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
/// Create the filter chain given the shader preset. /// Create the filter chain given the shader preset.
/// ///
/// The shader preset is immediately invalidated and must be recreated after /// The shader preset is immediately invalidated and must be recreated after
@ -356,7 +356,7 @@ extern "C" {
libra_d3d11_filter_chain_t* out); libra_d3d11_filter_chain_t* out);
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
/// Draw a frame with the given parameters for the given filter chain. /// Draw a frame with the given parameters for the given filter chain.
/// ///
/// ## Safety /// ## Safety
@ -375,7 +375,7 @@ extern "C" {
const struct FrameOptions* opt); const struct FrameOptions* opt);
#endif #endif
#if defined(RUNTIME_D3D11) #if defined(LIBRA_RUNTIME_D3D11)
/// Free a D3D11 filter chain. /// Free a D3D11 filter chain.
/// ///
/// The resulting value in `chain` then becomes null. /// The resulting value in `chain` then becomes null.

View file

@ -28,6 +28,8 @@ pub enum FilterChainError {
GLLoadError, GLLoadError,
#[error("opengl could not link program")] #[error("opengl could not link program")]
GLLinkError, GLLinkError,
#[error("opengl could not compile program")]
GlCompileError
} }
/// Result type for OpenGL filter chains. /// Result type for OpenGL filter chains.

View file

@ -1,8 +1,10 @@
use gl::types::{GLenum, GLuint}; use gl::types::{GLenum, GLuint};
use librashader_reflect::back::cross::GlslVersion; use librashader_reflect::back::cross::GlslVersion;
use crate::error;
use crate::error::FilterChainError;
pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint { pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> error::Result<GLuint> {
let shader = gl::CreateShader(stage); let shader = gl::CreateShader(stage);
gl::ShaderSource( gl::ShaderSource(
shader, shader,
@ -15,9 +17,10 @@ pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status); gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);
if compile_status == 0 { if compile_status == 0 {
panic!("failed to compile") Err(FilterChainError::GlCompileError)
} else {
Ok(shader)
} }
shader
} }
pub fn gl_get_version() -> GlslVersion { pub fn gl_get_version() -> GlslVersion {

View file

@ -22,6 +22,8 @@ pub enum FilterChainError {
LutLoadError(#[from] ImageError), LutLoadError(#[from] ImageError),
#[error("vulkan error")] #[error("vulkan error")]
VulkanResult(#[from] ash::vk::Result), VulkanResult(#[from] ash::vk::Result),
#[error("could not find a valid vulkan memory type")]
VulkanMemoryError(u32),
} }
/// Result type for Vulkan filter chains. /// Result type for Vulkan filter chains.

View file

@ -1,6 +1,8 @@
use ash::vk; use ash::vk;
use librashader_reflect::reflect::semantics::BindingStage; use librashader_reflect::reflect::semantics::BindingStage;
use crate::error;
use crate::error::FilterChainError;
pub fn binding_stage_to_vulkan_stage(stage_mask: BindingStage) -> vk::ShaderStageFlags { pub fn binding_stage_to_vulkan_stage(stage_mask: BindingStage) -> vk::ShaderStageFlags {
let mut mask = vk::ShaderStageFlags::default(); let mut mask = vk::ShaderStageFlags::default();
@ -19,19 +21,19 @@ pub fn find_vulkan_memory_type(
props: &vk::PhysicalDeviceMemoryProperties, props: &vk::PhysicalDeviceMemoryProperties,
device_reqs: u32, device_reqs: u32,
host_reqs: vk::MemoryPropertyFlags, host_reqs: vk::MemoryPropertyFlags,
) -> u32 { ) -> error::Result<u32> {
for i in 0..vk::MAX_MEMORY_TYPES { for i in 0..vk::MAX_MEMORY_TYPES {
if device_reqs & (1 << i) != 0 if device_reqs & (1 << i) != 0
&& props.memory_types[i].property_flags & host_reqs == host_reqs && props.memory_types[i].property_flags & host_reqs == host_reqs
{ {
return i as u32; return Ok(i as u32);
} }
} }
if host_reqs == vk::MemoryPropertyFlags::empty() { if host_reqs == vk::MemoryPropertyFlags::empty() {
panic!("[vk] Failed to find valid memory type.") Err(FilterChainError::VulkanMemoryError(device_reqs))
} else { } else {
find_vulkan_memory_type(props, device_reqs, vk::MemoryPropertyFlags::empty()) Ok(find_vulkan_memory_type(props, device_reqs, vk::MemoryPropertyFlags::empty())?)
} }
} }

View file

@ -115,9 +115,6 @@ impl Drop for VulkanBuffer {
impl<'a> VulkanBufferMapHandle<'a> { impl<'a> VulkanBufferMapHandle<'a> {
pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) { pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) {
if self.buffer.size > (offset + src.len()) as u64 {
panic!("invalid write")
}
std::ptr::copy_nonoverlapping( std::ptr::copy_nonoverlapping(
src.as_ptr(), src.as_ptr(),
self.ptr self.ptr