[MG_Backend] (Disaggregated): make Magma descriptors and present barriers Vulkan-valid

This commit is contained in:
2026-09-20 05:17:21 -04:00
parent 7f42cb9d78
commit 4f762262a0
3 changed files with 43 additions and 3 deletions
@@ -7,6 +7,9 @@
// End of Source File Header
#include "FrameContext.h"
#if MOBILEGL_BUILD_DISAGGREGATED
#include <Config.h>
#endif
namespace MobileGL::MG_Backend::DirectVulkan {
VkResult FrameContext::Initialize(VkDevice device, VkCommandPool commandPool, Uint32 frameCount) {
@@ -217,6 +220,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkImageMemoryBarrier presentBarrier{};
presentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
presentBarrier.srcAccessMask = 0;
#if MOBILEGL_BUILD_DISAGGREGATED
// A layout transition writes the image too. Order it after the wire
// render pass's storeOp, clears and copies instead of relying on the old
// per-draw queue-idle path. This applies even when contents are discarded.
if (MG_Config::Transport != MG_Config::TransportMode::Monolith)
presentBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
#endif
presentBarrier.dstAccessMask = 0;
presentBarrier.oldLayout = oldLayout;
presentBarrier.newLayout = presentLayout;
@@ -228,7 +238,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
presentBarrier.subresourceRange.levelCount = 1;
presentBarrier.subresourceRange.baseArrayLayer = 0;
presentBarrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0,
vkCmdPipelineBarrier(commandBuffer,
#if MOBILEGL_BUILD_DISAGGREGATED
MG_Config::Transport != MG_Config::TransportMode::Monolith
? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
#else
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
#endif
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0,
nullptr, 0, nullptr, 1, &presentBarrier);
if (openedRecording) {
@@ -3365,6 +3365,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
updateAfterBindSampledImages + updateAfterBindStorageImages;
const auto& uab = m_updateAfterBindLimits;
entry.usesUpdateAfterBind =
#if MOBILEGL_BUILD_DISAGGREGATED
// Vulkan forbids ANY update-after-bind binding in a set layout that
// contains a dynamic buffer descriptor (VUID 03001/03011). Wire draws
// retain UniformManager's per-frame, content-versioned descriptor sets;
// this selects the legal ordinary pool, not in-place mutation of a live set.
(!program.IsWire() || entry.dynamicBindings.empty()) &&
#endif
uab.enabled && updateAfterBindSamplers <= uab.maxPerStageSamplers &&
updateAfterBindUniformBuffers <= uab.maxPerStageUniformBuffers &&
updateAfterBindStorageBuffers <= uab.maxPerStageStorageBuffers &&
@@ -7667,7 +7667,16 @@ void main() {
VkMemoryBarrier memoryBarrier = BuildMemoryBarrierForGlBarriers(barriers);
MGLOG_D("DirectVulkan: glMemoryBarrier(0x%x)", static_cast<Uint32>(barriers));
vkCmdPipelineBarrier(frame.commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
vkCmdPipelineBarrier(frame.commandBuffer,
#if MOBILEGL_BUILD_DISAGGREGATED
// ALL_COMMANDS does not include HOST. The barrier's
// HOST_WRITE access must have a matching source stage.
MG_Config::Transport != MG_Config::TransportMode::Monolith
? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_HOST_BIT
: VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
#else
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
#endif
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
1, &memoryBarrier, 0, nullptr, 0, nullptr);
}
@@ -14277,7 +14286,14 @@ void main() {
descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
VkPhysicalDeviceDescriptorIndexingProperties descriptorIndexingProperties{};
descriptorIndexingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
const Bool descriptorIndexingCore = m_physicalDevice.properties.apiVersion >= VK_API_VERSION_1_2;
const Bool descriptorIndexingCore =
#if MOBILEGL_BUILD_DISAGGREGATED && !defined(VK_USE_PLATFORM_WIN32_KHR)
// CreateInstance requests Vulkan 1.1 on these platforms. A 1.2+ GPU
// does not promote descriptor indexing into that application's core
// API; the wire path must enable VK_EXT_descriptor_indexing instead.
(MG_Config::Transport == MG_Config::TransportMode::Monolith) &&
#endif
m_physicalDevice.properties.apiVersion >= VK_API_VERSION_1_2;
const Bool descriptorIndexingExtension =
IsExtensionSupported(availableExtensions, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
auto getPhysicalDeviceProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2>(