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::InvalidPath(_) => LIBRA_ERRNO::INVALID_PATH,
LibrashaderError::PresetError(_) => LIBRA_ERRNO::PRESET_ERROR, LibrashaderError::PresetError(_) => LIBRA_ERRNO::PRESET_ERROR,
LibrashaderError::PreprocessError(_) => LIBRA_ERRNO::PREPROCESS_ERROR, LibrashaderError::PreprocessError(_) => LIBRA_ERRNO::PREPROCESS_ERROR,
LibrashaderError::ShaderCompileError(_) LibrashaderError::ShaderCompileError(_) | LibrashaderError::ShaderReflectError(_) => {
| LibrashaderError::ShaderReflectError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LIBRA_ERRNO::RUNTIME_ERROR
}
#[cfg(feature = "runtime-opengl")] #[cfg(feature = "runtime-opengl")]
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-d3d11")] #[cfg(feature = "runtime-d3d11")]

View file

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

View file

@ -123,22 +123,20 @@ impl From<&vk::Viewport> for Size<u32> {
} }
} }
impl From<FilterMode> for vk::Filter { impl From<FilterMode> for vk::Filter {
fn from(value: FilterMode) -> Self { fn from(value: FilterMode) -> Self {
match value { match value {
FilterMode::Linear => vk::Filter::LINEAR, FilterMode::Linear => vk::Filter::LINEAR,
FilterMode::Nearest => vk::Filter::NEAREST FilterMode::Nearest => vk::Filter::NEAREST,
} }
} }
} }
impl From<FilterMode> for vk::SamplerMipmapMode { impl From<FilterMode> for vk::SamplerMipmapMode {
fn from(value: FilterMode) -> Self { fn from(value: FilterMode) -> Self {
match value { match value {
FilterMode::Linear => vk::SamplerMipmapMode::LINEAR, 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::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER,
WrapMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE, WrapMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
WrapMode::Repeat => vk::SamplerAddressMode::REPEAT, 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::error;
use crate::vulkan_primitives::VulkanBuffer; use crate::vulkan_primitives::VulkanBuffer;
use ash::vk;
#[rustfmt::skip] #[rustfmt::skip]
static VBO_OFFSCREEN: &[f32; 16] = &[ static VBO_OFFSCREEN: &[f32; 16] = &[
@ -22,39 +22,55 @@ static VBO_DEFAULT_FINAL: &[f32; 16] = &[
pub enum VboType { pub enum VboType {
Offscreen, Offscreen,
Final Final,
} }
pub struct DrawQuad { pub struct DrawQuad {
buffer: VulkanBuffer, buffer: VulkanBuffer,
device: ash::Device device: ash::Device,
} }
impl DrawQuad { impl DrawQuad {
pub fn new(device: &ash::Device, mem_props: &vk::PhysicalDeviceMemoryProperties) -> error::Result<DrawQuad> { pub fn new(
let mut buffer = VulkanBuffer::new(device, mem_props, vk::BufferUsageFlags::VERTEX_BUFFER, 2 * std::mem::size_of::<[f32; 16]>())?; 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()?; let mut map = buffer.map()?;
unsafe { unsafe {
map.copy_from(0, bytemuck::cast_slice(VBO_OFFSCREEN)); 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 { Ok(DrawQuad {
buffer, buffer,
device: device.clone() device: device.clone(),
}) })
} }
pub fn bind_vbo(&self, cmd: &vk::CommandBuffer, vbo: VboType) { pub fn bind_vbo(&self, cmd: &vk::CommandBuffer, vbo: VboType) {
let offset = match vbo { let offset = match vbo {
VboType::Offscreen => 0, VboType::Offscreen => 0,
VboType::Final => std::mem::size_of::<[f32; 16]>() VboType::Final => std::mem::size_of::<[f32; 16]>(),
}; };
unsafe { 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::error;
use crate::filter_pass::FilterPass; use crate::filter_pass::FilterPass;
use crate::luts::LutTexture; use crate::luts::LutTexture;
use crate::samplers::SamplerSet;
use crate::texture::VulkanImage;
use crate::ubo_ring::VkUboRing;
use crate::vulkan_state::VulkanGraphicsPipeline; use crate::vulkan_state::VulkanGraphicsPipeline;
use ash::vk::{CommandPoolCreateFlags, PFN_vkGetInstanceProcAddr, Queue, StaticFn}; use ash::vk::{CommandPoolCreateFlags, PFN_vkGetInstanceProcAddr, Queue, StaticFn};
use ash::{vk, Device}; use ash::{vk, Device};
@ -19,9 +22,6 @@ use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::error::Error; use std::error::Error;
use std::path::Path; use std::path::Path;
use crate::samplers::SamplerSet;
use crate::texture::VulkanImage;
use crate::ubo_ring::VkUboRing;
pub struct Vulkan { pub struct Vulkan {
// physical_device: vk::PhysicalDevice, // physical_device: vk::PhysicalDevice,
@ -149,7 +149,7 @@ pub type FilterChainOptionsVulkan = ();
impl FilterChainVulkan { impl FilterChainVulkan {
/// Load the shader preset at the given path into a filter chain. /// Load the shader preset at the given path into a filter chain.
pub fn load_from_path( pub fn load_from_path(
vulkan: impl TryInto<Vulkan, Error=Box<dyn Error>>, vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
path: impl AsRef<Path>, path: impl AsRef<Path>,
options: Option<&FilterChainOptionsVulkan>, options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> { ) -> error::Result<FilterChainVulkan> {
@ -159,7 +159,7 @@ impl FilterChainVulkan {
} }
pub fn load_from_preset( pub fn load_from_preset(
vulkan: impl TryInto<Vulkan, Error=Box<dyn Error>>, vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
preset: ShaderPreset, preset: ShaderPreset,
options: Option<&FilterChainOptionsVulkan>, options: Option<&FilterChainOptionsVulkan>,
) -> error::Result<FilterChainVulkan> { ) -> error::Result<FilterChainVulkan> {
@ -172,7 +172,6 @@ impl FilterChainVulkan {
let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?; let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?;
let samplers = SamplerSet::new(&device.device)?; let samplers = SamplerSet::new(&device.device)?;
eprintln!("filters initialized ok."); eprintln!("filters initialized ok.");
Ok(FilterChainVulkan { Ok(FilterChainVulkan {
common: FilterCommon { common: FilterCommon {
@ -188,7 +187,7 @@ impl FilterChainVulkan {
}, },
}, },
passes: filters, passes: filters,
vulkan: device vulkan: device,
}) })
} }
@ -221,7 +220,8 @@ impl FilterChainVulkan {
Ok::<_, Box<dyn Error>>((shader, source, reflect)) Ok::<_, Box<dyn Error>>((shader, source, reflect))
}) })
.into_iter() .into_iter()
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?; .collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
)?;
for details in &passes { for details in &passes {
librashader_runtime::semantics::insert_pass_semantics( librashader_runtime::semantics::insert_pass_semantics(
@ -262,7 +262,8 @@ impl FilterChainVulkan {
.as_ref() .as_ref()
.map(|ubo| ubo.size as usize) .map(|ubo| ubo.size as usize)
.unwrap_or(0); .unwrap_or(0);
let uniform_storage = UniformStorage::new(ubo_size, let uniform_storage = UniformStorage::new(
ubo_size,
reflection reflection
.push_constant .push_constant
.as_ref() .as_ref()
@ -298,7 +299,12 @@ impl FilterChainVulkan {
images, 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 // shader_vulkan: 2026
filters.push(FilterPass { filters.push(FilterPass {
device: vulkan.device.clone(), device: vulkan.device.clone(),
@ -374,7 +380,7 @@ impl FilterChainVulkan {
viewport: &vk::Viewport, viewport: &vk::Viewport,
input: &VulkanImage, input: &VulkanImage,
options: Option<()>, options: Option<()>,
command_buffer: vk::CommandBuffer command_buffer: vk::CommandBuffer,
) -> error::Result<()> { ) -> error::Result<()> {
// limit number of passes to those enabled. // limit number of passes to those enabled.
let passes = &mut self.passes[0..self.common.config.passes_enabled]; let passes = &mut self.passes[0..self.common.config.passes_enabled];
@ -394,6 +400,5 @@ impl FilterChainVulkan {
// } // }
Ok(()) 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::error;
use crate::filter_chain::FilterCommon; use crate::filter_chain::FilterCommon;
use crate::rendertarget::RenderTarget; use crate::rendertarget::RenderTarget;
use crate::texture::Texture;
use crate::samplers::{SamplerSet, VulkanSampler}; use crate::samplers::{SamplerSet, VulkanSampler};
use crate::texture::Texture;
use crate::ubo_ring::VkUboRing; 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 struct FilterPass {
pub device: ash::Device, pub device: ash::Device,
@ -24,18 +26,18 @@ pub struct FilterPass {
pub source: ShaderSource, pub source: ShaderSource,
pub config: ShaderPassConfig, pub config: ShaderPassConfig,
pub graphics_pipeline: VulkanGraphicsPipeline, pub graphics_pipeline: VulkanGraphicsPipeline,
pub ubo_ring: VkUboRing pub ubo_ring: VkUboRing,
} }
impl FilterPass { impl FilterPass {
#[inline(always)] #[inline(always)]
fn bind_texture(device: &ash::Device, fn bind_texture(
samplers: &SamplerSet, device: &ash::Device,
descriptor_set: vk::DescriptorSet, samplers: &SamplerSet,
binding: &TextureBinding, descriptor_set: vk::DescriptorSet,
texture: &Texture) { binding: &TextureBinding,
texture: &Texture,
) {
let sampler = samplers.get(texture.wrap_mode, texture.filter_mode, texture.mip_filter); let sampler = samplers.get(texture.wrap_mode, texture.filter_mode, texture.mip_filter);
let image_info = [vk::DescriptorImageInfo::builder() let image_info = [vk::DescriptorImageInfo::builder()
.sampler(sampler.handle) .sampler(sampler.handle)
@ -53,7 +55,6 @@ impl FilterPass {
unsafe { unsafe {
device.update_descriptor_sets(&write_desc, &[]); device.update_descriptor_sets(&write_desc, &[]);
} }
} }
pub(crate) fn draw( pub(crate) fn draw(
@ -70,13 +71,24 @@ impl FilterPass {
) -> error::Result<()> { ) -> error::Result<()> {
let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[0]; let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[0];
self.build_semantics(pass_index, parent, &output.mvp, frame_count, frame_direction, output.output.size, self.build_semantics(
viewport.into(),&descriptor, original, source); pass_index,
parent,
&output.mvp,
frame_count,
frame_direction,
output.output.size,
viewport.into(),
&descriptor,
original,
source,
);
if let Some(ubo) = &self.reflection.ubo { if let Some(ubo) = &self.reflection.ubo {
// shader_vulkan: 2554 (ra uses uses one big buffer) // shader_vulkan: 2554 (ra uses uses one big buffer)
// itll be simpler for us if we just use a RingBuffer<vk::Buffer> tbh. // 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(()) Ok(())
@ -172,7 +184,7 @@ impl FilterPass {
&parent.samplers, &parent.samplers,
*descriptor_set, *descriptor_set,
binding, binding,
source source,
); );
} }
@ -301,12 +313,12 @@ impl FilterPass {
// bind float parameters // bind float parameters
for (id, offset) in for (id, offset) in
self.uniform_bindings self.uniform_bindings
.iter() .iter()
.filter_map(|(binding, value)| match binding { .filter_map(|(binding, value)| match binding {
UniformBinding::Parameter(id) => Some((id, value)), UniformBinding::Parameter(id) => Some((id, value)),
_ => None, _ => None,
}) })
{ {
let id = id.as_str(); let id = id.as_str();
@ -351,4 +363,4 @@ impl FilterPass {
// (textures, samplers) // (textures, samplers)
} }
} }

View file

@ -1,13 +1,10 @@
use crate::error; 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::filter_chain::Vulkan;
use crate::renderpass::VulkanRenderPass;
use crate::texture::OwnedTexture; use crate::texture::OwnedTexture;
use ash::vk;
use ash::vk::{ImageAspectFlags, ImageViewType};
use librashader_common::Size;
pub struct VulkanFramebuffer { pub struct VulkanFramebuffer {
pub device: ash::Device, pub device: ash::Device,
@ -74,7 +71,6 @@ pub(crate) struct OutputFramebuffer {
pub viewport: vk::Viewport, pub viewport: vk::Viewport,
} }
// //
// pub struct OutputFramebuffer<'a> { // pub struct OutputFramebuffer<'a> {
// device: ash::Device, // device: ash::Device,
@ -147,4 +143,4 @@ pub(crate) struct OutputFramebuffer {
// //
// builder.build() // 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::physicaldevice::find_queue_family;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use ash::prelude::VkResult;
use ash::vk;
pub struct VulkanCommandPool { pub struct VulkanCommandPool {
pool: vk::CommandPool, pool: vk::CommandPool,
device: ash::Device, device: ash::Device,
pub buffers: Vec<vk::CommandBuffer> pub buffers: Vec<vk::CommandBuffer>,
} }
impl VulkanCommandPool { impl VulkanCommandPool {
@ -34,5 +34,4 @@ impl VulkanCommandPool {
}) })
} }
} }
}
}

View file

@ -5,11 +5,15 @@ use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT};
pub struct VulkanDebug { pub struct VulkanDebug {
loader: DebugUtils, loader: DebugUtils,
messenger: DebugUtilsMessengerEXT messenger: DebugUtilsMessengerEXT,
} }
impl VulkanDebug { 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() let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder()
.message_severity( .message_severity(
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
@ -26,12 +30,12 @@ impl VulkanDebug {
let debug_utils_loader = DebugUtils::new(entry, instance); let debug_utils_loader = DebugUtils::new(entry, instance);
unsafe { unsafe {
let debug_call_back = debug_utils_loader let debug_call_back =
.create_debug_utils_messenger(&debug_info, None)?; debug_utils_loader.create_debug_utils_messenger(&debug_info, None)?;
Ok(VulkanDebug { Ok(VulkanDebug {
loader: debug_utils_loader, loader: debug_utils_loader,
messenger: debug_call_back messenger: debug_call_back,
}) })
} }
} }
@ -40,7 +44,8 @@ impl VulkanDebug {
impl Drop for VulkanDebug { impl Drop for VulkanDebug {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { 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::prelude::VkResult;
use ash::vk; use ash::vk;
use crate::hello_triangle::swapchain::VulkanSwapchain;
pub struct VulkanFramebuffer { pub struct VulkanFramebuffer {
pub framebuffer: vk::Framebuffer, pub framebuffer: vk::Framebuffer,
} }
impl VulkanFramebuffer { 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 attachments = &[*image_view];
let framebuffer_info = vk::FramebufferCreateInfo::builder() let framebuffer_info = vk::FramebufferCreateInfo::builder()
.render_pass(*render_pass) .render_pass(*render_pass)
@ -19,9 +25,7 @@ impl VulkanFramebuffer {
unsafe { unsafe {
let framebuffer = device.create_framebuffer(&framebuffer_info, None)?; let framebuffer = device.create_framebuffer(&framebuffer_info, None)?;
Ok(VulkanFramebuffer { Ok(VulkanFramebuffer { framebuffer })
framebuffer
})
} }
} }
} }

View file

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

View file

@ -1,5 +1,5 @@
use std::ffi::CStr;
use ash::vk; use ash::vk;
use std::ffi::CStr;
pub struct QueueFamilyIndices { pub struct QueueFamilyIndices {
graphics_family: Option<u32>, graphics_family: Option<u32>,
@ -62,16 +62,12 @@ fn is_physical_device_suitable(
device_name, device_properties.device_id, device_type device_name, device_properties.device_id, device_type
); );
println!( println!("\tAPI Version: {}", device_properties.api_version);
"\tAPI Version: {}",
device_properties.api_version
);
println!("\tSupport Queue Family: {}", device_queue_families.len()); println!("\tSupport Queue Family: {}", device_queue_families.len());
println!("\t\tQueue Count | Graphics, Compute, Transfer, Sparse Binding"); println!("\t\tQueue Count | Graphics, Compute, Transfer, Sparse Binding");
for queue_family in device_queue_families.iter() { 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" "support"
} else { } else {
"unsupport" "unsupport"
@ -81,8 +77,7 @@ fn is_physical_device_suitable(
} else { } else {
"unsupport" "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" "support"
} else { } else {
"unsupport" "unsupport"
@ -148,4 +143,4 @@ pub fn find_queue_family(
} }
queue_family_indices 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::find_memorytype_index;
use crate::hello_triangle::surface::VulkanSurface; use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::swapchain::VulkanSwapchain; use crate::hello_triangle::swapchain::VulkanSwapchain;
use crate::hello_triangle::vulkan_base::VulkanBase; 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)] #[derive(Default, Clone, Debug, Copy)]
struct Vertex { struct Vertex {
@ -38,7 +38,7 @@ impl VulkanPipeline {
&base.mem_props, &base.mem_props,
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, 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 { let index_allocate_info = vk::MemoryAllocateInfo {
allocation_size: index_buffer_memory_req.size, allocation_size: index_buffer_memory_req.size,
@ -90,7 +90,7 @@ impl VulkanPipeline {
&base.mem_props, &base.mem_props,
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, 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 { let vertex_buffer_allocate_info = vk::MemoryAllocateInfo {
allocation_size: vertex_input_buffer_memory_req.size, 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) .bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0)
.unwrap(); .unwrap();
// create pipeline // 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 = let vertex_code =
read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file"); read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file");
let vertex_shader_info = ShaderModule::new(&base.device, vertex_code)?; 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")) .name(CStr::from_bytes_with_nul_unchecked(b"main\0"))
.build(); .build();
let mut frag_spv_file =
let mut frag_spv_file = Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]); Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]);
let frag_code = let frag_code =
read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file"); read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file");
let frag_shader_info = ShaderModule::new(&base.device, frag_code)?; let frag_shader_info = ShaderModule::new(&base.device, frag_code)?;
@ -194,7 +194,6 @@ impl VulkanPipeline {
.create_pipeline_layout(&layout_create_info, None) .create_pipeline_layout(&layout_create_info, None)
.unwrap(); .unwrap();
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder() let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder()
.dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]) .dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR])
.build(); .build();
@ -244,16 +243,14 @@ impl VulkanPipeline {
.logic_op(vk::LogicOp::COPY) .logic_op(vk::LogicOp::COPY)
.attachments(&color_blend_attachment); .attachments(&color_blend_attachment);
let renderpass_attachments = [ let renderpass_attachments = [vk::AttachmentDescription {
vk::AttachmentDescription { format: swapchain.format.format,
format: swapchain.format.format, samples: vk::SampleCountFlags::TYPE_1,
samples: vk::SampleCountFlags::TYPE_1, load_op: vk::AttachmentLoadOp::CLEAR,
load_op: vk::AttachmentLoadOp::CLEAR, store_op: vk::AttachmentStoreOp::STORE,
store_op: vk::AttachmentStoreOp::STORE, final_layout: vk::ImageLayout::PRESENT_SRC_KHR,
final_layout: vk::ImageLayout::PRESENT_SRC_KHR, ..Default::default()
..Default::default() }];
},
];
let color_attachment_refs = [vk::AttachmentReference { let color_attachment_refs = [vk::AttachmentReference {
attachment: 0, attachment: 0,
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
@ -295,7 +292,6 @@ impl VulkanPipeline {
.layout(pipeline_layout) .layout(pipeline_layout)
.render_pass(renderpass); .render_pass(renderpass);
let graphics_pipelines = base let graphics_pipelines = base
.device .device
.create_graphics_pipelines( .create_graphics_pipelines(
@ -305,13 +301,12 @@ impl VulkanPipeline {
) )
.expect("Unable to create graphics pipeline"); .expect("Unable to create graphics pipeline");
let graphic_pipeline = graphics_pipelines[0]; let graphic_pipeline = graphics_pipelines[0];
Ok(VulkanPipeline { Ok(VulkanPipeline {
graphic_pipeline, graphic_pipeline,
renderpass, renderpass,
pipeline_layout pipeline_layout,
}) })
} }
} }
@ -323,18 +318,13 @@ pub struct ShaderModule {
impl ShaderModule { impl ShaderModule {
pub fn new(device: &ash::Device, spirv: Vec<u32>) -> VkResult<ShaderModule> { pub fn new(device: &ash::Device, spirv: Vec<u32>) -> VkResult<ShaderModule> {
let create_info = vk::ShaderModuleCreateInfo::builder() let create_info = vk::ShaderModuleCreateInfo::builder().code(&spirv).build();
.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 { Ok(ShaderModule {
module, 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::prelude::VkResult;
use ash::vk; use ash::vk;
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use crate::hello_triangle::vulkan_base::VulkanBase;
pub struct VulkanSurface { pub struct VulkanSurface {
surface_loader: ash::extensions::khr::Surface, surface_loader: ash::extensions::khr::Surface,
pub surface: vk::SurfaceKHR, pub surface: vk::SurfaceKHR,
pub present_queue: vk::Queue pub present_queue: vk::Queue,
} }
impl VulkanSurface { impl VulkanSurface {
pub fn new(base: &VulkanBase, pub fn new(base: &VulkanBase, window: &winit::window::Window) -> VkResult<VulkanSurface> {
window: &winit::window::Window) -> VkResult<VulkanSurface>
{
let surface = unsafe { let surface = unsafe {
ash_window::create_surface( ash_window::create_surface(
&base.entry, &base.entry,
@ -26,7 +24,8 @@ impl VulkanSurface {
let surface_loader = ash::extensions::khr::Surface::new(&base.entry, &base.instance); let surface_loader = ash::extensions::khr::Surface::new(&base.entry, &base.instance);
let present_queue = unsafe { let present_queue = unsafe {
let queue_family = base.instance let queue_family = base
.instance
.get_physical_device_queue_family_properties(base.physical_device) .get_physical_device_queue_family_properties(base.physical_device)
.iter() .iter()
.enumerate() .enumerate()
@ -34,12 +33,12 @@ impl VulkanSurface {
let supports_graphic_and_surface = let supports_graphic_and_surface =
info.queue_flags.contains(vk::QueueFlags::GRAPHICS) info.queue_flags.contains(vk::QueueFlags::GRAPHICS)
&& surface_loader && surface_loader
.get_physical_device_surface_support( .get_physical_device_surface_support(
base.physical_device, base.physical_device,
index as u32, index as u32,
surface, surface,
) )
.unwrap(); .unwrap();
if supports_graphic_and_surface { if supports_graphic_and_surface {
Some(index) Some(index)
} else { } else {
@ -53,13 +52,15 @@ impl VulkanSurface {
Ok(VulkanSurface { Ok(VulkanSurface {
surface, surface,
surface_loader, surface_loader,
present_queue present_queue,
}) })
} }
pub fn choose_format(&self, base: &VulkanBase) -> VkResult<vk::SurfaceFormatKHR> { pub fn choose_format(&self, base: &VulkanBase) -> VkResult<vk::SurfaceFormatKHR> {
unsafe { 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() { for available_format in available_formats.iter() {
if available_format.format == vk::Format::B8G8R8A8_SRGB if available_format.format == vk::Format::B8G8R8A8_SRGB
&& available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR && 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> { pub fn choose_present_mode(&self, base: &VulkanBase) -> VkResult<vk::PresentModeKHR> {
unsafe { 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) { Ok(
vk::PresentModeKHR::MAILBOX if available_formats.contains(&vk::PresentModeKHR::MAILBOX) {
} else { vk::PresentModeKHR::MAILBOX
vk::PresentModeKHR::FIFO } 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)?; let capabilities = self.get_capabilities(base)?;
if capabilities.current_extent.width != u32::MAX { if capabilities.current_extent.width != u32::MAX {
Ok(capabilities.current_extent) Ok(capabilities.current_extent)
@ -108,7 +118,8 @@ impl VulkanSurface {
pub fn get_capabilities(&self, base: &VulkanBase) -> VkResult<vk::SurfaceCapabilitiesKHR> { pub fn get_capabilities(&self, base: &VulkanBase) -> VkResult<vk::SurfaceCapabilitiesKHR> {
unsafe { 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); 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::surface::VulkanSurface;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util::find_vulkan_memory_type; use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory; use crate::vulkan_primitives::VulkanImageMemory;
use ash::prelude::VkResult;
use ash::vk;
use ash::vk::Extent3D;
pub struct VulkanSwapchain { pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR, pub swapchain: vk::SwapchainKHR,
@ -21,7 +21,12 @@ pub struct VulkanSwapchain {
} }
impl 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 format = surface.choose_format(base)?;
let mode = surface.choose_present_mode(base)?; let mode = surface.choose_present_mode(base)?;
let extent = surface.choose_swapchain_extent(base, width, height)?; 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 loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device);
let swapchain = unsafe { let swapchain = unsafe { loader.create_swapchain(&create_info, None)? };
loader.create_swapchain(&create_info, None)?
};
let swapchain_images = unsafe { loader.get_swapchain_images(swapchain)? }; let swapchain_images = unsafe { loader.get_swapchain_images(swapchain)? };
let mut render_images = vec![]; let mut render_images = vec![];
for _ in 0..swapchain_images.len() { for _ in 0..swapchain_images.len() {
@ -79,10 +81,7 @@ impl VulkanSwapchain {
.tiling(vk::ImageTiling::OPTIMAL) .tiling(vk::ImageTiling::OPTIMAL)
.array_layers(1) .array_layers(1)
.mip_levels(1) .mip_levels(1)
.usage( .usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT)
vk::ImageUsageFlags::SAMPLED
| vk::ImageUsageFlags::COLOR_ATTACHMENT
)
.initial_layout(vk::ImageLayout::UNDEFINED); .initial_layout(vk::ImageLayout::UNDEFINED);
unsafe { unsafe {
@ -100,70 +99,68 @@ impl VulkanSwapchain {
.build(); .build();
// todo: optimize by reusing existing memory. // todo: optimize by reusing existing memory.
let memory = VulkanImageMemory::new(&base.device, &alloc_info) let memory = VulkanImageMemory::new(&base.device, &alloc_info).unwrap();
.unwrap(); memory.bind(&image).unwrap();
memory.bind(&image)
.unwrap();
render_images.push((image, memory)) render_images.push((image, memory))
} }
} }
let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images.iter().map(|image| { let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
let create_info = vk::ImageViewCreateInfo::builder() .iter()
.view_type(vk::ImageViewType::TYPE_2D) .map(|image| {
.format(format.format) let create_info = vk::ImageViewCreateInfo::builder()
.components(vk::ComponentMapping { .view_type(vk::ImageViewType::TYPE_2D)
r: vk::ComponentSwizzle::IDENTITY, .format(format.format)
g: vk::ComponentSwizzle::IDENTITY, .components(vk::ComponentMapping {
b: vk::ComponentSwizzle::IDENTITY, r: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY, g: vk::ComponentSwizzle::IDENTITY,
}) b: vk::ComponentSwizzle::IDENTITY,
.subresource_range(vk::ImageSubresourceRange { a: vk::ComponentSwizzle::IDENTITY,
aspect_mask: vk::ImageAspectFlags::COLOR, })
base_mip_level: 0, .subresource_range(vk::ImageSubresourceRange {
level_count: 1, aspect_mask: vk::ImageAspectFlags::COLOR,
base_array_layer: 0, base_mip_level: 0,
layer_count: 1, level_count: 1,
}) base_array_layer: 0,
.image(*image) layer_count: 1,
.build(); })
.image(*image)
.build();
let view = unsafe { base.device.create_image_view(&create_info, None)? };
let view = unsafe { Ok(view)
base.device.create_image_view(&create_info, None)? })
}; .collect();
Ok(view) let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
}).collect(); .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 view = unsafe { base.device.create_image_view(&create_info, None)? };
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();
Ok(view)
let view = unsafe { })
base.device.create_image_view(&create_info, None)? .collect();
};
Ok(view)
}).collect();
Ok(VulkanSwapchain { Ok(VulkanSwapchain {
swapchain, swapchain,
loader, loader,
@ -174,7 +171,7 @@ impl VulkanSwapchain {
render_images, render_images,
swapchain_image_views: image_views?, swapchain_image_views: image_views?,
render_image_views: render_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) self.loader.destroy_swapchain(self.swapchain, None)
} }
} }
} }

View file

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

View file

@ -1,14 +1,13 @@
use ash::vk;
use std::borrow::Cow; use std::borrow::Cow;
use std::error::Error; use std::error::Error;
use ash::vk;
use std::ffi::{CStr, CString};
use ash::prelude::VkResult;
use crate::filter_chain::Vulkan; use crate::filter_chain::Vulkan;
use crate::hello_triangle::debug::VulkanDebug; use crate::hello_triangle::debug::VulkanDebug;
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device}; use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
use crate::hello_triangle::surface::VulkanSurface; use crate::hello_triangle::surface::VulkanSurface;
use ash::prelude::VkResult;
use std::ffi::{CStr, CString};
const WINDOW_TITLE: &'static str = "librashader Vulkan"; const WINDOW_TITLE: &'static str = "librashader Vulkan";
@ -39,13 +38,11 @@ impl VulkanBase {
let extensions = [ let extensions = [
ash::extensions::khr::Surface::name().as_ptr(), ash::extensions::khr::Surface::name().as_ptr(),
ash::extensions::khr::Win32Surface::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 { let layers = unsafe {
[CStr::from_bytes_with_nul_unchecked( [CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr()]
b"VK_LAYER_KHRONOS_validation\0",
).as_ptr()]
}; };
let create_info = vk::InstanceCreateInfo::builder() let create_info = vk::InstanceCreateInfo::builder()
@ -54,9 +51,7 @@ impl VulkanBase {
.enabled_extension_names(&extensions) .enabled_extension_names(&extensions)
.build(); .build();
let instance = unsafe { let instance = unsafe { entry.create_instance(&create_info, None)? };
entry.create_instance(&create_info, None)?
};
let debug = VulkanDebug::new(&entry, &instance, Some(vulkan_debug_callback))?; 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 (device, queue) = VulkanBase::create_device(&instance, &physical_device)?;
let mem_props = unsafe { let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) };
instance.get_physical_device_memory_properties(physical_device)
};
Ok(VulkanBase { Ok(VulkanBase {
entry, 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 { let debug = unsafe {
CStr::from_bytes_with_nul_unchecked( CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr()
b"VK_LAYER_KHRONOS_validation\0",
).as_ptr()
}; };
let indices = find_queue_family(&instance, *physical_device); let indices = find_queue_family(&instance, *physical_device);
@ -97,15 +91,12 @@ impl VulkanBase {
let device_create_info = vk::DeviceCreateInfo::builder() let device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(&[queue_info]) .queue_create_infos(&[queue_info])
.enabled_layer_names(&[debug]) .enabled_layer_names(&[debug])
.enabled_extension_names(&[ .enabled_extension_names(&[ash::extensions::khr::Swapchain::name().as_ptr()])
ash::extensions::khr::Swapchain::name().as_ptr()
])
.enabled_features(&physical_device_features) .enabled_features(&physical_device_features)
.build(); .build();
let device = unsafe { let device =
instance.create_device(*physical_device, &device_create_info, None)? unsafe { instance.create_device(*physical_device, &device_create_info, None)? };
};
let queue = unsafe { device.get_device_queue(indices.graphics_family(), 0) }; let queue = unsafe { device.get_device_queue(indices.graphics_family(), 0) };
@ -113,7 +104,6 @@ impl VulkanBase {
} }
} }
unsafe extern "system" fn vulkan_debug_callback( unsafe extern "system" fn vulkan_debug_callback(
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
message_type: vk::DebugUtilsMessageTypeFlagsEXT, message_type: vk::DebugUtilsMessageTypeFlagsEXT,
@ -159,6 +149,10 @@ impl TryFrom<&VulkanBase> for Vulkan {
type Error = Box<dyn Error>; type Error = Box<dyn Error>;
fn try_from(value: &VulkanBase) -> Result<Self, Self::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_chain;
mod filter_pass; mod filter_pass;
mod framebuffer; mod framebuffer;
mod hello_triangle;
mod luts; mod luts;
mod renderpass; mod renderpass;
mod rendertarget;
mod samplers;
mod texture;
mod ubo_ring;
mod util; mod util;
mod vulkan_primitives; mod vulkan_primitives;
mod vulkan_state; mod vulkan_state;
mod samplers;
mod texture;
mod rendertarget;
mod ubo_ring;
mod hello_triangle;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -26,15 +26,14 @@ mod tests {
#[test] #[test]
fn triangle_vk() { fn triangle_vk() {
let entry = unsafe { let entry = unsafe { ash::Entry::load().unwrap() };
ash::Entry::load().unwrap()
};
let base = VulkanBase::new(entry).unwrap(); let base = VulkanBase::new(entry).unwrap();
let mut filter = FilterChainVulkan::load_from_path( let mut filter = FilterChainVulkan::load_from_path(
&base, &base,
"../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp",
None None,
).unwrap(); )
.unwrap();
crate::hello_triangle::main(base, filter) crate::hello_triangle::main(base, filter)

View file

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

View file

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

View file

@ -1,8 +1,8 @@
use crate::framebuffer::OutputFramebuffer;
use ash::vk; use ash::vk;
use crate::framebuffer::{OutputFramebuffer,};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct RenderTarget<'a> { pub(crate) struct RenderTarget<'a> {
pub mvp: &'a [f32; 16], pub mvp: &'a [f32; 16],
pub output: OutputFramebuffer, 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 crate::error;
use ash::vk;
use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
pub struct VulkanSampler { pub struct VulkanSampler {
pub handle: vk::Sampler, pub handle: vk::Sampler,
device: ash::Device device: ash::Device,
} }
impl VulkanSampler { 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() let create_info = vk::SamplerCreateInfo::builder()
.mip_lod_bias(0.0) .mip_lod_bias(0.0)
.max_anisotropy(1.0) .max_anisotropy(1.0)
@ -26,13 +31,11 @@ impl VulkanSampler {
.address_mode_w(wrap.into()) .address_mode_w(wrap.into())
.build(); .build();
let sampler = unsafe { let sampler = unsafe { device.create_sampler(&create_info, None)? };
device.create_sampler(&create_info, None)?
};
Ok(VulkanSampler { Ok(VulkanSampler {
handle: sampler, handle: sampler,
device: device.clone() device: device.clone(),
}) })
} }
} }
@ -47,7 +50,6 @@ impl Drop for VulkanSampler {
} }
} }
pub struct SamplerSet { pub struct SamplerSet {
// todo: may need to deal with differences in mip filter. // todo: may need to deal with differences in mip filter.
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), VulkanSampler>, samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), VulkanSampler>,
@ -79,11 +81,11 @@ impl SamplerSet {
samplers.insert( samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Nearest), (*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( samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Linear), (*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::error;
use crate::filter_chain::Vulkan; use crate::filter_chain::Vulkan;
use crate::util::find_vulkan_memory_type; use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory; use crate::vulkan_primitives::VulkanImageMemory;
use 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 struct OwnedTexture {
pub device: ash::Device, pub device: ash::Device,
@ -16,16 +19,17 @@ pub struct OwnedTexture {
} }
impl OwnedTexture { impl OwnedTexture {
pub fn new(vulkan: &Vulkan, size: Size<u32>, format: ImageFormat, max_miplevels: u32) pub fn new(
-> error::Result<OwnedTexture> { vulkan: &Vulkan,
size: Size<u32>,
format: ImageFormat,
max_miplevels: u32,
) -> error::Result<OwnedTexture> {
let image_create_info = vk::ImageCreateInfo::builder() let image_create_info = vk::ImageCreateInfo::builder()
.image_type(ImageType::TYPE_2D) .image_type(ImageType::TYPE_2D)
.format(format.into()) .format(format.into())
.extent(size.into()) .extent(size.into())
.mip_levels(std::cmp::min( .mip_levels(std::cmp::min(max_miplevels, size.calculate_miplevels()))
max_miplevels,
size.calculate_miplevels(),
))
.array_layers(1) .array_layers(1)
.samples(SampleCountFlags::TYPE_1) .samples(SampleCountFlags::TYPE_1)
.tiling(ImageTiling::OPTIMAL) .tiling(ImageTiling::OPTIMAL)
@ -86,7 +90,7 @@ impl OwnedTexture {
image: VulkanImage { image: VulkanImage {
image, image,
size, size,
format: format.into() format: format.into(),
}, },
memory, memory,
max_miplevels, max_miplevels,
@ -109,7 +113,6 @@ impl OwnedTexture {
.a(vk::ComponentSwizzle::A) .a(vk::ComponentSwizzle::A)
.build(); .build();
let mut view_info = vk::ImageViewCreateInfo::builder() let mut view_info = vk::ImageViewCreateInfo::builder()
.view_type(ImageViewType::TYPE_2D) .view_type(ImageViewType::TYPE_2D)
.format(self.image.format) .format(self.image.format)

View file

@ -1,8 +1,8 @@
use crate::error;
use crate::vulkan_primitives::VulkanBuffer;
use ash::vk; use ash::vk;
use librashader_runtime::ringbuffer::{BoxRingBuffer, InlineRingBuffer, RingBuffer}; use librashader_runtime::ringbuffer::{BoxRingBuffer, InlineRingBuffer, RingBuffer};
use librashader_runtime::uniforms::UniformStorageAccess; use librashader_runtime::uniforms::UniformStorageAccess;
use crate::error;
use crate::vulkan_primitives::VulkanBuffer;
pub struct VkUboRing { pub struct VkUboRing {
ring: BoxRingBuffer<VulkanBuffer>, ring: BoxRingBuffer<VulkanBuffer>,
@ -10,19 +10,34 @@ pub struct VkUboRing {
} }
impl 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(); let mut ring = Vec::new();
for _ in 0..ring_size { 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 { Ok(VkUboRing {
ring: BoxRingBuffer::from_vec(ring), 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(); let mut buffer = self.ring.current_mut();
// todo: write directly to allocated buffer. // todo: write directly to allocated buffer.
unsafe { unsafe {

View file

@ -124,8 +124,13 @@ 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]) {
std::ptr::copy_nonoverlapping(src.as_ptr(), std::ptr::copy_nonoverlapping(
self.ptr.map_addr(|original| original.wrapping_add(offset)).cast(), src.len()); 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. /// This pointer must be valid for the lifetime of the implementing struct.
fn push_pointer(&self) -> *const u8; fn push_pointer(&self) -> *const u8;
/// Get a slice to the backing Push Constant buffer storage. /// Get a slice to the backing Push Constant buffer storage.
/// This pointer must be valid for the lifetime of the implementing struct. /// This pointer must be valid for the lifetime of the implementing struct.
fn push_slice(&self) -> &[u8]; fn push_slice(&self) -> &[u8];
} }
impl<T, H> UniformStorageAccess for UniformStorage<T, H> { impl<T, H> UniformStorageAccess for UniformStorage<T, H> {
fn ubo_pointer(&self) -> *const u8 { fn ubo_pointer(&self) -> *const u8 {
self.ubo.as_ptr() self.ubo.as_ptr()
} }