Code Monkey home page Code Monkey logo

gfx's Introduction

Matrix room gfx-hal on crates.io Build Status
Getting Started | Documentation | Blog | Funding

gfx-rs

gfx-rs is a low-level, cross-platform graphics and compute abstraction library in Rust. It consists of the following components:

gfx-hal deprecation

As of the v0.9 release, gfx-hal is now in maintenance mode. gfx-hal development was mainly driven by wgpu, which has now switched to its own GPU abstraction called wgpu-hal. For this reason, gfx-hal development has switched to maintenance only, until the developers figure out the story for gfx-portability. Read more about the transition in #3768.

hal

  • gfx-hal which is gfx's hardware abstraction layer: a Vulkan-ic mostly unsafe API which translates to native graphics backends.
  • gfx-backend-* which contains graphics backends for various platforms:
  • gfx-warden which is a data-driven reference test framework, used to verify consistency across all graphics backends.

gfx-rs is hard to use, it's recommended for performance-sensitive libraries and engines. If that's not your domain, take a look at wgpu-rs for a safe and simple alternative.

Hardware Abstraction Layer

The Hardware Abstraction Layer (HAL), is a thin, low-level graphics and compute layer which translates API calls to various backends, which allows for cross-platform support. The API of this layer is based on the Vulkan API, adapted to be more Rust-friendly.

Hardware Abstraction Layer (HAL)

Currently HAL has backends for Vulkan, DirectX 12/11, Metal, and OpenGL/OpenGL ES/WebGL.

The HAL layer is consumed directly by user applications or libraries. HAL is also used in efforts such as gfx-portability.

See the Big Picture blog post for connections.

The old gfx crate (pre-ll)

This repository was originally home to the gfx crate, which is now deprecated. You can find the latest versions of the code for that crate in the pre-ll branch of this repository.

The master branch of this repository is now focused on developing gfx-hal and its associated backend and helper libraries, as described above. gfx-hal is a complete rewrite of gfx, but it is not necessarily the direct successor to gfx. Instead, it serves a different purpose than the original gfx crate, by being "lower level" than the original. Hence, the name of gfx-hal was originally ll, which stands for "lower level", and the original gfx is now referred to as pre-ll.

The spiritual successor to the original gfx is actually wgpu, which stands on a similar level of abstraction to the old gfx crate, but with a modernized API that is more fit for being used over Vulkan/DX12/Metal. If you want something similar to the old gfx crate that is being actively developed, wgpu is probably what you're looking for, rather than gfx-hal.

Contributing

We are actively looking for new contributors and aim to be welcoming and helpful to anyone that is interested! We know the code base can be a bit intimidating in size and depth at first, and to this end we have a label on the issue tracker which marks issues that are new contributor friendly and have some basic direction for completion in the issue comments. If you have any questions about any of these issues (or any other issues) you may want to work on, please comment on GitHub and/or drop a message in our Matrix chat!

License

This repository is licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

gfx's People

Contributors

aleksijuvani avatar bastacyclop avatar bors[bot] avatar brendanzab avatar burtonageo avatar bvssvni avatar csherratt avatar cwfitzgerald avatar emberian avatar eugene2k avatar fkaa avatar gabrielmajeri avatar goddessfreya avatar gordon-f avatar grovesnl avatar hannobraun avatar homu avatar jackmott avatar johncolanduoni avatar kichristensen avatar kimundi avatar kvark avatar kyren avatar michael-lfx avatar msiglreith avatar mtak- avatar sectopod avatar tangmi avatar uniformbuffer3 avatar vickenty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gfx's Issues

Design the high-level drawing layer above gfx-rs

As we are getting settled with the scope (see #108), we should start thinking about the layer above gfx-rs. I hope to see it as a separate projects in our gfx-rs organization, where this issue is the ideas hub for the initial design.

Here is what I expect this layer to do:

  • Define a concept of Material. For starters, we can just use gfx::ShaderBundle for it.
  • Define a spatial system: world space, connections, and hierarchies. This would probably lock it to a particular math library (e.g. cgmath-rs)
  • Define a concept of DrawList
  • Automatically re-order calls inside each draw list

Invalid mesh attribute.

the function fn create_mesh(&self, num_vert: mesh::VertexCount, data: Vec<f32>, stride0: u8) The first argument, num_vert is used for two different and contradicting purposes.

First it is used to set the width of the vertex attribute here. Secondly it is used here to specify the length of the array.

This also means the triangle example is a bit wrong, it should be 2 not 3. But since the stride is set correctly, and the vertex shader thinks it is a vec2 vs vec3 it has masked the bug.

Asynchronous interface for the client

Despite the multi-layered approach, based on the asynchronous duplex streams, all our client endpoints are synchronous:

pub fn create_program(&self, vs_code: Vec<u8>, fs_code: Vec<u8>) -> ProgramHandle {
    self.stream.send(CallNewProgram(vs_code, fs_code));
    match self.stream.recv() {
        ReplyProgram(handle) => handle,
        _ => fail!("unknown reply")
    }
}

We need to find a good interface that exposes the asynchronous nature of gfx-rs in the most convenient way.

Essentially, asynchronous requests and replies are a queue (First In - First Out). I managed to build a heterogeneous queue with an idea that it's going to be exposed to the client in gfx-rs. However, I can't find a good way to enclose it into the Client structure without having associated types feature of Rust.

Let's discuss ideas and prototype asynchronous interfaces for the client.

Error codes for `update_*` routines

Since we have SurfaceInfo and TextureInfo stored on the renderer side, we can check this right away and return a Result:

  • format size matches T size
  • number of elements matches the vec len

Generalize buffer creation over the input type

This is what we have:

fn create_vertex_buffer(&self, data: Vec<f32>)
fn create_index_buffer(&self, data: Vec<u16>)
fn create_raw_buffer(&self)
fn update_buffer(&self, buf: BufferHandle, data: Vec<f32>)

This is what we need:

fn create_buffer<T>(&self, Option<Vec<T>>)
fn update_buffer_vec<T>(&self, data: Vec<T>)
fn update_buffer_struct<T>(&self, data: T)

Implement Texture creation and binding

TODO:

  • ability to create a Texture with given contents. We may need a descriptor for it to encapsulate all the parameters (type, width, height, depth, multisampling, mipmaps)
  • ability to create an immutable Sampler object
  • binding texture parameters with their samplers to shader programs

Implement a simple GL back-end

GL back-end needs to be able to create various types of objects (Buffer, ArrayBuffer, Shader, Program, FrameBuffer, Surface, Texture) and bind them properly, as well as to support draw calls.

Triangle example should also be completed to demonstrate the back-end in action.

Cache shader object and program creation

Program caching is easy: we can just compare vectors of the attached shader names directly.

Shader object caching would need either a hash to be computed, or the whole text to be stored.

Define scope and philosophy

What should gfx-rs handle?

What should gfx-rs defer to the client, or higher level libraries/frameworks/engines?

Automate mesh description via a macro

Current interface for mesh construction has a single position attribute hard-coded, and that's what it expects to have in the user-provided buffer. This is simple and was put it to get us going, but now is the time to replace it by something more generic and solid.

The most generic way of describing a mesh is providing all the attributes separately, and I don't believe we can make it any simpler. However, the most common use-case is to have all the mesh attributes interleaved in a single vertex buffer. We could extract the field sizes and offsets (even the types, perhaps?) from the struct declaration:

#[vertex]
struct MyVertex {
   pos: [f32, ..3],
   normal: [f32, ..3],
}
// type Format
trait VertexFormat {
   fn get_format() -> Format;
}
//...
let format = MyVertex::get_format();
let mesh = Mesh::new(num_verts, format);

Implement resource handle management

EDIT - New description:

Currently, we don't have any way to dispose resources and re-use API's internal handles. We need to find a way to do that safely, and expose these functions in Renderer interface.

Old description:

@photex had a prototype shelved. I propose the following structure:

render::handle::{Handle, Manager<T>}

For the starters we can use the buffers by handles, then move other entities and enable async error reporting, deferred loading, etc.

Add support for a D3D11 backend

I'm working on this. Everything we do so far is D3D11 compatible. I am not checking for D3D9 compatability, having a D3D9 fallback would be a later project.

Remove ```server::Request``` in favor of the naming convention

I don't know about Erlang but in Rust we don't seem to able to enforce Call to have a reply following and Cast to do not. Hence, I believe the current usage of server::Request just adds more cruft to the message passing. My proposal:

Remove the "server.rs" entirely, instead just follow the naming convention of CallSomething to be a request with a reply, and CastSomething to be a one-way request. This would also greatly help #9 since it requires bare message passing by the sides.

`cargo build` errors

--- stderr
gl/tex.rs:218:43: 218:73 error: unresolved name `gl::TEXTURE_MAX_ANISOTROPY_EXT`.
gl/tex.rs:218                 gl::TexParameterf(target, gl::TEXTURE_MAX_ANISOTROPY_EXT, fac as GLfloat),
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gl/tex.rs:338:41: 338:71 error: unresolved name `gl::TEXTURE_MAX_ANISOTROPY_EXT`.
gl/tex.rs:338             gl::SamplerParameterf(name, gl::TEXTURE_MAX_ANISOTROPY_EXT, fac as GLfloat),

It could be an environment issue, but it was working fine with the make version a couple of days ago.

Thoughts about project structure

In the Piston project we use Rust-Empty to build dependencies by symlinks. This allows us great flexibility when working with lots of dependencies.

I noticed this library uses multiple crates and git submodules. This easily causes problems when using the project as dependency.

Rust-Empty uses the same structure as Cargo, so users can do 'cargo build' and then replace the dependencies with symlinks when working on multiple repositories at once. You type 'make symlink-build' to create a script and then './build.sh deps' to build all the dependencies by symlinks.

I also suggest moving examples to a separate repo like Piston-Examples.

Figure out the best format to represent strings for names of uniform parameters, blocks, and attributes.

Here are the instances of names that we need to store:

  • Uniform parameter
  • Uniform block
  • Texture name
  • Shader attribute
  • Mesh attribute

These may need to be accessed at run-time for draw-call execution. Using String type will force the heap allocation (prevents static initialization of, to say, mesh::Attribute) and involve a guaranteed data cache miss on access due to indirection.

One of the possible solutions is to have fixed-size u8 arrays:

pub static MAX_UNIFORM_NAME: uint = 24;
pub type UniformName = [u8, ..MAX_UNIFORM_NAME];

Find a solution for shader language support

Different graphics APIs have their own shading languages or ideas for what a shading language should be. In our quest to support multiple backend APIs, we need a way to unify these.

Simplify device architecture

TODO:

  • Remove device::Client
  • Move device::Server implementation to the API-dependent part
  • Move device module into a separate crate (optional)

This task partially addresses #9 and #38.
@csherratt seems to be in agreement with this.

How to sell gfx-rs

I'm just trying to think of as how a novice would see GFX. I mean the first though is, why use this over bare opengl or HGL? Might be a marketing question more then a technical question. - @csherratt


I'm very positive about the low-level interface that gfx-rs provides at the moment. We have a narrow but pretty definite scope, which gives a chance to produce a high quality library for that domain. A small piece to do its thing right - abstract the device, put it into its own thread, provide safe interface for drawing stuff. - @kvark


It's safe, it's bindless, it supports multiple backends to help support older architectures. It gives the user a mult-threaded render. - @csherratt

Find a solution for sending data to device

Right now, we use Box<Blob + Send> and always send Vec<T>. This is really bad:

  1. Copy vertex/texture data into a dedicated Vec for sending
  2. Send to device (very cheap)
  3. Call OpenGL function
  4. (GL driver copies entire buffer into local space so that modifications to the data you passed it won't have races)
  5. (GL driver uploads to GPU somehow)

Ideally we'd avoid this needless copy by sending a slice somehow. Certainly will need unsafe code somewhere...

Add Rasterizer state support

Rasterizer state is (in this context) the configuration of fixed-function hardware functions (i.e. fragment shader is not a part of this state) that are responsible for bringing the output geometry to the framebuffer. It can include the following blocks (roughly in the order they are executed by HW):

  • Viewport (optionally - leave that to framebuffer to manage in #50)
  • Primitive setup (points/lines/triangles, face culling)
  • Polygon offset
  • Multisampling
  • Scissor
  • Stencil (test, mask)
  • Depth (test, mask)
  • Blending (equation)
  • Color mask

We could have them stored in one big descriptor (either passed with every draw call - heavy, immutably defined and represented by a handle), or split into groups:

  1. Rasterization (primitive, culling, offset, multisample)
  2. Mask (Scissor, stencil mask, depth mask, color mask)
  3. Depth-stencil (functions, params)
  4. Blending (equation, params)

The reason why I put masks into a separate group with scissor is because it's a subset of the only states that affect Clear function.

Reduce the number of layers our commands go through

Here are the current stops in a one-way trip of a client command:

  1. render::Client::do_something() creates a Cast or Call message and sends it through the pipe
  2. render::Server receives the message and calls some the device::Client methods
  3. device::Client:::do_something() creates a message and sends it down the pipe
  4. device::Server receives the message and calls some of the back-end methods
  5. the back-end actually executes them

You can see there are 5 layers of execution... While we certainly need abstraction, we'd be fine with just 2 - 3 layers. I propose to remove device::Client methods in favor of render just sending messages directly. We can also remove the render::Client in favor of pure messages.

(+) less code for us to maintain, less layers to loose yourself in
(+) exposing asynchronous nature actually allows to benefit from it, i.e. send a bunch of commands and then receive some (instead of send-receive cycles)
(-) less convenient for the client (the problem does not apply to device <-> render interaction)

Async error reporting

We need a way for the client to get errors coming from the device (and potentially the renderer). Completion of #21 allows using the device channel in a free manner, so we can add error codes there.

Need support for Indexed arrays.

create_mesh currently only supports vertex information. There is no way to call the equivalent of glDrawElements. So we will need a way to pass in an index array to build an indexed mesh.

Transition away from DuplexStreams

Whilst running make on the latest rustc we get:

rustc -L lib -L deps/gl-rs/lib -L deps/glfw-rs/lib --out-dir=lib --cfg=gl -O src/device/lib.rs
src/device/lib.rs:119:19: 119:41 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:119             match self.stream.recv_opt() {
                                        ^~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:127:21: 127:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:127                     self.stream.send(ReplyNewBuffer(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:132:21: 132:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:132                     self.stream.send(ReplyNewBuffer(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:136:21: 136:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:136                     self.stream.send(ReplyNewBuffer(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:140:21: 140:64 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:140                     self.stream.send(ReplyNewArrayBuffer(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:144:21: 144:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:144                     self.stream.send(ReplyNewShader(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:148:21: 148:60 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:148                     self.stream.send(ReplyNewProgram(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:152:21: 152:64 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:152                     self.stream.send(ReplyNewFrameBuffer(name));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/device/lib.rs:181:42: 181:54 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/device/lib.rs:181     let (client_stream, server_stream) = comm::duplex();
                                                               ^~~~~~~~~~~~
rustc -L lib -L deps/gl-rs/lib -L deps/glfw-rs/lib --out-dir=lib --cfg=glfw -O src/gfx/lib.rs
src/gfx/render/mod.rs:64:13: 64:52 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:64             device.send(device::CallNewArrayBuffer);
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:65:13: 65:52 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:65             device.send(device::CallNewFrameBuffer);
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:66:38: 66:51 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:66             let array_buffer = match device.recv() {
                                                              ^~~~~~~~~~~~~
src/gfx/render/mod.rs:70:38: 70:51 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:70             let frame_buffer = match device.recv() {
                                                              ^~~~~~~~~~~~~
src/gfx/render/mod.rs:93:9: 93:50 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:93         self.device.send(device::CastClear(data));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:110:9: 110:80 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:110         self.device.send(device::CastBindArrayBuffer(self.common_array_buffer));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:116:17: 116:63 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:116                 self.device.send(device::CastDraw(start, end));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:119:17: 119:61 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:119                 self.device.send(device::CastBindIndex(buf));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:120:17: 120:70 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:120                 self.device.send(device::CastDrawIndexed(start, end));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:126:9: 126:50 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:126         self.device.send(device::CastSwapBuffers);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:130:9: 130:64 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:130         self.device.send(device::CallNewShader(Vertex, vs_src));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:131:9: 131:66 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:131         self.device.send(device::CallNewShader(Fragment, fs_src));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:132:26: 132:44 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:132         let h_vs = match self.device.recv() {
                                                   ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:136:26: 136:44 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:136         let h_fs = match self.device.recv() {
                                                   ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:140:9: 140:67 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:140         self.device.send(device::CallNewProgram(vec![h_vs, h_fs]));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:141:15: 141:33 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:141         match self.device.recv() {
                                        ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:152:9: 152:60 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:152         self.device.send(device::CallNewVertexBuffer(data));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:153:28: 153:46 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:153         let buffer = match self.device.recv() {
                                                     ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:173:9: 173:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:173         self.device.send(device::CallNewIndexBuffer(data));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:174:15: 174:33 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:174         match self.device.recv() {
                                        ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:181:9: 181:51 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:181         self.device.send(device::CallNewRawBuffer);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:182:15: 182:33 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:182         match self.device.recv() {
                                        ^~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:207:9: 207:62 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:207         self.device.send(device::CastUpdateBuffer(buf, data));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:213:13: 213:85 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:213             self.device.send(device::CastBindFrameBuffer(self.default_frame_buffer));
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:215:13: 215:84 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:215             self.device.send(device::CastBindFrameBuffer(self.common_frame_buffer));
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:218:21: 218:89 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:218                     self.device.send(device::CastBindTarget(TargetColor(i as u8), *new));
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:222:17: 222:83 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:222                 self.device.send(device::CastBindTarget(TargetDepth, frame.depth));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:225:17: 225:87 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:225                 self.device.send(device::CastBindTarget(TargetStencil, frame.stencil));
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:234:30: 235:88 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:234                 Some(vat) => device.send(device::CastBindAttribute(sat.location as u8,
src/gfx/render/mod.rs:235                     vat.buffer, vat.size as u32, vat.offset as u32, vat.stride as u32)),
src/gfx/render/mod.rs:244:9: 244:59 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:244         device.send(device::CastBindProgram(program.name));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:249:13: 249:116 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:249             device.send(device::CastBindUniformBlock(program.name, i as u8, i as device::UniformBufferSlot, block));
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gfx/render/mod.rs:255:13: 255:78 warning: use of deprecated item: This type is replaced by having a pair of channels. This type is not fully composable with other channels in terms of or possible semantics on a duplex stream. It will be removed soon, #[warn(deprecated)] on by default
src/gfx/render/mod.rs:255             device.send(device::CastBindUniform(uniform_var.location, value));
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Implement abstract platform support

The device manager should ideally know as little as possible about the platform, perhaps only knowing how to swap buffers and access the framebuffer.

Add multisampling support

Multisampling is not something we need right now, but we will need eventually. Keeping track of it in a separate issue would allow us to close #51. Requires:

  • support for MSAA textures
  • support for MSAA surfaces
  • support for MSAA render states

Keep in mind that MSAA is not just a number. In EQAA, for example, it's (number_of_samples, number_of_fragments) pair.

Consider splitting up Render and Platform tasks into separate crates

This issue is intended for discussion about the architecture of gfx-rs and possibility of dissecting it into multiple sub-crates. Please close it only of the strong decision is found with a consensus.

Having the platform/device abstracted away and running on a separate thread is useful by itself, even outside of the render task. One might want to build his/her own abstractions (even though we strike to make ours as generic as possible) but still benefit from multi-API support. Besides, the platform task doesn't depend on anything, so it should be straightforward to move it out.

Another concern is the fact we have tasks. Currently we have 2 task boundaries to cross on any command, and I can see why someone would want to reduce this number (e.g. to deal with latency). Perhaps, we could allow using gfx-rs with the renderthread code being called directly (i.e. provide the server interface directly instead of the task messages)? Or even use the whole thing in the same task?

I realize this topic borders with over-engineering, but I'd like to start the discussion and see our options.

Implement a task-less render client alternative

We need an alternative render client that keeps the render::Server locally to avoid message passing overhead. According to @csherratt, messages take a big chunk of our time. Removing the render task in favor of direct calls can help with frame rate as well as latency.

Implement the mesh link

Uniforms

#40 lays out the environment structs, and it already had envir::Shortcut construction implemented. What is missing is a cache of these shortcuts.

Vertex attributes

A shortcut can be represented by a single u64 value that has up to 16 pointers (each 4 bits) into the mesh data. These are to be stored in some kind of cache and re-used. Also note that bind_mesh needs to be split into shortcut construction and usage functions.

Implementing this feature will make #24 irrelevant.

Swapbuffer only on command

gfx-rs currently will swap buffers if it's command queue is empty, or if it is explicitly told to swap buffers. It does not make sense to me to swap buffers in the first case and I don't think it was the intended behaviour.

Possibly enclose `draw()` arguments into a struct

"RainFly_X" proposed to have a struct holding all draw parameters on the reddit thread:

Some perceived benefits to a Draw struct.

  • Can be stored and reused.
  • Can be passed around.
  • Can be easily copied and modified, so you can set up an initial Draw struct, and then make a bunch of variations in a very clean, concise way.
  • Can iterate over a vector of Draws.

Let's discuss it!
My thought is that if we go this route, we might as well serialize all the call types (not just the draw) in something similar to this enum Call. But then, since it can be done by a higher-level code, maybe we should leave it for the upper library?

On one hand, passing and storing all the draw parameters is appealing. On the other hand, mutating the struct between calls is basically turning our bind-less interface into a state machine... which I'd like to avoid, at least in scope of gfx-rs.

Design the shader parameters logic

A draw call from the user side should provide the following entities:

  • SubMesh, which is a slice into the attributes and vertex indices, which themselves are linked to raw buffers
  • target::Frame, which contains the surfaces to be bound as colors and depth targets
  • shader::Program, which is not just the shader program ID, but also has meta-data attached about all the used attributes and uniform values/buffers
  • shader::Environment, the unresolved key structure to encapsulate all needed shader parameters in some form, including the material data, camera, lights, etc.

The last thing is what needs to be designed efficiently, since it needs to be accessed on every call, matched against shader meta-data (see Draw Call Verification), and also passed around a lot.
In Claymore I used the Map to store parameters by name:

pub struct DataMap( HashMap<~str,Uniform> );

pub enum Uniform {
    Uninitialized,
    UniFloat(f32),
    UniInt(i32),
    UniFloatVec(Vec4<f32>),
    UniIntVec(Vec4<i32>),
    UniFloatVecArray(~[Vec4<f32>]),
    UniMatrix(bool,Mat4<f32>),
    UniTexture(uint,texture::TexturePtr,Option<texture::Sampler>),
}

I consider it to be not efficient enough, because there is a lot of allocations, and carrying out names everywhere (and comparing them) is a bit too heavy. We'll need something very generic and more efficient than this.

Refactor `clear()` to help the user to avoid `ClearData`

Currently, we accept ClearData and pass it to the device. It is not convenient for the user though, who would likely prefer to just pass all three options as clear() parameters. With that in, there would be no need to expose ClearData publicly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.