018: Data for the vertex shader

This commit is contained in:
zawz 2024-07-31 10:10:50 +02:00
parent 84019305a9
commit 7be29cb3a9
9 changed files with 292 additions and 52 deletions

96
Cargo.lock generated
View file

@ -505,6 +505,19 @@ dependencies = [
"wasi",
]
[[package]]
name = "gpu-allocator"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd"
dependencies = [
"ash",
"log",
"presser",
"thiserror",
"windows",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -792,6 +805,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "presser"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@ -1159,17 +1178,6 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vk-mem"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cb12b79bcec57a3334d0284f1364c1846f378bb47df9779c6dbfcfc245c9404"
dependencies = [
"ash",
"bitflags 2.6.0",
"cc",
]
[[package]]
name = "vk-shader-macros"
version = "0.2.10"
@ -1190,9 +1198,9 @@ dependencies = [
"ash-window",
"dotenvy",
"env_logger",
"gpu-allocator",
"log",
"thiserror",
"vk-mem",
"vk-shader-macros",
"winit",
]
@ -1417,6 +1425,70 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
"windows-core",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-implement",
"windows-interface",
"windows-result",
"windows-strings",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-result"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.45.0"

View file

@ -10,8 +10,8 @@ ash = "0.38.0"
ash-window = "0.13.0"
dotenvy = "0.15.7"
env_logger = "0.11.3"
gpu-allocator = "0.27.0"
log = "0.4.22"
thiserror = "1.0.62"
vk-mem = "0.4.0"
vk-shader-macros = "0.2.10"
winit = { version = "0.29", features = ["rwh_06"] }

View file

@ -2,8 +2,8 @@
layout(location = 0) out vec4 theColour;
layout(location = 1) in vec4 colourdata_from_the_vertexshader;
layout(location = 0) in vec4 data_from_the_vertexshader;
void main() {
theColour = colourdata_from_the_vertexshader;
theColour = data_from_the_vertexshader;
}

View file

@ -1,9 +1,13 @@
#version 450
layout(location = 1) out vec4 colourdata_from_the_vertexshader;
layout(location = 0) in vec4 position;
layout(location = 1) in float size;
layout(location = 2) in vec4 colour;
layout(location = 0) out vec4 colourdata_for_the_fragmentshader;
void main() {
gl_PointSize = 10.0;
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
colourdata_from_the_vertexshader = vec4(0.0, 0.6, 1.0, 1.0);
gl_PointSize = size;
gl_Position = position;
colourdata_for_the_fragmentshader = vec4(0.4, 1.0, 0.5, 1.0);
}

89
src/instance/buffer.rs Normal file
View file

@ -0,0 +1,89 @@
use ash::vk;
use gpu_allocator::vulkan::Allocation as GpuAllocation;
use gpu_allocator::vulkan::AllocationCreateDesc;
use gpu_allocator::vulkan::AllocationScheme;
use gpu_allocator::vulkan::Allocator as GpuAllocator;
use gpu_allocator::vulkan::AllocatorCreateDesc;
use gpu_allocator::MemoryLocation;
use super::EngineError;
pub struct BufferAllocator {
pub allocator: GpuAllocator,
}
pub struct Buffer {
pub allocation: Option<GpuAllocation>,
pub buffer: vk::Buffer,
}
impl BufferAllocator {
pub fn init(
ash_instance: &ash::Instance,
physical_device: vk::PhysicalDevice,
device: &ash::Device,
) -> Result<Self, EngineError> {
let allocator = GpuAllocator::new(&AllocatorCreateDesc {
instance: ash_instance.clone(),
device: device.clone(),
physical_device,
debug_settings: Default::default(),
buffer_device_address: true, // Ideally, check the BufferDeviceAddressFeatures struct.
allocation_sizes: Default::default(),
})?;
Ok(Self { allocator })
}
pub fn create_buffer(
&mut self,
device: &ash::Device,
size: u64,
) -> Result<Buffer, EngineError> {
let vk_info = vk::BufferCreateInfo::default()
.size(size)
.usage(vk::BufferUsageFlags::STORAGE_BUFFER);
let buffer = unsafe { device.create_buffer(&vk_info, None) }.unwrap();
let requirements = unsafe { device.get_buffer_memory_requirements(buffer) };
let allocation = self.allocator.allocate(&AllocationCreateDesc {
name: "Example allocation",
requirements,
location: MemoryLocation::CpuToGpu,
linear: true, // Buffers are always linear
allocation_scheme: AllocationScheme::GpuAllocatorManaged,
})?;
// Bind memory to the buffer
unsafe {
device
.bind_buffer_memory(buffer, allocation.memory(), allocation.offset())
.unwrap()
};
Ok(Buffer {
allocation: Some(allocation),
buffer,
})
}
pub fn free_buffer_allocation(&mut self, device: &ash::Device, buffer: &mut Buffer) {
let allocation = buffer.allocation.take();
self.allocator.free(allocation.unwrap()).unwrap();
unsafe { device.destroy_buffer(buffer.buffer, None) };
}
}
impl Buffer {
pub fn mapped_slice_mut(&mut self) -> Option<&mut [u8]> {
if let Some(v) = &mut self.allocation {
v.mapped_slice_mut()
} else {
None
}
}
pub unsafe fn fill(&mut self, data: &[u8]) {
let inner_buffer = self.mapped_slice_mut().unwrap();
inner_buffer.copy_from_slice(data);
}
}

17
src/instance/error.rs Normal file
View file

@ -0,0 +1,17 @@
use ash::vk;
#[derive(Debug, thiserror::Error)]
pub enum EngineError {
#[error(transparent)]
VkError(#[from] vk::Result),
#[error(transparent)]
AshLoadingError(#[from] ash::LoadingError),
#[error(transparent)]
WinitOsError(#[from] winit::error::OsError),
#[error(transparent)]
WinitEventLoopError(#[from] winit::error::EventLoopError),
#[error(transparent)]
RWHError(#[from] winit::raw_window_handle::HandleError),
#[error(transparent)]
AllocationError(#[from] gpu_allocator::AllocationError),
}

View file

@ -1,8 +1,11 @@
use std::ffi::{c_char, CString};
use ash::vk;
use buffer::{Buffer, BufferAllocator};
pub mod buffer;
pub mod debug;
pub mod error;
pub mod pipeline;
pub mod pools;
pub mod queue;
@ -10,6 +13,8 @@ pub mod surface;
pub mod swapchain;
pub mod window;
pub use error::EngineError;
pub use debug::DebugInstance;
pub use pipeline::Pipeline;
use pools::Pools;
@ -23,20 +28,6 @@ use crate::frame_counter::FrameCounter;
const ENGINE_NAME: &core::ffi::CStr = c"UnknownGameEngine";
const APP_NAME: &core::ffi::CStr = c"Vulkan Tutorial";
#[derive(Debug, thiserror::Error)]
pub enum EngineError {
#[error(transparent)]
VkError(#[from] vk::Result),
#[error(transparent)]
AshLoadingError(#[from] ash::LoadingError),
#[error(transparent)]
WinitOsError(#[from] winit::error::OsError),
#[error(transparent)]
WinitEventLoopError(#[from] winit::error::EventLoopError),
#[error(transparent)]
RWHError(#[from] winit::raw_window_handle::HandleError),
}
pub struct EngineInstance {
pub entry: ash::Entry,
pub ash_instance: ash::Instance,
@ -53,6 +44,9 @@ pub struct EngineInstance {
pub pipeline: Pipeline,
pub pools: Pools,
pub commandbuffers: Vec<vk::CommandBuffer>,
pub allocator: std::mem::ManuallyDrop<BufferAllocator>,
pub buffer1: Buffer,
pub buffer2: Buffer,
pub framecount: FrameCounter,
}
@ -118,8 +112,62 @@ impl EngineInstance {
let renderpass = Self::init_renderpass(&device, surface_format.format)?;
swapchain.create_framebuffers(&device, renderpass)?;
log::debug!("Create allocator");
let mut allocator = BufferAllocator::init(&ash_instance, physical_device, &device)?;
let mut buffer1 = allocator.create_buffer(&device, 16)?;
unsafe {
let data: [u8; 16] = std::mem::transmute([-0.5f32, 0.0f32, 0.0f32, 1.0f32]);
buffer1.fill(&data);
}
let mut buffer2 = allocator.create_buffer(&device, 20)?;
unsafe {
let data: [u8; 20] = std::mem::transmute([5.0f32, 1.0f32, 1.0f32, 0.0f32, 1.0f32]);
buffer2.fill(&data);
}
let vertex_attrib_descs = [
vk::VertexInputAttributeDescription {
binding: 0,
location: 0,
offset: 0,
format: vk::Format::R32G32B32A32_SFLOAT,
},
vk::VertexInputAttributeDescription {
binding: 1,
location: 1,
offset: 0,
format: vk::Format::R32_SFLOAT,
},
vk::VertexInputAttributeDescription {
binding: 1,
location: 2,
offset: 4,
format: vk::Format::R32G32B32A32_SFLOAT,
},
];
let vertex_binding_descs = [
vk::VertexInputBindingDescription {
binding: 0,
stride: 16,
input_rate: vk::VertexInputRate::VERTEX,
},
vk::VertexInputBindingDescription {
binding: 1,
stride: 20,
input_rate: vk::VertexInputRate::VERTEX,
},
];
log::debug!("Init pipeline");
let pipeline = Pipeline::init(&device, &swapchain, &renderpass)?;
let pipeline = Pipeline::init(
&device,
&swapchain,
&renderpass,
&vertex_attrib_descs,
&vertex_binding_descs,
)?;
log::debug!("Init pools");
let pools = Pools::init(&device, &queue_families)?;
@ -127,7 +175,16 @@ impl EngineInstance {
log::debug!("Create command buffers");
let commandbuffers = pools.create_commandbuffers(&device, swapchain.framebuffers.len())?;
for (i, &commandbuffer) in commandbuffers.iter().enumerate() {
Self::fill_commandbuffer(&device, commandbuffer, renderpass, &swapchain, i, &pipeline)?;
Self::fill_commandbuffer(
&device,
commandbuffer,
renderpass,
&swapchain,
i,
&pipeline,
buffer1.buffer,
buffer2.buffer,
)?;
}
Ok(Self {
@ -146,6 +203,9 @@ impl EngineInstance {
pipeline,
pools,
commandbuffers,
allocator: std::mem::ManuallyDrop::new(allocator),
buffer1,
buffer2,
framecount: FrameCounter::new(),
})
}
@ -156,8 +216,14 @@ impl EngineInstance {
.device_wait_idle()
.expect("something wrong while waiting");
self.pools.cleanup(&self.device);
// self.queues.cleanup();
self.pipeline.cleanup(&self.device);
self.allocator
.free_buffer_allocation(&self.device, &mut self.buffer1);
self.allocator
.free_buffer_allocation(&self.device, &mut self.buffer2);
std::mem::ManuallyDrop::drop(&mut self.allocator);
self.device.destroy_render_pass(self.renderpass, None);
self.swapchain.cleanup(&self.device);
std::mem::ManuallyDrop::drop(&mut self.surface);
@ -325,6 +391,9 @@ impl EngineInstance {
swapchain: &Swapchain,
framebuffer_index: usize,
pipeline: &Pipeline,
// buffers: &[vk::Buffer],
buffer1: vk::Buffer,
buffer2: vk::Buffer,
) -> Result<(), vk::Result> {
let commandbuffer_begininfo = vk::CommandBufferBeginInfo::default();
unsafe {
@ -356,6 +425,8 @@ impl EngineInstance {
vk::PipelineBindPoint::GRAPHICS,
pipeline.pipeline,
);
device.cmd_bind_vertex_buffers(commandbuffer, 0, &[buffer1], &[0]);
device.cmd_bind_vertex_buffers(commandbuffer, 1, &[buffer2], &[0]);
device.cmd_draw(commandbuffer, 1, 1, 0, 0);
device.cmd_end_render_pass(commandbuffer);
device.end_command_buffer(commandbuffer)?;

View file

@ -21,6 +21,8 @@ impl Pipeline {
logical_device: &ash::Device,
swapchain: &Swapchain,
renderpass: &vk::RenderPass,
vertex_attrib_descs: &[vk::VertexInputAttributeDescription],
vertex_binding_descs: &[vk::VertexInputBindingDescription],
) -> Result<Pipeline, vk::Result> {
let vertexshader_createinfo = vk::ShaderModuleCreateInfo::default()
.code(vk_shader_macros::include_glsl!("./shaders/shader.vert", kind: vert));
@ -42,18 +44,6 @@ impl Pipeline {
.name(&mainfunctionname);
let shader_stages = vec![vertexshader_stage, fragmentshader_stage];
let vertex_attrib_descs = [vk::VertexInputAttributeDescription {
binding: 0,
location: 0,
offset: 0,
format: vk::Format::R32G32B32A32_SFLOAT,
}];
let vertex_binding_descs = [vk::VertexInputBindingDescription {
binding: 0,
stride: 16,
input_rate: vk::VertexInputRate::VERTEX,
}];
let vertex_input_info = vk::PipelineVertexInputStateCreateInfo::default()
.vertex_attribute_descriptions(&vertex_attrib_descs)
.vertex_binding_descriptions(&vertex_binding_descs);

View file

@ -54,10 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let semaphores_available = [e.swapchain.image_available[e.swapchain.current_image]];
let waiting_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
let semaphores_finished = [
e.swapchain.rendering_finished[e.swapchain.current_image],
// e.swapchain.next_frame[next_image],
];
let semaphores_finished = [e.swapchain.rendering_finished[e.swapchain.current_image]];
let commandbuffers = [e.commandbuffers[image_index as usize]];
let submit_info = [vk::SubmitInfo::default()
.wait_semaphores(&semaphores_available)