Skip to content

Commit 8c8281c

Browse files
committed
hal: Improve buffer documentation and cleanup error handling
1 parent 5297132 commit 8c8281c

File tree

8 files changed

+75
-83
lines changed

8 files changed

+75
-83
lines changed

src/backend/dx11/src/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ impl hal::Device<Backend> for Device {
666666
buffer: &Buffer,
667667
format: Option<format::Format>,
668668
range: R,
669-
) -> Result<BufferView, buffer::ViewError> {
669+
) -> Result<BufferView, buffer::ViewCreationError> {
670670
unimplemented!()
671671
}
672672

src/backend/dx12/src/device.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1910,14 +1910,14 @@ impl d::Device<B> for Device {
19101910
buffer: &n::Buffer,
19111911
format: Option<format::Format>,
19121912
range: R,
1913-
) -> Result<n::BufferView, buffer::ViewError> {
1913+
) -> Result<n::BufferView, buffer::ViewCreationError> {
19141914
let buffer_features = {
19151915
let idx = format.map(|fmt| fmt as usize).unwrap_or(0);
19161916
self.format_properties[idx].buffer_features
19171917
};
19181918
let (format, format_desc) = match format.and_then(conv::map_format) {
19191919
Some(fmt) => (fmt, format.unwrap().surface_desc()),
1920-
None => return Err(buffer::ViewError::Unsupported),
1920+
None => return Err(buffer::ViewCreationError::UnsupportedFormat { format }),
19211921
};
19221922

19231923
let start = *range.start().unwrap_or(&0);

src/backend/empty/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl hal::Device<Backend> for Device {
177177
unimplemented!()
178178
}
179179

180-
fn create_buffer_view<R: RangeArg<u64>>(&self, _: &(), _: Option<format::Format>, _: R) -> Result<(), buffer::ViewError> {
180+
fn create_buffer_view<R: RangeArg<u64>>(&self, _: &(), _: Option<format::Format>, _: R) -> Result<(), buffer::ViewCreationError> {
181181
unimplemented!()
182182
}
183183

src/backend/gl/src/device.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -672,16 +672,15 @@ impl d::Device<B> for Device {
672672
) -> Result<UnboundBuffer, buffer::CreationError> {
673673
if !self.share.legacy_features.contains(LegacyFeatures::CONSTANT_BUFFER) &&
674674
usage.contains(buffer::Usage::UNIFORM) {
675-
error!("Constant buffers are not supported by this GL version");
676-
return Err(buffer::CreationError::Other);
675+
return Err(buffer::CreationError::UnsupportedUsage { usage });
677676
}
678677

679678
let target = if self.share.private_caps.buffer_role_change {
680679
gl::ARRAY_BUFFER
681680
} else {
682681
match conv::buffer_usage_to_gl_target(usage) {
683682
Some(target) => target,
684-
None => return Err(buffer::CreationError::Usage(usage)),
683+
None => return Err(buffer::CreationError::UnsupportedUsage { usage }),
685684
}
686685
};
687686

@@ -838,7 +837,7 @@ impl d::Device<B> for Device {
838837

839838
fn create_buffer_view<R: RangeArg<u64>>(
840839
&self, _: &n::Buffer, _: Option<Format>, _: R
841-
) -> Result<n::BufferView, buffer::ViewError> {
840+
) -> Result<n::BufferView, buffer::ViewCreationError> {
842841
unimplemented!()
843842
}
844843

src/backend/metal/src/device.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ fn create_depth_stencil_state(
166166
raw.set_front_face_stencil(Some(&front_desc));
167167

168168
let back_desc = metal::StencilDescriptor::new();
169-
back_desc.set_stencil_compare_function(conv::map_compare_function(back.fun));
169+
back_desc.set_stencil_compare_function(conv::map_compare_function(back.fun));
170170

171171
dss.stencil.back_read_mask = back.mask_read;
172172
match back.mask_read {
@@ -1667,22 +1667,22 @@ impl hal::Device<Backend> for Device {
16671667

16681668
fn create_buffer_view<R: RangeArg<u64>>(
16691669
&self, buffer: &n::Buffer, format_maybe: Option<format::Format>, range: R
1670-
) -> Result<n::BufferView, buffer::ViewError> {
1670+
) -> Result<n::BufferView, buffer::ViewCreationError> {
16711671
let start = buffer.range.start + *range.start().unwrap_or(&0);
16721672
let end_rough = *range.end().unwrap_or(&buffer.raw.length());
16731673
let format = match format_maybe {
16741674
Some(fmt) => fmt,
1675-
None => return Err(buffer::ViewError::Unsupported),
1675+
None => return Err(buffer::ViewCreationError::UnsupportedFormat { format: format_maybe }),
16761676
};
16771677
let format_desc = format.surface_desc();
16781678
if format_desc.aspects != format::Aspects::COLOR {
16791679
// no depth/stencil support for buffer views here
1680-
return Err(buffer::ViewError::Unsupported)
1680+
return Err(buffer::ViewCreationError::UnsupportedFormat { format: format_maybe })
16811681
}
16821682
let block_count = (end_rough - start) * 8 / format_desc.bits as u64;
16831683
let mtl_format = self.private_caps
16841684
.map_format(format)
1685-
.ok_or(buffer::ViewError::Unsupported)?;
1685+
.ok_or(buffer::ViewCreationError::UnsupportedFormat { format: format_maybe })?;
16861686

16871687
let descriptor = metal::TextureDescriptor::new();
16881688
descriptor.set_texture_type(MTLTextureType::D2);

src/backend/vulkan/src/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ impl d::Device<B> for Device {
930930

931931
fn create_buffer_view<R: RangeArg<u64>>(
932932
&self, buffer: &n::Buffer, format: Option<format::Format>, range: R
933-
) -> Result<n::BufferView, buffer::ViewError> {
933+
) -> Result<n::BufferView, buffer::ViewCreationError> {
934934
let (offset, size) = conv::map_range_arg(&range);
935935
let info = vk::BufferViewCreateInfo {
936936
s_type: vk::StructureType::BufferViewCreateInfo,

src/hal/src/buffer.rs

+59-68
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,58 @@
1-
//! Memory buffers
1+
//! Memory buffers.
2+
//!
3+
//! # Buffer
4+
//!
5+
//! Buffers interpret memory slices as linear continguous data array.
6+
//! They can be used as shader resources, vertex buffers, index buffers or for
7+
//! specifying the action commands for indirect exection.
28
3-
use std::error::Error;
4-
use std::fmt;
5-
6-
use {IndexType, Backend};
9+
use {format, IndexType, Backend};
710

811

912
/// An offset inside a buffer, in bytes.
1013
pub type Offset = u64;
1114

15+
/// Buffer state.
16+
pub type State = Access;
17+
1218
/// Error creating a buffer.
13-
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
19+
#[derive(Fail, Debug, Clone, PartialEq, Eq)]
1420
pub enum CreationError {
15-
/// Required `Usage` is not supported.
16-
Usage(Usage),
17-
/// Some other problem.
18-
Other,
19-
}
20-
21-
impl fmt::Display for CreationError {
22-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23-
let description = self.description();
24-
match *self {
25-
CreationError::Usage(usage) => write!(f, "{}: {:?}", description, usage),
26-
_ => write!(f, "{}", description)
27-
}
28-
}
21+
/// Memory allocation on the host side failed.
22+
/// This could be caused by a lack of memory.
23+
#[fail(display = "Host memory allocation failed.")]
24+
OutOfHostMemory,
25+
/// Memory allocation on the device side failed.
26+
/// This could be caused by a lack of memory.
27+
#[fail(display = "Device memory allocation failed.")]
28+
OutOfDeviceMemory,
29+
/// Requested buffer usage is not supported.
30+
///
31+
/// Older GL version don't support constant buffers or multiple usage flags.
32+
#[fail(display = "Buffer usage unsupported ({:?}).", usage)]
33+
UnsupportedUsage {
34+
/// Unsupported usage passed on buffer creation.
35+
usage: Usage,
36+
},
2937
}
3038

31-
impl Error for CreationError {
32-
fn description(&self) -> &str {
33-
match *self {
34-
CreationError::Usage(_) =>
35-
"Required `Usage` is not supported",
36-
CreationError::Other =>
37-
"Some other problem",
38-
}
39-
}
40-
}
41-
42-
/// Error creating a `BufferView`.
43-
#[derive(Clone, Debug, PartialEq)]
44-
pub enum ViewError {
45-
/// The required usage flag is not present in the image.
46-
Usage(Usage),
47-
/// The backend refused for some reason.
48-
Unsupported,
49-
}
50-
51-
impl fmt::Display for ViewError {
52-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53-
let description = self.description();
54-
match *self {
55-
ViewError::Usage(usage) => write!(f, "{}: {:?}", description, usage),
56-
_ => write!(f, "{}", description)
57-
}
58-
}
59-
}
60-
61-
impl Error for ViewError {
62-
fn description(&self) -> &str {
63-
match *self {
64-
ViewError::Usage(_) =>
65-
"The required usage flag is not present in the image",
66-
ViewError::Unsupported =>
67-
"The backend refused for some reason",
68-
}
69-
}
39+
/// Error creating a buffer view.
40+
#[derive(Fail, Debug, Clone, PartialEq, Eq)]
41+
pub enum ViewCreationError {
42+
/// Memory allocation on the host side failed.
43+
/// This could be caused by a lack of memory.
44+
#[fail(display = "Host memory allocation failed.")]
45+
OutOfHostMemory,
46+
/// Memory allocation on the device side failed.
47+
/// This could be caused by a lack of memory.
48+
#[fail(display = "Device memory allocation failed.")]
49+
OutOfDeviceMemory,
50+
/// Buffer view format is not supported.
51+
#[fail(display = "Buffer view format unsupported ({:?}).", format)]
52+
UnsupportedFormat {
53+
/// Unsupported format passed on view creation.
54+
format: Option<format::Format>,
55+
},
7056
}
7157

7258
bitflags!(
@@ -95,21 +81,27 @@ bitflags!(
9581
);
9682

9783
impl Usage {
98-
/// Can this buffer be used in transfer operations ?
84+
/// Returns if the buffer can be used in transfer operations.
9985
pub fn can_transfer(&self) -> bool {
10086
self.intersects(Usage::TRANSFER_SRC | Usage::TRANSFER_DST)
10187
}
10288
}
10389

10490
bitflags!(
105-
/// Buffer state flags.
91+
/// Buffer access flags.
92+
///
93+
/// Access of buffers by the pipeline or shaders.
10694
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10795
pub struct Access: u32 {
108-
///
96+
/// Read commands instruction for indirect execution.
10997
const INDIRECT_COMMAND_READ = 0x1;
98+
/// Read index values for indexed draw commands.
11099
///
100+
/// See [`draw_indexed`](../command/trait.RawCommandBuffer.html#tymethod.draw_indexed)
101+
/// and [`draw_indexed_indirect`](../command/trait.RawCommandBuffer.html#tymethod.draw_indexed_indirect).
111102
const INDEX_BUFFER_READ = 0x2;
112-
///
103+
/// Read vertices from vertex buffer for draw commands in the [`VERTEX_INPUT`](
104+
/// ../pso/struct.PipelineStage.html#associatedconstant.VERTEX_INPUT) stage.
113105
const VERTEX_BUFFER_READ = 0x4;
114106
///
115107
const CONSTANT_BUFFER_READ = 0x8;
@@ -132,11 +124,10 @@ bitflags!(
132124
}
133125
);
134126

135-
/// Buffer state
136-
pub type State = Access;
137-
138-
/// Index buffer view for `bind_index_buffer`, slightly
139-
/// analogous to an index table into an array.
127+
/// Index buffer view for `bind_index_buffer`.
128+
///
129+
/// Defines a buffer slice used for acquiring the indicies on draw commands.
130+
/// Indices are used to lookup vertex indices in the vertex buffers.
140131
pub struct IndexBufferView<'a, B: Backend> {
141132
/// The buffer to bind.
142133
pub buffer: &'a B::Buffer,

src/hal/src/device.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Logical device
2+
//!
13
//! # Device
24
//!
35
//! This module exposes the `Device` trait, which provides methods for creating
@@ -306,7 +308,7 @@ pub trait Device<B: Backend>: Any + Send + Sync {
306308
///
307309
fn create_buffer_view<R: RangeArg<u64>>(
308310
&self, buf: &B::Buffer, fmt: Option<format::Format>, range: R
309-
) -> Result<B::BufferView, buffer::ViewError>;
311+
) -> Result<B::BufferView, buffer::ViewCreationError>;
310312

311313
///
312314
fn destroy_buffer_view(&self, view: B::BufferView);

0 commit comments

Comments
 (0)