Skip to content

Instantly share code, notes, and snippets.

@tomaka
Last active February 15, 2020 06:24
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tomaka/623781c5af6ebbc5dcfe to your computer and use it in GitHub Desktop.
Save tomaka/623781c5af6ebbc5dcfe to your computer and use it in GitHub Desktop.
Gfx vs glium comparison table
Gfx and glium are Rust libraries that aim to provide a "rusty" abstraction over graphics programming APIs.
Both may look similar, and one of the questions that gets asked frequently on IRC is "what are the differences between gfx and glium?". Here is a comparison table:
| Gfx | Glium
-------------------------------------|-------------------------------------------------------------------------------------------------------------------|--------------------------------
URL | <https://github.com/gfx-rs/gfx-rs> | <https://github.com/tomaka/glium>
History | Papers since Oct 2013. Really started in June 2014. | Private/confidential from Feb 2014 to July 2014. Announced and made public in July 2014[1].
Supported backends | OpenGL 2.0 to 4.5, maybe OpenGL ES 3 (untested) | OpenGL 1.0 (with the right extensions) to 4.5, maybe OpenGL ES 3 (untested)
Potential support for other backends | All: DirectX, Mantle, Metal, OpenGL NG, OpenGL ES 2, etc. | OpenGL ES 2, maybe OpenGL NG depending on what it looks like
Level of abstraction | API oriented around modern rendering techniques ("zero driver overhead"). | Maps OpenGL concepts. Uses GLSL. Not everything is exposed for safety purposes.
Stateless API[2] | Yes | Yes
Learning curve | A bit more difficult than glium | A bit easier than gfx
Context creation library | Independent of the backend (glutin, SDL, GLFW, ... all work) | Tightly coupled with glutin (aims to provide an alternative unsafe API)
Context management safety | Partially unsafe because of OpenGL, but it's hard to screw up | Totally safe
Compile-time checks | Offsets and types of vertex attributes and uniforms | Offsets and types of vertex attributes and uniforms. Strong texture typing to avoid invalid operations. Uses `&` and `&mut` to avoid invalid operations[3].
Runtime checks | Detects common errors ahead of the rendering process | Aims to detect 100% of OpenGL errors or undefined behaviors, even the most obscure ones, some of them during the rendering process
Resource destruction | Still work in progress, currently manually destructed, potentially will use linear types when they are available | RAII
Test suit | None | 174 headless OpenGL tests that can run on travis
CPU overhead (compared to raw GL) | Safety checks outside of the rendering process. Very minor. | Heavier safety checks than gfx. Uses a background thread for OpenGL context safety (could be changed in the future). Drawing involves more CPU operations than gfx. Lot of unoptimized code with many avoidable allocations.
GPU overhead (compared to raw GL) | Minor unoptimized state changes. Redundant uniform uploads. Doesn't use DSA or immutable storage. | Redundant uniform uploads
Multithreaded rendering | Draw operations can be prepared (as if they were compiled) from multiple threads ahead of the drawing | Allows safe multithreaded drawing at any time, but for best performances users are encouraged to implement themselves something similar to what gfx enforces
Supports render-to-texture | Yes | Yes
Supports multiple render targets | Yes | Yes
Supports geometry shaders | Yes (untested) | Yes
Supports uniform blocks | Yes | Yes
Supports tessellation shading | Not yet | Yes
Supports instancing | Yes | Yes
Supports commands batches | Yes for APIs that support them, emulated for OpenGL | No (and not until OpenGL supports them with an ARB or EXT extension)
Supports buffer persistent mapping | Not yet | Yes
Supports bindless textures | Not yet | Not yet (troubles with API design)
Supports transform feedback | Not yet | Not yet
Supports occlusion queries | Not yet | Not yet
Github stars | 294 | 143
Total contributors | 43 | 11
Pulse in the last month | 43 active pull requests, 41 active issues | 117 active pull requests, 92 active issues
Misc:
- Both libraries have a steep learning curve if you have never done graphics programming.
- Nobody has written benchmarks that compare gfx and glium yet.
- A list of projects that use gfx/glium would be hard to write. Piston works with both but the glium backend is only two weeks old. Gfx has [Snowmew](https://github.com/csherratt/snowmew).
- Glium safely supports changing the context's attributes (for example switching windowed/fullscreen). This is out of scope of Gfx.
Notes:
[1]: Even though glium was announced shortly after gfx, it was not started as a reaction to it.
[2]: "Stateless API" means that the same function calls will always produce the same result. OpenGL is often criticized for its stateful API.
[3]: OpenGL doesn't permit operating on objects while they are in a certain state (for example, when a buffer is mapped). Glium uses mutable borrows when an object is in these states (for example, mapping a buffer), and immutable borrows for other operations.
@kvark
Copy link

kvark commented Feb 21, 2015

I'll review it here (duplicated on the gitter):

  1. "Uses & and &mut to avoid invalid operations." - this sounds vague. Why is this the case for glium but not gfx?
  2. "Runtime checks" - most of the errors we detect up-front at the init stage. Glium checks for them at rendering stage. It is a major difference that has to be noted.
  3. "Resource destruction" - lets say "still WIP, currently manually destructed, potentially will use linear types when they are available"
  4. "CPU overhead" - why are you saying Glium has more checks? That's a tricky point. Even if there is a difference, nothing stops either side from closing the gap in a matter of hours/days. I'd prefer pointing to the architectural differences than minor implementation details. So unless our architecture prevents us to do some checks, this is not a valid point to differentiate.
  5. "CPU overhead" - aren't you matching all the uniforms? Not sure about vertex attributes. Also, quite importantly, is the number of heap allocations per call.
  6. "Supports geometry shaders" - potentially, not tested.
  7. "Supports tessellation shading" - not yet.
  8. "Supports instancing" - "Yes, with strong typing" - what is this supposed to mean?
  9. "Github stars", "Number of contributors" - completely irrelevant. Even "Pulse in the last month" is questionable. Do you want the comparison to be outdated a month after you release it?
  10. You missed one of the major points - "multi-threaded rendering", where Gfx would score high.

@kvark
Copy link

kvark commented Feb 21, 2015

(11) "History" - I believe it's important to say that Glium didn't start as gfx competitor. It was a thin OpenGL wrapper aka hgl-rs plus some enhancements. Perhaps, you could add a date when you switched to bind-less interfaces?

(12) Support for single-threaded operation

@tomaka
Copy link
Author

tomaka commented Feb 22, 2015

I updated the gist

4: The point is not that Glium has more checks, but that Glium's checks take more CPU as we are in the "CPU overhead" line. It's probably a problem of vocabulary, I don't know how to say this other than "Heavier safety checks".

8: The idea was to show that it's a slightly different design, but after some thoughts it's probably not worth mentionning

9: There are a lot of points that would be outdated anyway. I included them to show that they are not minor projects (relative to other rust projects), and to counter-balance the "pulse in the last month" in favor of glium.

12: I don't know what I'm supposed to put in that section

@kvark
Copy link

kvark commented Feb 22, 2015

Second Review

1: "Runtime checks" - you are highly subjective here

Detects common errors ahead of the rendering process

vs

Aims to detect 100% of OpenGL errors or undefined behaviors, even the most obscure ones, some of them during the rendering process

First, you are comparing a fact (about gfx) with an intention (about Glium). We also aim to detect 100% OpenGL errors/UB, even the most obscure ones. Next, you are clearly putting "some of them during the rendering process" out of focus. Does glium even do any run-time checks ahead of rendering?

2: "History" - I don't know what you had in mind, but I recall glium being basically hgl-rs + gfx_macros.

3: About single threading. Instead of putting it as a separate point, perhaps we could change "Multithreaded rendering" to "Threading model", where you could say about gfx-rs:

Draw operations can be prepared (as if they were compiled) from multiple threads ahead of the drawing, or they can be executed on the device on a single thread.

@tomaka
Copy link
Author

tomaka commented Feb 22, 2015

Here is a quick list of what I check at runtime (from memory, some things may be missing):

  • I checked the minimum GL version of every single OpenGL call, and glium checks whether the backend supports it first
  • Checking that the values of depth_range is between 0 and 1
  • Checking that the dimensions of the viewport and the scissor box are inferior to MAX_VIEWPORT_DIMS
  • Checking that the number of framebuffer attachments are inferior to MAX_DRAW_BUFFERS
  • Checking that all framebuffer attachments have the same dimensions, because this is required by EXT_framebuffer_objects
  • Checking that there's a depth buffer before drawing with a depth test
  • Checking the types of attributes, uniform values, and fragment output
  • Checking for missing uniforms or attributes
  • Checking if we're out of memory when creating a buffer
  • Checking the alignment of elements when uploading a buffer
  • Checking that the backend supports the requested format when creating a texture
  • Checking that the format of the client data is compatible with the requested texture format
  • Checking the layout of uniform blocks
  • Checking that the requested anisotropic filtering level is inferior to MAX_TEXTURE_MAX_ANISOTROPY
  • Checking that the program has tessellation shaders when you draw with patches

Most of them are outside the rendering process.

You seem to be really underestimating the amount of work that I put in this.

@tomaka
Copy link
Author

tomaka commented Feb 22, 2015

I don't know what you had in mind, but I recall glium being basically hgl-rs + gfx_macros.

I didn't even know that hgl existed when I published glium, plus I figured out the vertex format attribute myself. Just like the bindless API, automatically determining the vertex layout is nothing spectacular.
As I told you the other day, the only thing that I took from gfx is the #[uniform] attribute (and by "took" I mean that I saw it in gfx, thought that this was a good idea and reimplemented it myself).

@tomaka
Copy link
Author

tomaka commented Feb 22, 2015

I really didn't think that "Runtime checks" would be problematic. The idea that I have of gfx is that you're checking almost nothing, but I put "Detects common errors" to be gentle.

@kvark
Copy link

kvark commented Feb 23, 2015

I didn't want to imply you do little or less checks. Your list is truly impressive. However, the way you want to describe it is still subjective. Instead of "Aims to detect 100% of OpenGL errors or undefined behaviors,.. " a better way to say it would be "Glium detects a broader range of errors at the moment, some at rendering time as opposed to init time".

I don't know Glium good enough to properly group your list, but I can select the following points that you do at rendering time, at least:

Checking that there's a depth buffer before drawing with a depth test

We also do it at rendering time. In addition, we check for stencil to be there and for color attachments to be provided if blending is requested.

Checking the types of attributes, uniform values, and fragment output

These are heavy checks, and we do most of them (attributes+uniforms) at init time.

Checking for missing uniforms or attributes

Again, we do it at init time.

Checking that the program has tessellation shaders when you draw with patches

We will do it at init time once we have tessellation.

The fact that you do more checks (even though we still have stuff you don't check for) at this point is not very relevant to me, simply because nothing stops us from doing the same. But the fact that you do the heavier ones at rendering time is relevant, because it's an architectural limitation of yours.

Also, what do you think about the threading model?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment