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

New shader_primitive_index::draw and shader_primitive_index::draw_indexed tests fail on Linux Vulkan back end #2751

Closed
jimblandy opened this issue Jun 8, 2022 · 12 comments · Fixed by #2754

Comments

@jimblandy
Copy link
Member

#2716 seems to break the following tests on Linux on a Vulkan back end:

shader_primitive_index::draw
shader_primitive_index::draw_indexed
---- shader_primitive_index::draw_indexed stdout ----
thread 'shader_primitive_index::draw_indexed' panicked at 'assertion failed: `(left == right)`
  left: `[255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255]`,
 right: `[255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255]`', wgpu/tests/shader_primitive_index/mod.rs:196:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'shader_primitive_index::draw_indexed' panicked at 'UNEXPECTED TEST FAILURE DUE TO PANIC', wgpu/tests/common/mod.rs:307:9

---- shader_primitive_index::draw stdout ----
thread 'shader_primitive_index::draw' panicked at 'assertion failed: `(left == right)`
  left: `[255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255]`,
 right: `[255, 255, 255, 255, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255]`', wgpu/tests/shader_primitive_index/mod.rs:196:5
thread 'shader_primitive_index::draw' panicked at 'UNEXPECTED TEST FAILURE DUE TO PANIC', wgpu/tests/common/mod.rs:307:9

@jimblandy
Copy link
Member Author

cc @kwillemsen @cwfitzgerald

@jimblandy jimblandy changed the title shader_primitive_index::draw and shader_primitive_index::draw_indexed tests broken by #2716 New shader_primitive_index::draw and shader_primitive_index::draw_indexed tests fail on Linux Vulkan back end Jun 8, 2022
@cwfitzgerald
Copy link
Member

To be fair, they added the tests

Any validation errors? What gpu?

@jimblandy
Copy link
Member Author

The GPU is "AMD RADV POLARIS12", according to wgpu-info.

@jimblandy
Copy link
Member Author

No Vulkan validation errors.

@kwillemsen
Copy link
Contributor

kwillemsen commented Jun 8, 2022

I've asked some colleagues to run the tests on their Windows machines with Radeon Pro WX3100 and Radeon Pro WX3200 GPUs. For them the tests succeed. Not sure if those GPUs have exactly the same chipset, though... I guess it is more likely that the problem is with the Linux driver. And it's even more likely the problem is with my changes 😝 Unfortunately I'm not experienced with (the internals of) Vulkan or spir-v, so I don't really know where to start looking here...

My current understanding is that the primitive_index built-in in the fragment shader requires the Geometry capability because it is generated by "geometry-shader-like" hardware (did I already mention I'm not familiar with low-level hardware stuff?). I was assuming nothing else would be required, but maybe that assumption is wrong, and some hardware and drivers just happen to generate the correct index, while technically the spir-v is wrong?

@jimblandy
Copy link
Member Author

I'm still trying to understand the context here, but I think your change was correct:

Vulkan §15.7 Builtin Variables says:

In a geometry shader, [a variable decorated with PrimitiveId] will contain the number of primitives presented as input to the shader since the current set of rendering primitives was started.

In a fragment shader, it will contain the primitive index written by the mesh shader if a mesh shader is present, or the primitive index written by the geometry shader if a geometry shader is present, or with the value that would have been presented as input to the geometry shader had it been present.

Since WGSL can't provide geometry or mesh shaders, a WGSL fragment shader's @builtin(primitive_index) argument should see "the number of primitives presented as input to the shader since the current set of rendering primitives was started." So it's as if you had sort of an empty or 'identity' geometry shader.

But the Geometry capability still needs to be present, per VUID-PrimitiveId-Fragment-04333:

If Fragment Execution Model contains a variable decorated with PrimitiveId, then either the MeshShadingNV, Geometry or Tessellation capability must also be declared

@jimblandy
Copy link
Member Author

jimblandy commented Jun 9, 2022

In case anyone's curious, I looked at the SPIR-V generated for the test's primitive_index.wgsl file.

SPIR-V disassembly
; SPIR-V
; Version: 1.0
; Generator: Khronos; 28
; Bound: 28
; Schema: 0
               OpCapability Shader
               OpCapability Geometry
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %fs_main "fs_main" %index %15
               OpExecutionMode %fs_main OriginUpperLeft
               OpSource GLSL 450
               OpName %index "index"
               OpName %fs_main "fs_main"
               OpDecorate %index BuiltIn PrimitiveId
               OpDecorate %15 Location 0
       %void = OpTypeVoid
      %float = OpTypeFloat 32
    %float_0 = OpConstant %float 0
    %float_1 = OpConstant %float 1
       %uint = OpTypeInt 32 0
     %uint_2 = OpConstant %uint 2
     %uint_0 = OpConstant %uint 0
    %v2float = OpTypeVector %float 2
    %v4float = OpTypeVector %float 4
%_ptr_Input_uint = OpTypePointer Input %uint
      %index = OpVariable %_ptr_Input_uint Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
         %15 = OpVariable %_ptr_Output_v4float Output
         %18 = OpTypeFunction %void
       %bool = OpTypeBool
    %fs_main = OpFunction %void None %18
         %11 = OpLabel
         %14 = OpLoad %uint %index
               OpBranch %19
         %19 = OpLabel
         %20 = OpUMod %uint %14 %uint_2
         %22 = OpIEqual %bool %20 %uint_0
               OpSelectionMerge %23 None
               OpBranchConditional %22 %24 %25
         %24 = OpLabel
         %26 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_1
               OpStore %15 %26
               OpReturn
         %25 = OpLabel
         %27 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_1
               OpStore %15 %27
               OpReturn
         %23 = OpLabel
               OpReturn
               OpFunctionEnd

@jimblandy
Copy link
Member Author

So my machine actually just colors both the NE and SW corners red. There's no blue. (NW and SE are white, as expected.) I wonder if this isn't a difference in rasterization.

@jimblandy
Copy link
Member Author

To avoid rasterization problems, I tried enlarging the texture to 4x4 and shifting the triangles to ensure that there was a pixel in each quadrant that was fully covered. With Vulkan "AMD RADV POLARIS12", everything is red. I suspect this means that the primitive ID is always being passed as zero.

With Vulkan "llvmpipe (LLVM 14.0.0, 256 bits)", the unmodified test passes.

@jimblandy
Copy link
Member Author

For the record, these drivers are from mesa-vulkan-drivers 22.0.3 on Fedora.

jimblandy added a commit to jimblandy/wgpu that referenced this issue Jun 9, 2022
On Fedora, mesa-vulkan-drivers 22.0.3 AMD RADV POLARIS12 just colors
both the NE and SW corners red. There's no blue. (NW and SE are white,
as expected.) I suspect
this means that the primitive ID is always being passed as zero.

This is probably not just due to a difference in rasterization: I
tried enlarging the texture to 4x4 and shifting the triangles to
ensure that there was a pixel in each quadrant that was fully covered.

With Vulkan "llvmpipe (LLVM 14.0.0, 256 bits)", the unmodified test passes.

This is probably limited to Linux, but
`wgpu_tests::common::TestParameters` doesn't have a slot for that.

Fixes gfx-rs#2751.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Jun 9, 2022
On Fedora, mesa-vulkan-drivers 22.0.3 AMD RADV POLARIS12 just colors
both the NE and SW corners red. There's no blue. (NW and SE are white,
as expected.) I suspect
this means that the primitive ID is always being passed as zero.

This is probably not just due to a difference in rasterization: I
tried enlarging the texture to 4x4 and shifting the triangles to
ensure that there was a pixel in each quadrant that was fully covered.

With Vulkan "llvmpipe (LLVM 14.0.0, 256 bits)", the unmodified test passes.

This is probably limited to Linux, but
`wgpu_tests::common::TestParameters` doesn't have a slot for that.

Fixes gfx-rs#2751.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Jun 9, 2022
On Fedora, mesa-vulkan-drivers 22.0.3 AMD RADV POLARIS12 just colors
both the NE and SW corners red. There's no blue. (NW and SE are white,
as expected.) I suspect
this means that the primitive ID is always being passed as zero.

This is probably not just due to a difference in rasterization: I
tried enlarging the texture to 4x4 and shifting the triangles to
ensure that there was a pixel in each quadrant that was fully covered.

With Vulkan "llvmpipe (LLVM 14.0.0, 256 bits)", the unmodified test passes.

This is probably limited to Linux, but
`wgpu_tests::common::TestParameters` doesn't have a slot for that.

Fixes gfx-rs#2751.
cwfitzgerald pushed a commit that referenced this issue Jun 10, 2022
On Fedora, mesa-vulkan-drivers 22.0.3 AMD RADV POLARIS12 just colors
both the NE and SW corners red. There's no blue. (NW and SE are white,
as expected.) I suspect
this means that the primitive ID is always being passed as zero.

This is probably not just due to a difference in rasterization: I
tried enlarging the texture to 4x4 and shifting the triangles to
ensure that there was a pixel in each quadrant that was fully covered.

With Vulkan "llvmpipe (LLVM 14.0.0, 256 bits)", the unmodified test passes.

This is probably limited to Linux, but
`wgpu_tests::common::TestParameters` doesn't have a slot for that.

Fixes #2751.
@victorvde
Copy link
Contributor

For what it;s worth I still get this test failure on "Intel(R) UHD Graphics (TGL GT2)", Arch Linux. vulkan-intel 22.1.2-1

@jimblandy
Copy link
Member Author

@victorvde My test exception was for AMD only, so it would not have affected Intel. See the PR for how I added it.

Maybe the bug is in all the Mesa Vulkan drivers, though.

jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 1, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 1, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 1, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 1, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 1, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit to jimblandy/wgpu that referenced this issue Sep 2, 2022
This removes an expected failure on AMD RADV. I guess gfx-rs#2751 was our
bug all along.
jimblandy added a commit that referenced this issue Sep 2, 2022
This removes an expected failure on AMD RADV. I guess #2751 was our
bug all along.
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 a pull request may close this issue.

4 participants