fmt: run cargo fmt

This commit is contained in:
chyyran 2023-01-09 22:54:54 -05:00
parent 47b5625095
commit 48321d997b
27 changed files with 564 additions and 450 deletions

View file

@ -158,8 +158,9 @@ impl LibrashaderError {
LibrashaderError::InvalidPath(_) => LIBRA_ERRNO::INVALID_PATH,
LibrashaderError::PresetError(_) => LIBRA_ERRNO::PRESET_ERROR,
LibrashaderError::PreprocessError(_) => LIBRA_ERRNO::PREPROCESS_ERROR,
LibrashaderError::ShaderCompileError(_)
| LibrashaderError::ShaderReflectError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
LibrashaderError::ShaderCompileError(_) | LibrashaderError::ShaderReflectError(_) => {
LIBRA_ERRNO::RUNTIME_ERROR
}
#[cfg(feature = "runtime-opengl")]
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-d3d11")]

View file

@ -44,5 +44,5 @@ pub mod ctypes;
pub mod error;
mod ffi;
pub mod presets;
pub mod runtime;
pub mod reflect;
pub mod runtime;

View file

@ -1,13 +1,18 @@
use std::error::Error;
use crate::error;
use librashader::preprocess::ShaderSource;
use librashader::presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
use librashader::reflect::{CompilerBackend, CompileShader, FromCompilation, GlslangCompilation, ReflectShader, ShaderCompilerOutput, ShaderReflection};
use librashader::reflect::image::{Image, RGBA8, UVDirection};
use librashader::reflect::semantics::{Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics};
use librashader::reflect::image::{Image, UVDirection, RGBA8};
use librashader::reflect::semantics::{
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
};
use librashader::reflect::targets::SpirV;
use librashader::reflect::{
CompileShader, CompilerBackend, FromCompilation, GlslangCompilation, ReflectShader,
ShaderCompilerOutput, ShaderReflection,
};
use librashader::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
use crate::error;
use std::error::Error;
pub(crate) struct LookupTexture {
wrap_mode: WrapMode,
@ -16,22 +21,25 @@ pub(crate) struct LookupTexture {
/// Whether or not to generate mipmaps for this texture.
mipmap: bool,
/// The image data of the texture
image: Image
image: Image,
}
pub(crate) struct PassReflection {
reflection: ShaderReflection,
config: ShaderPassConfig,
spirv: ShaderCompilerOutput<Vec<u32>>
spirv: ShaderCompilerOutput<Vec<u32>>,
}
pub(crate) struct FilterReflection {
semantics: ShaderSemantics,
passes: Vec<PassReflection>,
textures: Vec<LookupTexture>
textures: Vec<LookupTexture>,
}
impl FilterReflection {
pub fn load_from_preset(preset: ShaderPreset, direction: UVDirection) -> Result<FilterReflection, error::LibrashaderError>{
pub fn load_from_preset(
preset: ShaderPreset,
direction: UVDirection,
) -> Result<FilterReflection, error::LibrashaderError> {
let (passes, textures) = (preset.shaders, preset.textures);
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
@ -59,7 +67,10 @@ impl FilterReflection {
Ok::<_, error::LibrashaderError>((shader, source, reflect))
})
.into_iter()
.collect::<Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>, error::LibrashaderError>>()?;
.collect::<Result<
Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>,
error::LibrashaderError,
>>()?;
for details in &passes {
librashader::runtime::helper::insert_pass_semantics(
@ -80,7 +91,6 @@ impl FilterReflection {
texture_semantics,
};
let mut reflects = Vec::new();
for (index, (config, _source, mut compiler)) in passes.into_iter().enumerate() {
@ -89,21 +99,24 @@ impl FilterReflection {
reflects.push(PassReflection {
reflection,
config,
spirv: words
spirv: words,
})
}
let textures = textures.into_iter().map(|texture| {
let lut = Image::<RGBA8>::load(&texture.path, direction)
.map_err(|e| error::LibrashaderError::UnknownError(Box::new(e)))?;
Ok(LookupTexture {
wrap_mode: texture.wrap_mode,
filter_mode: texture.filter_mode,
mipmap: texture.mipmap,
image: lut,
let textures = textures
.into_iter()
.map(|texture| {
let lut = Image::<RGBA8>::load(&texture.path, direction)
.map_err(|e| error::LibrashaderError::UnknownError(Box::new(e)))?;
Ok(LookupTexture {
wrap_mode: texture.wrap_mode,
filter_mode: texture.filter_mode,
mipmap: texture.mipmap,
image: lut,
})
})
}).into_iter().collect::<Result<Vec<LookupTexture>, error::LibrashaderError>>()?;
.into_iter()
.collect::<Result<Vec<LookupTexture>, error::LibrashaderError>>()?;
Ok(FilterReflection {
semantics,
@ -111,4 +124,4 @@ impl FilterReflection {
textures,
})
}
}
}

View file

@ -123,22 +123,20 @@ impl From<&vk::Viewport> for Size<u32> {
}
}
impl From<FilterMode> for vk::Filter {
fn from(value: FilterMode) -> Self {
match value {
FilterMode::Linear => vk::Filter::LINEAR,
FilterMode::Nearest => vk::Filter::NEAREST
FilterMode::Nearest => vk::Filter::NEAREST,
}
}
}
impl From<FilterMode> for vk::SamplerMipmapMode {
fn from(value: FilterMode) -> Self {
match value {
FilterMode::Linear => vk::SamplerMipmapMode::LINEAR,
FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST
FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST,
}
}
}
@ -149,7 +147,7 @@ impl From<WrapMode> for vk::SamplerAddressMode {
WrapMode::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER,
WrapMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
WrapMode::Repeat => vk::SamplerAddressMode::REPEAT,
WrapMode::MirroredRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT
WrapMode::MirroredRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT,
}
}
}
}

View file

@ -1,6 +1,6 @@
use ash::vk;
use crate::error;
use crate::vulkan_primitives::VulkanBuffer;
use ash::vk;
#[rustfmt::skip]
static VBO_OFFSCREEN: &[f32; 16] = &[
@ -22,39 +22,55 @@ static VBO_DEFAULT_FINAL: &[f32; 16] = &[
pub enum VboType {
Offscreen,
Final
Final,
}
pub struct DrawQuad {
buffer: VulkanBuffer,
device: ash::Device
device: ash::Device,
}
impl DrawQuad {
pub fn new(device: &ash::Device, mem_props: &vk::PhysicalDeviceMemoryProperties) -> error::Result<DrawQuad> {
let mut buffer = VulkanBuffer::new(device, mem_props, vk::BufferUsageFlags::VERTEX_BUFFER, 2 * std::mem::size_of::<[f32; 16]>())?;
pub fn new(
device: &ash::Device,
mem_props: &vk::PhysicalDeviceMemoryProperties,
) -> error::Result<DrawQuad> {
let mut buffer = VulkanBuffer::new(
device,
mem_props,
vk::BufferUsageFlags::VERTEX_BUFFER,
2 * std::mem::size_of::<[f32; 16]>(),
)?;
{
let mut map = buffer.map()?;
unsafe {
map.copy_from(0, bytemuck::cast_slice(VBO_OFFSCREEN));
map.copy_from(std::mem::size_of::<[f32; 16]>(), bytemuck::cast_slice(VBO_DEFAULT_FINAL));
map.copy_from(
std::mem::size_of::<[f32; 16]>(),
bytemuck::cast_slice(VBO_DEFAULT_FINAL),
);
}
}
Ok(DrawQuad {
buffer,
device: device.clone()
device: device.clone(),
})
}
pub fn bind_vbo(&self, cmd: &vk::CommandBuffer, vbo: VboType) {
let offset = match vbo {
VboType::Offscreen => 0,
VboType::Final => std::mem::size_of::<[f32; 16]>()
VboType::Final => std::mem::size_of::<[f32; 16]>(),
};
unsafe {
self.device.cmd_bind_vertex_buffers(*cmd, 0, &[self.buffer.handle], &[offset as vk::DeviceSize])
self.device.cmd_bind_vertex_buffers(
*cmd,
0,
&[self.buffer.handle],
&[offset as vk::DeviceSize],
)
}
}
}

View file

@ -1,6 +1,9 @@
use crate::error;
use crate::filter_pass::FilterPass;
use crate::luts::LutTexture;
use crate::samplers::SamplerSet;
use crate::texture::VulkanImage;
use crate::ubo_ring::VkUboRing;
use crate::vulkan_state::VulkanGraphicsPipeline;
use ash::vk::{CommandPoolCreateFlags, PFN_vkGetInstanceProcAddr, Queue, StaticFn};
use ash::{vk, Device};
@ -19,9 +22,6 @@ use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap;
use std::error::Error;
use std::path::Path;
use crate::samplers::SamplerSet;
use crate::texture::VulkanImage;
use crate::ubo_ring::VkUboRing;
pub struct Vulkan {
// physical_device: vk::PhysicalDevice,
@ -149,7 +149,7 @@ pub type FilterChainOptionsVulkan = ();
impl FilterChainVulkan {
/// Load the shader preset at the given path into a filter chain.
pub fn load_from_path(
vulkan: impl TryInto<Vulkan, Error=Box<dyn Error>>,
vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
path: impl AsRef<Path>,
options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> {
@ -159,7 +159,7 @@ impl FilterChainVulkan {
}
pub fn load_from_preset(
vulkan: impl TryInto<Vulkan, Error=Box<dyn Error>>,
vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
preset: ShaderPreset,
options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> {
@ -172,7 +172,6 @@ impl FilterChainVulkan {
let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?;
let samplers = SamplerSet::new(&device.device)?;
eprintln!("filters initialized ok.");
Ok(FilterChainVulkan {
common: FilterCommon {
@ -188,7 +187,7 @@ impl FilterChainVulkan {
},
},
passes: filters,
vulkan: device
vulkan: device,
})
}
@ -221,7 +220,8 @@ impl FilterChainVulkan {
Ok::<_, Box<dyn Error>>((shader, source, reflect))
})
.into_iter()
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
)?;
for details in &passes {
librashader_runtime::semantics::insert_pass_semantics(
@ -262,7 +262,8 @@ impl FilterChainVulkan {
.as_ref()
.map(|ubo| ubo.size as usize)
.unwrap_or(0);
let uniform_storage = UniformStorage::new(ubo_size,
let uniform_storage = UniformStorage::new(
ubo_size,
reflection
.push_constant
.as_ref()
@ -298,7 +299,12 @@ impl FilterChainVulkan {
images,
)?;
let ubo_ring = VkUboRing::new(&vulkan.device, &vulkan.memory_properties, images as usize, ubo_size)?;
let ubo_ring = VkUboRing::new(
&vulkan.device,
&vulkan.memory_properties,
images as usize,
ubo_size,
)?;
// shader_vulkan: 2026
filters.push(FilterPass {
device: vulkan.device.clone(),
@ -374,7 +380,7 @@ impl FilterChainVulkan {
viewport: &vk::Viewport,
input: &VulkanImage,
options: Option<()>,
command_buffer: vk::CommandBuffer
command_buffer: vk::CommandBuffer,
) -> error::Result<()> {
// limit number of passes to those enabled.
let passes = &mut self.passes[0..self.common.config.passes_enabled];
@ -394,6 +400,5 @@ impl FilterChainVulkan {
// }
Ok(())
}
}

View file

@ -1,19 +1,21 @@
use ash::vk;
use crate::vulkan_state::VulkanGraphicsPipeline;
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics};
use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap;
use librashader_common::Size;
use librashader_reflect::reflect::ShaderReflection;
use crate::error;
use crate::filter_chain::FilterCommon;
use crate::rendertarget::RenderTarget;
use crate::texture::Texture;
use crate::samplers::{SamplerSet, VulkanSampler};
use crate::texture::Texture;
use crate::ubo_ring::VkUboRing;
use crate::vulkan_state::VulkanGraphicsPipeline;
use ash::vk;
use librashader_common::Size;
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{
MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics,
};
use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap;
pub struct FilterPass {
pub device: ash::Device,
@ -24,18 +26,18 @@ pub struct FilterPass {
pub source: ShaderSource,
pub config: ShaderPassConfig,
pub graphics_pipeline: VulkanGraphicsPipeline,
pub ubo_ring: VkUboRing
pub ubo_ring: VkUboRing,
}
impl FilterPass {
#[inline(always)]
fn bind_texture(device: &ash::Device,
samplers: &SamplerSet,
descriptor_set: vk::DescriptorSet,
binding: &TextureBinding,
texture: &Texture) {
fn bind_texture(
device: &ash::Device,
samplers: &SamplerSet,
descriptor_set: vk::DescriptorSet,
binding: &TextureBinding,
texture: &Texture,
) {
let sampler = samplers.get(texture.wrap_mode, texture.filter_mode, texture.mip_filter);
let image_info = [vk::DescriptorImageInfo::builder()
.sampler(sampler.handle)
@ -53,7 +55,6 @@ impl FilterPass {
unsafe {
device.update_descriptor_sets(&write_desc, &[]);
}
}
pub(crate) fn draw(
@ -70,13 +71,24 @@ impl FilterPass {
) -> error::Result<()> {
let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[0];
self.build_semantics(pass_index, parent, &output.mvp, frame_count, frame_direction, output.output.size,
viewport.into(),&descriptor, original, source);
self.build_semantics(
pass_index,
parent,
&output.mvp,
frame_count,
frame_direction,
output.output.size,
viewport.into(),
&descriptor,
original,
source,
);
if let Some(ubo) = &self.reflection.ubo {
// shader_vulkan: 2554 (ra uses uses one big buffer)
// itll be simpler for us if we just use a RingBuffer<vk::Buffer> tbh.
self.ubo_ring.bind_to_descriptor_set(descriptor, ubo.binding, &self.uniform_storage)?;
self.ubo_ring
.bind_to_descriptor_set(descriptor, ubo.binding, &self.uniform_storage)?;
}
Ok(())
@ -172,7 +184,7 @@ impl FilterPass {
&parent.samplers,
*descriptor_set,
binding,
source
source,
);
}
@ -301,12 +313,12 @@ impl FilterPass {
// bind float parameters
for (id, offset) in
self.uniform_bindings
.iter()
.filter_map(|(binding, value)| match binding {
UniformBinding::Parameter(id) => Some((id, value)),
_ => None,
})
self.uniform_bindings
.iter()
.filter_map(|(binding, value)| match binding {
UniformBinding::Parameter(id) => Some((id, value)),
_ => None,
})
{
let id = id.as_str();
@ -351,4 +363,4 @@ impl FilterPass {
// (textures, samplers)
}
}
}

View file

@ -1,13 +1,10 @@
use crate::error;
use crate::renderpass::VulkanRenderPass;
use ash::vk;
use ash::vk::{
ImageAspectFlags,
ImageViewType,
};
use librashader_common::Size;
use crate::filter_chain::Vulkan;
use crate::renderpass::VulkanRenderPass;
use crate::texture::OwnedTexture;
use ash::vk;
use ash::vk::{ImageAspectFlags, ImageViewType};
use librashader_common::Size;
pub struct VulkanFramebuffer {
pub device: ash::Device,
@ -74,7 +71,6 @@ pub(crate) struct OutputFramebuffer {
pub viewport: vk::Viewport,
}
//
// pub struct OutputFramebuffer<'a> {
// device: ash::Device,
@ -147,4 +143,4 @@ pub(crate) struct OutputFramebuffer {
//
// builder.build()
// }
// }
// }

View file

@ -1,12 +1,12 @@
use ash::prelude::VkResult;
use ash::vk;
use crate::hello_triangle::physicaldevice::find_queue_family;
use crate::hello_triangle::vulkan_base::VulkanBase;
use ash::prelude::VkResult;
use ash::vk;
pub struct VulkanCommandPool {
pool: vk::CommandPool,
device: ash::Device,
pub buffers: Vec<vk::CommandBuffer>
pub buffers: Vec<vk::CommandBuffer>,
}
impl VulkanCommandPool {
@ -34,5 +34,4 @@ impl VulkanCommandPool {
})
}
}
}
}

View file

@ -5,11 +5,15 @@ use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT};
pub struct VulkanDebug {
loader: DebugUtils,
messenger: DebugUtilsMessengerEXT
messenger: DebugUtilsMessengerEXT,
}
impl VulkanDebug {
pub fn new(entry: &ash::Entry, instance: &ash::Instance, callback: PFN_vkDebugUtilsMessengerCallbackEXT) -> VkResult<VulkanDebug>{
pub fn new(
entry: &ash::Entry,
instance: &ash::Instance,
callback: PFN_vkDebugUtilsMessengerCallbackEXT,
) -> VkResult<VulkanDebug> {
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder()
.message_severity(
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
@ -26,12 +30,12 @@ impl VulkanDebug {
let debug_utils_loader = DebugUtils::new(entry, instance);
unsafe {
let debug_call_back = debug_utils_loader
.create_debug_utils_messenger(&debug_info, None)?;
let debug_call_back =
debug_utils_loader.create_debug_utils_messenger(&debug_info, None)?;
Ok(VulkanDebug {
loader: debug_utils_loader,
messenger: debug_call_back
messenger: debug_call_back,
})
}
}
@ -40,7 +44,8 @@ impl VulkanDebug {
impl Drop for VulkanDebug {
fn drop(&mut self) {
unsafe {
self.loader.destroy_debug_utils_messenger(self.messenger, None);
self.loader
.destroy_debug_utils_messenger(self.messenger, None);
}
}
}
}

View file

@ -1,13 +1,19 @@
use crate::hello_triangle::swapchain::VulkanSwapchain;
use ash::prelude::VkResult;
use ash::vk;
use crate::hello_triangle::swapchain::VulkanSwapchain;
pub struct VulkanFramebuffer {
pub framebuffer: vk::Framebuffer,
}
impl VulkanFramebuffer {
pub fn new(device: &ash::Device, image_view: &vk::ImageView, render_pass: &vk::RenderPass, width: u32, height: u32) -> VkResult<VulkanFramebuffer> {
pub fn new(
device: &ash::Device,
image_view: &vk::ImageView,
render_pass: &vk::RenderPass,
width: u32,
height: u32,
) -> VkResult<VulkanFramebuffer> {
let attachments = &[*image_view];
let framebuffer_info = vk::FramebufferCreateInfo::builder()
.render_pass(*render_pass)
@ -19,9 +25,7 @@ impl VulkanFramebuffer {
unsafe {
let framebuffer = device.create_framebuffer(&framebuffer_info, None)?;
Ok(VulkanFramebuffer {
framebuffer
})
Ok(VulkanFramebuffer { framebuffer })
}
}
}
}

View file

@ -1,18 +1,13 @@
pub mod vulkan_base;
mod command;
mod debug;
mod framebuffer;
mod physicaldevice;
mod pipeline;
mod surface;
mod swapchain;
mod pipeline;
mod framebuffer;
mod command;
mod syncobjects;
pub mod vulkan_base;
use ash::vk;
use ash::vk::RenderingInfo;
use winit::event::{Event, VirtualKeyCode, ElementState, KeyboardInput, WindowEvent};
use winit::event_loop::{EventLoop, ControlFlow, EventLoopBuilder};
use winit::platform::windows::EventLoopBuilderExtWindows;
use crate::filter_chain::{FilterChainVulkan, Vulkan};
use crate::hello_triangle::command::VulkanCommandPool;
use crate::hello_triangle::framebuffer::VulkanFramebuffer;
@ -22,6 +17,11 @@ use crate::hello_triangle::swapchain::VulkanSwapchain;
use crate::hello_triangle::syncobjects::SyncObjects;
use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util;
use ash::vk;
use ash::vk::RenderingInfo;
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
use winit::platform::windows::EventLoopBuilderExtWindows;
// Constants
const WINDOW_TITLE: &'static str = "librashader Vulkan";
@ -40,49 +40,49 @@ impl VulkanWindow {
.expect("Failed to create window.")
}
pub fn main_loop(event_loop: EventLoop<()>, window: winit::window::Window, vulkan: VulkanDraw, mut filter_chain: FilterChainVulkan) {
event_loop.run(move |event, _, control_flow| {
match event {
| Event::WindowEvent { event, .. } => {
match event {
| WindowEvent::CloseRequested => {
pub fn main_loop(
event_loop: EventLoop<()>,
window: winit::window::Window,
vulkan: VulkanDraw,
mut filter_chain: FilterChainVulkan,
) {
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput { input, .. } => match input {
KeyboardInput {
virtual_keycode,
state,
..
} => match (virtual_keycode, state) {
(Some(VirtualKeyCode::Escape), ElementState::Pressed) => {
*control_flow = ControlFlow::Exit
},
| WindowEvent::KeyboardInput { input, .. } => {
match input {
| KeyboardInput { virtual_keycode, state, .. } => {
match (virtual_keycode, state) {
| (Some(VirtualKeyCode::Escape), ElementState::Pressed) => {
*control_flow = ControlFlow::Exit
},
| _ => {},
}
},
}
},
| _ => {},
}
}
_ => {}
},
},
| Event::MainEventsCleared => {
window.request_redraw();
},
| Event::RedrawRequested(_window_id) => {
VulkanWindow::draw_frame(&vulkan, &mut filter_chain);
},
_ => (),
_ => {}
},
Event::MainEventsCleared => {
window.request_redraw();
}
Event::RedrawRequested(_window_id) => {
VulkanWindow::draw_frame(&vulkan, &mut filter_chain);
}
_ => (),
})
}
unsafe fn record_command_buffer(vulkan: &VulkanDraw, framebuffer: vk::Framebuffer, cmd: vk::CommandBuffer) {
let clear_values = [
vk::ClearValue {
color: vk::ClearColorValue {
float32: [0.3, 0.3, 0.5, 0.0],
},
unsafe fn record_command_buffer(
vulkan: &VulkanDraw,
framebuffer: vk::Framebuffer,
cmd: vk::CommandBuffer,
) {
let clear_values = [vk::ClearValue {
color: vk::ClearColorValue {
float32: [0.3, 0.3, 0.5, 0.0],
},
];
}];
let render_pass_begin = vk::RenderPassBeginInfo::builder()
.render_pass(vulkan.pipeline.renderpass)
@ -94,51 +94,76 @@ impl VulkanWindow {
.clear_values(&clear_values)
.build();
vulkan.base.device.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())
vulkan
.base
.device
.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())
.expect("could not reset command buffer");
vulkan.base.device.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
vulkan
.base
.device
.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
.expect("failed to begin command buffer");
vulkan.base.device
.cmd_begin_render_pass(cmd,
&render_pass_begin, vk::SubpassContents::INLINE);
vulkan.base.device.cmd_begin_render_pass(
cmd,
&render_pass_begin,
vk::SubpassContents::INLINE,
);
vulkan.base.device
.cmd_bind_pipeline(cmd, vk::PipelineBindPoint::GRAPHICS, vulkan.pipeline.graphic_pipeline);
vulkan.base.device.cmd_bind_pipeline(
cmd,
vk::PipelineBindPoint::GRAPHICS,
vulkan.pipeline.graphic_pipeline,
);
vulkan.base.device
.cmd_set_viewport(cmd, 0, &[vk::Viewport {
vulkan.base.device.cmd_set_viewport(
cmd,
0,
&[vk::Viewport {
max_depth: 1.0,
width: vulkan.swapchain.extent.width as f32,
height: vulkan.swapchain.extent.height as f32,
..Default::default()
}]);
}],
);
vulkan.base.device
.cmd_set_scissor(cmd, 0, &[vk::Rect2D {
vulkan.base.device.cmd_set_scissor(
cmd,
0,
&[vk::Rect2D {
offset: Default::default(),
extent: vulkan.swapchain.extent
}]);
extent: vulkan.swapchain.extent,
}],
);
vulkan.base.device.cmd_draw(cmd, 3, 1, 0, 0);
vulkan.base.device.cmd_end_render_pass(cmd);
}
fn draw_frame(vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) {
unsafe {
vulkan.base.device.wait_for_fences(&[vulkan.sync.in_flight], true, u64::MAX)
vulkan
.base
.device
.wait_for_fences(&[vulkan.sync.in_flight], true, u64::MAX)
.unwrap();
vulkan.base.device.reset_fences(&[vulkan.sync.in_flight])
vulkan
.base
.device
.reset_fences(&[vulkan.sync.in_flight])
.unwrap();
let (swapchain_index, _) = vulkan.swapchain.loader.acquire_next_image(vulkan.swapchain.swapchain, u64::MAX, vulkan.sync.image_available, vk::Fence::null())
let (swapchain_index, _) = vulkan
.swapchain
.loader
.acquire_next_image(
vulkan.swapchain.swapchain,
u64::MAX,
vulkan.sync.image_available,
vk::Fence::null(),
)
.unwrap();
let cmd = vulkan.render_command_pool.buffers[swapchain_index as usize];
@ -148,21 +173,22 @@ impl VulkanWindow {
Self::record_command_buffer(vulkan, framebuffer, cmd);
util::vulkan_image_layout_transition_levels(&vulkan.base.device,
util::vulkan_image_layout_transition_levels(
&vulkan.base.device,
cmd,
framebuffer_image,
1,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
);
vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
let blit_subresource =vk::ImageSubresourceLayers::builder()
let blit_subresource = vk::ImageSubresourceLayers::builder()
.layer_count(1)
.aspect_mask(vk::ImageAspectFlags::COLOR)
.build();
@ -184,8 +210,11 @@ impl VulkanWindow {
z: 1,
},
];
vulkan.base.device.cmd_blit_image(cmd, framebuffer_image, vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
swapchain_image,
vulkan.base.device.cmd_blit_image(
cmd,
framebuffer_image,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
swapchain_image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[vk::ImageBlit {
src_subresource: blit_subresource,
@ -193,25 +222,29 @@ impl VulkanWindow {
dst_subresource: blit_subresource,
dst_offsets,
}],
vk::Filter::LINEAR
vk::Filter::LINEAR,
);
util::vulkan_image_layout_transition_levels(&vulkan.base.device,
cmd,
swapchain_image,
1,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::PRESENT_SRC_KHR,
vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
util::vulkan_image_layout_transition_levels(
&vulkan.base.device,
cmd,
swapchain_image,
1,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::PRESENT_SRC_KHR,
vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
vulkan.base.device.end_command_buffer(cmd).expect("failed to record commandbuffer");
vulkan
.base
.device
.end_command_buffer(cmd)
.expect("failed to record commandbuffer");
let submit_info = vk::SubmitInfo::builder()
.wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT])
@ -220,7 +253,14 @@ impl VulkanWindow {
.command_buffers(&[cmd])
.build();
vulkan.base.device.queue_submit(vulkan.base.graphics_queue, &[submit_info], vulkan.sync.in_flight)
vulkan
.base
.device
.queue_submit(
vulkan.base.graphics_queue,
&[submit_info],
vulkan.sync.in_flight,
)
.expect("failed to submit queue");
let present_info = vk::PresentInfoKHR::builder()
@ -229,9 +269,11 @@ impl VulkanWindow {
.image_indices(&[swapchain_index])
.build();
vulkan.swapchain.loader.queue_present(vulkan.base.graphics_queue, &present_info)
vulkan
.swapchain
.loader
.queue_present(vulkan.base.graphics_queue, &present_info)
.unwrap();
}
}
}
@ -251,7 +293,6 @@ pub fn find_memorytype_index(
.map(|(index, _memory_type)| index as _)
}
pub struct VulkanDraw {
surface: VulkanSurface,
base: VulkanBase,
@ -271,32 +312,44 @@ pub fn main(vulkan: VulkanBase, filter_chain: FilterChainVulkan) {
.build();
let window = VulkanWindow::init_window(&event_loop);
let surface = VulkanSurface::new(&vulkan, &window)
.unwrap();
let surface = VulkanSurface::new(&vulkan, &window).unwrap();
let swapchain = VulkanSwapchain::new(&vulkan, &surface, WINDOW_WIDTH, WINDOW_HEIGHT)
.unwrap();
let swapchain = VulkanSwapchain::new(&vulkan, &surface, WINDOW_WIDTH, WINDOW_HEIGHT).unwrap();
let pipeline = unsafe { VulkanPipeline::new(&vulkan, &swapchain) }
.unwrap();
let pipeline = unsafe { VulkanPipeline::new(&vulkan, &swapchain) }.unwrap();
let mut swapchain_framebuffers = vec![];
for image in &swapchain.swapchain_image_views {
swapchain_framebuffers.push(VulkanFramebuffer::new(&vulkan.device, image, &pipeline.renderpass, WINDOW_WIDTH, WINDOW_HEIGHT).unwrap())
swapchain_framebuffers.push(
VulkanFramebuffer::new(
&vulkan.device,
image,
&pipeline.renderpass,
WINDOW_WIDTH,
WINDOW_HEIGHT,
)
.unwrap(),
)
}
let mut render_framebuffers = vec![];
for image in &swapchain.render_image_views {
render_framebuffers.push(VulkanFramebuffer::new(&vulkan.device, image, &pipeline.renderpass, WINDOW_WIDTH, WINDOW_HEIGHT).unwrap())
render_framebuffers.push(
VulkanFramebuffer::new(
&vulkan.device,
image,
&pipeline.renderpass,
WINDOW_WIDTH,
WINDOW_HEIGHT,
)
.unwrap(),
)
}
let swapchain_command_pool = VulkanCommandPool::new(&vulkan, 3)
.unwrap();
let render_command_pool = VulkanCommandPool::new(&vulkan, 3)
.unwrap();
let swapchain_command_pool = VulkanCommandPool::new(&vulkan, 3).unwrap();
let render_command_pool = VulkanCommandPool::new(&vulkan, 3).unwrap();
let sync = SyncObjects::new(&vulkan.device)
.unwrap();
let sync = SyncObjects::new(&vulkan.device).unwrap();
let vulkan = VulkanDraw {
surface,
@ -311,4 +364,4 @@ pub fn main(vulkan: VulkanBase, filter_chain: FilterChainVulkan) {
};
VulkanWindow::main_loop(event_loop, window, vulkan, filter_chain);
}
}

View file

@ -1,5 +1,5 @@
use std::ffi::CStr;
use ash::vk;
use std::ffi::CStr;
pub struct QueueFamilyIndices {
graphics_family: Option<u32>,
@ -62,16 +62,12 @@ fn is_physical_device_suitable(
device_name, device_properties.device_id, device_type
);
println!(
"\tAPI Version: {}",
device_properties.api_version
);
println!("\tAPI Version: {}", device_properties.api_version);
println!("\tSupport Queue Family: {}", device_queue_families.len());
println!("\t\tQueue Count | Graphics, Compute, Transfer, Sparse Binding");
for queue_family in device_queue_families.iter() {
let is_graphics_support = if queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS)
{
let is_graphics_support = if queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS) {
"support"
} else {
"unsupport"
@ -81,8 +77,7 @@ fn is_physical_device_suitable(
} else {
"unsupport"
};
let is_transfer_support = if queue_family.queue_flags.contains(vk::QueueFlags::TRANSFER)
{
let is_transfer_support = if queue_family.queue_flags.contains(vk::QueueFlags::TRANSFER) {
"support"
} else {
"unsupport"
@ -148,4 +143,4 @@ pub fn find_queue_family(
}
queue_family_indices
}
}

View file

@ -1,14 +1,14 @@
use std::ffi::CStr;
use std::io::Cursor;
use std::mem::align_of;
use ash::prelude::VkResult;
use ash::util::{Align, read_spv};
use ash::vk;
use bytemuck::offset_of;
use crate::hello_triangle::find_memorytype_index;
use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::swapchain::VulkanSwapchain;
use crate::hello_triangle::vulkan_base::VulkanBase;
use ash::prelude::VkResult;
use ash::util::{read_spv, Align};
use ash::vk;
use bytemuck::offset_of;
use std::ffi::CStr;
use std::io::Cursor;
use std::mem::align_of;
#[derive(Default, Clone, Debug, Copy)]
struct Vertex {
@ -38,7 +38,7 @@ impl VulkanPipeline {
&base.mem_props,
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT,
)
.expect("Unable to find suitable memorytype for the index buffer.");
.expect("Unable to find suitable memorytype for the index buffer.");
let index_allocate_info = vk::MemoryAllocateInfo {
allocation_size: index_buffer_memory_req.size,
@ -90,7 +90,7 @@ impl VulkanPipeline {
&base.mem_props,
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT,
)
.expect("Unable to find suitable memorytype for the vertex buffer.");
.expect("Unable to find suitable memorytype for the vertex buffer.");
let vertex_buffer_allocate_info = vk::MemoryAllocateInfo {
allocation_size: vertex_input_buffer_memory_req.size,
@ -141,9 +141,9 @@ impl VulkanPipeline {
.bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0)
.unwrap();
// create pipeline
let mut vertex_spv_file = Cursor::new(&include_bytes!("../../shader/triangle_simple/vert.spv")[..]);
let mut vertex_spv_file =
Cursor::new(&include_bytes!("../../shader/triangle_simple/vert.spv")[..]);
let vertex_code =
read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file");
let vertex_shader_info = ShaderModule::new(&base.device, vertex_code)?;
@ -153,8 +153,8 @@ impl VulkanPipeline {
.name(CStr::from_bytes_with_nul_unchecked(b"main\0"))
.build();
let mut frag_spv_file = Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]);
let mut frag_spv_file =
Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]);
let frag_code =
read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file");
let frag_shader_info = ShaderModule::new(&base.device, frag_code)?;
@ -194,7 +194,6 @@ impl VulkanPipeline {
.create_pipeline_layout(&layout_create_info, None)
.unwrap();
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder()
.dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR])
.build();
@ -244,16 +243,14 @@ impl VulkanPipeline {
.logic_op(vk::LogicOp::COPY)
.attachments(&color_blend_attachment);
let renderpass_attachments = [
vk::AttachmentDescription {
format: swapchain.format.format,
samples: vk::SampleCountFlags::TYPE_1,
load_op: vk::AttachmentLoadOp::CLEAR,
store_op: vk::AttachmentStoreOp::STORE,
final_layout: vk::ImageLayout::PRESENT_SRC_KHR,
..Default::default()
},
];
let renderpass_attachments = [vk::AttachmentDescription {
format: swapchain.format.format,
samples: vk::SampleCountFlags::TYPE_1,
load_op: vk::AttachmentLoadOp::CLEAR,
store_op: vk::AttachmentStoreOp::STORE,
final_layout: vk::ImageLayout::PRESENT_SRC_KHR,
..Default::default()
}];
let color_attachment_refs = [vk::AttachmentReference {
attachment: 0,
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
@ -295,7 +292,6 @@ impl VulkanPipeline {
.layout(pipeline_layout)
.render_pass(renderpass);
let graphics_pipelines = base
.device
.create_graphics_pipelines(
@ -305,13 +301,12 @@ impl VulkanPipeline {
)
.expect("Unable to create graphics pipeline");
let graphic_pipeline = graphics_pipelines[0];
Ok(VulkanPipeline {
graphic_pipeline,
renderpass,
pipeline_layout
pipeline_layout,
})
}
}
@ -323,18 +318,13 @@ pub struct ShaderModule {
impl ShaderModule {
pub fn new(device: &ash::Device, spirv: Vec<u32>) -> VkResult<ShaderModule> {
let create_info = vk::ShaderModuleCreateInfo::builder()
.code(&spirv)
.build();
let create_info = vk::ShaderModuleCreateInfo::builder().code(&spirv).build();
let module = unsafe {
device.create_shader_module(&create_info, None)?
};
let module = unsafe { device.create_shader_module(&create_info, None)? };
Ok(ShaderModule {
module,
device: device.clone()
device: device.clone(),
})
}
}
@ -346,4 +336,3 @@ impl Drop for ShaderModule {
}
}
}

View file

@ -1,18 +1,16 @@
use crate::hello_triangle::vulkan_base::VulkanBase;
use ash::prelude::VkResult;
use ash::vk;
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use crate::hello_triangle::vulkan_base::VulkanBase;
pub struct VulkanSurface {
surface_loader: ash::extensions::khr::Surface,
pub surface: vk::SurfaceKHR,
pub present_queue: vk::Queue
pub present_queue: vk::Queue,
}
impl VulkanSurface {
pub fn new(base: &VulkanBase,
window: &winit::window::Window) -> VkResult<VulkanSurface>
{
pub fn new(base: &VulkanBase, window: &winit::window::Window) -> VkResult<VulkanSurface> {
let surface = unsafe {
ash_window::create_surface(
&base.entry,
@ -26,7 +24,8 @@ impl VulkanSurface {
let surface_loader = ash::extensions::khr::Surface::new(&base.entry, &base.instance);
let present_queue = unsafe {
let queue_family = base.instance
let queue_family = base
.instance
.get_physical_device_queue_family_properties(base.physical_device)
.iter()
.enumerate()
@ -34,12 +33,12 @@ impl VulkanSurface {
let supports_graphic_and_surface =
info.queue_flags.contains(vk::QueueFlags::GRAPHICS)
&& surface_loader
.get_physical_device_surface_support(
base.physical_device,
index as u32,
surface,
)
.unwrap();
.get_physical_device_surface_support(
base.physical_device,
index as u32,
surface,
)
.unwrap();
if supports_graphic_and_surface {
Some(index)
} else {
@ -53,13 +52,15 @@ impl VulkanSurface {
Ok(VulkanSurface {
surface,
surface_loader,
present_queue
present_queue,
})
}
pub fn choose_format(&self, base: &VulkanBase) -> VkResult<vk::SurfaceFormatKHR> {
unsafe {
let available_formats = self.surface_loader.get_physical_device_surface_formats(base.physical_device, self.surface)?;
let available_formats = self
.surface_loader
.get_physical_device_surface_formats(base.physical_device, self.surface)?;
for available_format in available_formats.iter() {
if available_format.format == vk::Format::B8G8R8A8_SRGB
&& available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
@ -74,17 +75,26 @@ impl VulkanSurface {
pub fn choose_present_mode(&self, base: &VulkanBase) -> VkResult<vk::PresentModeKHR> {
unsafe {
let available_formats = self.surface_loader.get_physical_device_surface_present_modes(base.physical_device, self.surface)?;
let available_formats = self
.surface_loader
.get_physical_device_surface_present_modes(base.physical_device, self.surface)?;
Ok(if available_formats.contains(&vk::PresentModeKHR::MAILBOX) {
vk::PresentModeKHR::MAILBOX
} else {
vk::PresentModeKHR::FIFO
})
Ok(
if available_formats.contains(&vk::PresentModeKHR::MAILBOX) {
vk::PresentModeKHR::MAILBOX
} else {
vk::PresentModeKHR::FIFO
},
)
}
}
pub fn choose_swapchain_extent(&self, base: &VulkanBase, width: u32, height: u32) -> VkResult<vk::Extent2D> {
pub fn choose_swapchain_extent(
&self,
base: &VulkanBase,
width: u32,
height: u32,
) -> VkResult<vk::Extent2D> {
let capabilities = self.get_capabilities(base)?;
if capabilities.current_extent.width != u32::MAX {
Ok(capabilities.current_extent)
@ -108,7 +118,8 @@ impl VulkanSurface {
pub fn get_capabilities(&self, base: &VulkanBase) -> VkResult<vk::SurfaceCapabilitiesKHR> {
unsafe {
self.surface_loader.get_physical_device_surface_capabilities(base.physical_device, self.surface)
self.surface_loader
.get_physical_device_surface_capabilities(base.physical_device, self.surface)
}
}
}
@ -119,4 +130,4 @@ impl Drop for VulkanSurface {
self.surface_loader.destroy_surface(self.surface, None);
}
}
}
}

View file

@ -1,10 +1,10 @@
use ash::prelude::VkResult;
use ash::vk;
use ash::vk::Extent3D;
use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory;
use ash::prelude::VkResult;
use ash::vk;
use ash::vk::Extent3D;
pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR,
@ -21,7 +21,12 @@ pub struct VulkanSwapchain {
}
impl VulkanSwapchain {
pub fn new(base: &VulkanBase, surface: &VulkanSurface, width: u32, height:u32 ) -> VkResult<VulkanSwapchain> {
pub fn new(
base: &VulkanBase,
surface: &VulkanSurface,
width: u32,
height: u32,
) -> VkResult<VulkanSwapchain> {
let format = surface.choose_format(base)?;
let mode = surface.choose_present_mode(base)?;
let extent = surface.choose_swapchain_extent(base, width, height)?;
@ -56,13 +61,10 @@ impl VulkanSwapchain {
let loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device);
let swapchain = unsafe {
loader.create_swapchain(&create_info, None)?
};
let swapchain = unsafe { loader.create_swapchain(&create_info, None)? };
let swapchain_images = unsafe { loader.get_swapchain_images(swapchain)? };
let mut render_images = vec![];
for _ in 0..swapchain_images.len() {
@ -79,10 +81,7 @@ impl VulkanSwapchain {
.tiling(vk::ImageTiling::OPTIMAL)
.array_layers(1)
.mip_levels(1)
.usage(
vk::ImageUsageFlags::SAMPLED
| vk::ImageUsageFlags::COLOR_ATTACHMENT
)
.usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT)
.initial_layout(vk::ImageLayout::UNDEFINED);
unsafe {
@ -100,70 +99,68 @@ impl VulkanSwapchain {
.build();
// todo: optimize by reusing existing memory.
let memory = VulkanImageMemory::new(&base.device, &alloc_info)
.unwrap();
memory.bind(&image)
.unwrap();
let memory = VulkanImageMemory::new(&base.device, &alloc_info).unwrap();
memory.bind(&image).unwrap();
render_images.push((image, memory))
}
}
let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images.iter().map(|image| {
let create_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D)
.format(format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(*image)
.build();
let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
.iter()
.map(|image| {
let create_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D)
.format(format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(*image)
.build();
let view = unsafe { base.device.create_image_view(&create_info, None)? };
let view = unsafe {
base.device.create_image_view(&create_info, None)?
};
Ok(view)
})
.collect();
Ok(view)
}).collect();
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
.iter()
.map(|(image, _)| {
let create_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D)
.format(format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(*image)
.build();
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images.iter().map(|(image, _)| {
let create_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D)
.format(format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(*image)
.build();
let view = unsafe { base.device.create_image_view(&create_info, None)? };
let view = unsafe {
base.device.create_image_view(&create_info, None)?
};
Ok(view)
}).collect();
Ok(view)
})
.collect();
Ok(VulkanSwapchain {
swapchain,
loader,
@ -174,7 +171,7 @@ impl VulkanSwapchain {
render_images,
swapchain_image_views: image_views?,
render_image_views: render_image_views?,
device: base.device.clone()
device: base.device.clone(),
})
}
}
@ -188,4 +185,4 @@ impl Drop for VulkanSwapchain {
self.loader.destroy_swapchain(self.swapchain, None)
}
}
}
}

View file

@ -4,21 +4,28 @@ use ash::vk;
pub struct SyncObjects {
pub image_available: vk::Semaphore,
pub render_finished: vk::Semaphore,
pub in_flight: vk::Fence
pub in_flight: vk::Fence,
}
impl SyncObjects {
pub fn new(device: &ash::Device) -> VkResult<SyncObjects> {
unsafe {
let image_available = device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?;
let render_finished = device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?;
let in_flight = device.create_fence(&vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED).build(), None)?;
let image_available =
device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?;
let render_finished =
device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?;
let in_flight = device.create_fence(
&vk::FenceCreateInfo::builder()
.flags(vk::FenceCreateFlags::SIGNALED)
.build(),
None,
)?;
Ok(SyncObjects {
image_available,
render_finished,
in_flight
in_flight,
})
}
}
}
}

View file

@ -1,14 +1,13 @@
use ash::vk;
use std::borrow::Cow;
use std::error::Error;
use ash::vk;
use std::ffi::{CStr, CString};
use ash::prelude::VkResult;
use crate::filter_chain::Vulkan;
use crate::hello_triangle::debug::VulkanDebug;
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
use crate::hello_triangle::surface::VulkanSurface;
use ash::prelude::VkResult;
use std::ffi::{CStr, CString};
const WINDOW_TITLE: &'static str = "librashader Vulkan";
@ -39,13 +38,11 @@ impl VulkanBase {
let extensions = [
ash::extensions::khr::Surface::name().as_ptr(),
ash::extensions::khr::Win32Surface::name().as_ptr(),
ash::extensions::ext::DebugUtils::name().as_ptr()
ash::extensions::ext::DebugUtils::name().as_ptr(),
];
let layers = unsafe {
[CStr::from_bytes_with_nul_unchecked(
b"VK_LAYER_KHRONOS_validation\0",
).as_ptr()]
let layers = unsafe {
[CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr()]
};
let create_info = vk::InstanceCreateInfo::builder()
@ -54,9 +51,7 @@ impl VulkanBase {
.enabled_extension_names(&extensions)
.build();
let instance = unsafe {
entry.create_instance(&create_info, None)?
};
let instance = unsafe { entry.create_instance(&create_info, None)? };
let debug = VulkanDebug::new(&entry, &instance, Some(vulkan_debug_callback))?;
@ -64,9 +59,7 @@ impl VulkanBase {
let (device, queue) = VulkanBase::create_device(&instance, &physical_device)?;
let mem_props = unsafe {
instance.get_physical_device_memory_properties(physical_device)
};
let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) };
Ok(VulkanBase {
entry,
@ -79,11 +72,12 @@ impl VulkanBase {
})
}
fn create_device(instance: &ash::Instance, physical_device: &vk::PhysicalDevice) -> VkResult<(ash::Device, vk::Queue)> {
fn create_device(
instance: &ash::Instance,
physical_device: &vk::PhysicalDevice,
) -> VkResult<(ash::Device, vk::Queue)> {
let debug = unsafe {
CStr::from_bytes_with_nul_unchecked(
b"VK_LAYER_KHRONOS_validation\0",
).as_ptr()
CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr()
};
let indices = find_queue_family(&instance, *physical_device);
@ -97,15 +91,12 @@ impl VulkanBase {
let device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(&[queue_info])
.enabled_layer_names(&[debug])
.enabled_extension_names(&[
ash::extensions::khr::Swapchain::name().as_ptr()
])
.enabled_extension_names(&[ash::extensions::khr::Swapchain::name().as_ptr()])
.enabled_features(&physical_device_features)
.build();
let device = unsafe {
instance.create_device(*physical_device, &device_create_info, None)?
};
let device =
unsafe { instance.create_device(*physical_device, &device_create_info, None)? };
let queue = unsafe { device.get_device_queue(indices.graphics_family(), 0) };
@ -113,7 +104,6 @@ impl VulkanBase {
}
}
unsafe extern "system" fn vulkan_debug_callback(
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
message_type: vk::DebugUtilsMessageTypeFlagsEXT,
@ -159,6 +149,10 @@ impl TryFrom<&VulkanBase> for Vulkan {
type Error = Box<dyn Error>;
fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> {
Vulkan::try_from((value.device.clone(), value.graphics_queue.clone(), value.mem_props))
Vulkan::try_from((
value.device.clone(),
value.graphics_queue.clone(),
value.mem_props,
))
}
}
}

View file

@ -7,16 +7,16 @@ mod error;
mod filter_chain;
mod filter_pass;
mod framebuffer;
mod hello_triangle;
mod luts;
mod renderpass;
mod rendertarget;
mod samplers;
mod texture;
mod ubo_ring;
mod util;
mod vulkan_primitives;
mod vulkan_state;
mod samplers;
mod texture;
mod rendertarget;
mod ubo_ring;
mod hello_triangle;
#[cfg(test)]
mod tests {
@ -26,15 +26,14 @@ mod tests {
#[test]
fn triangle_vk() {
let entry = unsafe {
ash::Entry::load().unwrap()
};
let entry = unsafe { ash::Entry::load().unwrap() };
let base = VulkanBase::new(entry).unwrap();
let mut filter = FilterChainVulkan::load_from_path(
&base,
"../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp",
None
).unwrap();
None,
)
.unwrap();
crate::hello_triangle::main(base, filter)

View file

@ -1,16 +1,16 @@
use crate::filter_chain::Vulkan;
use crate::texture::{Texture, VulkanImage};
use crate::vulkan_primitives::{VulkanBuffer, VulkanImageMemory};
use crate::{error, util};
use ash::vk;
use librashader_presets::TextureConfig;
use librashader_runtime::image::{Image, BGRA8};
use librashader_runtime::scaling::MipmapSize;
use crate::texture::{Texture, VulkanImage};
pub struct LutTexture {
pub memory: VulkanImageMemory,
pub staging: VulkanBuffer,
pub image: Texture
pub image: Texture,
}
impl LutTexture {
@ -238,12 +238,12 @@ impl LutTexture {
image: VulkanImage {
size: image.size,
image: texture,
format: vk::Format::B8G8R8A8_UNORM
format: vk::Format::B8G8R8A8_UNORM,
},
filter_mode: config.filter_mode,
wrap_mode: config.wrap_mode,
mip_filter: config.filter_mode,
}
},
})
}
}

View file

@ -50,10 +50,7 @@ impl VulkanRenderPass {
unsafe {
let rp = device.create_render_pass(&renderpass_info, None)?;
Ok(Self {
handle: rp,
format,
})
Ok(Self { handle: rp, format })
}
}
}

View file

@ -1,8 +1,8 @@
use crate::framebuffer::OutputFramebuffer;
use ash::vk;
use crate::framebuffer::{OutputFramebuffer,};
#[derive(Debug, Clone)]
pub(crate) struct RenderTarget<'a> {
pub mvp: &'a [f32; 16],
pub output: OutputFramebuffer,
}
}

View file

@ -1,15 +1,20 @@
use ash::vk;
use rustc_hash::FxHashMap;
use librashader_common::{FilterMode, WrapMode};
use crate::error;
use ash::vk;
use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
pub struct VulkanSampler {
pub handle: vk::Sampler,
device: ash::Device
device: ash::Device,
}
impl VulkanSampler {
pub fn new(device: &ash::Device, wrap: WrapMode, filter: FilterMode, mipmap: FilterMode) -> error::Result<VulkanSampler> {
pub fn new(
device: &ash::Device,
wrap: WrapMode,
filter: FilterMode,
mipmap: FilterMode,
) -> error::Result<VulkanSampler> {
let create_info = vk::SamplerCreateInfo::builder()
.mip_lod_bias(0.0)
.max_anisotropy(1.0)
@ -26,13 +31,11 @@ impl VulkanSampler {
.address_mode_w(wrap.into())
.build();
let sampler = unsafe {
device.create_sampler(&create_info, None)?
};
let sampler = unsafe { device.create_sampler(&create_info, None)? };
Ok(VulkanSampler {
handle: sampler,
device: device.clone()
device: device.clone(),
})
}
}
@ -47,7 +50,6 @@ impl Drop for VulkanSampler {
}
}
pub struct SamplerSet {
// todo: may need to deal with differences in mip filter.
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), VulkanSampler>,
@ -79,11 +81,11 @@ impl SamplerSet {
samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Nearest),
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Nearest)?
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Nearest)?,
);
samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Linear),
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Linear)?
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Linear)?,
);
}

View file

@ -1,11 +1,14 @@
use ash::vk;
use ash::vk::{ImageAspectFlags, ImageLayout, ImageTiling, ImageType, ImageUsageFlags, ImageViewType, SampleCountFlags, SharingMode};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::scaling::MipmapSize;
use crate::error;
use crate::filter_chain::Vulkan;
use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory;
use ash::vk;
use ash::vk::{
ImageAspectFlags, ImageLayout, ImageTiling, ImageType, ImageUsageFlags, ImageViewType,
SampleCountFlags, SharingMode,
};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::scaling::MipmapSize;
pub struct OwnedTexture {
pub device: ash::Device,
@ -16,16 +19,17 @@ pub struct OwnedTexture {
}
impl OwnedTexture {
pub fn new(vulkan: &Vulkan, size: Size<u32>, format: ImageFormat, max_miplevels: u32)
-> error::Result<OwnedTexture> {
pub fn new(
vulkan: &Vulkan,
size: Size<u32>,
format: ImageFormat,
max_miplevels: u32,
) -> error::Result<OwnedTexture> {
let image_create_info = vk::ImageCreateInfo::builder()
.image_type(ImageType::TYPE_2D)
.format(format.into())
.extent(size.into())
.mip_levels(std::cmp::min(
max_miplevels,
size.calculate_miplevels(),
))
.mip_levels(std::cmp::min(max_miplevels, size.calculate_miplevels()))
.array_layers(1)
.samples(SampleCountFlags::TYPE_1)
.tiling(ImageTiling::OPTIMAL)
@ -86,7 +90,7 @@ impl OwnedTexture {
image: VulkanImage {
image,
size,
format: format.into()
format: format.into(),
},
memory,
max_miplevels,
@ -109,7 +113,6 @@ impl OwnedTexture {
.a(vk::ComponentSwizzle::A)
.build();
let mut view_info = vk::ImageViewCreateInfo::builder()
.view_type(ImageViewType::TYPE_2D)
.format(self.image.format)

View file

@ -1,8 +1,8 @@
use crate::error;
use crate::vulkan_primitives::VulkanBuffer;
use ash::vk;
use librashader_runtime::ringbuffer::{BoxRingBuffer, InlineRingBuffer, RingBuffer};
use librashader_runtime::uniforms::UniformStorageAccess;
use crate::error;
use crate::vulkan_primitives::VulkanBuffer;
pub struct VkUboRing {
ring: BoxRingBuffer<VulkanBuffer>,
@ -10,19 +10,34 @@ pub struct VkUboRing {
}
impl VkUboRing {
pub fn new(device: &ash::Device, mem_props: &vk::PhysicalDeviceMemoryProperties, ring_size: usize, buffer_size: usize) -> error::Result<Self> {
pub fn new(
device: &ash::Device,
mem_props: &vk::PhysicalDeviceMemoryProperties,
ring_size: usize,
buffer_size: usize,
) -> error::Result<Self> {
let mut ring = Vec::new();
for _ in 0..ring_size {
ring.push(VulkanBuffer::new(device, mem_props, vk::BufferUsageFlags::UNIFORM_BUFFER, buffer_size)?);
ring.push(VulkanBuffer::new(
device,
mem_props,
vk::BufferUsageFlags::UNIFORM_BUFFER,
buffer_size,
)?);
}
Ok(VkUboRing {
ring: BoxRingBuffer::from_vec(ring),
device: device.clone()
device: device.clone(),
})
}
pub fn bind_to_descriptor_set(&mut self, descriptor_set: vk::DescriptorSet, binding: u32, storage: &impl UniformStorageAccess) -> error::Result<()>{
pub fn bind_to_descriptor_set(
&mut self,
descriptor_set: vk::DescriptorSet,
binding: u32,
storage: &impl UniformStorageAccess,
) -> error::Result<()> {
let mut buffer = self.ring.current_mut();
// todo: write directly to allocated buffer.
unsafe {

View file

@ -124,8 +124,13 @@ impl Drop for VulkanBuffer {
impl<'a> VulkanBufferMapHandle<'a> {
pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) {
std::ptr::copy_nonoverlapping(src.as_ptr(),
self.ptr.map_addr(|original| original.wrapping_add(offset)).cast(), src.len());
std::ptr::copy_nonoverlapping(
src.as_ptr(),
self.ptr
.map_addr(|original| original.wrapping_add(offset))
.cast(),
src.len(),
);
}
}

View file

@ -31,14 +31,12 @@ pub trait UniformStorageAccess {
/// This pointer must be valid for the lifetime of the implementing struct.
fn push_pointer(&self) -> *const u8;
/// Get a slice to the backing Push Constant buffer storage.
/// This pointer must be valid for the lifetime of the implementing struct.
fn push_slice(&self) -> &[u8];
}
impl<T, H> UniformStorageAccess for UniformStorage<T, H> {
fn ubo_pointer(&self) -> *const u8 {
self.ubo.as_ptr()
}