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

VideoCommon: Don't add garbage to shader uids in debug builds #10755

Merged
merged 1 commit into from Jun 22, 2022

Conversation

TellowKrinkle
Copy link
Contributor

Prevents debug builds from leaving stack data in UIDs, making them no longer compare equal

There wasn't anything stopping compilers from doing it in release builds either, but most optimizations would make the padding zero

There wasn't anything stopping compilers from doing it in release builds either, but most optimizations would make the padding zero
@iwubcode
Copy link
Contributor

iwubcode commented Jun 15, 2022

This is fine but I don't get why it's needed? Aren't the shader uid structs (ex geometry_shader_uid_data) containing bit-fields and thus default initialized by our brace initialization?

@Pokechu22
Copy link
Contributor

A similar memset call also already exists:

// We use memcmp() for comparing pipelines as std::tie generates a large number of instructions,
// and this map lookup can happen every draw call. However, as using memcmp() will also compare
// any padding bytes, we have to ensure these are zeroed out.
GXPipelineUid() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }

GXUberPipelineUid() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }

@TellowKrinkle
Copy link
Contributor Author

This is fine but I don't get why it's needed? Aren't the shader uid structs (ex geometry_shader_uid_data) containing bit-fields and thus default initialized by our brace initialization?

The active fields are initialized, but Clang doesn't think it needs to initialize the padding: https://gcc.godbolt.org/z/cf7KxdEcs

A similar memset call also already exists:

// We use memcmp() for comparing pipelines as std::tie generates a large number of instructions,
// and this map lookup can happen every draw call. However, as using memcmp() will also compare
// any padding bytes, we have to ensure these are zeroed out.
GXPipelineUid() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }

GXUberPipelineUid() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }

Indeed, we zero pipeline uids there. But then this happens:

  1. UpdatePipelineConfig calls UberShader::GetVertexShaderUid
    m_current_uber_pipeline_config.vs_uid = UberShader::GetVertexShaderUid();
  2. UberShader::GetVertexShaderUid creates a VertexShaderUid on the stack, populates it, and returns it. Padding bytes on the new VertexShaderUid are garbage.
    VertexShaderUid out;
    vertex_ubershader_uid_data* const uid_data = out.GetUidData();
    uid_data->num_texgens = xfmem.numTexGen.numTexGens;
    return out;
  3. The VertexShaderUid is copied into the pipeline uid, garbage padding included.

@shuffle2
Copy link
Contributor

shuffle2 commented Jun 17, 2022

  1. Can we enable some init-all compiler flag to just force all padding initialized? At least msvc and clang has this.
  2. Can this be solved instead by defining yet another constructor type to also do the memset? (The intent was that this was the case)
  3. Can it be solved by packing the structs?

Edit: I see you’re doing 2. Nvm then :p maybe the other topics are interesting though.

@delroth
Copy link
Member

delroth commented Jun 22, 2022

I was going to suggest to move this memset to individual uid_data constructors instead -- but since we're already checking that the types are POD / trivially copiable I think this is good enough.

I'm -0.5 on doing this via compiler flags, seems like a really big hammer for a very localized problem.

@delroth delroth merged commit 6ddff87 into dolphin-emu:master Jun 22, 2022
10 checks passed
@TellowKrinkle TellowKrinkle deleted the DebugUID branch June 22, 2022 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants