feat: ui sprites + openxr skybox
This commit is contained in:
102
src/graphics/dds.rs
Normal file
102
src/graphics/dds.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use image_dds::{ImageFormat, Surface};
|
||||
use std::{io::Read, sync::Arc};
|
||||
use vulkano::{
|
||||
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
|
||||
command_buffer::CopyBufferToImageInfo,
|
||||
format::Format,
|
||||
image::{Image, ImageCreateInfo, ImageType, ImageUsage},
|
||||
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter},
|
||||
DeviceSize,
|
||||
};
|
||||
|
||||
use super::WlxCommandBuffer;
|
||||
|
||||
pub trait WlxCommandBufferDds {
|
||||
fn texture2d_dds<R>(&mut self, r: R) -> anyhow::Result<Arc<Image>>
|
||||
where
|
||||
R: Read;
|
||||
}
|
||||
|
||||
impl WlxCommandBufferDds for WlxCommandBuffer {
|
||||
fn texture2d_dds<R>(&mut self, r: R) -> anyhow::Result<Arc<Image>>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let Ok(dds) = image_dds::ddsfile::Dds::read(r) else {
|
||||
anyhow::bail!("Not a valid DDS file.\nSee: https://github.com/galister/wlx-overlay-s/wiki/Custom-Textures");
|
||||
};
|
||||
|
||||
let surface = Surface::from_dds(&dds)?;
|
||||
|
||||
if surface.depth != 1 {
|
||||
anyhow::bail!("Not a 2D texture.")
|
||||
}
|
||||
|
||||
let image = Image::new(
|
||||
self.graphics.memory_allocator.clone(),
|
||||
ImageCreateInfo {
|
||||
image_type: ImageType::Dim2d,
|
||||
format: dds_to_vk(surface.image_format)?,
|
||||
extent: [surface.width, surface.height, surface.depth],
|
||||
usage: ImageUsage::TRANSFER_DST | ImageUsage::TRANSFER_SRC | ImageUsage::SAMPLED,
|
||||
..Default::default()
|
||||
},
|
||||
AllocationCreateInfo::default(),
|
||||
)?;
|
||||
|
||||
let buffer: Subbuffer<[u8]> = Buffer::new_slice(
|
||||
self.graphics.memory_allocator.clone(),
|
||||
BufferCreateInfo {
|
||||
usage: BufferUsage::TRANSFER_SRC,
|
||||
..Default::default()
|
||||
},
|
||||
AllocationCreateInfo {
|
||||
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||
..Default::default()
|
||||
},
|
||||
surface.data.len() as DeviceSize,
|
||||
)?;
|
||||
|
||||
buffer.write()?.copy_from_slice(surface.data);
|
||||
|
||||
self.command_buffer
|
||||
.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(buffer, image.clone()))?;
|
||||
|
||||
Ok(image)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dds_to_vk(dds_fmt: ImageFormat) -> anyhow::Result<Format> {
|
||||
match dds_fmt {
|
||||
ImageFormat::R8Unorm => Ok(Format::R8_UNORM),
|
||||
ImageFormat::Rgba8Unorm => Ok(Format::R8G8B8A8_UNORM),
|
||||
ImageFormat::Rgba8UnormSrgb => Ok(Format::R8G8B8A8_SRGB),
|
||||
ImageFormat::Rgba16Float => Ok(Format::R16G16B16A16_SFLOAT),
|
||||
ImageFormat::Rgba32Float => Ok(Format::R32G32B32A32_SFLOAT),
|
||||
ImageFormat::Bgra8Unorm => Ok(Format::B8G8R8A8_UNORM),
|
||||
ImageFormat::Bgra8UnormSrgb => Ok(Format::B8G8R8A8_SRGB),
|
||||
// DXT1
|
||||
ImageFormat::BC1RgbaUnorm => Ok(Format::BC1_RGBA_UNORM_BLOCK),
|
||||
ImageFormat::BC1RgbaUnormSrgb => Ok(Format::BC1_RGBA_SRGB_BLOCK),
|
||||
// DXT3
|
||||
ImageFormat::BC2RgbaUnorm => Ok(Format::BC2_UNORM_BLOCK),
|
||||
ImageFormat::BC2RgbaUnormSrgb => Ok(Format::BC2_SRGB_BLOCK),
|
||||
// DXT5
|
||||
ImageFormat::BC3RgbaUnorm => Ok(Format::BC3_UNORM_BLOCK),
|
||||
ImageFormat::BC3RgbaUnormSrgb => Ok(Format::BC3_SRGB_BLOCK),
|
||||
// RGTC1
|
||||
ImageFormat::BC4RUnorm => Ok(Format::BC4_UNORM_BLOCK),
|
||||
ImageFormat::BC4RSnorm => Ok(Format::BC4_SNORM_BLOCK),
|
||||
// RGTC2
|
||||
ImageFormat::BC5RgUnorm => Ok(Format::BC5_UNORM_BLOCK),
|
||||
ImageFormat::BC5RgSnorm => Ok(Format::BC5_SNORM_BLOCK),
|
||||
// BPTC
|
||||
ImageFormat::BC6hRgbUfloat => Ok(Format::BC6H_UFLOAT_BLOCK),
|
||||
ImageFormat::BC6hRgbSfloat => Ok(Format::BC6H_SFLOAT_BLOCK),
|
||||
// BPTC
|
||||
ImageFormat::BC7RgbaUnorm => Ok(Format::BC7_UNORM_BLOCK),
|
||||
ImageFormat::BC7RgbaUnormSrgb => Ok(Format::BC7_SRGB_BLOCK),
|
||||
_ => anyhow::bail!("Unsupported format {:?}", dds_fmt),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user