Gfx: Lower level GPU abstraction

Created on 24 Dec 2016  路  5Comments  路  Source: gfx-rs/gfx

We need to provide a level of GPU abstraction that doesn't have any overhead over using some API bindings directly. That means no resource lifetime management and preferably no heap allocation.

If we try to implement such a layer from scratch, we'd end up re-using most of the existing code from gfx_core and the backends. Thus, I believe we should steer the gfx_core towards this no-overhead goal, reaching it before we stabilize the API.

One effect of this transition would be - clearer separation between gfx_render and gfx_core. Another - opened use cases for applications demanding no overhead, like webrender. These applications may have limited use cases, allowing them to manage resource lifetimes more efficiently than us.

hard hal ready for work api optimization strategic

Most helpful comment

Conceptually, this is implemented 馃帀 . Separate issues are filed for missing features.

All 5 comments

We already have these 3 levels of resource type abstraction:

  1. Raw untracked structs (gfx_core, R::Texture).
  2. Tracked Arc/Rc handles with metadata (gfx_render, handle::RawTexture<R>).
  3. Tracked generically-typed handles (gfx_render, handle::Texture<R, Type>).

So the transition would be to make gfx_core operate on R::* structs entirely, not be aware of the tracked handles (which will live in gfx_render only), and minimize any heap allocations.

We need to provide a level of GPU abstraction that doesn't have any overhead over using some API bindings directly.

This is really difficult with regards to Vulkan/D3D12 as we would have to provide a very thin layer above those two APIs exposing concepts like resource barriers and explicit memory control. There was a talk by Chajdas concerning this some time ago (http://gpuopen.com/wp-content/uploads/2016/03/d3d12_vulkan_lessons_learned.pdf), which states that such a low level wrapper might be the best way for implementation.
(For gfx I started implementing something similar but I was kinda stuck at descriptor stuff and other projects had priority https://github.com/msiglreith/gfx/tree/gfx_next/src/core_next/src)

I assume the new architecture would be to implement core as some kind of bare metal API, which is kind of unsafe for the user. Render is then an higher-level entry point for users, which rather want an easy and safe gfx layer to use for quickly building applications, but don't need the full control over the GPU.

@msiglreith thanks for the info! You seem to not only understand the goal clearly, but also already having the first bits of the implementation. That's pretty impressive and exciting to see 馃憤

Small status update for corell:
Currently playing around with shaders and pipelines, trying to come up with a nice API and gathering all the required information to create a pipeline state (quite verbose!).
In my current design iteration I replaced Shader with ShaderLib, constisting of multiple shaders similar to Vulkan's SPIR-V modules and Metals .metallib approach. For pipeline creation the user then passes the library and an entrypoint (e.g "main") for each shader stage. (On OpenGL a shaderlib would always be a single shader with the fixed entrypoint "main".)

New factory interface (haven't worked out the factory methods for RenderPass and Signature so far):

fn create_shader_library(&mut self, code: &[u8]) -> Result<R::ShaderLib, shade::CreateShaderError>;
fn create_graphics_pipelines<'a>(&mut self, &[(&GraphicsShaderSet<R>, &R::PipelineSignature, &R::SubPass, &pso::GraphicsPipelineDesc)])
            -> Vec<Result<R::PipelineStateObject, pso::CreationError>>;
fn create_compute_pipelines(&mut self) -> Vec<Result<R::PipelineStateObject, pso::CreationError>>;

I'm still a bit unsure about how to handle SubPass and PipelineSignature (Vulkan: PipelineLayout, D3D12: RootSignature). Vulkan's PSO need to be compiled for a specific RenderPass and SubPass.
The PipelineSignature could be derived automatically from the render pso macro, but the user might want to fine-tune it to avoid register spilling and more efficient desciptor handling.
RenderPass would be emulated on the other backends by automatically insert the required transitions between the attachments.

Conceptually, this is implemented 馃帀 . Separate issues are filed for missing features.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Michael-Lfx picture Michael-Lfx  路  5Comments

Bastacyclop picture Bastacyclop  路  3Comments

kvark picture kvark  路  3Comments

Fluci picture Fluci  路  5Comments

InMath picture InMath  路  5Comments