Finish generator implementation
This commit is contained in:
parent
13aa2ba04d
commit
14236e1cd8
3 changed files with 241 additions and 16 deletions
|
@ -1,7 +1,12 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform Descriptor {
|
||||
vec3 color;
|
||||
vec4 background_color;
|
||||
vec4 border_color;
|
||||
|
||||
uint width;
|
||||
uint height;
|
||||
uint border_thickness;
|
||||
} descriptor;
|
||||
|
||||
layout (location = 0) out vec4 out_color;
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
mod position_only;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use utilities::color::Color;
|
||||
use utilities::{color::Color, impl_reprc, prelude::cgmath::vec2};
|
||||
use vulkan_rs::prelude::*;
|
||||
|
||||
use self::position_only::PositionOnlyVertex;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ElementBorderThickness {
|
||||
Pixel(u32),
|
||||
|
@ -47,6 +52,42 @@ impl ElementDescriptor {
|
|||
}
|
||||
}
|
||||
|
||||
impl_reprc!(
|
||||
pub struct FragmentShaderInfo {
|
||||
#[assume_reprc]
|
||||
background_color: [f32; 4],
|
||||
#[assume_reprc]
|
||||
border_color: [f32; 4],
|
||||
|
||||
#[assume_reprc]
|
||||
width: u32,
|
||||
#[assume_reprc]
|
||||
height: u32,
|
||||
#[assume_reprc]
|
||||
border_thickness: u32,
|
||||
}
|
||||
);
|
||||
|
||||
impl FragmentShaderInfo {
|
||||
fn color_conversion(c: Color) -> [f32; 4] {
|
||||
let a: [f32; 3] = c.into();
|
||||
|
||||
[a[0], a[1], a[2], 1.0]
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ElementDefinition> for FragmentShaderInfo {
|
||||
fn from(value: ElementDefinition) -> Self {
|
||||
Self {
|
||||
background_color: Self::color_conversion(value.background_color),
|
||||
border_color: Self::color_conversion(value.border_color),
|
||||
width: value.width,
|
||||
height: value.height,
|
||||
border_thickness: value.border_thickness,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
||||
struct ElementDefinition {
|
||||
width: u32,
|
||||
|
@ -58,19 +99,16 @@ struct ElementDefinition {
|
|||
}
|
||||
|
||||
pub struct ElementCreator {
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Mutex<Queue>>,
|
||||
|
||||
generator: Generator,
|
||||
elements: HashMap<ElementDefinition, Arc<Image>>,
|
||||
}
|
||||
|
||||
impl ElementCreator {
|
||||
pub fn new(device: Arc<Device>, queue: Arc<Mutex<Queue>>) -> Self {
|
||||
Self {
|
||||
device,
|
||||
queue,
|
||||
pub fn new(device: Arc<Device>, queue: Arc<Mutex<Queue>>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
generator: Generator::new(device, queue)?,
|
||||
elements: HashMap::new(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
|
@ -97,17 +135,13 @@ impl ElementCreator {
|
|||
match self.elements.get(&definition) {
|
||||
Some(element) => Ok(element.clone()),
|
||||
None => {
|
||||
let element = self.create_element(definition)?;
|
||||
let element = self.generator.generate(definition)?;
|
||||
self.elements.insert(definition, element.clone());
|
||||
|
||||
Ok(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_element(&self, definition: ElementDefinition) -> Result<Arc<Image>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Generator {
|
||||
|
@ -139,9 +173,66 @@ impl Generator {
|
|||
}
|
||||
|
||||
fn generate(&self, definition: ElementDefinition) -> Result<Arc<Image>> {
|
||||
// create image
|
||||
let image = self.create_image(definition.width, definition.height)?;
|
||||
|
||||
todo!()
|
||||
// create fragment shader info
|
||||
let fragment_info = Buffer::builder()
|
||||
.set_usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
|
||||
.set_memory_usage(MemoryUsage::CpuOnly)
|
||||
.set_data(&[FragmentShaderInfo::from(definition)])
|
||||
.build(self.device.clone())?;
|
||||
|
||||
// create descriptor set
|
||||
let descriptor_layout = DescriptorSetLayout::builder()
|
||||
.add_layout_binding(
|
||||
0,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0,
|
||||
)
|
||||
.build(self.device.clone())?;
|
||||
|
||||
let desc_pool = DescriptorPool::builder()
|
||||
.set_layout(descriptor_layout.clone())
|
||||
.build(self.device.clone())?;
|
||||
|
||||
let descriptor_set = desc_pool.prepare_set().allocate()?;
|
||||
descriptor_set.update(&[DescriptorWrite::uniform_buffers(0, &[&fragment_info])])?;
|
||||
|
||||
// create render target
|
||||
let render_target = self.render_target(&image)?;
|
||||
|
||||
// create pipeline
|
||||
let pipeline = self.pipeline(
|
||||
&descriptor_layout,
|
||||
&render_target,
|
||||
definition.width,
|
||||
definition.height,
|
||||
)?;
|
||||
|
||||
let vertex_buffer = self.vertex_buffer(definition.width, definition.height)?;
|
||||
|
||||
let command_buffer =
|
||||
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
|
||||
|
||||
SingleSubmit::builder(&command_buffer, &self.queue, |recorder| {
|
||||
render_target.begin(recorder, VK_SUBPASS_CONTENTS_INLINE, 0);
|
||||
|
||||
recorder.bind_pipeline(&pipeline)?;
|
||||
|
||||
recorder.bind_descriptor_sets_minimal(&[&descriptor_set]);
|
||||
recorder.bind_vertex_buffer(&vertex_buffer);
|
||||
recorder.draw_complete_single_instance(vertex_buffer.size() as u32);
|
||||
|
||||
render_target.end(recorder);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.wait_for_timeout(Duration::from_secs(5))
|
||||
.submit()?;
|
||||
|
||||
Ok(image)
|
||||
}
|
||||
|
||||
fn create_image(&self, width: u32, height: u32) -> Result<Arc<Image>> {
|
||||
|
@ -180,4 +271,66 @@ impl Generator {
|
|||
)
|
||||
.build(image.device())
|
||||
}
|
||||
|
||||
fn pipeline(
|
||||
&self,
|
||||
|
||||
descriptor_layout: &Arc<DescriptorSetLayout>,
|
||||
render_target: &RenderTarget,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result<Arc<Pipeline>> {
|
||||
let viewport = VkViewport {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
width: width as f32,
|
||||
height: height as f32,
|
||||
minDepth: 0.0,
|
||||
maxDepth: 1.0,
|
||||
};
|
||||
|
||||
let scissor = VkRect2D {
|
||||
offset: VkOffset2D { x: 0, y: 0 },
|
||||
extent: VkExtent2D { width, height },
|
||||
};
|
||||
|
||||
Pipeline::new_graphics()
|
||||
.set_vertex_shader::<PositionOnlyVertex>(self.vertex_shader.clone())
|
||||
.set_fragment_shader(self.fragment_shader.clone())
|
||||
.input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false)
|
||||
.default_depth_stencil(false, false)
|
||||
.default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()])
|
||||
.default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE)
|
||||
.default_multisample(self.max_supported_sample_count)
|
||||
.add_viewport(viewport)
|
||||
.add_scissor(scissor)
|
||||
.build(
|
||||
self.device.clone(),
|
||||
&PipelineLayout::builder()
|
||||
.add_descriptor_set_layout(&descriptor_layout)
|
||||
.build(self.device.clone())?,
|
||||
render_target.render_pass(),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
fn vertex_buffer(&self, width: u32, height: u32) -> Result<Arc<Buffer<PositionOnlyVertex>>> {
|
||||
let ortho = ortho(0.0, width as f32, 0.00, height as f32, -1.0, 1.0);
|
||||
|
||||
let vertices = PositionOnlyVertex::from_2d_corners(
|
||||
ortho,
|
||||
[
|
||||
vec2(0.0, height as f32),
|
||||
vec2(0.0, 0.0),
|
||||
vec2(width as f32, 0.0),
|
||||
vec2(width as f32, height as f32),
|
||||
],
|
||||
);
|
||||
|
||||
Buffer::builder()
|
||||
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||
.set_memory_usage(MemoryUsage::CpuOnly)
|
||||
.set_data(&vertices)
|
||||
.build(self.device.clone())
|
||||
}
|
||||
}
|
||||
|
|
67
src/element_creator/position_only.rs
Normal file
67
src/element_creator/position_only.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use std::mem;
|
||||
|
||||
use utilities::impl_reprc;
|
||||
use vulkan_rs::prelude::*;
|
||||
|
||||
impl_reprc!(
|
||||
pub struct PositionOnlyVertex {
|
||||
#[assume_reprc]
|
||||
position: cgmath::Vector4<f32>,
|
||||
}
|
||||
);
|
||||
|
||||
impl PositionOnlyVertex {
|
||||
///
|
||||
/// corners[0] - bottom left
|
||||
/// corners[1] - top left
|
||||
/// corners[2] - top right
|
||||
/// corners[3] - bottom right
|
||||
///
|
||||
pub fn from_2d_corners(
|
||||
ortho: cgmath::Matrix4<f32>,
|
||||
corners: [cgmath::Vector2<f32>; 4],
|
||||
) -> [Self; 6] {
|
||||
[
|
||||
Self {
|
||||
position: ortho * corners[0].extend(0.0).extend(1.0),
|
||||
},
|
||||
Self {
|
||||
position: ortho * corners[1].extend(0.0).extend(1.0),
|
||||
},
|
||||
Self {
|
||||
position: ortho * corners[2].extend(0.0).extend(1.0),
|
||||
},
|
||||
Self {
|
||||
position: ortho * corners[2].extend(0.0).extend(1.0),
|
||||
},
|
||||
Self {
|
||||
position: ortho * corners[3].extend(0.0).extend(1.0),
|
||||
},
|
||||
Self {
|
||||
position: ortho * corners[0].extend(0.0).extend(1.0),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl VertexInputDescription for PositionOnlyVertex {
|
||||
fn bindings() -> Vec<vulkan_rs::prelude::VkVertexInputBindingDescription> {
|
||||
vec![VkVertexInputBindingDescription {
|
||||
binding: 0,
|
||||
stride: mem::size_of::<PositionOnlyVertex>() as u32,
|
||||
inputRate: VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
}]
|
||||
}
|
||||
|
||||
fn attributes() -> Vec<vulkan_rs::prelude::VkVertexInputAttributeDescription> {
|
||||
vec![
|
||||
// position
|
||||
VkVertexInputAttributeDescription {
|
||||
location: 0,
|
||||
binding: 0,
|
||||
format: VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
offset: 0,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue