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

UBO/SSBO Improvements, Structs, BufferObject and sub data update #1782

Merged
merged 4 commits into from
Jan 21, 2024

Conversation

riccardobl
Copy link
Member

This PR is made by multiple parts that together are used to reimplement UBOs and SSBOs in a more convenient and performant way. The main concepts are explained below

BufferObject

A BufferObject is a generic memory buffer that exists in OpenGL and from which all the other specialized buffers are derived. In JME we currently have some specialized Buffers (eg. VertexBuffer) but not a generic one.
This is needed to implement UBOs and SSBOs and can be used as parent class for VertexBuffer in a future refactoring, unlocking some performance improvements (see below)

BufferObject layout and sub data update

This PR introduces the concept of buffer layout, this is an abstraction and doesn't exist in OpenGL, nevertheless it can be used in jme to split the buffer in logical regions that can be marked for update and efficiently pushed to the GPU by the renderer while leaving the rest of the buffer untouched.

StructStd140BufferObject

This is an abstraction on top of BufferObject and BufferObject layouts, it generates an updates a BufferObject from a specially defined object that implements the Struct interface. This makes the creation and update of buffer objects user friendly and matches perfectly the glsl side of the code when using UBO/SSBO.
The goal when implementing this was to make it the default way to maintain BufferObjects (even inside the core), for this reason the implementation forces some limitations that are there to avoid any meaningful performance burden that might be caused by a more flexible implementation.
The limitations are:

  • Only fields that are of one of the types defined in com.jme3.util.struct.fields.* are serialized: this permits to track changes to the fields and update only what changes
  • Every serializable field must be final : this allows the code to trust that the class layout will never change

These limitations can be avoided by creating and maintaining the BufferObject manually with StructUtils, but shouldn't be needed in common usecases.

Usage example

This is an example and unit test for the UBO implementation

Final thoughts

This PR solves all the issues in he current UBO/SSBO implementation and, thanks to the sub data update, should always result in a performance improvement over sparse uniforms.
In future the bufferobject regions could be used to split large vertex buffers and allow a more efficient update (eg. for instances position).
There is an important change from the previous proposal (#1317) in the use of hardcoded com.jme3.util.struct.fields.* types, instead of a generic type StructField object, this is used to avoid ambiguity when using StructFields containing immutable types.
In the previous proposal, two methods were used:

  • setValue() : to update immutable fields
  • getValueForUpdate() : to update mutable fields

This is now handled internally by the com.jme3.util.struct.fields.* types.

@riccardobl
Copy link
Member Author

I am not 100% confident in the correctness of the std140 implementation.
I will start using this PR on some real code and see if any issue arises

@Ali-RS
Copy link
Member

Ali-RS commented Dec 31, 2022

What is the state of this? I see there are conflicts.
Can this become a candidate for the next release?
Is anybody willing to review and possibly merge it?

@riccardobl
Copy link
Member Author

PR updated to the current master.

@stephengold
Copy link
Member

This PR adds 37 Java source files. Please add the JME license (with appropriate year(s)) at the top of each file.

commit 81fe1e0
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:15:45 2022 +0200

    fix access to constructor

commit ac1d23c
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:15:18 2022 +0200

    Fix shader buffer block managment

commit cce6f80
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:14:56 2022 +0200

    Replace deprecated newInstance, pass exception to runtime exception

commit e917c4e
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:14:47 2022 +0200

    fix sub struct padding

commit 2f4e006
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:14:23 2022 +0200

    Fix UBO/SSBO rebinding

commit 58a371c
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Sun Apr 3 09:14:04 2022 +0200

    Ensure fields are final only when exported

commit ef7982d
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Tue Mar 8 21:10:07 2022 +0100

    Struct based BufferObjects and Std140 layout

commit 4797356
Author: riccardobl <riccardo0blb@gmail.com>
Date:   Tue Mar 8 20:49:01 2022 +0100

    Improved UBO/SSBO support implemented over generic BufferObjects with glBufferSubData support

commit 7f93b64
Author: Riccardo Balbo <riccardo@forkforge.net>
Date:   Thu Apr 2 14:40:41 2020 +0200

    Generic BufferObject and memory regions
@riccardobl
Copy link
Member Author

This PR is now rebased to the current master and with updated licenses

@scenemax3d scenemax3d merged commit 0b40bba into jMonkeyEngine:master Jan 21, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants