Vulkan: Reorder descriptor sets
This change moves driver uniforms to a set with a lower id than the one
that includes (emulation) transform feedback buffers. Imagine the
following:
- Program 1 with xfb: UniformsSet: 1 VS uniforms buffer, 1 FS uniforms
buffer, 1 xfb buffer
- Program 2 without xfb: UniformsSet: 1 VS uniforms bufer, 1 FS uniforms
buffer.
Previously, UniformsSet was index 0, and DriverUniformsSet was index 3.
When switching from Program 1 to Program 2, the layout of UniformsSet
changes, which means every subsequent set needs to be rebound. This is
a Vulkan pipeline layout compatibility rule. This is done with
invalidateCurrentTextures() and invalidateCurrentShaderResources()
already when handling gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE. The bug
is that the driver uniforms are not invalidated.
This is normally not an issue, because usually when switching from
Program 1 to Program 2, transform feedback is paused, and this state
change does invalidate driver uniforms. However, the following scenario
doesn't do this:
- Begin Xfb
- Pause Xfb
- Use Program 1
- Draw
- Use Program 2
- Draw
- End Xfb
There is no driver state change between the two draw calls, which means
the second draw will attempt to draw using the driver uniforms bound for
the first draw call. There is a Vulkan validation error here due to the
above pipeline layout validation rule.
The issue manifests itself only when the second draw call actually uses
driver uniforms, as otherwise that set is inactive and not validated;
i.e. when line raster emulation is used.
In summary, the validation error manifests itself when:
- Transform feedback and line raster both use emulation
- Transform feedback is paused
- A draw with an xfb program is followed by a non-xfb program
- The second draw is a line draw
A test is added for this.
The solution is to reorder the sets so that DriverUniformsSet is placed
before UniformsSet. This way, changes to the layout of UniformsSet
don't invalidate DriverUniformsSet.
In fact, based on the above, any change in the layout of the program
should have required an invalidation of the driver uniforms. This bug
is probably masked by the fact that
ContextVk::handleDirtyDescriptorSetsImpl() always rebinds the graphics
driver every time any descriptor set needs rebinding. That should be
removed in a follow up change.
Bug: angleproject:4261
Change-Id: I21ad4152b454a1fe70554be02e18a9c94fb3e7a8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1986927Reviewed-by:
Tobin Ehlis <tobine@google.com>
Reviewed-by:
Jamie Madill <jmadill@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Showing
Please
register
or
sign in
to comment