From 54a8609c64a3944469446fe922e43d8242710f6e Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Fri, 31 Jul 2026 18:45:52 -0400 Subject: [PATCH] [Feat] (DirectVulkan): depth-stencil GetTexImage The depth-stencil ReadPixels core (per-aspect copies + CPU repack) is now shared, and glGetTexImage serves GL_DEPTH_COMPONENT / GL_DEPTH_STENCIL / GL_STENCIL_INDEX queries of depth textures with it instead of rejecting every non-color aspect (packed_depth_stencil.verify_get_tex_image.* now passes). --- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 35 ++++++++++++++++--- .../DirectVulkan/Renderer/VulkanRenderer.h | 6 ++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 55595df0..78e5484f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -7024,6 +7024,18 @@ void main() { return; } + ReadDepthStencilImageToClient(image, vkFormat, trackedLayout, imageAspect, mipLevel, baseArrayLayer, x, y, + width, height, format, type, pixels); + } + + void VulkanRenderer::ReadDepthStencilImageToClient(VkImage image, VkFormat vkFormat, VkImageLayout* trackedLayout, + VkImageAspectFlags imageAspect, Uint32 mipLevel, + Uint32 baseArrayLayer, GLint x, GLint y, GLsizei width, + GLsizei height, GLenum format, GLenum type, void* pixels) { + const Bool wantDepth = format != GL_STENCIL_INDEX; + const Bool wantStencil = format != GL_DEPTH_COMPONENT; + auto& frame = m_frameContext.GetCurrent(); + if (*trackedLayout == VK_IMAGE_LAYOUT_UNDEFINED) { MGLOG_E("DirectVulkan::ReadDepthStencilPixels skipped: source layout is undefined"); return; @@ -7272,10 +7284,6 @@ void main() { textureObject->GetExternalIndex()); return; } - if ((resource->aspect & VK_IMAGE_ASPECT_COLOR_BIT) == 0) { - MGLOG_E("DirectVulkan::GetTexImage skipped: only color textures are supported right now"); - return; - } auto& frame = m_frameContext.GetCurrent(); if (!frame.isCommandRecording) { @@ -7289,6 +7297,25 @@ void main() { "GetTexImage: failed to materialize pending clear for textureId=%d", textureObject->GetExternalIndex()); + if ((resource->aspect & VK_IMAGE_ASPECT_COLOR_BIT) == 0) { + if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL || format == GL_STENCIL_INDEX) { + const auto levelSize = + textureMipmapObject->GetMipmapTexelSize(textureUploadTarget, static_cast(level)); + const Bool isCubeFace = textureUploadTarget >= TextureUploadTarget::CubeMapPositiveX && + textureUploadTarget <= TextureUploadTarget::CubeMapNegativeZ; + const Uint32 arrayLayer = isCubeFace + ? static_cast(textureUploadTarget) - + static_cast(TextureUploadTarget::CubeMapPositiveX) + : 0; + ReadDepthStencilImageToClient(resource->image, resource->format, &resource->layout, resource->aspect, + static_cast(level), arrayLayer, 0, 0, levelSize.x(), + levelSize.y(), format, type, pixels); + } else { + MGLOG_E("DirectVulkan::GetTexImage skipped: color query of a non-color texture"); + } + return; + } + const auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadTarget, static_cast(level)); const GLsizei width = texelSize.x(); const GLsizei height = texelSize.y(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index acb6e073..e94434ff 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -205,6 +205,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { // CPU repacking into the requested client layout). void ReadDepthStencilPixels(MG_State::GLState::FramebufferObject& readFbo, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); + // Copy-and-repack core shared by depth-stencil ReadPixels and GetTexImage; + // expects command recording to be active and any render pass already ended. + void ReadDepthStencilImageToClient(VkImage image, VkFormat vkFormat, VkImageLayout* trackedLayout, + VkImageAspectFlags imageAspect, Uint32 mipLevel, Uint32 baseArrayLayer, + GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + void* pixels); static SizeT GetReadbackTexelSize(VkFormat sourceFormat); static Bool ConvertReadbackPixels(const Uint8* sourcePixels, VkFormat sourceFormat, GLsizei width, GLsizei height, GLenum destinationFormat,