mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (DirectVulkan): answer a texture-image query from the CPU shadow when the texture has no VkImage
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "MG_State/GLState/SamplerState/SamplerObject.h"
|
||||
#include "MG_State/GLState/TextureState/TextureObject.h"
|
||||
#include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h"
|
||||
#include "MG_Impl/GLImpl/Texture/GL_Texture.h"
|
||||
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
|
||||
// Only reached from an MGLOG_W, which the shipping INFO log level compiles out - so the
|
||||
// missing include never broke a default build and did break every WARN/DEBUG-level one.
|
||||
@@ -10412,8 +10413,23 @@ void main() {
|
||||
|
||||
auto* resource = m_textureManager->SyncTextureAndGetDescriptor(*textureObject);
|
||||
if (resource == nullptr || resource->image == VK_NULL_HANDLE) {
|
||||
MGLOG_E_ONCE("DirectVulkan::GetTexImage skipped: failed to sync textureId=%u",
|
||||
// No VkImage exists for this texture, so by construction nothing GPU-side has ever
|
||||
// written it and the CPU shadow IS its content - answer from there instead of leaving
|
||||
// the caller's buffer untouched. Gated on "no image at all", never on "the image exists
|
||||
// but syncing it was inconvenient": a blanket shadow answer would silently return stale
|
||||
// bytes for every render-to-texture result.
|
||||
//
|
||||
// The live shape that lands here is a mutable texture whose GL level 0 was never defined
|
||||
// - glTexImage2D(GL_TEXTURE_2D, 5, ...) and nothing else, which is exactly what the
|
||||
// clear_tex_image conformance cases build. VkTextureManager refuses to back such a
|
||||
// texture (CheckMipmapCompleteness takes storage mip 0 as the image extent), so it is
|
||||
// invisible to sampling and rendering as well; this fallback fixes the readback only.
|
||||
MGLOG_D("DirectVulkan::GetTexImage: textureId=%u has no VkImage (GL level 0 undefined?); "
|
||||
"answering from the CPU shadow",
|
||||
textureObject->GetExternalIndex());
|
||||
MG_Impl::GLImpl::CopyTextureImageToClientOrPBO_State(textureObject, textureUploadTarget, level, format,
|
||||
type, bufSize, pixels,
|
||||
"DirectVulkan::GetTextureImage");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,17 @@
|
||||
|
||||
#pragma once
|
||||
#include <Includes.h>
|
||||
#include <MG_State/GLState/TextureState/TextureObject.h>
|
||||
|
||||
namespace MobileGL::MG_Impl::GLImpl {
|
||||
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
|
||||
// Answers a texture-image query straight out of the CPU shadow, honouring the pack state and a
|
||||
// bound PIXEL_PACK_BUFFER. This is the whole of glGetTexImage on a build with no backend
|
||||
// readback, and it is also the sound fallback for a backend that has no GPU image to read: with
|
||||
// no image, nothing GPU-side can ever have written the texture, so the shadow IS its content.
|
||||
void CopyTextureImageToClientOrPBO_State(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject,
|
||||
TextureUploadTarget textureUploadTarget, GLint level, GLenum format,
|
||||
GLenum type, GLsizei bufSize, void* pixels, const char* caller);
|
||||
// The sized internal formats a buffer texture accepts (GL 4.6 core table 8.16). The buffer
|
||||
// clears take the same list, so it is shared rather than written out twice.
|
||||
Bool IsBufferTextureInternalFormat(GLenum internalformat);
|
||||
|
||||
Reference in New Issue
Block a user