Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
  • This project
    • Loading...
  • Sign in / Register
A
angle
  • Project
    • Overview
    • Details
    • Activity
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 0
    • Issues 0
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Chen Yisong
  • angle
  • Repository

Switch branch/tag
  • angle
  • src
  • tests
  • gl_tests
  • StateChangeTest.cpp
Find file
BlameHistoryPermalink
  • Shahbaz Youssefi's avatar
    Vulkan: Reorder descriptor sets · 806d812e
    Shahbaz Youssefi authored Jan 03, 2020
    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: 's avatarTobin Ehlis <tobine@google.com>
    Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
    Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
    806d812e
StateChangeTest.cpp 172 KB
EditWeb IDE
×

Replace StateChangeTest.cpp

Attach a file by drag & drop or click to upload


Cancel
A new branch will be created in your fork and a new merge request will be started.