diff --git a/build/converter/src/main.rs b/build/converter/src/main.rs index 29a3e6d..d913dd7 100644 --- a/build/converter/src/main.rs +++ b/build/converter/src/main.rs @@ -8,13 +8,11 @@ fn main() { let tex_conv_output = std::process::Command::new("build/nvidia-texture-converter/nvtt_export.exe") .arg("-q").arg("fastest") .arg("-f").arg("bc1") - .arg("--no-mips") .arg("-o").arg(format!("textures/{}.dds", image.name().unwrap())) .arg(uri) .current_dir("models") .output().expect("Failed to run texture converter."); println!("{:?}", tex_conv_output); } - } } \ No newline at end of file diff --git a/models/textures/cobblestone_large_01_diff_4k.dds b/models/textures/cobblestone_large_01_diff_4k.dds new file mode 100644 index 0000000..10dfe20 Binary files /dev/null and b/models/textures/cobblestone_large_01_diff_4k.dds differ diff --git a/models/textures/cobblestone_large_01_nor_4k.dds b/models/textures/cobblestone_large_01_nor_4k.dds new file mode 100644 index 0000000..1623d4f Binary files /dev/null and b/models/textures/cobblestone_large_01_nor_4k.dds differ diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 085727b..6795741 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use std::time::SystemTime; use cgmath::{Matrix4, SquareMatrix}; -use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::SubpassContents, image::MipmapsCount}; +use vulkano::{buffer::{BufferAccess, BufferUsage, CpuAccessibleBuffer}, command_buffer::{CommandBuffer, SubpassContents}, image::{ImageLayout, ImageUsage, MipmapsCount, immutable::SubImage}}; use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState}; use vulkano::descriptor::DescriptorSet; use vulkano::device::{Device, DeviceExtensions, Queue}; @@ -433,12 +433,78 @@ impl VulkanRenderer { pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, device: Arc) { let dimensions = Dimensions::Dim2d { width, height }; - let (image_view, future) = ImmutableImage::from_iter(bytes.iter().cloned(), dimensions, MipmapsCount::One, format, self.queue.clone()).unwrap(); + + let usage = ImageUsage { + transfer_destination: true, + transfer_source: false, + sampled: true, + ..ImageUsage::none() + }; + + let layout = ImageLayout::ShaderReadOnlyOptimal; + + let (image_view, initializer) = ImmutableImage::uninitialized( + device.clone(), + dimensions, + format, + MipmapsCount::Specific(13), + usage, + layout, + device.active_queue_families(), + ).unwrap(); + + let init = SubImage::new( + Arc::new(initializer), + 0, + 13, + 0, + 1, + ImageLayout::ShaderReadOnlyOptimal, + ); + + let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap(); + + let mut offset: usize = 0; + + for i in 0..13 { + let source = CpuAccessibleBuffer::from_iter( + device.clone(), + BufferUsage::transfer_source(), + false, + bytes[offset..].iter().cloned(), + ).unwrap(); + + let mut mip_size = dimensions.width_height_depth(); + mip_size[0] = mip_size[0] / u32::pow(2, i); + mip_size[1] = mip_size[1] / u32::pow(2, i); + + cbb.copy_buffer_to_image_dimensions( + source.clone(), + init.clone(), + [0, 0, 0], + mip_size, + 0, + dimensions.array_layers_with_cube(), + i, + ) + .unwrap(); + + // 4 bits per pixel -> 1/2 byte + offset += ((mip_size[0] * mip_size[1]) / 2) as usize; + } + + let cb = cbb.build().unwrap(); + + let future = match cb.execute(self.queue.clone()) { + Ok(f) => f, + Err(e) => unreachable!("{:?}", e) + }; + future.flush().unwrap(); let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear, - MipmapMode::Linear, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, - SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, image_view.mipmap_levels() as f32).unwrap(); + MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, + SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 12 as f32).unwrap(); self.game_data.textures.push(Texture { image: image_view, sampler }); }