vk: get closer to having shaders render
This commit is contained in:
parent
48321d997b
commit
4595a5ccc3
|
@ -3,7 +3,7 @@ use crate::vulkan_primitives::VulkanBuffer;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static VBO_OFFSCREEN: &[f32; 16] = &[
|
pub(crate) static VBO_OFFSCREEN: &[f32; 16] = &[
|
||||||
// Offscreen
|
// Offscreen
|
||||||
-1.0, -1.0, 0.0, 0.0,
|
-1.0, -1.0, 0.0, 0.0,
|
||||||
-1.0, 1.0, 0.0, 1.0,
|
-1.0, 1.0, 0.0, 1.0,
|
||||||
|
@ -12,7 +12,7 @@ static VBO_OFFSCREEN: &[f32; 16] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static VBO_DEFAULT_FINAL: &[f32; 16] = &[
|
pub(crate) static VBO_DEFAULT_FINAL: &[f32; 16] = &[
|
||||||
// Final
|
// Final
|
||||||
0.0, 0.0, 0.0, 0.0,
|
0.0, 0.0, 0.0, 0.0,
|
||||||
0.0, 1.0, 0.0, 1.0,
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::error;
|
use crate::{error, util};
|
||||||
use crate::filter_pass::FilterPass;
|
use crate::filter_pass::FilterPass;
|
||||||
use crate::luts::LutTexture;
|
use crate::luts::LutTexture;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::texture::VulkanImage;
|
use crate::texture::{OwnedTexture, Texture, VulkanImage};
|
||||||
use crate::ubo_ring::VkUboRing;
|
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};
|
||||||
use librashader_common::ImageFormat;
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::SpirV;
|
use librashader_reflect::back::targets::SpirV;
|
||||||
|
@ -22,6 +22,9 @@ 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::draw_quad::{VBO_DEFAULT_FINAL, VBO_OFFSCREEN};
|
||||||
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
|
use crate::rendertarget::RenderTarget;
|
||||||
|
|
||||||
pub struct Vulkan {
|
pub struct Vulkan {
|
||||||
// physical_device: vk::PhysicalDevice,
|
// physical_device: vk::PhysicalDevice,
|
||||||
|
@ -124,7 +127,7 @@ pub struct FilterChainVulkan {
|
||||||
pub(crate) common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
pub(crate) passes: Box<[FilterPass]>,
|
pub(crate) passes: Box<[FilterPass]>,
|
||||||
pub(crate) vulkan: Vulkan,
|
pub(crate) vulkan: Vulkan,
|
||||||
// pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
pub(crate) output_framebuffers: Box<[OwnedTexture]>,
|
||||||
// pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
// pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
// pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
// pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||||
// pub(crate) draw_quad: DrawQuad,
|
// pub(crate) draw_quad: DrawQuad,
|
||||||
|
@ -172,6 +175,18 @@ 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)?;
|
||||||
|
|
||||||
|
let mut output_framebuffers = Vec::new();
|
||||||
|
output_framebuffers.resize_with(filters.len(), || {
|
||||||
|
OwnedTexture::new(
|
||||||
|
&device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let output_framebuffers: error::Result<Vec<OwnedTexture>> = output_framebuffers.into_iter().collect();
|
||||||
|
|
||||||
eprintln!("filters initialized ok.");
|
eprintln!("filters initialized ok.");
|
||||||
Ok(FilterChainVulkan {
|
Ok(FilterChainVulkan {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
|
@ -188,6 +203,7 @@ impl FilterChainVulkan {
|
||||||
},
|
},
|
||||||
passes: filters,
|
passes: filters,
|
||||||
vulkan: device,
|
vulkan: device,
|
||||||
|
output_framebuffers: output_framebuffers?.into_boxed_slice(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,16 +395,87 @@ impl FilterChainVulkan {
|
||||||
count: usize,
|
count: usize,
|
||||||
viewport: &vk::Viewport,
|
viewport: &vk::Viewport,
|
||||||
input: &VulkanImage,
|
input: &VulkanImage,
|
||||||
|
cmd: vk::CommandBuffer,
|
||||||
options: Option<()>,
|
options: Option<()>,
|
||||||
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];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// todo: see if we can find a less conservative transition,
|
||||||
|
// but this ensures that the image is rendered at least
|
||||||
|
util::vulkan_image_layout_transition_levels(
|
||||||
|
&self.vulkan.device,
|
||||||
|
cmd,
|
||||||
|
input.image,
|
||||||
|
1,
|
||||||
|
vk::ImageLayout::UNDEFINED,
|
||||||
|
vk::ImageLayout::GENERAL,
|
||||||
|
vk::AccessFlags::empty(),
|
||||||
|
vk::AccessFlags::SHADER_READ | vk::AccessFlags::COLOR_ATTACHMENT_READ,
|
||||||
|
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
|
||||||
|
vk::PipelineStageFlags::FRAGMENT_SHADER,
|
||||||
|
vk::QUEUE_FAMILY_IGNORED,
|
||||||
|
vk::QUEUE_FAMILY_IGNORED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let original_image_view = unsafe {
|
||||||
|
let create_info = vk::ImageViewCreateInfo::builder()
|
||||||
|
.image(input.image)
|
||||||
|
.format(input.format)
|
||||||
|
.view_type(vk::ImageViewType::TYPE_2D)
|
||||||
|
.subresource_range(vk::ImageSubresourceRange::builder()
|
||||||
|
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
||||||
|
.level_count(1)
|
||||||
|
.layer_count(1)
|
||||||
|
.build())
|
||||||
|
.components(vk::ComponentMapping::builder()
|
||||||
|
.r(vk::ComponentSwizzle::R)
|
||||||
|
.g(vk::ComponentSwizzle::G)
|
||||||
|
.b(vk::ComponentSwizzle::B)
|
||||||
|
.a(vk::ComponentSwizzle::A)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
self.vulkan.device.create_image_view(&create_info, None)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let filter = passes[0].config.filter;
|
||||||
|
let wrap_mode = passes[0].config.wrap_mode;
|
||||||
|
|
||||||
|
let original = Texture {
|
||||||
|
image: input.clone(),
|
||||||
|
image_view: original_image_view,
|
||||||
|
wrap_mode,
|
||||||
|
filter_mode: filter,
|
||||||
|
mip_filter: filter,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut source = original.clone();
|
||||||
|
|
||||||
|
// rescale render buffers to ensure all bindings are valid.
|
||||||
|
for (index, pass) in passes.iter_mut().enumerate() {
|
||||||
|
self.output_framebuffers[index].scale(
|
||||||
|
pass.config.scaling.clone(),
|
||||||
|
pass.get_format(),
|
||||||
|
&viewport.into(),
|
||||||
|
&original,
|
||||||
|
&source,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// for (index, pass) in passes.iter_mut().enumerate() {
|
for (index, pass) in passes.iter_mut().enumerate() {
|
||||||
// pass.draw(index, &self.common, count as u32, 0, viewport, &Default::default(), &Texture {}, &Texture {})
|
let target = &self.output_framebuffers[index];
|
||||||
// }
|
// todo: use proper mode
|
||||||
|
let out = RenderTarget {
|
||||||
|
mvp: VBO_DEFAULT_FINAL,
|
||||||
|
output: OutputFramebuffer::new(&self.vulkan, &pass.graphics_pipeline.render_pass, target.image.image, target.image.size)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
pass.draw(cmd, index, &self.common, count as u32, 0, viewport, &original, &source, &out)?;
|
||||||
|
}
|
||||||
|
|
||||||
// unsafe {
|
// unsafe {
|
||||||
// self.vulkan.device.queue_submit(self.vulkan.queue, &[vk::SubmitInfo::builder()
|
// self.vulkan.device.queue_submit(self.vulkan.queue, &[vk::SubmitInfo::builder()
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::texture::Texture;
|
||||||
use crate::ubo_ring::VkUboRing;
|
use crate::ubo_ring::VkUboRing;
|
||||||
use crate::vulkan_state::VulkanGraphicsPipeline;
|
use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use librashader_common::Size;
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::ShaderPassConfig;
|
use librashader_presets::ShaderPassConfig;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
|
@ -57,6 +57,16 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_format(&self) -> ImageFormat {
|
||||||
|
let mut fb_format = ImageFormat::R8G8B8A8Unorm;
|
||||||
|
if self.config.srgb_framebuffer {
|
||||||
|
fb_format = ImageFormat::R8G8B8A8Srgb;
|
||||||
|
} else if self.config.float_framebuffer {
|
||||||
|
fb_format = ImageFormat::R16G16B16A16Sfloat;
|
||||||
|
}
|
||||||
|
fb_format
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn draw(
|
pub(crate) fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
|
|
|
@ -20,55 +20,56 @@ impl Drop for VulkanFramebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// pub struct OwnedFramebuffer {
|
||||||
|
// pub size: Size<u32>,
|
||||||
|
// pub image: OwnedTexture,
|
||||||
|
// pub render_pass: VulkanRenderPass,
|
||||||
|
// pub framebuffer: VulkanFramebuffer,
|
||||||
|
// pub view: vk::ImageView,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl OwnedFramebuffer {
|
||||||
|
// pub fn new(
|
||||||
|
// vulkan: &Vulkan,
|
||||||
|
// size: Size<u32>,
|
||||||
|
// render_pass: VulkanRenderPass,
|
||||||
|
// max_miplevels: u32,
|
||||||
|
// ) -> error::Result<Self> {
|
||||||
|
// let image = OwnedTexture::new(vulkan, size, render_pass.format, max_miplevels)?;
|
||||||
|
// let fb_view = image.create_texture_view()?;
|
||||||
|
// let framebuffer = unsafe {
|
||||||
|
// vulkan.device.create_framebuffer(
|
||||||
|
// &vk::FramebufferCreateInfo::builder()
|
||||||
|
// .render_pass(render_pass.handle)
|
||||||
|
// .attachments(&[image.image_view])
|
||||||
|
// .width(image.image.size.width)
|
||||||
|
// .height(image.image.size.height)
|
||||||
|
// .layers(1)
|
||||||
|
// .build(),
|
||||||
|
// None,
|
||||||
|
// )?
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// Ok(OwnedFramebuffer {
|
||||||
|
// size,
|
||||||
|
// image,
|
||||||
|
// view: fb_view,
|
||||||
|
// render_pass,
|
||||||
|
// framebuffer: VulkanFramebuffer {
|
||||||
|
// device: vulkan.device.clone(),
|
||||||
|
// framebuffer,
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
pub struct OwnedFramebuffer {
|
#[derive(Clone)]
|
||||||
pub size: Size<u32>,
|
|
||||||
pub image: OwnedTexture,
|
|
||||||
pub render_pass: VulkanRenderPass,
|
|
||||||
pub framebuffer: VulkanFramebuffer,
|
|
||||||
pub view: vk::ImageView,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OwnedFramebuffer {
|
|
||||||
pub fn new(
|
|
||||||
vulkan: &Vulkan,
|
|
||||||
size: Size<u32>,
|
|
||||||
render_pass: VulkanRenderPass,
|
|
||||||
max_miplevels: u32,
|
|
||||||
) -> error::Result<Self> {
|
|
||||||
let image = OwnedTexture::new(vulkan, size, render_pass.format, max_miplevels)?;
|
|
||||||
let fb_view = image.create_texture_view()?;
|
|
||||||
let framebuffer = unsafe {
|
|
||||||
vulkan.device.create_framebuffer(
|
|
||||||
&vk::FramebufferCreateInfo::builder()
|
|
||||||
.render_pass(render_pass.handle)
|
|
||||||
.attachments(&[image.image_view])
|
|
||||||
.width(image.image.size.width)
|
|
||||||
.height(image.image.size.height)
|
|
||||||
.layers(1)
|
|
||||||
.build(),
|
|
||||||
None,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(OwnedFramebuffer {
|
|
||||||
size,
|
|
||||||
image,
|
|
||||||
view: fb_view,
|
|
||||||
render_pass,
|
|
||||||
framebuffer: VulkanFramebuffer {
|
|
||||||
device: vulkan.device.clone(),
|
|
||||||
framebuffer,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) struct OutputFramebuffer {
|
pub(crate) struct OutputFramebuffer {
|
||||||
pub framebuffer: vk::Framebuffer,
|
pub framebuffer: vk::Framebuffer,
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub viewport: vk::Viewport,
|
device: ash::Device,
|
||||||
|
image_view: vk::ImageView,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -81,66 +82,77 @@ pub(crate) struct OutputFramebuffer {
|
||||||
// pub image_view: vk::ImageView,
|
// pub image_view: vk::ImageView,
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// impl<'a> OutputFramebuffer<'a> {
|
impl OutputFramebuffer {
|
||||||
// pub fn new(vulkan: &Vulkan, render_pass: &'a VulkanRenderPass, image: vk::Image, size: Size<u32>) -> error::Result<OutputFramebuffer<'a>> {
|
pub fn new(vulkan: &Vulkan, render_pass: &VulkanRenderPass, image: vk::Image, size: Size<u32>) -> error::Result<OutputFramebuffer> {
|
||||||
// let image_subresource = vk::ImageSubresourceRange::builder()
|
let image_subresource = vk::ImageSubresourceRange::builder()
|
||||||
// .base_mip_level(0)
|
.base_mip_level(0)
|
||||||
// .base_array_layer(0)
|
.base_array_layer(0)
|
||||||
// .level_count(1)
|
.level_count(1)
|
||||||
// .layer_count(1)
|
.layer_count(1)
|
||||||
// .aspect_mask(ImageAspectFlags::COLOR)
|
.aspect_mask(ImageAspectFlags::COLOR)
|
||||||
// .build();
|
.build();
|
||||||
//
|
|
||||||
// let swizzle_components = vk::ComponentMapping::builder()
|
let swizzle_components = vk::ComponentMapping::builder()
|
||||||
// .r(vk::ComponentSwizzle::R)
|
.r(vk::ComponentSwizzle::R)
|
||||||
// .g(vk::ComponentSwizzle::G)
|
.g(vk::ComponentSwizzle::G)
|
||||||
// .b(vk::ComponentSwizzle::B)
|
.b(vk::ComponentSwizzle::B)
|
||||||
// .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(render_pass.format.into())
|
.format(render_pass.format.into())
|
||||||
// .image(image.clone())
|
.image(image.clone())
|
||||||
// .subresource_range(image_subresource)
|
.subresource_range(image_subresource)
|
||||||
// .components(swizzle_components)
|
.components(swizzle_components)
|
||||||
// .build();
|
.build();
|
||||||
//
|
|
||||||
// let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
|
let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
|
||||||
//
|
|
||||||
// let framebuffer = unsafe {
|
let framebuffer = unsafe {
|
||||||
// vulkan.device.create_framebuffer(
|
vulkan.device.create_framebuffer(
|
||||||
// &vk::FramebufferCreateInfo::builder()
|
&vk::FramebufferCreateInfo::builder()
|
||||||
// .render_pass(render_pass.handle)
|
.render_pass(render_pass.handle)
|
||||||
// .attachments(&[image_view])
|
.attachments(&[image_view])
|
||||||
// .width(size.width)
|
.width(size.width)
|
||||||
// .height(size.height)
|
.height(size.height)
|
||||||
// .layers(1)
|
.layers(1)
|
||||||
// .build(),
|
.build(),
|
||||||
// None,
|
None,
|
||||||
// )?
|
)?
|
||||||
// };
|
};
|
||||||
//
|
|
||||||
// Ok(OutputFramebuffer {
|
Ok(OutputFramebuffer {
|
||||||
// device: vulkan.device.clone(),
|
device: vulkan.device.clone(),
|
||||||
// image,
|
size,
|
||||||
// image_view,
|
framebuffer,
|
||||||
// render_pass,
|
image_view,
|
||||||
// size,
|
})
|
||||||
// handle: framebuffer,
|
}
|
||||||
// })
|
|
||||||
// }
|
// pub fn get_renderpass_begin_info(&self, area: vk::Rect2D, clear: Option<&[vk::ClearValue]>) -> vk::RenderPassBeginInfo {
|
||||||
//
|
// let mut builder = vk::RenderPassBeginInfo::builder()
|
||||||
// pub fn get_renderpass_begin_info(&self, area: vk::Rect2D, clear: Option<&[vk::ClearValue]>) -> vk::RenderPassBeginInfo {
|
// .render_pass(self.render_pass.handle)
|
||||||
// let mut builder = vk::RenderPassBeginInfo::builder()
|
// .framebuffer(self.handle)
|
||||||
// .render_pass(self.render_pass.handle)
|
// .render_area(area);
|
||||||
// .framebuffer(self.handle)
|
//
|
||||||
// .render_area(area);
|
// if let Some(clear) = clear {
|
||||||
//
|
// builder = builder.clear_values(clear)
|
||||||
// if let Some(clear) = clear {
|
// }
|
||||||
// builder = builder.clear_values(clear)
|
//
|
||||||
// }
|
// builder.build()
|
||||||
//
|
// }
|
||||||
// builder.build()
|
}
|
||||||
// }
|
|
||||||
// }
|
impl Drop for OutputFramebuffer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
if self.framebuffer != vk::Framebuffer::null() {
|
||||||
|
self.device.destroy_framebuffer(self.framebuffer, None);
|
||||||
|
}
|
||||||
|
if self.image_view != vk::ImageView::null() {
|
||||||
|
self.device.destroy_image_view(self.image_view, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ use ash::vk::RenderingInfo;
|
||||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
||||||
use winit::platform::windows::EventLoopBuilderExtWindows;
|
use winit::platform::windows::EventLoopBuilderExtWindows;
|
||||||
|
use crate::texture::VulkanImage;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
||||||
|
@ -173,6 +174,20 @@ impl VulkanWindow {
|
||||||
|
|
||||||
Self::record_command_buffer(vulkan, framebuffer, cmd);
|
Self::record_command_buffer(vulkan, framebuffer, cmd);
|
||||||
|
|
||||||
|
filter.frame(0, &vk::Viewport {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
width: vulkan.swapchain.extent.width as f32,
|
||||||
|
height: vulkan.swapchain.extent.height as f32,
|
||||||
|
min_depth: 0.0,
|
||||||
|
max_depth: 1.0,
|
||||||
|
}, &VulkanImage {
|
||||||
|
size: vulkan.swapchain.extent.into(),
|
||||||
|
image: framebuffer_image,
|
||||||
|
format: vulkan.swapchain.format.format,
|
||||||
|
}, cmd, None)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&vulkan.base.device,
|
&vulkan.base.device,
|
||||||
cmd,
|
cmd,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::framebuffer::OutputFramebuffer;
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(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,
|
||||||
|
|
|
@ -8,10 +8,12 @@ use ash::vk::{
|
||||||
SampleCountFlags, SharingMode,
|
SampleCountFlags, SharingMode,
|
||||||
};
|
};
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_runtime::scaling::MipmapSize;
|
use librashader_presets::Scale2D;
|
||||||
|
use librashader_runtime::scaling::{MipmapSize, ViewportSize};
|
||||||
|
|
||||||
pub struct OwnedTexture {
|
pub struct OwnedTexture {
|
||||||
pub device: ash::Device,
|
pub device: ash::Device,
|
||||||
|
pub mem_props: vk::PhysicalDeviceMemoryProperties,
|
||||||
pub image_view: vk::ImageView,
|
pub image_view: vk::ImageView,
|
||||||
pub image: VulkanImage,
|
pub image: VulkanImage,
|
||||||
pub memory: VulkanImageMemory,
|
pub memory: VulkanImageMemory,
|
||||||
|
@ -19,8 +21,9 @@ pub struct OwnedTexture {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedTexture {
|
impl OwnedTexture {
|
||||||
pub fn new(
|
fn new_internal(
|
||||||
vulkan: &Vulkan,
|
device: ash::Device,
|
||||||
|
mem_props: vk::PhysicalDeviceMemoryProperties,
|
||||||
size: Size<u32>,
|
size: Size<u32>,
|
||||||
format: ImageFormat,
|
format: ImageFormat,
|
||||||
max_miplevels: u32,
|
max_miplevels: u32,
|
||||||
|
@ -43,20 +46,20 @@ impl OwnedTexture {
|
||||||
.initial_layout(ImageLayout::UNDEFINED)
|
.initial_layout(ImageLayout::UNDEFINED)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let image = unsafe { vulkan.device.create_image(&image_create_info, None)? };
|
let image = unsafe { device.create_image(&image_create_info, None)? };
|
||||||
let mem_reqs = unsafe { vulkan.device.get_image_memory_requirements(image.clone()) };
|
let mem_reqs = unsafe { device.get_image_memory_requirements(image.clone()) };
|
||||||
|
|
||||||
let alloc_info = vk::MemoryAllocateInfo::builder()
|
let alloc_info = vk::MemoryAllocateInfo::builder()
|
||||||
.allocation_size(mem_reqs.size)
|
.allocation_size(mem_reqs.size)
|
||||||
.memory_type_index(find_vulkan_memory_type(
|
.memory_type_index(find_vulkan_memory_type(
|
||||||
&vulkan.memory_properties,
|
&mem_props,
|
||||||
mem_reqs.memory_type_bits,
|
mem_reqs.memory_type_bits,
|
||||||
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// todo: optimize by reusing existing memory.
|
// todo: optimize by reusing existing memory.
|
||||||
let memory = VulkanImageMemory::new(&vulkan.device, &alloc_info)?;
|
let memory = VulkanImageMemory::new(&device, &alloc_info)?;
|
||||||
memory.bind(&image)?;
|
memory.bind(&image)?;
|
||||||
|
|
||||||
let image_subresource = vk::ImageSubresourceRange::builder()
|
let image_subresource = vk::ImageSubresourceRange::builder()
|
||||||
|
@ -82,10 +85,11 @@ impl OwnedTexture {
|
||||||
.components(swizzle_components)
|
.components(swizzle_components)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
|
let image_view = unsafe { device.create_image_view(&view_info, None)? };
|
||||||
|
|
||||||
Ok(OwnedTexture {
|
Ok(OwnedTexture {
|
||||||
device: vulkan.device.clone(),
|
device,
|
||||||
|
mem_props,
|
||||||
image_view,
|
image_view,
|
||||||
image: VulkanImage {
|
image: VulkanImage {
|
||||||
image,
|
image,
|
||||||
|
@ -97,6 +101,40 @@ impl OwnedTexture {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
vulkan: &Vulkan,
|
||||||
|
size: Size<u32>,
|
||||||
|
format: ImageFormat,
|
||||||
|
max_miplevels: u32,
|
||||||
|
) -> error::Result<OwnedTexture> {
|
||||||
|
Self::new_internal(vulkan.device.clone(), vulkan.memory_properties, size, format, max_miplevels)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn scale(
|
||||||
|
&mut self,
|
||||||
|
scaling: Scale2D,
|
||||||
|
format: ImageFormat,
|
||||||
|
viewport_size: &Size<u32>,
|
||||||
|
_original: &Texture,
|
||||||
|
source: &Texture,
|
||||||
|
) -> error::Result<Size<u32>> {
|
||||||
|
|
||||||
|
|
||||||
|
let size = source.image.size.scale_viewport(scaling, *viewport_size);
|
||||||
|
|
||||||
|
if self.image.size != size {
|
||||||
|
let mut new = OwnedTexture::new_internal(self.device.clone(), self.mem_props, size, if format == ImageFormat::Unknown {
|
||||||
|
ImageFormat::R8G8B8A8Unorm
|
||||||
|
} else {
|
||||||
|
format
|
||||||
|
}, self.max_miplevels)?;
|
||||||
|
|
||||||
|
std::mem::swap(self, &mut new)
|
||||||
|
}
|
||||||
|
Ok(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn create_texture_view(&self) -> error::Result<vk::ImageView> {
|
pub fn create_texture_view(&self) -> error::Result<vk::ImageView> {
|
||||||
let image_subresource = vk::ImageSubresourceRange::builder()
|
let image_subresource = vk::ImageSubresourceRange::builder()
|
||||||
.base_mip_level(0)
|
.base_mip_level(0)
|
||||||
|
@ -139,12 +177,14 @@ impl Drop for OwnedTexture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct VulkanImage {
|
pub struct VulkanImage {
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub image: vk::Image,
|
pub image: vk::Image,
|
||||||
pub format: vk::Format,
|
pub format: vk::Format,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
pub image: VulkanImage,
|
pub image: VulkanImage,
|
||||||
pub image_view: vk::ImageView,
|
pub image_view: vk::ImageView,
|
||||||
|
|
Loading…
Reference in a new issue