1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#![deny(unsafe_code)]
use crate::error::*;
use crate::graphics::render_state::RenderState;
use crate::linear_algebra::{ Vec3, Vec4, Transformation };
use crate::shader_data::VertexPushBlock;
use std::f32::consts::{ TAU };
use std::mem::size_of;
use vulkanalia::Device;
use vulkanalia::vk::{ self, HasBuilder, DeviceV1_0 };
#[allow(unsafe_code)]
pub fn generate_scene_commands<'a>(image_index: usize, time: f32,
render_state: &'a RenderState,
device: &Device, extent: &vk::Extent2D)
-> Result<&'a vk::CommandBuffer>
{
let command_buffer = &render_state.command_buffers[image_index];
let framebuffer = &render_state.framebuffers[image_index];
let descriptor_set = &render_state.descriptor_sets[image_index];
let inheritance_info = vk::CommandBufferInheritanceInfo::builder();
let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder()
.flags(vk::CommandBufferUsageFlags::empty())
.inheritance_info(&inheritance_info);
unsafe {
device.begin_command_buffer(*command_buffer, &command_buffer_begin_info)
}?;
let render_area = vk::Rect2D::builder()
.offset(vk::Offset2D::default())
.extent(*extent);
let color_clear_value = vk::ClearValue {
color: vk::ClearColorValue {
float32: [0.0, 0.0, 0.0, 1.0]
}
};
let depth_clear_value = vk::ClearValue {
depth_stencil: vk::ClearDepthStencilValue {
depth: 1.0,
stencil: 0,
}
};
let clear_values = [color_clear_value, depth_clear_value];
let begin_pass_info = vk::RenderPassBeginInfo::builder()
.render_pass(render_state.render_pass)
.framebuffer(*framebuffer)
.render_area(render_area)
.clear_values(&clear_values);
unsafe {
device.cmd_begin_render_pass(*command_buffer, &begin_pass_info,
vk::SubpassContents::INLINE)
};
unsafe {
device.cmd_bind_pipeline(*command_buffer,
vk::PipelineBindPoint::GRAPHICS,
render_state.pipeline)
};
unsafe {
device.cmd_bind_vertex_buffers(*command_buffer, 0,
&[render_state.vertex_buffer], &[0])
};
unsafe {
device.cmd_bind_index_buffer(*command_buffer, render_state.index_buffer,
0, vk::IndexType::UINT32)
};
unsafe {
device.cmd_bind_descriptor_sets(*command_buffer,
vk::PipelineBindPoint::GRAPHICS,
render_state.pipeline_layout,
0,
&[*descriptor_set],
&[])
};
let scale = Vec3::new(1.0, 1.0, 1.0);
let model = Transformation {
rotation: Vec4::rotation_quaternion(&Vec3::new(0.0, 1.0, 0.0), time % TAU),
translation: Vec3::new(0.0, 0.0, 0.0),
};
let push_block = VertexPushBlock::<f32> { scale, model };
let size = size_of::<VertexPushBlock::<f32>>();
let push_block_bytes = unsafe {
std::slice::from_raw_parts(&push_block as *const VertexPushBlock<f32>
as *const u8,
size)
};
unsafe {
device.cmd_push_constants(*command_buffer, render_state.pipeline_layout,
vk::ShaderStageFlags::VERTEX,
0,
push_block_bytes)
};
unsafe {
device.cmd_draw_indexed(*command_buffer, render_state.index_count as u32,
1, 0, 0, 0)
};
unsafe { device.cmd_end_render_pass(*command_buffer) };
unsafe { device.end_command_buffer(*command_buffer) }?;
Ok(command_buffer)
}
|