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

Update syntax of GlUniformBuffer to match that of GlUniformInput #1683 #1690

Merged
merged 5 commits into from
Sep 22, 2024

Conversation

EdvinLndh
Copy link
Contributor

Made some similar changes as to what was done on #1683. Hope this is somewhat what you had in mind.

My first PR ever! =)

@heinezen heinezen linked an issue Sep 18, 2024 that may be closed by this pull request
3 tasks
@heinezen heinezen added improvement Enhancement of an existing component area: renderer Concerns our graphics renderer lang: c++ Done in C++ code labels Sep 18, 2024
Copy link
Member

@heinezen heinezen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks a lot! Also great that it runs when I tested it because that's not a given for contributions :D

There's a few things that still need to be added in the PR:

  • The changes in the GlUniformInput input class should be reflected in the GlUniformBufferInput class, i.e. in uniform_input.h both classes should look the same apart from the constructor. (This is part of the first task in the issue)
  • You need to add your info to the table in copying.md file in our repo. That's the reason why the CI fails currently.

@EdvinLndh
Copy link
Contributor Author

Ah, I see now that it says so quite clearly in the contribution page 😅.

I have made some changes to the GlUniformBufferInput class.

@heinezen
Copy link
Member

Nicely done! I'm currently testing your changes locally and will report back later.

Copy link
Member

@heinezen heinezen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good! I found one potential problem but once you have fixed that, it should be good to go.

Comment on lines 64 to 70
const auto &update_offs = glunif_in->update_offs;
uint8_t const *data = glunif_in->update_data.data();
for (auto const &pair : glunif_in->update_offs) {
uint8_t const *ptr = data + pair.second;
auto unif_def = this->uniforms[pair.first];
for (auto const &pair : this->uniforms_by_name) {
auto id = pair.second;
auto offset = update_offs[id];
uint8_t const *ptr = data + offset.offset;
auto unif_def = this->uniforms.find(pair.first)->second;
Copy link
Member

@heinezen heinezen Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not iterate through this->uniforms_by_name here and instead use glunif_in->used_uniforms. Reasons for this are:

  • UniformBufferInput can be partial updates where only a few uniforms in the buffer are updated and not all. If you iterate on this->uniforms_by_name, this could then read some uninitialized data into the buffer.
  • Iterating on a std::unordered_map like this->uniforms_by_name will be very slow compared to iterating on a std::vector (because of their memory layout). This is part of the reason why we want to "vectorize" these parameters: The vectors are much faster in our renderer.

You can check out the update for the regular UniformInput in this code sample for inspiration:

const auto &update_offs = unif_in->update_offs;
const auto &used_uniforms = unif_in->used_uniforms;
const auto &uniforms = this->uniforms;
uint8_t const *data = unif_in->update_data.data();
size_t unif_count = used_uniforms.size();
for (size_t i = 0; i < unif_count; ++i) {
uniform_id_t unif_id = used_uniforms[i];
const auto &update_off = update_offs[unif_id];
uint8_t const *ptr = data + update_off.offset;
const auto &unif = uniforms[unif_id];
auto loc = unif.location;

The syntax of your code can be roughly the same I think :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I think one of the reasons I went with that approach was in order to be able to lookup the GlBlockInUniform in the uniforms map. When iterating over the id's I'm not really sure how I should retrieve the correct value from the uniforms map. Do you think the uniforms attribute should be kept as a std::unordered_map?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this might be a good opportunity to change the type of GlUniformBuffer::uniforms to std::vector. That's already something we do for the uniforms in shader_program.h for uniforms outside of blocks:

/// Uniforms in the shader program. Contains only
/// uniforms in the default block, i.e. not within named blocks.
std::vector<GlUniform> uniforms;
/// Maps uniform names to their ID (the index in the uniform vector).
std::unordered_map<std::string, uniform_id_t> uniforms_by_name;

The change should be pretty straight-forward I hope. Apart from the type of uniforms, you'll have to change the constructor of GlUniformBuffer and the Renderer::add_uniform_buffer methods:

std::shared_ptr<UniformBuffer> GlRenderer::add_uniform_buffer(resources::UniformBufferInfo const &info) {

std::shared_ptr<UniformBuffer> GlRenderer::add_uniform_buffer(std::shared_ptr<ShaderProgram> const &prog,

Copy link
Member

@heinezen heinezen Sep 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shader_data.h also needs to be changed for the GlInBlockUniform:

/**
* Maps uniform names within this block to their descriptions.
*/
std::unordered_map<std::string, GlInBlockUniform> uniforms;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have now changed from std::unordered_map to std::vector. I did add a name attribute in the GlInBlockUniform. the name is used instead of the the key that was stored with the map previously, mostly debugging and for creating the uniforms_by_name map. I'm not sure if this is how it should be, but I suppose some performance was gained, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I'll check it out now.

@heinezen
Copy link
Member

The code already looks good. I'll run a few performance tests now.

@heinezen heinezen merged commit 66098ce into SFTtech:master Sep 22, 2024
13 checks passed
@heinezen
Copy link
Member

Very nice, it works like a charm and is also faster than before :)

@heinezen
Copy link
Member

@EdvinLndh If you want, there are other renderer issues that should be easily doable now that you worked with part of the code already 😄

@EdvinLndh
Copy link
Contributor Author

Cool! I'll check them out.

@EdvinLndh EdvinLndh deleted the uniform_syntax_change branch September 23, 2024 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: renderer Concerns our graphics renderer improvement Enhancement of an existing component lang: c++ Done in C++ code
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Use same syntax for updating uniform inputs and uniform buffer inputs
2 participants