• Show log

    Commit

  • Hash : cecefe53
    Author : Igor Nazarov
    Date : 2024-11-21T22:11:17

    Vulkan: Improve recreateSwapchain() error handling
    
    The `WindowSurfaceVk::recreateSwapchain()` method may fail in many
    points. After failing, state of `WindowSurfaceVk` may become invalid,
    causing undefined behavior.
    
    Invalid state examples:
    - Skip adding `cleanupData` into the `mOldSwapchains` while
      `mPresentHistory already cleared (resource leak).
    - `mSwapchain` may remain `VK_NULL_HANDLE` after the failure.
    - `lastSwapchain` may be not retired, causing subsequent swapchain
      creation to fail.
    
    Change adds `mLastSwapchain` member to continue tracking last created
    swapchain during the `mSwapchain` recreation process until it is
    retired. This process now may span multiple API calls. The `mSwapchain`
    pointer is invalidated as soon as recreate starts - to indicate that we
    do not have usable swapchain and still need to create one.
    
    Notable difference with the old code is that old swapchain and present
    history are now collected into the `mOldSwapchains` after new swapchain
    is created (or old swapchain is retired in case of a failure). Because
    of this, code can now be simplified and easily refactored into a
    separate method. The `kMaxOldSwapchains` is now also checked after old
    swapchain is collected - this is to prevent resource leak if `finish()`
    fails. Added `cleanUpOldSwapchains()` call to reduce a chance of hitting
    the `kMaxOldSwapchains` limit.
    
    Change also renamed `presentOutOfDate` parameter where it does not
    always make sense. As a side effect, fixed a bug when calling
    `prepareForAcquireNextSwapchainImage()` with true, is then replaced
    with false in the `computePresentOutOfDate()` call.
    
    Bug: angleproject:380234227
    Change-Id: Ie6d85c1b9760cda68c8fc9368235756659a9bdac
    Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6040159
    Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
    Reviewed-by: Charlie Lao <cclao@google.com>
    Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
    

  • Properties

  • Git HTTP https://git.kmx.io/kc3-lang/angle.git
    Git SSH git@git.kmx.io:kc3-lang/angle.git
    Public access ? public
    Description

    A conformant OpenGL ES implementation for Windows, Mac, Linux, iOS and Android.

    Homepage

    Github

    Users
    kc3_lang_org thodg_w www_kmx_io thodg_l thodg thodg_m
    Tags

  • README.md

  • ANGLE: Vulkan Back-end

    ANGLE’s Vulkan back-end implementation lives in this folder.

    Vulkan is an explicit graphics API. Compared to APIs like OpenGL or D3D11 explicit APIs can offer a number of significant benefits:

    • Lower API call CPU overhead.
    • A smaller API surface with more direct hardware control.
    • Better support for multi-core programming.
    • Vulkan in particular has open-source tooling and tests.

    Back-end Design

    The vk::Renderer class represents an EGLDisplay. vk::Renderer owns shared global resources like the VkDevice, VkQueue, the Vulkan format tables and internal Vulkan shaders. The ContextVk class implements the back-end of a front-end OpenGL Context. ContextVk processes state changes and handles action commands like glDrawArrays and glDrawElements.

    Command recording

    A render pass has three states: unstarted, started and active (we call it active in short), started but inactive (we call it inactive in short). The back-end records commands into command buffers via the following ContextVk APIs:

    • beginNewRenderPass: Writes out (aka flushes) prior pending commands into a primary command buffer, then starts a new render pass. Returns a secondary command buffer inside a render pass instance.
    • getOutsideRenderPassCommandBuffer: May flush prior command buffers and close the render pass if necessary, in addition to issuing the appropriate barriers. Returns a secondary command buffer outside a render pass instance.
    • getStartedRenderPassCommands: Returns a reference to the currently open render pass’ commands buffer.
    • onRenderPassFinished: Puts render pass into inactive state where you can not record more commands into secondary command buffer, except in some special cases where ANGLE does some optimization internally.
    • flushCommandsAndEndRenderPassWithoutSubmit: Marks the end of render pass. It flushes secondary command buffer into vulkan’s primary command buffer, puts secondary command buffer back to unstarted state and then goes into recycler for reuse.

    The back-end (mostly) records Image and Buffer barriers through additional CommandBufferAccess APIs, the result of which is passed to getOutsideRenderPassCommandBuffer. Note that the barriers are not actually recorded until getOutsideRenderPassCommandBuffer is called:

    • onBufferTransferRead and onBufferComputeShaderRead accumulate VkBuffer read barriers.
    • onBufferTransferWrite and onBufferComputeShaderWrite accumulate VkBuffer write barriers.
    • onBuffferSelfCopy is a special case for VkBuffer self copies. It behaves the same as write.
    • onImageTransferRead and onImageComputerShadeRead accumulate VkImage read barriers.
    • onImageTransferWrite and onImageComputerShadeWrite accumulate VkImage write barriers.
    • onImageRenderPassRead and onImageRenderPassWrite accumulate VkImage barriers inside a started RenderPass.

    After the back-end records commands to the primary buffer and we flush (e.g. on swap) or when we call vk::Renderer::finishQueueSerial, ANGLE submits the primary command buffer to a VkQueue.

    See the code for more details.

    Simple command recording example

    In this example we’ll be recording a buffer copy command:

        // Ensure that ANGLE sets proper read and write barriers for the Buffers.
        vk::CommandBufferAccess access;
        access.onBufferTransferWrite(dstBuffer);
        access.onBufferTransferRead(srcBuffer);
    
        // Get a pointer to a secondary command buffer for command recording.
        vk::OutsideRenderPassCommandBuffer *commandBuffer;
        ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
    
        // Record the copy command into the secondary buffer. We're done!
        commandBuffer->copyBuffer(srcBuffer->getBuffer(), dstBuffer->getBuffer(), copyCount, copies);

    Additional Reading

    More implementation details can be found in the doc directory: