#![deny(missing_docs)]
use std::{fmt, mem};
use std::hash::Hash;
pub use draw_state::target;
pub use draw_state::state;
pub mod attrib;
pub mod draw;
pub mod handle;
pub mod mapping;
pub mod shade;
pub mod tex;
mod arc;
pub type VertexCount = u32;
pub type InstanceCount = u32;
pub type UniformBlockIndex = u8;
pub type AttributeSlot = u8;
pub type UniformBufferSlot = u8;
pub type TextureSlot = u8;
pub fn as_byte_slice<T>(slice: &[T]) -> &[u8] {
use std::slice;
let len = mem::size_of::<T>() * slice.len();
unsafe {
slice::from_raw_parts(slice.as_ptr() as *const u8, len)
}
}
#[derive(Copy, Clone, Debug)]
#[allow(missing_docs)] pub struct Capabilities {
pub shader_model: shade::ShaderModel,
pub max_draw_buffers: usize,
pub max_texture_size: usize,
pub max_vertex_attributes: usize,
pub array_buffer_supported: bool,
pub fragment_output_supported: bool,
pub immutable_storage_supported: bool,
pub instance_base_supported: bool,
pub instance_call_supported: bool,
pub instance_rate_supported: bool,
pub render_targets_supported: bool,
pub sampler_objects_supported: bool,
pub srgb_color_supported: bool,
pub uniform_block_supported: bool,
pub vertex_base_supported: bool,
}
#[derive(Copy, Clone)]
pub enum MapAccess {
Readable,
Writable,
RW
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(u8)]
pub enum PrimitiveType {
Point,
Line,
LineStrip,
TriangleList,
TriangleStrip,
TriangleFan,
}
pub type IndexType = attrib::IntSize;
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
#[repr(u8)]
pub enum BufferRole {
Vertex,
Index,
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
#[repr(u8)]
pub enum BufferUsage {
Static,
Dynamic,
Stream,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct BufferInfo {
pub role: BufferRole,
pub usage: BufferUsage,
pub size: usize,
}
#[allow(missing_docs)]
pub trait Resources: Clone + Hash + fmt::Debug + Eq + PartialEq {
type Buffer: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type ArrayBuffer: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type Shader: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type Program: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type FrameBuffer: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type Surface: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type Texture: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
type Sampler: Copy + Clone + Hash + fmt::Debug + Eq + PartialEq + Send + Sync;
}
#[allow(missing_docs)]
pub trait Factory<R: Resources> {
type Mapper: Clone + mapping::Raw;
fn create_buffer_raw(&mut self, size: usize, usage: BufferUsage) -> handle::RawBuffer<R>;
fn create_buffer<T>(&mut self, num: usize, usage: BufferUsage) -> handle::Buffer<R, T> {
handle::Buffer::from_raw(
self.create_buffer_raw(num * mem::size_of::<T>(), usage))
}
fn create_buffer_static_raw(&mut self, data: &[u8], role: BufferRole) -> handle::RawBuffer<R>;
fn create_buffer_static<T>(&mut self, data: &[T]) -> handle::Buffer<R, T> {
handle::Buffer::from_raw(
self.create_buffer_static_raw(as_byte_slice(data), BufferRole::Vertex))
}
fn create_buffer_index<T>(&mut self, data: &[T]) -> handle::IndexBuffer<R, T> {
handle::IndexBuffer::from_raw(
self.create_buffer_static_raw(as_byte_slice(data), BufferRole::Index))
}
fn create_array_buffer(&mut self) -> Result<handle::ArrayBuffer<R>, ()>;
fn create_shader(&mut self, stage: shade::Stage, code: &[u8]) ->
Result<handle::Shader<R>, shade::CreateShaderError>;
fn create_program(&mut self, shaders: &[handle::Shader<R>], targets: Option<&[&str]>)
-> Result<handle::Program<R>, shade::CreateProgramError>;
fn create_frame_buffer(&mut self) -> handle::FrameBuffer<R>;
fn create_surface(&mut self, tex::SurfaceInfo) -> Result<handle::Surface<R>, tex::SurfaceError>;
fn create_texture(&mut self, tex::TextureInfo) -> Result<handle::Texture<R>, tex::TextureError>;
fn create_sampler(&mut self, tex::SamplerInfo) -> handle::Sampler<R>;
fn update_buffer_raw(&mut self, buf: &handle::RawBuffer<R>, data: &[u8], offset_bytes: usize);
fn update_buffer<T>(&mut self, buf: &handle::Buffer<R, T>, data: &[T], offset_elements: usize) {
self.update_buffer_raw(buf.raw(), as_byte_slice(data), mem::size_of::<T>() * offset_elements)
}
fn map_buffer_raw(&mut self, &handle::RawBuffer<R>, MapAccess) -> Self::Mapper;
fn unmap_buffer_raw(&mut self, Self::Mapper);
fn map_buffer_readable<T: Copy>(&mut self, &handle::Buffer<R, T>) -> mapping::Readable<T, R, Self>;
fn map_buffer_writable<T: Copy>(&mut self, &handle::Buffer<R, T>) -> mapping::Writable<T, R, Self>;
fn map_buffer_rw<T: Copy>(&mut self, &handle::Buffer<R, T>) -> mapping::RW<T, R, Self>;
fn update_texture_raw(&mut self, tex: &handle::Texture<R>,
img: &tex::ImageInfo, data: &[u8],
kind: Option<tex::TextureKind>) -> Result<(), tex::TextureError>;
fn update_texture<T>(&mut self, tex: &handle::Texture<R>,
img: &tex::ImageInfo, data: &[T],
kind: Option<tex::TextureKind>) -> Result<(), tex::TextureError> {
self.update_texture_raw(tex, img, as_byte_slice(data), kind)
}
fn generate_mipmap(&mut self, &handle::Texture<R>);
fn create_texture_static<T>(&mut self, info: tex::TextureInfo, data: &[T])
-> Result<handle::Texture<R>, tex::TextureError> {
let image_info = info.to_image_info();
match self.create_texture(info) {
Ok(handle) => self.update_texture(&handle, &image_info, data, None)
.map(|_| handle),
Err(e) => Err(e),
}
}
fn cleanup(&mut self);
}
pub type SubmitInfo<'a, D: Device> = (
&'a D::CommandBuffer,
&'a draw::DataBuffer,
&'a handle::Manager<D::Resources>
);
pub trait Device {
type Resources: Resources;
type CommandBuffer: draw::CommandBuffer<Self::Resources>;
fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
fn reset_state(&mut self);
fn submit(&mut self, SubmitInfo<Self>);
fn after_frame(&mut self);
}