Skip to content

[WIP] Use associated types for device resources #562

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 2 commits 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
2 changes: 1 addition & 1 deletion src/device/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub trait CommandBuffer {
fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
/// Bind a texture
fn bind_texture(&mut self, ::TextureSlot, tex::TextureKind, back::Texture,
Option<::SamplerHandle>);
Option<::SamplerHandle<back::GlDevice>>);
/// Select, which color buffers are going to be targetted by the shader
fn set_draw_color_buffers(&mut self, usize);
/// Set primitive topology
Expand Down
6 changes: 3 additions & 3 deletions src/device/gl_device/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ use Command;
use std::slice;

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

impl GlCommandBuffer {
pub fn iter<'a>(&'a self) -> slice::Iter<'a, ::Command> {
pub fn iter<'a>(&'a self) -> slice::Iter<'a, ::Command<super::GlDevice>> {
self.buf.iter()
}
}
Expand Down Expand Up @@ -83,7 +83,7 @@ impl ::draw::CommandBuffer for GlCommandBuffer {
self.buf.push(Command::BindUniform(loc, value));
}
fn bind_texture(&mut self, slot: ::TextureSlot, kind: ::tex::TextureKind,
tex: super::Texture, sampler: Option<::SamplerHandle>) {
tex: super::Texture, sampler: Option<::SamplerHandle<super::GlDevice>>) {
self.buf.push(Command::BindTexture(slot, kind, tex, sampler));
}

Expand Down
110 changes: 60 additions & 50 deletions src/device/gl_device/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern crate libc;
extern crate "gfx_gl" as gl;

use log::LogLevel;
use std::fmt;

use attrib::{SignFlag, IntSubType, IntSize, FloatSubType, FloatSize, Type};
use state::{CullMode, RasterMethod, WindingOrder};
Expand Down Expand Up @@ -82,29 +83,6 @@ impl GlError {
}
}

static RESET_CB: &'static [Command] = &[
Command::BindProgram(0),
Command::BindArrayBuffer(0),
//BindAttribute
Command::BindIndex(0),
Command::BindFrameBuffer(Access::Draw, 0),
Command::BindFrameBuffer(Access::Read, 0),
//UnbindTarget
//BindUniformBlock
//BindUniform
//BindTexture
Command::SetPrimitiveState(::state::Primitive {
front_face: WindingOrder::CounterClockwise,
method: RasterMethod::Fill(CullMode::Back),
offset: None,
}),
Command::SetViewport(::target::Rect{x: 0, y: 0, w: 0, h: 0}),
Command::SetScissor(None),
Command::SetDepthStencilState(None, None, CullMode::Nothing),
Command::SetBlendState(None),
Command::SetColorMask(::state::MASK_ALL),
];

fn primitive_to_gl(prim_type: ::PrimitiveType) -> gl::types::GLenum {
match prim_type {
PrimitiveType::Point => gl::POINTS,
Expand Down Expand Up @@ -139,6 +117,12 @@ pub struct GlDevice {
gl: gl::Gl,
}

impl fmt::Debug for GlDevice {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "GlDevice {{ info: {:?}, caps: {:?}, gl: Gl {{ ... }} }}", self.info, self.caps)
}
}

impl GlDevice {
/// Load OpenGL symbols and detect driver information
pub fn new<F>(fn_proc: F) -> GlDevice where F: FnMut(&str) -> *const ::libc::c_void {
Expand Down Expand Up @@ -170,7 +154,7 @@ impl GlDevice {
}

/// Fails during a debug build if the implementation's error flag was set.
fn check(&mut self, cmd: &::Command) {
fn check(&mut self, cmd: &::Command<GlDevice>) {
if cfg!(not(ndebug)) {
let err = GlError::from_error_code(unsafe { self.gl.GetError() });
if err != GlError::NoError {
Expand Down Expand Up @@ -221,7 +205,7 @@ impl GlDevice {
}
}

fn process(&mut self, cmd: &::Command, data_buf: &::draw::DataBuffer) {
fn process(&mut self, cmd: &::Command<GlDevice>, data_buf: &::draw::DataBuffer) {
match *cmd {
Command::Clear(ref data, mask) => {
let mut flags = 0;
Expand Down Expand Up @@ -569,15 +553,41 @@ impl GlDevice {
impl Device for GlDevice {
type CommandBuffer = GlCommandBuffer;

type Buffer = Buffer;
type ArrayBuffer = ArrayBuffer;
type Shader = Shader;
type Program = Program;
type FrameBuffer = FrameBuffer;
type Surface = Surface;
type Texture = Texture;
type Sampler = Sampler;

fn get_capabilities<'a>(&'a self) -> &'a ::Capabilities {
&self.caps
}

fn reset_state(&mut self) {
let data = ::draw::DataBuffer::new();
for com in RESET_CB.iter() {
self.process(com, &data);
}
self.process(&Command::BindProgram(0), &data);
self.process(&Command::BindArrayBuffer(0), &data);
// self.process(&command::BindAttribute, &data);
self.process(&Command::BindIndex(0), &data);
self.process(&Command::BindFrameBuffer(Access::Draw, 0), &data);
self.process(&Command::BindFrameBuffer(Access::Read, 0), &data);
// self.process(&command::UnbindTarget, &data);
// self.process(&command::BindUniformBlock, &data);
// self.process(&command::BindUniform, &data);
// self.process(&command::BindTexture, &data);
self.process(&Command::SetPrimitiveState(::state::Primitive {
front_face: WindingOrder::CounterClockwise,
method: RasterMethod::Fill(CullMode::Back),
offset: None,
}), &data);
self.process(&Command::SetViewport(::target::Rect{x: 0, y: 0, w: 0, h: 0}), &data);
self.process(&Command::SetScissor(None), &data);
self.process(&Command::SetDepthStencilState(None, None, CullMode::Nothing), &data);
self.process(&Command::SetBlendState(None), &data);
self.process(&Command::SetColorMask(::state::MASK_ALL), &data);
}

fn submit(&mut self, (cb, db): (&GlCommandBuffer, &::draw::DataBuffer)) {
Expand All @@ -587,7 +597,7 @@ 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<GlDevice, ()> {
let name = self.create_buffer_internal();
let info = ::BufferInfo {
usage: usage,
Expand All @@ -597,7 +607,7 @@ impl Device for GlDevice {
::BufferHandle::from_raw(::Handle(name, info))
}

fn create_buffer_static_raw(&mut self, data: &[u8]) -> ::BufferHandle<()> {
fn create_buffer_static_raw(&mut self, data: &[u8]) -> ::BufferHandle<GlDevice, ()> {
let name = self.create_buffer_internal();

let info = ::BufferInfo {
Expand All @@ -609,7 +619,7 @@ impl Device for GlDevice {
::BufferHandle::from_raw(::Handle(name, info))
}

fn create_array_buffer(&mut self) -> Result<::ArrayBufferHandle, ()> {
fn create_array_buffer(&mut self) -> Result<::ArrayBufferHandle<GlDevice>, ()> {
if self.caps.array_buffer_supported {
let mut name = 0 as ArrayBuffer;
unsafe {
Expand All @@ -624,7 +634,7 @@ impl Device for GlDevice {
}

fn create_shader(&mut self, stage: ::shade::Stage, code: &[u8])
-> Result<::ShaderHandle, ::shade::CreateShaderError> {
-> Result<::ShaderHandle<GlDevice>, ::shade::CreateShaderError> {
let (name, info) = shade::create_shader(&self.gl, stage, code);
info.map(|info| {
let level = if name.is_err() { LogLevel::Error } else { LogLevel::Warn };
Expand All @@ -633,7 +643,7 @@ impl Device for GlDevice {
name.map(|sh| ::Handle(sh, stage))
}

fn create_program(&mut self, shaders: &[::ShaderHandle], targets: Option<&[&str]>) -> Result<::ProgramHandle, ()> {
fn create_program(&mut self, shaders: &[::ShaderHandle<GlDevice>], targets: Option<&[&str]>) -> Result<::ProgramHandle<GlDevice>, ()> {
let (prog, log) = shade::create_program(&self.gl, &self.caps, shaders, targets);
log.map(|log| {
let level = if prog.is_err() { LogLevel::Error } else { LogLevel::Warn };
Expand All @@ -642,7 +652,7 @@ impl Device for GlDevice {
prog
}

fn create_frame_buffer(&mut self) -> ::FrameBufferHandle {
fn create_frame_buffer(&mut self) -> ::FrameBufferHandle<GlDevice> {
if !self.caps.render_targets_supported {
panic!("No framebuffer objects, can't make a new one!");
}
Expand All @@ -656,12 +666,12 @@ impl Device for GlDevice {
}

fn create_surface(&mut self, info: ::tex::SurfaceInfo) ->
Result<::SurfaceHandle, ::tex::SurfaceError> {
Result<::SurfaceHandle<GlDevice>, ::tex::SurfaceError> {
tex::make_surface(&self.gl, &info).map(|suf| ::Handle(suf, info))
}

fn create_texture(&mut self, info: ::tex::TextureInfo) ->
Result<::TextureHandle, ::tex::TextureError> {
Result<::TextureHandle<GlDevice>, ::tex::TextureError> {
if info.width == 0 || info.height == 0 || info.levels == 0 {
return Err(::tex::TextureError::InvalidTextureInfo(info))
}
Expand All @@ -674,7 +684,7 @@ impl Device for GlDevice {
name.map(|tex| ::Handle(tex, info))
}

fn create_sampler(&mut self, info: ::tex::SamplerInfo) -> ::SamplerHandle {
fn create_sampler(&mut self, info: ::tex::SamplerInfo) -> ::SamplerHandle<GlDevice> {
let sam = if self.caps.sampler_objects_supported {
tex::make_sampler(&self.gl, &info)
} else {
Expand All @@ -683,61 +693,61 @@ impl Device for GlDevice {
::Handle(sam, info)
}

fn delete_buffer_raw(&mut self, handle: ::BufferHandle<()>) {
fn delete_buffer_raw(&mut self, handle: ::BufferHandle<GlDevice, ()>) {
let name = handle.get_name();
unsafe {
self.gl.DeleteBuffers(1, &name);
}
}

fn delete_shader(&mut self, handle: ::ShaderHandle) {
fn delete_shader(&mut self, handle: ::ShaderHandle<GlDevice>) {
unsafe { self.gl.DeleteShader(handle.get_name()) };
}

fn delete_program(&mut self, handle: ::ProgramHandle) {
fn delete_program(&mut self, handle: ::ProgramHandle<GlDevice>) {
unsafe { self.gl.DeleteProgram(handle.get_name()) };
}

fn delete_surface(&mut self, handle: ::SurfaceHandle) {
fn delete_surface(&mut self, handle: ::SurfaceHandle<GlDevice>) {
let name = handle.get_name();
unsafe {
self.gl.DeleteRenderbuffers(1, &name);
}
}

fn delete_texture(&mut self, handle: ::TextureHandle) {
fn delete_texture(&mut self, handle: ::TextureHandle<GlDevice>) {
let name = handle.get_name();
unsafe {
self.gl.DeleteTextures(1, &name);
}
}

fn delete_sampler(&mut self, handle: ::SamplerHandle) {
fn delete_sampler(&mut self, handle: ::SamplerHandle<GlDevice>) {
let name = handle.get_name();
unsafe {
self.gl.DeleteSamplers(1, &name);
}
}

fn update_buffer_raw(&mut self, buffer: ::BufferHandle<()>, data: &[u8],
fn update_buffer_raw(&mut self, buffer: ::BufferHandle<GlDevice, ()>, data: &[u8],
offset_bytes: usize) {
debug_assert!(offset_bytes + data.len() <= buffer.get_info().size);
self.update_sub_buffer(buffer.get_name(), data.as_ptr(), data.len(),
offset_bytes)
}

fn update_texture_raw(&mut self, texture: &::TextureHandle,
fn update_texture_raw(&mut self, texture: &::TextureHandle<GlDevice>,
img: &::tex::ImageInfo, data: &[u8])
-> Result<(), ::tex::TextureError> {
tex::update_texture(&self.gl, texture.get_info().kind,
texture.get_name(), img, data.as_ptr(), data.len())
}

fn generate_mipmap(&mut self, texture: &::TextureHandle) {
fn generate_mipmap(&mut self, texture: &::TextureHandle<GlDevice>) {
tex::generate_mipmap(&self.gl, texture.get_info().kind, texture.get_name());
}

fn map_buffer_raw(&mut self, buf: BufferHandle<()>, access: MapAccess) -> RawMapping {
fn map_buffer_raw(&mut self, buf: BufferHandle<GlDevice, ()>, access: MapAccess) -> RawMapping {
let ptr;
unsafe { self.gl.BindBuffer(gl::ARRAY_BUFFER, buf.get_name()) };
ptr = unsafe { self.gl.MapBuffer(gl::ARRAY_BUFFER, match access {
Expand All @@ -755,7 +765,7 @@ impl Device for GlDevice {
unsafe { self.gl.UnmapBuffer(map.target) };
}

fn map_buffer_readable<T: Copy>(&mut self, buf: BufferHandle<T>) -> ReadableMapping<T, GlDevice> {
fn map_buffer_readable<T: Copy>(&mut self, buf: BufferHandle<GlDevice, T>) -> ReadableMapping<T, GlDevice> {
let map = self.map_buffer_raw(buf.cast(), MapAccess::Readable);
ReadableMapping {
raw: map,
Expand All @@ -764,7 +774,7 @@ impl Device for GlDevice {
}
}

fn map_buffer_writable<T: Copy>(&mut self, buf: BufferHandle<T>) -> WritableMapping<T, GlDevice> {
fn map_buffer_writable<T: Copy>(&mut self, buf: BufferHandle<GlDevice, T>) -> WritableMapping<T, GlDevice> {
let map = self.map_buffer_raw(buf.cast(), MapAccess::Writable);
WritableMapping {
raw: map,
Expand All @@ -773,7 +783,7 @@ impl Device for GlDevice {
}
}

fn map_buffer_rw<T: Copy>(&mut self, buf: BufferHandle<T>) -> RWMapping<T, GlDevice> {
fn map_buffer_rw<T: Copy>(&mut self, buf: BufferHandle<GlDevice, T>) -> RWMapping<T, GlDevice> {
let map = self.map_buffer_raw(buf.cast(), MapAccess::RW);
RWMapping {
raw: map,
Expand Down
4 changes: 2 additions & 2 deletions src/device/gl_device/shade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ fn query_parameters(gl: &gl::Gl, caps: &::Capabilities, prog: super::Program) ->
(uniforms, textures)
}

pub fn create_program(gl: &gl::Gl, caps: &::Capabilities, shaders: &[::ShaderHandle], targets: Option<&[&str]>)
-> (Result<::ProgramHandle, ()>, Option<String>) {
pub fn create_program(gl: &gl::Gl, caps: &::Capabilities, shaders: &[::ShaderHandle<super::GlDevice>], targets: Option<&[&str]>)
-> (Result<::ProgramHandle<super::GlDevice>, ()>, Option<String>) {
let name = unsafe { gl.CreateProgram() };
for sh in shaders.iter() {
unsafe { gl.AttachShader(name, sh.get_name()) };
Expand Down
Loading