Skip to content
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

Lower level GPU abstraction #1102

Closed
kvark opened this issue Dec 24, 2016 · 5 comments
Closed

Lower level GPU abstraction #1102

kvark opened this issue Dec 24, 2016 · 5 comments

Comments

@kvark
Copy link
Member

kvark commented Dec 24, 2016

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.

@kvark
Copy link
Member Author

kvark commented Dec 24, 2016

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.

@msiglreith
Copy link
Contributor

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.

@kvark
Copy link
Member Author

kvark commented Dec 25, 2016

@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 👍

homu added a commit that referenced this issue Jan 26, 2017
 Initial groundwork for a low level api

## Motivation
The next gen APIs (Vulkan and D3D12) offer an low level interface of the GPU in comparison to older APIs like OpenGL or D3D11. To avoid overhead due to high level abstraction we want to investigate the implementation of a thin wrapper above the mentioned low level APIs to address #1102.

## Goals
This PR creates a new low level core API `corell` and two backend implementations for the low level core. corell is heavily based on the vulkan API and shares a lot of concepts like `Instance`, `Surface`, etc., but tries to also take d3d12 into account. In future steps further abstractions could be considered to reduce the amount of setup code.

Planned coverage for this PR:
- [x] Instance/Context
- [x] Surface
- [x] Swapchain
- [x] PhysicalDevice

Note: Also includes some dummy types for other objects.
`format` and `memory` are mainly copied from `core`.

Hoping for early feedback if this is the intended way to go with regards to #1102.

cc @MaikKlein for quick checking ash based vulkan implementation if you have time 😄
@msiglreith
Copy link
Contributor

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.

@kvark
Copy link
Member Author

kvark commented Jan 22, 2018

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

@kvark kvark closed this as completed Jan 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants