vk: some work on texture binding

This commit is contained in:
chyyran 2022-12-22 01:30:14 -05:00
parent abd38b9076
commit 2038da787e
8 changed files with 563 additions and 113 deletions

View file

@ -126,13 +126,18 @@ pub struct FilterChainVulkan {
// pub(crate) draw_quad: DrawQuad, // pub(crate) draw_quad: DrawQuad,
} }
pub struct FilterMutable {
pub(crate) passes_enabled: usize,
pub(crate) parameters: FxHashMap<String, f32>,
}
pub(crate) struct FilterCommon { pub(crate) struct FilterCommon {
pub(crate) luts: FxHashMap<usize, LutTexture>, pub(crate) luts: FxHashMap<usize, LutTexture>,
pub samplers: SamplerSet, pub samplers: SamplerSet,
// pub output_textures: Box<[Option<Texture>]>, // pub output_textures: Box<[Option<Texture>]>,
// pub feedback_textures: Box<[Option<Texture>]>, // pub feedback_textures: Box<[Option<Texture>]>,
// pub history_textures: Box<[Option<Texture>]>, // pub history_textures: Box<[Option<Texture>]>,
// pub config: FilterMutable, pub config: FilterMutable,
} }
pub type FilterChainOptionsVulkan = (); pub type FilterChainOptionsVulkan = ();
@ -164,7 +169,17 @@ impl FilterChainVulkan {
let samplers = SamplerSet::new(&device.device)?; let samplers = SamplerSet::new(&device.device)?;
eprintln!("filters initialized ok."); eprintln!("filters initialized ok.");
Ok(FilterChainVulkan { Ok(FilterChainVulkan {
common: FilterCommon { luts, samplers }, common: FilterCommon { luts,
samplers,
config: FilterMutable {
passes_enabled: preset.shader_count as usize,
parameters: preset
.parameters
.into_iter()
.map(|param| (param.name, param.value))
.collect(),
},
},
passes: filters, passes: filters,
}) })
} }
@ -278,6 +293,8 @@ impl FilterChainVulkan {
// shader_vulkan: 2026 // shader_vulkan: 2026
filters.push(FilterPass { filters.push(FilterPass {
device: vulkan.device.clone(),
reflection,
compiled: spirv_words, compiled: spirv_words,
uniform_storage, uniform_storage,
uniform_bindings, uniform_bindings,

View file

@ -1,12 +1,20 @@
use ash::vk;
use crate::vulkan_state::VulkanGraphicsPipeline; use crate::vulkan_state::VulkanGraphicsPipeline;
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;
use librashader_reflect::reflect::semantics::{MemberOffset, UniformBinding}; use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics};
use librashader_runtime::uniforms::UniformStorage; use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use librashader_common::Size;
use librashader_reflect::reflect::ShaderReflection;
use crate::filter_chain::FilterCommon;
use crate::texture::Texture;
use crate::samplers::{SamplerSet, VulkanSampler};
pub struct FilterPass { pub struct FilterPass {
pub device: ash::Device,
pub reflection: ShaderReflection,
pub(crate) compiled: ShaderCompilerOutput<Vec<u32>>, pub(crate) compiled: ShaderCompilerOutput<Vec<u32>>,
pub(crate) uniform_storage: UniformStorage, pub(crate) uniform_storage: UniformStorage,
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>, pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
@ -14,3 +22,298 @@ pub struct FilterPass {
pub config: ShaderPassConfig, pub config: ShaderPassConfig,
pub graphics_pipeline: VulkanGraphicsPipeline, pub graphics_pipeline: VulkanGraphicsPipeline,
} }
impl FilterPass {
#[inline(always)]
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)
.image_view(texture.image_view)
.image_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL)
.build()];
let write_desc = [vk::WriteDescriptorSet::builder()
.dst_set(descriptor_set)
.dst_binding(binding.binding)
.dst_array_element(0)
.descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.image_info(&image_info)
.build()];
unsafe {
device.update_descriptor_sets(&write_desc, &[]);
}
}
fn build_semantics(
&mut self,
pass_index: usize,
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
fb_size: Size<u32>,
viewport_size: Size<u32>,
descriptor_set: vk::DescriptorSet,
original: &Texture,
source: &Texture,
) {
if let Some(offset) = self.uniform_bindings.get(&UniqueSemantics::MVP.into()) {
self.uniform_storage.bind_mat4(*offset, mvp, None);
}
// bind OutputSize
if let Some(offset) = self.uniform_bindings.get(&UniqueSemantics::Output.into()) {
self.uniform_storage.bind_vec4(*offset, fb_size, None);
}
// bind FinalViewportSize
if let Some(offset) = self
.uniform_bindings
.get(&UniqueSemantics::FinalViewport.into())
{
self.uniform_storage.bind_vec4(*offset, viewport_size, None);
}
// bind FrameCount
if let Some(offset) = self
.uniform_bindings
.get(&UniqueSemantics::FrameCount.into())
{
self.uniform_storage.bind_scalar(*offset, frame_count, None);
}
// bind FrameDirection
if let Some(offset) = self
.uniform_bindings
.get(&UniqueSemantics::FrameDirection.into())
{
self.uniform_storage
.bind_scalar(*offset, frame_direction, None);
}
// bind Original sampler
if let Some(binding) = self
.reflection
.meta
.texture_meta
.get(&TextureSemantics::Original.semantics(0))
{
FilterPass::bind_texture(
&self.device,
&parent.samplers,
descriptor_set,
binding,
original,
);
}
// bind OriginalSize
if let Some(offset) = self
.uniform_bindings
.get(&TextureSemantics::Original.semantics(0).into())
{
self.uniform_storage
.bind_vec4(*offset, original.size, None);
}
// bind Source sampler
if let Some(binding) = self
.reflection
.meta
.texture_meta
.get(&TextureSemantics::Source.semantics(0))
{
// eprintln!("setting source binding to {}", binding.binding);
FilterPass::bind_texture(
&self.device,
&parent.samplers,
descriptor_set,
binding,
source
);
}
// bind SourceSize
if let Some(offset) = self
.uniform_bindings
.get(&TextureSemantics::Source.semantics(0).into())
{
self.uniform_storage
.bind_vec4(*offset, source.size, None);
}
if let Some(binding) = self
.reflection
.meta
.texture_meta
.get(&TextureSemantics::OriginalHistory.semantics(0))
{
FilterPass::bind_texture(
&self.device,
&parent.samplers,
descriptor_set,
binding,
original,
);
}
if let Some(offset) = self
.uniform_bindings
.get(&TextureSemantics::OriginalHistory.semantics(0).into())
{
self.uniform_storage
.bind_vec4(*offset, original.size, None);
}
// for (index, output) in parent.history_textures.iter().enumerate() {
// let Some(output) = output else {
// eprintln!("no history");
// continue;
// };
// if let Some(binding) = self
// .reflection
// .meta
// .texture_meta
// .get(&TextureSemantics::OriginalHistory.semantics(index + 1))
// {
// FilterPass::bind_texture(
// &self.device,
// &parent.samplers,
// descriptor_set,
// binding,
// output,
// );
// }
//
// if let Some(offset) = self.uniform_bindings.get(
// &TextureSemantics::OriginalHistory
// .semantics(index + 1)
// .into(),
// ) {
// self.uniform_storage
// .bind_vec4(*offset, output.size, None);
// }
// }
// PassOutput
// for (index, output) in parent.output_textures[0..pass_index].iter().enumerate() {
// let Some(output) = output else {
// eprintln!("no passoutput {index}");
//
// continue;
// };
// if let Some(binding) = self
// .reflection
// .meta
// .texture_meta
// .get(&TextureSemantics::PassOutput.semantics(index))
// {
// FilterPass::bind_texture(
// &self.device,
// &parent.samplers,
// descriptor_set,
// binding,
// output,
// );
// }
//
// if let Some(offset) = self
// .uniform_bindings
// .get(&TextureSemantics::PassOutput.semantics(index).into())
// {
// self.uniform_storage
// .bind_vec4(*offset, output.view.size, None);
// }
// }
// // PassFeedback
// for (index, feedback) in parent.feedback_textures.iter().enumerate() {
// let Some(feedback) = feedback else {
// eprintln!("no passfeedback {index}");
// continue;
// };
// if let Some(binding) = self
// .reflection
// .meta
// .texture_meta
// .get(&TextureSemantics::PassFeedback.semantics(index))
// {
// FilterPass::bind_texture(
// &parent.samplers,
// &mut textures,
// &mut samplers,
// binding,
// feedback,
// );
// }
//
// if let Some(offset) = self
// .uniform_bindings
// .get(&TextureSemantics::PassFeedback.semantics(index).into())
// {
// self.uniform_storage
// .bind_vec4(*offset, feedback.view.size, None);
// }
// }
// bind float parameters
for (id, offset) in
self.uniform_bindings
.iter()
.filter_map(|(binding, value)| match binding {
UniformBinding::Parameter(id) => Some((id, value)),
_ => None,
})
{
let id = id.as_str();
let default = self
.source
.parameters
.iter()
.find(|&p| p.id == id)
.map(|f| f.initial)
.unwrap_or(0f32);
let value = *parent.config.parameters.get(id).unwrap_or(&default);
self.uniform_storage.bind_scalar(*offset, value, None);
}
// bind luts
for (index, lut) in &parent.luts {
if let Some(binding) = self
.reflection
.meta
.texture_meta
.get(&TextureSemantics::User.semantics(*index))
{
FilterPass::bind_texture(
&self.device,
&parent.samplers,
descriptor_set,
binding,
&lut.image,
);
}
if let Some(offset) = self
.uniform_bindings
.get(&TextureSemantics::User.semantics(*index).into())
{
self.uniform_storage
.bind_vec4(*offset, lut.image.size, None);
}
}
// (textures, samplers)
}
}

View file

@ -1,31 +1,17 @@
use crate::error; use crate::error;
use crate::renderpass::VulkanRenderPass; use crate::renderpass::VulkanRenderPass;
use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory;
use ash::vk; use ash::vk;
use ash::vk::{ use ash::vk::{
Extent3D, ImageAspectFlags, ImageLayout, ImageTiling, ImageType, ImageUsageFlags, ImageAspectFlags,
ImageViewType, SampleCountFlags, SharingMode, ImageViewType,
}; };
use librashader_common::Size; use librashader_common::Size;
use librashader_runtime::scaling::MipmapSize; use crate::filter_chain::Vulkan;
use crate::texture::OwnedTexture;
pub struct Framebuffer {
device: ash::Device,
size: Size<u32>,
max_levels: u32,
mem_props: vk::PhysicalDeviceMemoryProperties,
render_pass: VulkanRenderPass,
framebuffer: Option<VulkanFramebuffer>,
}
pub struct VulkanFramebuffer { pub struct VulkanFramebuffer {
pub device: ash::Device, pub device: ash::Device,
pub framebuffer: vk::Framebuffer, pub framebuffer: vk::Framebuffer,
pub image_view: vk::ImageView,
pub fb_view: vk::ImageView,
pub image: vk::Image,
pub memory: VulkanImageMemory,
} }
impl Drop for VulkanFramebuffer { impl Drop for VulkanFramebuffer {
@ -34,87 +20,72 @@ impl Drop for VulkanFramebuffer {
if self.framebuffer != vk::Framebuffer::null() { if self.framebuffer != vk::Framebuffer::null() {
self.device.destroy_framebuffer(self.framebuffer, None); self.device.destroy_framebuffer(self.framebuffer, None);
} }
if self.image_view != vk::ImageView::null() {
self.device.destroy_image_view(self.image_view, None);
}
if self.fb_view != vk::ImageView::null() {
self.device.destroy_image_view(self.fb_view, None);
}
if self.image != vk::Image::null() {
self.device.destroy_image(self.image, None);
}
} }
} }
} }
impl Framebuffer { 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( pub fn new(
device: &ash::Device, vulkan: &Vulkan,
size: Size<u32>, size: Size<u32>,
render_pass: VulkanRenderPass, render_pass: VulkanRenderPass,
mip_levels: u32, max_miplevels: u32,
mem_props: vk::PhysicalDeviceMemoryProperties,
) -> error::Result<Self> { ) -> error::Result<Self> {
let mut framebuffer = Framebuffer { let image = OwnedTexture::new(vulkan, size, render_pass.format, max_miplevels)?;
device: device.clone(), let fb_view = image.create_texture_view()?;
size, let framebuffer = unsafe {
max_levels: mip_levels, vulkan.device.create_framebuffer(
mem_props, &vk::FramebufferCreateInfo::builder()
render_pass, .render_pass(render_pass.handle)
framebuffer: None, .attachments(&[image.image_view])
.width(image.size.width)
.height(image.size.height)
.layers(1)
.build(),
None,
)?
}; };
let vulkan_image = framebuffer.create_vulkan_image()?; Ok(OwnedFramebuffer {
framebuffer.framebuffer = Some(vulkan_image); size,
image,
Ok(framebuffer) view: fb_view,
render_pass,
framebuffer: VulkanFramebuffer {
device: vulkan.device.clone(),
framebuffer,
},
})
} }
}
pub fn create_vulkan_image(&mut self) -> error::Result<VulkanFramebuffer> { pub struct OutputFramebuffer<'a> {
let image_create_info = vk::ImageCreateInfo::builder() device: ash::Device,
.image_type(ImageType::TYPE_2D) render_pass: &'a VulkanRenderPass,
.format(self.render_pass.format.into()) pub handle: vk::Framebuffer,
.extent(self.size.into()) pub size: Size<u32>,
.mip_levels(std::cmp::min( pub image: vk::Image,
self.max_levels, pub image_view: vk::ImageView,
self.size.calculate_miplevels(), }
))
.array_layers(1)
.samples(SampleCountFlags::TYPE_1)
.tiling(ImageTiling::OPTIMAL)
.usage(
ImageUsageFlags::SAMPLED
| ImageUsageFlags::COLOR_ATTACHMENT
| ImageUsageFlags::TRANSFER_DST
| ImageUsageFlags::TRANSFER_SRC,
)
.sharing_mode(SharingMode::EXCLUSIVE)
.initial_layout(ImageLayout::UNDEFINED)
.build();
let image = unsafe { self.device.create_image(&image_create_info, None)? };
let mem_reqs = unsafe { self.device.get_image_memory_requirements(image.clone()) };
let alloc_info = vk::MemoryAllocateInfo::builder()
.allocation_size(mem_reqs.size)
.memory_type_index(find_vulkan_memory_type(
&self.mem_props,
mem_reqs.memory_type_bits,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
))
.build();
// todo: optimize by reusing existing memory.
let memory = VulkanImageMemory::new(&self.device, &alloc_info)?;
memory.bind(&image)?;
impl<'a> OutputFramebuffer<'a> {
pub fn new(vulkan: &Vulkan, render_pass: &'a VulkanRenderPass, image: vk::Image, size: Size<u32>) -> error::Result<OutputFramebuffer<'a>> {
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(image_create_info.mip_levels) .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)
@ -124,37 +95,47 @@ impl Framebuffer {
let mut view_info = vk::ImageViewCreateInfo::builder() let mut view_info = vk::ImageViewCreateInfo::builder()
.view_type(ImageViewType::TYPE_2D) .view_type(ImageViewType::TYPE_2D)
.format(self.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 { self.device.create_image_view(&view_info, None)? }; let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
view_info.subresource_range.level_count = 1;
let fb_view = unsafe { self.device.create_image_view(&view_info, None)? };
let framebuffer = unsafe { let framebuffer = unsafe {
self.device.create_framebuffer( vulkan.device.create_framebuffer(
&vk::FramebufferCreateInfo::builder() &vk::FramebufferCreateInfo::builder()
.render_pass(self.render_pass.render_pass) .render_pass(render_pass.handle)
.attachments(&[image_view]) .attachments(&[image_view])
.width(self.size.width) .width(size.width)
.height(self.size.height) .height(size.height)
.layers(1) .layers(1)
.build(), .build(),
None, None,
)? )?
}; };
Ok(VulkanFramebuffer { Ok(OutputFramebuffer {
device: self.device.clone(), device: vulkan.device.clone(),
framebuffer,
memory,
image_view,
fb_view,
image, image,
image_view,
render_pass,
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()
.render_pass(self.render_pass.handle)
.framebuffer(self.handle)
.render_area(area);
if let Some(clear) = clear {
builder = builder.clear_values(clear)
}
builder.build()
}
} }

View file

@ -13,6 +13,7 @@ mod util;
mod vulkan_primitives; mod vulkan_primitives;
mod vulkan_state; mod vulkan_state;
mod samplers; mod samplers;
mod texture;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -8,15 +8,12 @@ use librashader_common::{FilterMode, WrapMode};
use librashader_presets::TextureConfig; use librashader_presets::TextureConfig;
use librashader_runtime::image::{Image, BGRA8}; use librashader_runtime::image::{Image, BGRA8};
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
use crate::texture::Texture;
pub struct LutTexture { pub struct LutTexture {
pub texture: vk::Image,
pub texture_view: vk::ImageView,
pub memory: VulkanImageMemory, pub memory: VulkanImageMemory,
pub staging: VulkanBuffer, pub staging: VulkanBuffer,
pub filter_mode: FilterMode, pub image: Texture
pub wrap_mode: WrapMode,
pub mipmap: bool,
} }
impl LutTexture { impl LutTexture {
@ -237,13 +234,17 @@ impl LutTexture {
} }
Ok(LutTexture { Ok(LutTexture {
texture,
texture_view,
memory, memory,
staging, staging,
image: Texture {
size: image.size,
image_view: texture_view,
image: texture,
filter_mode: config.filter_mode, filter_mode: config.filter_mode,
wrap_mode: config.wrap_mode, wrap_mode: config.wrap_mode,
mipmap: config.mipmap, mip_filter: config.filter_mode,
format: vk::Format::B8G8R8A8_UNORM
}
}) })
} }
} }

View file

@ -6,7 +6,7 @@ use ash::vk::{
use librashader_common::ImageFormat; use librashader_common::ImageFormat;
pub struct VulkanRenderPass { pub struct VulkanRenderPass {
pub render_pass: vk::RenderPass, pub handle: vk::RenderPass,
pub format: ImageFormat, pub format: ImageFormat,
} }
@ -51,7 +51,7 @@ impl VulkanRenderPass {
unsafe { unsafe {
let rp = device.create_render_pass(&renderpass_info, None)?; let rp = device.create_render_pass(&renderpass_info, None)?;
Ok(Self { Ok(Self {
render_pass: rp, handle: rp,
format, format,
}) })
} }

View file

@ -0,0 +1,147 @@
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;
pub struct OwnedTexture {
pub device: ash::Device,
pub image_view: vk::ImageView,
pub image: vk::Image,
pub format: vk::Format,
pub memory: VulkanImageMemory,
pub size: Size<u32>,
pub max_miplevels: u32,
}
impl 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(),
))
.array_layers(1)
.samples(SampleCountFlags::TYPE_1)
.tiling(ImageTiling::OPTIMAL)
.usage(
ImageUsageFlags::SAMPLED
| ImageUsageFlags::COLOR_ATTACHMENT
| ImageUsageFlags::TRANSFER_DST
| ImageUsageFlags::TRANSFER_SRC,
)
.sharing_mode(SharingMode::EXCLUSIVE)
.initial_layout(ImageLayout::UNDEFINED)
.build();
let image = unsafe { vulkan.device.create_image(&image_create_info, None)? };
let mem_reqs = unsafe { vulkan.device.get_image_memory_requirements(image.clone()) };
let alloc_info = vk::MemoryAllocateInfo::builder()
.allocation_size(mem_reqs.size)
.memory_type_index(find_vulkan_memory_type(
&vulkan.memory_properties,
mem_reqs.memory_type_bits,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
))
.build();
// todo: optimize by reusing existing memory.
let memory = VulkanImageMemory::new(&vulkan.device, &alloc_info)?;
memory.bind(&image)?;
let image_subresource = vk::ImageSubresourceRange::builder()
.base_mip_level(0)
.base_array_layer(0)
.level_count(image_create_info.mip_levels)
.layer_count(1)
.aspect_mask(ImageAspectFlags::COLOR)
.build();
let swizzle_components = vk::ComponentMapping::builder()
.r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A)
.build();
let mut view_info = vk::ImageViewCreateInfo::builder()
.view_type(ImageViewType::TYPE_2D)
.format(format.into())
.image(image.clone())
.subresource_range(image_subresource)
.components(swizzle_components)
.build();
let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
Ok(OwnedTexture {
device: vulkan.device.clone(),
image_view,
image,
size,
format: format.into(),
memory,
max_miplevels,
})
}
pub fn create_texture_view(&self) -> error::Result<vk::ImageView> {
let image_subresource = vk::ImageSubresourceRange::builder()
.base_mip_level(0)
.base_array_layer(0)
.level_count(1)
.layer_count(1)
.aspect_mask(ImageAspectFlags::COLOR)
.build();
let swizzle_components = vk::ComponentMapping::builder()
.r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A)
.build();
let mut view_info = vk::ImageViewCreateInfo::builder()
.view_type(ImageViewType::TYPE_2D)
.format(self.format)
.image(self.image.clone())
.subresource_range(image_subresource)
.components(swizzle_components)
.build();
let image_view = unsafe { self.device.create_image_view(&view_info, None)? };
Ok(image_view)
}
}
impl Drop for OwnedTexture {
fn drop(&mut self) {
unsafe {
if self.image_view != vk::ImageView::null() {
self.device.destroy_image_view(self.image_view, None);
}
if self.image != vk::Image::null() {
self.device.destroy_image(self.image, None);
}
}
}
}
pub struct Texture {
pub size: Size<u32>,
pub image_view: vk::ImageView,
pub image: vk::Image,
pub format: vk::Format,
pub wrap_mode: WrapMode,
pub filter_mode: FilterMode,
pub mip_filter: FilterMode,
}

View file

@ -302,7 +302,7 @@ impl VulkanGraphicsPipeline {
.viewport_state(&viewport_state) .viewport_state(&viewport_state)
.depth_stencil_state(&depth_stencil_state) .depth_stencil_state(&depth_stencil_state)
.dynamic_state(&dynamic_state) .dynamic_state(&dynamic_state)
.render_pass(render_pass.render_pass.clone()) .render_pass(render_pass.handle.clone())
.layout(pipeline_layout.layout) .layout(pipeline_layout.layout)
.build(); .build();