Skip to content

Implement an abstraction layer for buffers and resources #280

@adriengivry

Description

@adriengivry

Problem this feature should fix

Buffers and resources such as shaders and textures currently use direct OpenGL calls to create/destroy/bind/unbind/resize... This causes the implementation of a proper HAL (Hardware Abstraction Layer) more tedious.

Expected solution

Following #277, the proposed HAL solution should be expanded to cover buffer and resource manipulation.

Additional Information

Libraries like BGFX usually provide functions in their HAL to manipulate buffers and resources, i.e.:
https://github.com/bkaradzic/bgfx/blob/07be0f213acd73a4f6845dc8f7b20b93f66b7cc4/include/bgfx/bgfx.h#L2779

Texture Creation

TextureHandle createTexture(
  const Memory* _mem
  , uint64_t _flags = BGFX_TEXTURE_NONE|BGFX_SAMPLER_NONE
  , uint8_t _skip = 0
  , TextureInfo* _info = NULL
);

Texture Read

uint32_t readTexture(
  TextureHandle _handle
  , void* _data
  , uint8_t _mip = 0
);

Bind Index Buffer

void setIndexBuffer(
  const TransientIndexBuffer* _tib
  , uint32_t _firstIndex
  , uint32_t _numIndices
);

Buffers and Resource classes should then use these driver functions in their cpp implementation.

Early investigations

The idea behind is to have 2 levels for resources:

  • one at the driver level, graphicsAPI-agnostic (using classes like Shader, Buffer, Texture, Framebuffer)
  • one internal to the graphics API, where resources are identified using ResourceHandle.
    Storing a ResourceHandle inside of a DriverResource allows us to make this connection between an engine/driver resource, vs an internal graphics API resource.

The Driver and GraphicsAPI will be responsible for implementing methods to:

  • Create/Destroy resources
  • Bind/Unbind resources
  • Update resources
    Provide other utility functions like reading back a pixel from a texture.

Another approach that I'm exploring would be to have resources (mainly buffers), with CPU/CPU copies of the underlying data, with the ability to upload data from the CPU to GPU using synchronization points (typically before rendering a frame you would process the buffer data upload all at once, to avoid unnecessary operations and potentially run these operations in parallel). Buffers could be created with flags like IMMEDIATE_BUFFER_TRANSFER and SYNCHRONIZED_BUFFER_TRANSFER.

image

Further considerations

We could also separate the HAL from OvRendering by introducing OvHAL or OvGraphics. This project would be 100% focused on providing a platform-agnostic way to manage graphics context, while OvRendering would provide a layer of abstraction and rendering features (lighting, post-processing, shadow casting, material system, etc...).

Metadata

Metadata

Assignees

No one assigned

    Labels

    GraphicsGraphical featureRefactoringSomething that needs a refactoring

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions