1- pub struct Buffer ;
1+ use gfx_hal:: {
2+ memory:: SparseFlags ,
3+ Backend ,
4+ } ;
5+
6+ use super :: gpu:: Gpu ;
7+
8+ // Reuse gfx-hal buffer usage & properties for now.
9+ pub type Usage = gfx_hal:: buffer:: Usage ;
10+ pub type Properties = gfx_hal:: memory:: Properties ;
11+
12+ /// A buffer is a block of memory that can be used to store data that can be
13+ /// accessed by the GPU.
14+ pub struct Buffer < RenderBackend : super :: internal:: Backend > {
15+ buffer : RenderBackend :: Buffer ,
16+ memory : RenderBackend :: Memory ,
17+ }
218
319pub struct BufferBuilder {
420 buffer_length : usize ,
5- usage : gfx_hal:: buffer:: Usage ,
21+ usage : Usage ,
22+ properties : Properties ,
623}
724
825impl BufferBuilder {
926 pub fn new ( ) -> Self {
1027 return Self {
1128 buffer_length : 0 ,
1229 usage : gfx_hal:: buffer:: Usage :: empty ( ) ,
30+ properties : gfx_hal:: memory:: Properties :: empty ( ) ,
1331 } ;
1432 }
1533
@@ -18,15 +36,79 @@ impl BufferBuilder {
1836 return self ;
1937 }
2038
21- pub fn with_usage ( & mut self , usage : gfx_hal :: buffer :: Usage ) -> & mut Self {
39+ pub fn with_usage ( & mut self , usage : Usage ) -> & mut Self {
2240 self . usage = usage;
2341 return self ;
2442 }
2543
44+ pub fn with_properties ( & mut self , properties : Properties ) -> & mut Self {
45+ return self ;
46+ }
47+
2648 pub fn build < RenderBackend : super :: internal:: Backend > (
2749 self ,
28- device : & mut RenderBackend :: Device ,
29- ) -> Buffer {
30- todo ! ( ) ;
50+ gpu : & mut Gpu < RenderBackend > ,
51+ ) -> Result < Buffer < RenderBackend > , & ' static str > {
52+ use gfx_hal:: {
53+ adapter:: PhysicalDevice ,
54+ device:: Device ,
55+ MemoryTypeId ,
56+ } ;
57+ let logical_device = super :: internal:: logical_device_for ( gpu) ;
58+ let physical_device = super :: internal:: physical_device_for ( gpu) ;
59+
60+ // Allocate buffer
61+ let mut buffer_result = unsafe {
62+ logical_device. create_buffer (
63+ self . buffer_length as u64 ,
64+ self . usage ,
65+ SparseFlags :: empty ( ) ,
66+ )
67+ } ;
68+
69+ if buffer_result. is_err ( ) {
70+ return Err ( "Failed to create buffer for allocating memory." ) ;
71+ }
72+
73+ let mut buffer = buffer_result. unwrap ( ) ;
74+
75+ let requirements =
76+ unsafe { logical_device. get_buffer_requirements ( & buffer) } ;
77+ let memory_types = physical_device. memory_properties ( ) . memory_types ;
78+
79+ // Find a memory type that supports the requirements of the buffer.
80+ let memory_type = memory_types
81+ . iter ( )
82+ . enumerate ( )
83+ . find ( |( id, memory_type) | {
84+ let type_supported = requirements. type_mask & ( 1 << id) != 0 ;
85+ type_supported && memory_type. properties . contains ( self . properties )
86+ } )
87+ . map ( |( id, _) | MemoryTypeId ( id) )
88+ . unwrap ( ) ;
89+
90+ let buffer_memory_allocation =
91+ unsafe { logical_device. allocate_memory ( memory_type, requirements. size ) } ;
92+
93+ if buffer_memory_allocation. is_err ( ) {
94+ return Err ( "Failed to allocate memory for buffer." ) ;
95+ }
96+
97+ let buffer_memory = buffer_memory_allocation. unwrap ( ) ;
98+
99+ let buffer_binding = unsafe {
100+ logical_device. bind_buffer_memory ( & buffer_memory, 0 , & mut buffer)
101+ } ;
102+
103+ // Destroy the buffer if we failed to bind it to memory.
104+ if buffer_binding. is_err ( ) {
105+ unsafe { logical_device. destroy_buffer ( buffer) } ;
106+ return Err ( "Failed to bind buffer memory." ) ;
107+ }
108+
109+ return Ok ( Buffer {
110+ buffer,
111+ memory : buffer_memory,
112+ } ) ;
31113 }
32114}
0 commit comments