fmt: run cargo fmt
This commit is contained in:
parent
47b5625095
commit
48321d997b
|
@ -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")]
|
||||
|
|
|
@ -44,5 +44,5 @@ pub mod ctypes;
|
|||
pub mod error;
|
||||
mod ffi;
|
||||
pub mod presets;
|
||||
pub mod runtime;
|
||||
pub mod reflect;
|
||||
pub mod runtime;
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -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 {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue