Compare commits
3 Commits
9125878840
...
vulkano
| Author | SHA1 | Date | |
|---|---|---|---|
| e1c085c060 | |||
| d941b2d6cd | |||
| 0a41daf4eb |
25
Cargo.toml
25
Cargo.toml
@@ -6,18 +6,19 @@ edition = "2018"
|
||||
default-run = "rust-engine"
|
||||
|
||||
[dependencies]
|
||||
vulkano-shaders = "0.20"
|
||||
vulkano = "0.20"
|
||||
vulkano-win = "0.20"
|
||||
cgmath = "0.17.0"
|
||||
winit = "0.24"
|
||||
image = "0.23.6"
|
||||
serde = "1.0.114"
|
||||
serde_json = "1.0.59"
|
||||
serde_derive = "1.0.114"
|
||||
toml = "0.5.6"
|
||||
gilrs = "0.7.4"
|
||||
gltf = "0.15.2"
|
||||
vulkano-shaders = "0.24"
|
||||
vulkano = "0.24"
|
||||
vulkano-win = "0.24"
|
||||
cgmath = "0.18.0"
|
||||
winit = "0.25"
|
||||
image = "0.23"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde_derive = "1.0"
|
||||
toml = "0.5"
|
||||
gilrs = "0.7"
|
||||
gltf = "0.15"
|
||||
gfx_glyph = "0.17"
|
||||
|
||||
[[bin]]
|
||||
name = "converter"
|
||||
|
||||
BIN
build/debug.rdbg
BIN
build/debug.rdbg
Binary file not shown.
@@ -1,5 +1,9 @@
|
||||
vulkan_validation_layers = true
|
||||
mesh_load_info = true
|
||||
debug_errors = true
|
||||
debug_warnings = true
|
||||
debug_info = true
|
||||
debug_verbose = true
|
||||
|
||||
[input]
|
||||
mouse_motion = false
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::fs;
|
||||
use std::{convert::TryInto, fs};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use toml;
|
||||
use vulkano::image::SampleCount;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct LogConfigInput {
|
||||
@@ -14,7 +15,11 @@ pub struct LogConfigInput {
|
||||
pub struct LogConfig {
|
||||
pub vulkan_validation_layers: bool,
|
||||
pub mesh_load_info: bool,
|
||||
pub input: LogConfigInput
|
||||
pub input: LogConfigInput,
|
||||
pub debug_errors: bool,
|
||||
pub debug_warnings: bool,
|
||||
pub debug_info: bool,
|
||||
pub debug_verbose: bool
|
||||
}
|
||||
|
||||
impl LogConfig {
|
||||
@@ -32,4 +37,8 @@ impl RenderConfig {
|
||||
pub fn from_file(path: &str) -> Self {
|
||||
toml::from_slice(&fs::read(path).expect("Failed to read render config!")).expect("Failed to parse render config!")
|
||||
}
|
||||
|
||||
pub fn get_msaa(&self) -> Option<SampleCount> {
|
||||
self.msaa_samples.try_into().ok()
|
||||
}
|
||||
}
|
||||
@@ -66,8 +66,6 @@ impl Game for TestGame {
|
||||
|
||||
if self.input.button_down("print_framerate") {
|
||||
println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time);
|
||||
print_quat_as_euler(self.player.camera.rotation);
|
||||
println!();
|
||||
}
|
||||
|
||||
if self.input.button_just_pressed("test") {
|
||||
@@ -174,7 +172,7 @@ impl TestGame {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_quat_as_euler(quat: Quaternion<f32>) {
|
||||
pub fn _print_quat_as_euler(quat: Quaternion<f32>) {
|
||||
let euler = Euler::from(quat);
|
||||
print!("({:?},{:?},{:?})", Deg::from(euler.x), Deg::from(euler.y), Deg::from(euler.z));
|
||||
}
|
||||
@@ -83,7 +83,7 @@ impl Camera {
|
||||
self.rotation.invert().rotate_vector(vec)
|
||||
}
|
||||
|
||||
pub fn world_to_local(&self, vec:Vector3<f32>) -> Vector3<f32> {
|
||||
pub fn _world_to_local(&self, vec:Vector3<f32>) -> Vector3<f32> {
|
||||
self.rotation.rotate_vector(vec)
|
||||
}
|
||||
}
|
||||
@@ -187,6 +187,7 @@ impl Updatable for Player {
|
||||
let mesh = &renderer.game_data.meshes[game_object.mesh_index];
|
||||
if let Some(dist) = intersection_distance(self.camera.position, ray_direction, mesh, game_object) {
|
||||
game_object.is_selected = !game_object.is_selected;
|
||||
println!("distance: {}", dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ fn main() {
|
||||
let (mut renderer, event_loop) = VulkanRenderer::init(
|
||||
line_vertices,
|
||||
log_config.vulkan_validation_layers,
|
||||
RenderConfig::from_file("config/graphics.toml")
|
||||
RenderConfig::from_file("config/graphics.toml"),
|
||||
log_config.clone()
|
||||
);
|
||||
|
||||
game.game_start(&mut renderer);
|
||||
|
||||
@@ -3,9 +3,10 @@ use std::sync::Arc;
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::format::Format;
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract};
|
||||
use vulkano::image::{AttachmentImage, ImageUsage, SwapchainImage};
|
||||
use vulkano::image::view::ImageView;
|
||||
use vulkano::image::{AttachmentImage, ImageUsage, SampleCount, SwapchainImage};
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::render_pass::{Framebuffer, FramebufferAbstract, RenderPass};
|
||||
use winit::window::Window;
|
||||
use vulkano::swapchain::Swapchain;
|
||||
|
||||
@@ -13,8 +14,8 @@ use vulkano::swapchain::Swapchain;
|
||||
pub fn create_framebuffers(device: Arc<Device>,
|
||||
swapchain: &Arc<Swapchain<Window>>,
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
msaa_sample_count: u32,
|
||||
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
||||
msaa_samples: Option<SampleCount>,
|
||||
render_pass: Arc<RenderPass>,
|
||||
dynamic_state: &mut DynamicState)
|
||||
-> Vec<Arc<dyn FramebufferAbstract + Send + Sync>> {
|
||||
|
||||
@@ -28,13 +29,13 @@ pub fn create_framebuffers(device: Arc<Device>,
|
||||
};
|
||||
dynamic_state.viewports = Some(vec!(viewport));
|
||||
|
||||
let depth_image = if msaa_sample_count > 0 {
|
||||
let depth_image = if let Some(msaa_sample_count) = msaa_samples {
|
||||
AttachmentImage::multisampled_with_usage(device.clone(), dim_array, msaa_sample_count, Format::D16Unorm, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
} else {
|
||||
AttachmentImage::with_usage(device.clone(), dim_array, Format::D16Unorm, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
};
|
||||
|
||||
let msaa_buffers = if msaa_sample_count > 0 {
|
||||
let msaa_buffers = if let Some(msaa_sample_count) = msaa_samples {
|
||||
Some(create_msaa_buffers(device.clone(), dim_array, swapchain, msaa_sample_count))
|
||||
} else {
|
||||
None
|
||||
@@ -44,18 +45,22 @@ pub fn create_framebuffers(device: Arc<Device>,
|
||||
|
||||
for i in 0..images.len() {
|
||||
let image_buffer = &images[i];
|
||||
let image_view = ImageView::new(image_buffer.clone()).unwrap();
|
||||
let depth_view = ImageView::new(depth_image.clone()).unwrap();
|
||||
|
||||
if let Some(msaa_buffers_exist) = &msaa_buffers {
|
||||
let msaa_view = ImageView::new((&msaa_buffers_exist[i]).clone()).unwrap();
|
||||
|
||||
framebuffers.push(Arc::new(Framebuffer::start(render_pass.clone())
|
||||
.add(image_buffer.clone()).unwrap()
|
||||
.add((&msaa_buffers_exist[i]).clone()).unwrap()
|
||||
.add(depth_image.clone()).unwrap()
|
||||
.add(image_view).unwrap()
|
||||
.add(msaa_view).unwrap()
|
||||
.add(depth_view).unwrap()
|
||||
.build().unwrap()
|
||||
) as Arc<dyn FramebufferAbstract + Send + Sync>);
|
||||
} else {
|
||||
framebuffers.push(Arc::new(Framebuffer::start(render_pass.clone())
|
||||
.add(image_buffer.clone()).unwrap()
|
||||
.add(depth_image.clone()).unwrap()
|
||||
.add(image_view).unwrap()
|
||||
.add(depth_view).unwrap()
|
||||
.build().unwrap()
|
||||
) as Arc<dyn FramebufferAbstract + Send + Sync>);
|
||||
}
|
||||
@@ -64,7 +69,7 @@ pub fn create_framebuffers(device: Arc<Device>,
|
||||
framebuffers
|
||||
}
|
||||
|
||||
fn create_msaa_buffers(device: Arc<Device>, dimensions: [u32; 2], swapchain: &Arc<Swapchain<Window>>, sample_count: u32) -> Vec<Arc<AttachmentImage>> {
|
||||
fn create_msaa_buffers(device: Arc<Device>, dimensions: [u32; 2], swapchain: &Arc<Swapchain<Window>>, sample_count: SampleCount) -> Vec<Arc<AttachmentImage>> {
|
||||
let mut msaa_attachments = vec![];
|
||||
for _ in 0..swapchain.num_images() {
|
||||
msaa_attachments.push(AttachmentImage::transient_multisampled(device.clone(), dimensions, sample_count, swapchain.format()).unwrap());
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use std::sync::Arc;
|
||||
use std::{sync::Arc};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use cgmath::{Matrix4, SquareMatrix};
|
||||
use dds::get_block_size;
|
||||
use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::{CommandBuffer, SubpassContents}, image::{ImageLayout, ImageUsage, MipmapsCount, immutable::SubImage}};
|
||||
use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState};
|
||||
use vulkano::command_buffer::CommandBufferUsage::{MultipleSubmit, SimultaneousUse};
|
||||
use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::{PrimaryAutoCommandBuffer, SubpassContents}, image::{ImageDimensions, ImageLayout, ImageUsage, MipmapsCount, immutable::SubImage}, render_pass::{FramebufferAbstract, RenderPass}};
|
||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryCommandBuffer, DynamicState};
|
||||
use vulkano::descriptor::DescriptorSet;
|
||||
use vulkano::device::{Device, DeviceExtensions, Queue};
|
||||
use vulkano::device::{Device, Features, Queue};
|
||||
use vulkano::format::{ClearValue, Format};
|
||||
use vulkano::framebuffer::{RenderPassAbstract, FramebufferAbstract};
|
||||
use vulkano::image::{Dimensions, ImmutableImage};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, PhysicalDevice, Version};
|
||||
use vulkano::image::{ImageCreateFlags, ImmutableImage};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, PhysicalDevice, Version};
|
||||
use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{AcquireError, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
@@ -28,7 +28,8 @@ use pipelines::line_vs::ty::LinePushConstants;
|
||||
use pipelines::DefaultShader;
|
||||
use pipelines::vs;
|
||||
|
||||
use crate::config::RenderConfig;
|
||||
use crate::config::LogConfig;
|
||||
use crate::{config::RenderConfig};
|
||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle};
|
||||
|
||||
pub mod pipelines;
|
||||
@@ -82,7 +83,7 @@ pub struct MeshHandle {
|
||||
|
||||
pub(crate) type TextureHandle = usize;
|
||||
pub struct Texture {
|
||||
pub image: Arc<ImmutableImage<Format>>,
|
||||
pub image: Arc<ImmutableImage>,
|
||||
pub sampler: Arc<Sampler>
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@ pub struct VulkanRenderer {
|
||||
pub pipelines: Vec<Box<dyn Drawcall>>,
|
||||
pub surface: Arc<Surface<Window>>,
|
||||
pub swapchain: Arc<Swapchain<Window>>,
|
||||
pub render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
||||
pub render_pass: Arc<RenderPass>,
|
||||
pub queue: Arc<Queue>,
|
||||
pub recreate_swapchain: bool,
|
||||
pub debug_callback: Option<DebugCallback>,
|
||||
@@ -120,7 +121,7 @@ pub struct VulkanRenderer {
|
||||
}
|
||||
|
||||
impl VulkanRenderer {
|
||||
pub fn init(line_vertices: Vec<LinePoint>, enable_validation_layers: bool, render_config: RenderConfig) -> (VulkanRenderer, EventLoop<()>) {
|
||||
pub fn init(line_vertices: Vec<LinePoint>, enable_validation_layers: bool, render_config: RenderConfig, log_config: LogConfig) -> (VulkanRenderer, EventLoop<()>) {
|
||||
// Create empty game data struct to be filled
|
||||
let mut data = GameData {
|
||||
line_push_constants: LinePushConstants {
|
||||
@@ -141,7 +142,7 @@ impl VulkanRenderer {
|
||||
|
||||
// Create basic vulkan instance with layers and info
|
||||
let instance = {
|
||||
let extensions = InstanceExtensions {
|
||||
let extensions = vulkano::instance::InstanceExtensions {
|
||||
ext_debug_utils: true,
|
||||
..vulkano_win::required_extensions()
|
||||
};
|
||||
@@ -164,9 +165,9 @@ impl VulkanRenderer {
|
||||
}
|
||||
});
|
||||
|
||||
Instance::new(Some(&app_info), &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
|
||||
Instance::new(Some(&app_info), Version::V1_2, &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
|
||||
} else {
|
||||
Instance::new(Some(&app_info), &extensions, None).expect("failed to create Vulkan instance")
|
||||
Instance::new(Some(&app_info), Version::V1_2, &extensions, None).expect("failed to create Vulkan instance")
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,24 +189,22 @@ impl VulkanRenderer {
|
||||
validation: true
|
||||
};
|
||||
|
||||
debug_callback = DebugCallback::new(&instance, msg_severity, msg_types, |msg| {
|
||||
let type_str = match (msg.severity.error, msg.severity.warning, msg.severity.information, msg.severity.verbose) {
|
||||
(true, _, _, _) => "!!",
|
||||
(_, true, _, _) => "!",
|
||||
(_, _, _, true) => "i",
|
||||
_ => " "
|
||||
debug_callback = DebugCallback::new(&instance, msg_severity, msg_types, move |msg| {
|
||||
let (type_str, will_log) = match (msg.severity.error, msg.severity.warning, msg.severity.information, msg.severity.verbose) {
|
||||
(true, _, _, _) => ("!!", log_config.debug_errors),
|
||||
(_, true, _, _) => ("!", log_config.debug_warnings),
|
||||
(_, _, _, true) => ("i", log_config.debug_info),
|
||||
_ => (" ", log_config.debug_verbose)
|
||||
};
|
||||
|
||||
let layer_str = msg.layer_prefix;
|
||||
|
||||
println!("[{}][{}]: {}", type_str, layer_str, msg.description);
|
||||
if will_log { println!("[{}][{:?}]: {}", type_str, layer_str, msg.description); }
|
||||
}).ok();
|
||||
}
|
||||
|
||||
// TODO: Just get the first physical device we find, it's fiiiine...
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let events_loop = EventLoop::new();
|
||||
let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let window = surface.window();
|
||||
@@ -218,8 +217,8 @@ impl VulkanRenderer {
|
||||
}).unwrap();
|
||||
|
||||
// Queue
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() };
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
|
||||
let device_ext = vulkano::device::DeviceExtensions { khr_swapchain: true, ..vulkano::device::DeviceExtensions::none() };
|
||||
let (device, mut queues) = Device::new(physical, &Features::none(), &device_ext,
|
||||
[(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
@@ -232,9 +231,19 @@ impl VulkanRenderer {
|
||||
let inner_size = window.inner_size();
|
||||
data.dimensions = [inner_size.width, inner_size.height];
|
||||
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
|
||||
data.dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
|
||||
PresentMode::Fifo, FullscreenExclusive::Default, true, color_space).unwrap()
|
||||
Swapchain::start(device.clone(), surface.clone())
|
||||
.num_images(caps.min_image_count)
|
||||
.format(format)
|
||||
.dimensions(data.dimensions)
|
||||
.usage(usage)
|
||||
.sharing_mode(&queue)
|
||||
.transform(SurfaceTransform::Identity)
|
||||
.composite_alpha(alpha)
|
||||
.present_mode(PresentMode::Fifo)
|
||||
.fullscreen_exclusive(FullscreenExclusive::Default)
|
||||
.clipped(true)
|
||||
.color_space(color_space)
|
||||
.build().unwrap()
|
||||
};
|
||||
|
||||
// Render pass
|
||||
@@ -244,7 +253,7 @@ impl VulkanRenderer {
|
||||
|
||||
let pipelines: Vec<Box<dyn Drawcall>> = vec![
|
||||
Box::new(DefaultShader::new(device.clone(), render_pass.clone())),
|
||||
// Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())),
|
||||
Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())),
|
||||
];
|
||||
|
||||
// Dynamic viewports allow us to recreate just the viewport when the window is resized
|
||||
@@ -255,7 +264,7 @@ impl VulkanRenderer {
|
||||
|
||||
// The render pass we created above only describes the layout of our framebuffers. Before we
|
||||
// can draw we also need to create the actual framebuffers.
|
||||
let framebuffers = framebuffers::create_framebuffers(device.clone(), &swapchain, &images, render_config.msaa_samples, render_pass.clone(), &mut dynamic_state);
|
||||
let framebuffers = framebuffers::create_framebuffers(device.clone(), &swapchain, &images, render_config.get_msaa(), render_pass.clone(), &mut dynamic_state);
|
||||
|
||||
let mut uniform_buffers = Vec::new();
|
||||
let uniform_buffer = vs::ty::ObjectUniformData {
|
||||
@@ -296,10 +305,10 @@ impl VulkanRenderer {
|
||||
}, events_loop)
|
||||
}
|
||||
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: vs::ty::ObjectUniformData) -> Arc<AutoCommandBuffer> {
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: vs::ty::ObjectUniformData) -> Arc<PrimaryAutoCommandBuffer> {
|
||||
// General setup
|
||||
let mut builder = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap();
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), uniform_buffer_data).unwrap();
|
||||
let mut builder = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), SimultaneousUse).unwrap();
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), Arc::new(uniform_buffer_data)).unwrap();
|
||||
if self.render_config.msaa_samples > 0 {
|
||||
builder.begin_render_pass(self.framebuffers[fb_index].clone(), SubpassContents::Inline, vec![ClearValue::None, ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||
} else {
|
||||
@@ -328,7 +337,7 @@ impl VulkanRenderer {
|
||||
let inner_size = window.inner_size();
|
||||
self.game_data.dimensions = [inner_size.width, inner_size.height];
|
||||
|
||||
let (new_swapchain, new_images) = match self.swapchain.recreate_with_dimensions(self.game_data.dimensions) {
|
||||
let (new_swapchain, new_images) = match self.swapchain.recreate().dimensions(self.game_data.dimensions).build() {
|
||||
Ok(r) => r,
|
||||
// This error tends to happen when the user is manually resizing the window.
|
||||
// Simply restarting the loop is the easiest way to fix this issue.
|
||||
@@ -343,13 +352,13 @@ impl VulkanRenderer {
|
||||
|
||||
self.pipelines = vec![
|
||||
Box::new(DefaultShader::new(self.device.clone(), self.render_pass.clone())),
|
||||
// Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())),
|
||||
Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())),
|
||||
];
|
||||
|
||||
self.swapchain = new_swapchain;
|
||||
// Because framebuffers contains an Arc on the old swapchain, we need to
|
||||
// recreate framebuffers as well.
|
||||
self.framebuffers = framebuffers::create_framebuffers(self.device.clone(), &self.swapchain, &new_images, self.render_config.msaa_samples, self.render_pass.clone(), &mut self.dynamic_state);
|
||||
self.framebuffers = framebuffers::create_framebuffers(self.device.clone(), &self.swapchain, &new_images, self.render_config.get_msaa(), self.render_pass.clone(), &mut self.dynamic_state);
|
||||
|
||||
self.recreate_swapchain = false;
|
||||
}
|
||||
@@ -428,7 +437,7 @@ impl VulkanRenderer {
|
||||
}
|
||||
|
||||
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, device: Arc<Device>) {
|
||||
let dimensions = Dimensions::Dim2d { width, height };
|
||||
let dimensions = ImageDimensions::Dim2d { width, height, array_layers: 1 };
|
||||
|
||||
let usage = ImageUsage {
|
||||
transfer_destination: true,
|
||||
@@ -439,12 +448,13 @@ impl VulkanRenderer {
|
||||
|
||||
let layout = ImageLayout::ShaderReadOnlyOptimal;
|
||||
|
||||
let (image_view, initializer) = ImmutableImage::uninitialized(
|
||||
let (immutable_image, initializer) = ImmutableImage::uninitialized(
|
||||
device.clone(),
|
||||
dimensions,
|
||||
format,
|
||||
MipmapsCount::Log2,
|
||||
usage,
|
||||
ImageCreateFlags::default(),
|
||||
layout,
|
||||
device.active_queue_families(),
|
||||
).unwrap();
|
||||
@@ -452,20 +462,21 @@ impl VulkanRenderer {
|
||||
let init = SubImage::new(
|
||||
Arc::new(initializer),
|
||||
0,
|
||||
image_view.mipmap_levels(),
|
||||
immutable_image.mipmap_levels(),
|
||||
0,
|
||||
1,
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
);
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap();
|
||||
// TODO: do we need multiple submit?
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(device.clone(), self.queue.family(), MultipleSubmit).unwrap();
|
||||
|
||||
let mut offset = 0;
|
||||
|
||||
let block_bytes = get_block_size(format).expect(&format!("Unknown texture format {:?}!", format));
|
||||
|
||||
for i in 0..image_view.mipmap_levels() {
|
||||
let mip_size = dimensions.to_image_dimensions().mipmap_dimensions(i).unwrap().width_height_depth();
|
||||
for i in 0..immutable_image.mipmap_levels() {
|
||||
let mip_size = dimensions.mipmap_dimensions(i).unwrap().width_height_depth();
|
||||
|
||||
let mip_byte_size = (
|
||||
(u32::max(4, mip_size[0]) / 4)
|
||||
@@ -485,10 +496,9 @@ impl VulkanRenderer {
|
||||
[0, 0, 0],
|
||||
mip_size,
|
||||
0,
|
||||
dimensions.array_layers_with_cube(),
|
||||
dimensions.array_layers(),
|
||||
i,
|
||||
)
|
||||
.unwrap();
|
||||
).unwrap();
|
||||
|
||||
offset += mip_byte_size;
|
||||
}
|
||||
@@ -504,9 +514,9 @@ impl VulkanRenderer {
|
||||
|
||||
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() - 1) as f32).unwrap();
|
||||
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, (immutable_image.mipmap_levels() - 1) as f32).unwrap();
|
||||
|
||||
self.game_data.textures.push(Texture { image: image_view, sampler });
|
||||
self.game_data.textures.push(Texture { image: immutable_image, sampler });
|
||||
}
|
||||
|
||||
pub fn add_game_object(self: &mut Self, mut game_object: GameObject, pipeline_index: usize) -> GameObjectHandle {
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
|
||||
|
||||
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::ShaderModule};
|
||||
use vulkano::{command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}, descriptor::{descriptor_set::PersistentDescriptorSet}, image::view::ImageView, pipeline::{shader::{ShaderModule}}, render_pass::{RenderPass, Subpass}};
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::framebuffer::RenderPassAbstract;
|
||||
use vulkano::framebuffer::Subpass;
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::GraphicsPipelineAbstract;
|
||||
use vulkano::pipeline::shader::GraphicsShaderType;
|
||||
|
||||
use crate::GameObject;
|
||||
use crate::vulkan::{LinePoint, Vertex};
|
||||
use crate::vulkan::GameData;
|
||||
use crate::VulkanRenderer;
|
||||
|
||||
type RP = Arc<dyn RenderPassAbstract + Send + Sync>;
|
||||
type RP = Arc<RenderPass>;
|
||||
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
|
||||
|
||||
pub trait Drawcall {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState);
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState);
|
||||
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer);
|
||||
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
|
||||
fn get_pipeline(self: &Self) -> &GP;
|
||||
@@ -43,7 +40,7 @@ pub struct DefaultShader {
|
||||
pipeline: GP,
|
||||
}
|
||||
|
||||
fn shader_module_from_file(device: Arc<Device>, path: &str) -> Arc<ShaderModule> {
|
||||
fn _shader_module_from_file(device: Arc<Device>, path: &str) -> Arc<ShaderModule> {
|
||||
let mut file = std::fs::File::open(path).unwrap();
|
||||
let mut buffer = vec![];
|
||||
file.read_to_end(&mut buffer).unwrap();
|
||||
@@ -101,42 +98,42 @@ impl DefaultShader {
|
||||
compile_shaders().unwrap();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
||||
let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
|
||||
// unsafe {
|
||||
|
||||
let fs_module = shader_module_from_file(device.clone(), "shaders/triangle.frag.spv");
|
||||
let fs_layout = fs::Layout(ShaderStages {
|
||||
fragment: true,
|
||||
..ShaderStages::none()
|
||||
});
|
||||
let fs_entry = fs_module.graphics_entry_point(entry_name_c, fs::MainInput, fs::MainOutput, fs_layout, GraphicsShaderType::Fragment);
|
||||
// static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
||||
// let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
|
||||
|
||||
let vs_module = shader_module_from_file(device.clone(), "shaders/triangle.vert.spv");
|
||||
let vs_layout = vs::Layout(ShaderStages {
|
||||
vertex: true,
|
||||
..ShaderStages::none()
|
||||
});
|
||||
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs::MainInput, vs::MainOutput, vs_layout, GraphicsShaderType::Vertex);
|
||||
// let fs_module = shader_module_from_file(device.clone(), "shaders/triangle.frag.spv");
|
||||
// let fs_entry = fs_module.graphics_entry_point(entry_name_c, yeet, &[], ref_shader.main_entry_point().input().clone(), ref_shader.main_entry_point().output().clone(), GraphicsShaderType::Fragment);
|
||||
|
||||
// let vs_module = shader_module_from_file(device.clone(), "shaders/triangle.vert.spv");
|
||||
// let vs_layout = vs::Layout(ShaderStages {
|
||||
// vertex: true,
|
||||
// ..ShaderStages::none()
|
||||
// });
|
||||
// let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs_layout, &[], vs::MainInput, vs::MainOutput, GraphicsShaderType::Vertex);
|
||||
|
||||
let fs = fs::Shader::load(device.clone()).unwrap();
|
||||
let vs = vs::Shader::load(device.clone()).unwrap();
|
||||
|
||||
Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<Vertex>()
|
||||
.vertex_shader(vs_entry, ())
|
||||
.vertex_shader(vs.main_entry_point(), ())
|
||||
.triangle_list()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.depth_stencil_simple_depth()
|
||||
.fragment_shader(fs_entry, ())
|
||||
.fragment_shader(fs.main_entry_point(), ())
|
||||
.blend_alpha_blending()
|
||||
.cull_mode_back()
|
||||
.render_pass(sub_pass.clone())
|
||||
.build(device.clone())
|
||||
.unwrap())
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drawcall for DefaultShader {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
for i in 0..game_data.game_objects.len() {
|
||||
let game_object = &game_data.game_objects[i];
|
||||
let mesh = &game_data.meshes[game_object.mesh_index];
|
||||
@@ -148,12 +145,13 @@ impl Drawcall for DefaultShader {
|
||||
vec![mesh.vertex_buffer.clone()],
|
||||
mesh.index_buffer.clone(),
|
||||
game_object.descriptor_sets[fb_index].clone(),
|
||||
push_constants).unwrap();
|
||||
push_constants,
|
||||
vec![]).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) {
|
||||
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
|
||||
let descriptor_set_layout = self.get_pipeline().layout().descriptor_set_layout(0).unwrap().clone();
|
||||
|
||||
println!("Diff: {:?}, Norm: {:?}", game_object.texture_index, game_object.normal_map_index);
|
||||
|
||||
@@ -162,12 +160,14 @@ impl Drawcall for DefaultShader {
|
||||
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
|
||||
|
||||
let diffuse = &renderer.game_data.textures[game_object.texture_index];
|
||||
let diffuse_view = ImageView::new(diffuse.image.clone()).unwrap();
|
||||
let normal_map = &renderer.game_data.textures[game_object.normal_map_index];
|
||||
let normal_view = ImageView::new(normal_map.image.clone()).unwrap();
|
||||
|
||||
descriptor_set = Arc::new(builder
|
||||
.add_buffer(uniform_buffer.clone()).unwrap()
|
||||
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap()
|
||||
.add_sampled_image(normal_map.image.clone(), normal_map.sampler.clone()).unwrap()
|
||||
.add_sampled_image(diffuse_view, diffuse.sampler.clone()).unwrap()
|
||||
.add_sampled_image(normal_view, normal_map.sampler.clone()).unwrap()
|
||||
.build().unwrap());
|
||||
|
||||
descriptor_set
|
||||
@@ -230,12 +230,13 @@ impl LineShader {
|
||||
}
|
||||
|
||||
impl Drawcall for LineShader {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, _fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
builder.draw(self.pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vec![self.vertex_buffer.clone()],
|
||||
(),
|
||||
game_data.line_push_constants.clone()).unwrap();
|
||||
game_data.line_push_constants.clone(),
|
||||
vec![]).unwrap();
|
||||
}
|
||||
|
||||
fn create_descriptor_set(self: &Self, _game_object: &mut GameObject, _renderer: &VulkanRenderer) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::RenderConfig;
|
||||
use std::sync::Arc;
|
||||
use vulkano::framebuffer::RenderPassAbstract;
|
||||
use vulkano::format::Format;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::render_pass::RenderPass;
|
||||
|
||||
pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swapchain_format: Format) -> Arc<dyn RenderPassAbstract + Send + Sync> {
|
||||
pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swapchain_format: Format) -> Arc<RenderPass> {
|
||||
if render_config.msaa_samples > 0 {
|
||||
Arc::new(vulkano::single_pass_renderpass!(
|
||||
device.clone(),
|
||||
|
||||
Reference in New Issue
Block a user