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

Fix set_push_constants bug. #6540

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
Open

Fix set_push_constants bug. #6540

wants to merge 11 commits into from

Conversation

fyellin
Copy link

@fyellin fyellin commented Nov 13, 2024

Fixes #6532.
Fixes #2683.

The use of RenderBundleEncoder.SetPushConstants would cause a panic on the subsequent call to RenderPass.ExecuteBundles(). The .finish() method was failing to copy its push_constant_data from the render bundle encoder to the render bundle.

Currently string_data is unused, but it seemed safest to copy it to prevent future bugs.

I have confirmed with a toy program that the old code panics and the new code works (and correctly accesses the pushed constants).

@fyellin fyellin requested a review from a team as a code owner November 13, 2024 18:20
@fyellin
Copy link
Author

fyellin commented Nov 13, 2024 via email

@fyellin
Copy link
Author

fyellin commented Nov 14, 2024

I realized the argument is self. So we own it. I can just use self.base.<field>. Also added tests to show that things are working now.

@fyellin
Copy link
Author

fyellin commented Nov 15, 2024

My changes fixed one bug, but it seems there is another bug in the Vulkan and DX12 implementation. For now, I can fix the code so that it works on everything else, but I don't know enough about the internal implementations of Vulkan or DX12. For Vulcan there is an error message that makes no sense. For DX12, naga seems to produce bad code, and there is a compiler failure.

My code in the test suite is just a basic use of SetPushConstant on a RenderPassEncoder and a RenderBundleEncoder. The fact that the code is now running successfully on RenderBundleEncoders means that I've fixed the generic bug. Someone else is going to need to fix the implementation specific bugs, since I don't know about the internals.

@teoxoy
Copy link
Member

teoxoy commented Nov 15, 2024

The DX12 issue is #5683 / #5571, can you wrap the push constants in the shader in a struct? That should get things working.

I think the Vulkan validation error is #4502. Can you change the test to not use non-0 start ranges? This will most likely become a validation error emitted by us in the future as the WebGPU spec proposal also doesn't allow users to specify non-0 start ranges.

@fyellin
Copy link
Author

fyellin commented Nov 15, 2024

I've converted the code to use a struct. The naga compiler does the right thing now.

Since push_constants no longer exists in WGPU or WebGPU, I was using the Vulkan documentation as my guide. According to those specs, one can separate the vertex shader constants from the fragment shader constants, and specify that a certain byte-range of the constants are are only for the vertex shader or only for the fragment shader. When doing this, you are also required to call set_push_constants separately for each of the byte-ranges.

So I performed multiple tests.

  1. Separate constants for the vertex shader and fragment shader.

    • Both Linux/Vulkan and Windows/DX12 failed. Linux gave the message that the "set_push_constant" was out of range. Windows
      gave the wrong answer.
  2. Create a single constant pool shared by both shaders. This seems to be the intent of the spec proposal you mentioned above.

    • Linux and Metal passed. Windows/DX12 ran, but gave the wrong answer.
  3. Create a single constant pool, but use two separate set_push_constant operations to separately push the constants intended for the vertex shader and those intended for the fragment shader.

    • The results were the same as previously. Windows/DX12 ran, but gave the wrong answer.

It seems that there are two possibly new bugs:

  • Linux/Vulkan cannot handle having the constants separated by stages, as per the Vulkan spec.
  • Windows/DX12 is just broken.
    It also seems that there is no problem with using a non-zero offset. Vulkan's problem is dealing with multiple stages.

I will resubmit my PR using #2 above, and exclude DX12.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RenderBundleEncoderSetPushConstants always crashes Push constants in render bundles are half-implemented
3 participants