[Fix] (MG_Backend/DirectVulkan): support Voxy rendering

Implemented:

- Advertise Voxy-required DirectVulkan extensions without raising the reported OpenGL version.

- Add DirectVulkan compute, indirect draw count, DSA, readback, and buffer state paths needed by Voxy.

Fixed:

- Enable Vulkan shaderInt64 and drawIndirectFirstInstance so Voxy baseInstance-driven LOD draws address the correct section data.

- Fix DirectVulkan synchronization, framebuffer, texture readback, and shader interface handling used by Voxy and Minecraft screenshots.

Tests:

- Add MG_Test coverage for DirectVulkan extension advertising, DSA buffer/texture/framebuffer/vertex-array behavior, persistent mapped readback, and shader/program paths.
This commit is contained in:
2026-06-09 00:37:37 +08:00
parent ab9db43599
commit cf165c0db5
65 changed files with 3724 additions and 239 deletions
@@ -621,7 +621,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat());
const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo);
perMipSampledView = CreateImageView(resource->image, resource->format, resource->aspect, resource->viewType,
const VkImageAspectFlags sampledAspect = ResolveSampledImageViewAspectMask(resource->aspect);
perMipSampledView = CreateImageView(resource->image, resource->format, sampledAspect, resource->viewType,
mipLevel, 1, resource->arrayLayers, &sampledComponents);
if (perMipSampledView == VK_NULL_HANDLE) {
MGLOG_D("%s: CreateImageView failed for textureId=%d mipLevel=%u", __func__, texture.GetExternalIndex(),
@@ -1014,6 +1015,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void VkTextureManager::DeferResourceRelease(TextureResource&& resource) {
if (resource.image == VK_NULL_HANDLE && resource.fullView == VK_NULL_HANDLE &&
resource.sampledView == VK_NULL_HANDLE &&
resource.perMipViews.empty() && resource.perMipSampledViews.empty()) {
return;
}
@@ -1088,6 +1090,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const Bool needsRecreate =
resource.fullView == VK_NULL_HANDLE ||
resource.sampledView == VK_NULL_HANDLE ||
resource.sampledBaseMipLevel != baseMipLevel ||
resource.sampledLevelCount != levelCount ||
resource.syncedTextureParamsVersion != texture.GetTextureParamsVersion();
@@ -1099,6 +1102,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
DeferViewRelease(resource.fullView);
resource.fullView = VK_NULL_HANDLE;
}
if (resource.sampledView != VK_NULL_HANDLE) {
DeferViewRelease(resource.sampledView);
resource.sampledView = VK_NULL_HANDLE;
}
for (auto& sampledView : resource.perMipSampledViews) {
if (sampledView != VK_NULL_HANDLE) {
DeferViewRelease(sampledView);
@@ -1109,10 +1116,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat());
const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo);
resource.fullView = CreateImageView(resource.image, resource.format, resource.aspect, resource.viewType,
baseMipLevel, levelCount, resource.arrayLayers, &sampledComponents);
baseMipLevel, levelCount, resource.arrayLayers);
if (resource.fullView == VK_NULL_HANDLE) {
return false;
}
const VkImageAspectFlags sampledAspect = ResolveSampledImageViewAspectMask(resource.aspect);
resource.sampledView = CreateImageView(resource.image, resource.format, sampledAspect, resource.viewType,
baseMipLevel, levelCount, resource.arrayLayers, &sampledComponents);
if (resource.sampledView == VK_NULL_HANDLE) {
return false;
}
resource.sampledBaseMipLevel = baseMipLevel;
resource.sampledLevelCount = levelCount;
@@ -1441,4 +1454,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
VkImageAspectFlags VkTextureManager::ResolveSampledImageViewAspectMask(VkImageAspectFlags imageAspect) {
if ((imageAspect & VK_IMAGE_ASPECT_COLOR_BIT) != 0) {
return VK_IMAGE_ASPECT_COLOR_BIT;
}
if ((imageAspect & VK_IMAGE_ASPECT_DEPTH_BIT) != 0) {
return VK_IMAGE_ASPECT_DEPTH_BIT;
}
if ((imageAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) {
return VK_IMAGE_ASPECT_STENCIL_BIT;
}
return imageAspect;
}
} // namespace MobileGL::MG_Backend::DirectVulkan