Skip to content

ImageLayouts.kt

src/jvmMain/kotlin/afield/graphics/vulkan/device/ImageLayouts.kt · 46 lines

package afield.graphics.vulkan.device

import org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
import org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_GENERAL
import org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_PREINITIALIZED
import org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_UNDEFINED

Maps Field's logical image layouts to the layout handed to Vulkan, collapsing to GENERAL when the driver supports VK_KHR_unified_image_layouts.

Every call that passes a layout to Vulkan goes through vkLayout; ImageLayouts holds the switch that Device sets.

object ImageLayouts

VK_KHR_unified_image_layouts: with it, GENERAL is as good as any specialised layout for every use, so a driver that offers it has nothing to gain from Field's per-use layouts, and a layered driver such as KosmicKrisp has work to lose (a transition it must honour for Metal).

Field keeps its logical layouts everywhere: afield.graphics.texture.Image's per-command-buffer tracking, every comparison that decides whether a barrier is needed, and every barrier itself. Those still carry the synchronisation. Only the value handed to Vulkan changes, through vkLayout, at each call that takes a layout — barriers, descriptor and attachment infos, copies, blits, clears. Because the mapping is a pure function of the logical layout, the two ends of every transition agree, which is the one thing a partial conversion would get wrong.

Kept as they are: UNDEFINED and PREINITIALIZED (they discard or describe initial contents) and PRESENT_SRC_KHR (presentation still requires it).

object ImageLayouts {

var unified: Boolean

Set by Device once unifiedImageLayouts is enabled; off with OpenXR, whose runtimes expect specific layouts on swapchain release.

    @Volatile
    var unified: Boolean = false
        internal set

fun vk(layout: Int): Int

    fun vk(layout: Int): Int =
        if (!unified || layout == VK_IMAGE_LAYOUT_UNDEFINED || layout == VK_IMAGE_LAYOUT_PREINITIALIZED ||
            layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
        ) layout else VK_IMAGE_LAYOUT_GENERAL
}

fun vkLayout(layout: Int): Int = ImageLayouts.vk(layout)

The layout to hand Vulkan for logical layout; see ImageLayouts.