Skip to content

[WIP] Moving Device to associated types #517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/device/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl DataBuffer {

/// An interface of the abstract command buffer. It collects commands in an
/// efficient API-specific manner, to be ready for execution on the device.
pub trait CommandBuffer {
pub trait CommandBuffer<B> {
/// An empty constructor
fn new() -> Self;
/// Clear the command buffer contents, retain the allocated storage
Expand All @@ -86,9 +86,9 @@ pub trait CommandBuffer {
/// Bind an array buffer object
fn bind_array_buffer(&mut self, back::ArrayBuffer);
/// Bind a vertex attribute
fn bind_attribute(&mut self, ::AttributeSlot, back::Buffer, attrib::Format);
fn bind_attribute(&mut self, ::AttributeSlot, B, attrib::Format);
/// Bind an index buffer
fn bind_index(&mut self, back::Buffer);
fn bind_index(&mut self, B);
/// Bind a frame buffer object
fn bind_frame_buffer(&mut self, target::Access, back::FrameBuffer);
/// Unbind any surface from the specified target slot
Expand All @@ -100,7 +100,7 @@ pub trait CommandBuffer {
target::Level, Option<target::Layer>);
/// Bind a uniform block
fn bind_uniform_block(&mut self, back::Program, ::UniformBufferSlot,
::UniformBlockIndex, back::Buffer);
::UniformBlockIndex, B);
/// Bind a single uniform in the default block
fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
/// Bind a texture
Expand All @@ -124,7 +124,7 @@ pub trait CommandBuffer {
/// Set output color mask for all targets
fn set_color_mask(&mut self, ::state::ColorMask);
/// Update a vertex/index/uniform buffer
fn update_buffer(&mut self, back::Buffer, DataPointer, usize);
fn update_buffer(&mut self, B, DataPointer, usize);
/// Update a texture region
fn update_texture(&mut self, tex::TextureKind, back::Texture,
tex::ImageInfo, DataPointer);
Expand Down
14 changes: 8 additions & 6 deletions src/device/gl_device/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
use Command;
use std::slice;

type Buffer = <super::GlDevice as ::Device>::Buffer;

pub struct GlCommandBuffer {
buf: Vec<::Command>,
buf: Vec<::Command<Buffer>>,
}

impl GlCommandBuffer {
Expand All @@ -27,7 +29,7 @@ impl GlCommandBuffer {
}
}

impl ::draw::CommandBuffer for GlCommandBuffer {
impl ::draw::CommandBuffer<Buffer> for GlCommandBuffer {
fn new() -> GlCommandBuffer {
GlCommandBuffer {
buf: Vec::new(),
Expand All @@ -46,12 +48,12 @@ impl ::draw::CommandBuffer for GlCommandBuffer {
self.buf.push(Command::BindArrayBuffer(vao));
}

fn bind_attribute(&mut self, slot: ::AttributeSlot, buf: super::Buffer,
fn bind_attribute(&mut self, slot: ::AttributeSlot, buf: Buffer,
format: ::attrib::Format) {
self.buf.push(Command::BindAttribute(slot, buf, format));
}

fn bind_index(&mut self, buf: super::Buffer) {
fn bind_index(&mut self, buf: Buffer) {
self.buf.push(Command::BindIndex(buf));
}

Expand All @@ -75,7 +77,7 @@ impl ::draw::CommandBuffer for GlCommandBuffer {
}

fn bind_uniform_block(&mut self, prog: super::Program, slot: ::UniformBufferSlot,
index: ::UniformBlockIndex, buf: super::Buffer) {
index: ::UniformBlockIndex, buf: Buffer) {
self.buf.push(Command::BindUniformBlock(prog, slot, index, buf));
}

Expand Down Expand Up @@ -120,7 +122,7 @@ impl ::draw::CommandBuffer for GlCommandBuffer {
self.buf.push(Command::SetColorMask(mask));
}

fn update_buffer(&mut self, buf: super::Buffer, data: ::draw::DataPointer,
fn update_buffer(&mut self, buf: Buffer, data: ::draw::DataPointer,
offset_bytes: usize) {
self.buf.push(Command::UpdateBuffer(buf, data, offset_bytes));
}
Expand Down
5 changes: 3 additions & 2 deletions src/device/gl_device/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub struct RawMapping {
target: gl::types::GLenum,
}

pub type Buffer = gl::types::GLuint;
pub type ArrayBuffer = gl::types::GLuint;
pub type Shader = gl::types::GLuint;
pub type Program = gl::types::GLuint;
Expand Down Expand Up @@ -567,6 +566,7 @@ impl GlDevice {
}

impl Device for GlDevice {
type Buffer = gl::types::GLuint;
type CommandBuffer = GlCommandBuffer;

fn get_capabilities<'a>(&'a self) -> &'a ::Capabilities {
Expand All @@ -587,7 +587,8 @@ impl Device for GlDevice {
}
}

fn create_buffer_raw(&mut self, size: usize, usage: BufferUsage) -> ::BufferHandle<()> {
fn create_buffer_raw(&mut self, size: usize, usage: BufferUsage)
-> ::BufferHandle<<Self as Device>::Buffer, ()> {
let name = self.create_buffer_internal();
let info = ::BufferInfo {
usage: usage,
Expand Down
79 changes: 48 additions & 31 deletions src/device/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,25 @@ impl<T: Copy, I> Handle<T, I> {

/// Type-safe buffer handle
#[derive(Copy, Debug, PartialEq, Clone)]
pub struct BufferHandle<T> {
raw: RawBufferHandle,
pub struct BufferHandle<B, T> {
raw: RawBufferHandle<B>,
}

impl<T> BufferHandle<T> {
impl<B, T> BufferHandle<B, T> {
/// Create a type-safe BufferHandle from a RawBufferHandle
pub fn from_raw(handle: RawBufferHandle) -> BufferHandle<T> {
pub fn from_raw(handle: RawBufferHandle<B>) -> BufferHandle<B, T> {
BufferHandle {
raw: handle,
}
}

/// Cast the type this BufferHandle references
pub fn cast<U>(self) -> BufferHandle<U> {
pub fn cast<U>(self) -> BufferHandle<B, U> {
BufferHandle::from_raw(self.raw)
}

/// Get the underlying GL name for this BufferHandle
pub fn get_name(&self) -> back::Buffer {
pub fn get_name(&self) -> B {
self.raw.get_name()
}

Expand All @@ -187,7 +187,7 @@ impl<T> BufferHandle<T> {
}

/// Get the underlying raw Handle
pub fn raw(&self) -> RawBufferHandle {
pub fn raw(&self) -> RawBufferHandle<B> {
self.raw
}

Expand All @@ -200,8 +200,8 @@ impl<T> BufferHandle<T> {
}
}

/// Raw (untyped) Buffer Handle
pub type RawBufferHandle = Handle<back::Buffer, BufferInfo>;
/// Raw (untyped) buffer handle
pub type RawBufferHandle<B> = Handle<B, BufferInfo>;
/// Array Buffer Handle
pub type ArrayBufferHandle = Handle<back::ArrayBuffer, ()>;
/// Shader Handle
Expand Down Expand Up @@ -321,11 +321,11 @@ pub struct BufferInfo {
/// such as OpenGL (prior to GLNG) and DirectX (prior to DX12)
#[allow(missing_docs)]
#[derive(Copy, Debug)]
pub enum Command {
pub enum Command<B> {
BindProgram(back::Program),
BindArrayBuffer(back::ArrayBuffer),
BindAttribute(AttributeSlot, back::Buffer, attrib::Format),
BindIndex(back::Buffer),
BindAttribute(AttributeSlot, B, attrib::Format),
BindIndex(B),
BindFrameBuffer(target::Access, back::FrameBuffer),
/// Unbind any surface from the specified target slot
UnbindTarget(target::Access, target::Target),
Expand All @@ -334,7 +334,7 @@ pub enum Command {
/// Bind a level of the texture to the specified target slot
BindTargetTexture(target::Access, target::Target, back::Texture,
target::Level, Option<target::Layer>),
BindUniformBlock(back::Program, UniformBufferSlot, UniformBlockIndex, back::Buffer),
BindUniformBlock(back::Program, UniformBufferSlot, UniformBlockIndex, B),
BindUniform(shade::Location, shade::UniformValue),
BindTexture(TextureSlot, tex::TextureKind, back::Texture, Option<SamplerHandle>),
SetDrawColorBuffers(usize),
Expand All @@ -345,7 +345,7 @@ pub enum Command {
SetDepthStencilState(Option<state::Depth>, Option<state::Stencil>, state::CullMode),
SetBlendState(Option<state::Blend>),
SetColorMask(state::ColorMask),
UpdateBuffer(back::Buffer, draw::DataPointer, usize),
UpdateBuffer(B, draw::DataPointer, usize),
UpdateTexture(tex::TextureKind, back::Texture, tex::ImageInfo, draw::DataPointer),
// drawing
Clear(target::ClearData, target::Mask),
Expand All @@ -357,8 +357,10 @@ pub enum Command {
/// An interface for performing draw calls using a specific graphics API
#[allow(missing_docs)]
pub trait Device {

type CommandBuffer: draw::CommandBuffer;
/// Raw buffer
type Buffer;
/// Command buffer to collect calls and data
type CommandBuffer: draw::CommandBuffer<Self::Buffer>;

/// Returns the capabilities available to the specific API implementation
fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
Expand All @@ -368,12 +370,16 @@ pub trait Device {
fn submit(&mut self, buffer: (&Self::CommandBuffer, &draw::DataBuffer));

// resource creation
fn create_buffer_raw(&mut self, size: usize, usage: BufferUsage) -> BufferHandle<()>;
fn create_buffer<T>(&mut self, num: usize, usage: BufferUsage) -> BufferHandle<T> {
fn create_buffer_raw(&mut self, size: usize, usage: BufferUsage)
-> BufferHandle<Self::Buffer, ()>;
fn create_buffer<T>(&mut self, num: usize, usage: BufferUsage)
-> BufferHandle<Self::Buffer, T> {
self.create_buffer_raw(num * mem::size_of::<T>(), usage).cast()
}
fn create_buffer_static_raw(&mut self, data: &[u8]) -> BufferHandle<()>;
fn create_buffer_static<T: Copy>(&mut self, data: &[T]) -> BufferHandle<T> {
fn create_buffer_static_raw(&mut self, data: &[u8])
-> BufferHandle<Self::Buffer, ()>;
fn create_buffer_static<T: Copy>(&mut self, data: &[T])
-> BufferHandle<Self::Buffer, T> {
self.create_buffer_static_raw(as_byte_slice(data)).cast()
}
fn create_array_buffer(&mut self) -> Result<ArrayBufferHandle, ()>;
Expand All @@ -386,8 +392,8 @@ pub trait Device {
fn create_sampler(&mut self, info: tex::SamplerInfo) -> SamplerHandle;

// resource deletion
fn delete_buffer_raw(&mut self, buf: BufferHandle<()>);
fn delete_buffer<T>(&mut self, buf: BufferHandle<T>) {
fn delete_buffer_raw(&mut self, buf: BufferHandle<Self::Buffer, ()>);
fn delete_buffer<T>(&mut self, buf: BufferHandle<Self::Buffer, T>) {
self.delete_buffer_raw(buf.cast());
}
fn delete_shader(&mut self, ShaderHandle);
Expand All @@ -397,17 +403,27 @@ pub trait Device {
fn delete_sampler(&mut self, SamplerHandle);

/// Update the information stored in a specific buffer
fn update_buffer_raw(&mut self, buf: BufferHandle<()>, data: &[u8],
fn update_buffer_raw(&mut self, buf: BufferHandle<Self::Buffer, ()>, data: &[u8],
offset_bytes: usize);
fn update_buffer<T: Copy>(&mut self, buf: BufferHandle<T>, data: &[T],
offset_elements: usize) {
self.update_buffer_raw(buf.cast(), as_byte_slice(data), mem::size_of::<T>() * offset_elements)
fn update_buffer<T: Copy>(&mut self, buf: BufferHandle<Self::Buffer, T>,
data: &[T], offset_elements: usize) {
self.update_buffer_raw(
buf.cast(),
as_byte_slice(data),
mem::size_of::<T>() * offset_elements
)
}
fn map_buffer_raw(&mut self, buf: BufferHandle<()>, access: MapAccess) -> back::RawMapping;
fn map_buffer_raw(&mut self, buf: BufferHandle<Self::Buffer, ()>,
access: MapAccess) -> back::RawMapping;
fn unmap_buffer_raw(&mut self, map: back::RawMapping);
fn map_buffer_readable<T: Copy>(&mut self, buf: BufferHandle<T>) -> ReadableMapping<T, Self>;
fn map_buffer_writable<T: Copy>(&mut self, buf: BufferHandle<T>) -> WritableMapping<T, Self>;
fn map_buffer_rw<T: Copy>(&mut self, buf: BufferHandle<T>) -> RWMapping<T, Self>;
fn map_buffer_readable<T: Copy>(&mut self,
buf: BufferHandle<Self::Buffer, T>)
-> ReadableMapping<T, Self>;
fn map_buffer_writable<T: Copy>(&mut self,
buf: BufferHandle<Self::Buffer, T>)
-> WritableMapping<T, Self>;
fn map_buffer_rw<T: Copy>(&mut self, buf: BufferHandle<Self::Buffer, T>)
-> RWMapping<T, Self>;

/// Update the information stored in a texture
fn update_texture_raw(&mut self, tex: &TextureHandle, img: &tex::ImageInfo,
Expand All @@ -426,7 +442,8 @@ mod test {
use super::{BufferHandle, Handle};
use super::{BufferInfo, BufferUsage};

fn mock_buffer<T>(usage: BufferUsage, len: usize) -> BufferHandle<T> {
fn mock_buffer<T>(usage: BufferUsage, len: usize)
-> BufferHandle<Self::Buffer, T> {
BufferHandle {
raw: Handle(
0,
Expand Down