[Misc] (MG_Backend/DirectGLES): Separate BackendTextureObject::SyncToBackend

This commit is contained in:
BZLZHH
2026-02-02 20:35:03 +08:00
parent 39a8e72ee9
commit de17fdf5b0
3 changed files with 297 additions and 240 deletions
@@ -192,7 +192,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
} else { } else {
backendTextureObject = backendTextureIt->second; backendTextureObject = backendTextureIt->second;
} }
backendTextureObject->SyncToBackend(textureObject); backendTextureObject->SyncTextureParamsToBackend(textureObject);
backendTextureObject->SyncBuiltinSamplerToBackend(textureObject);
backendTextureObject->SyncMipmapsToBackend(textureObject);
return backendTextureObject; return backendTextureObject;
} }
+97 -44
View File
@@ -319,17 +319,24 @@ namespace MobileGL::MG_Backend::DirectGLES {
return m_backendTextureId; return m_backendTextureId;
} }
void BackendTextureObject::SyncToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) { void BackendTextureObject::SyncMipmapsToBackend(
#ifdef TRACY_ENABLE SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) { if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend."); MGLOG_E("State texture object is null, cannot sync to backend.");
return; return;
} }
MGLOG_D("Syncing texture with backend ID %u to backend for state ID %u", m_backendTextureId, if (!stateTextureObject->CheckDirtyBit(MG_State::GLState::TextureDirtyBit::StorageDirtyBit)) {
MGLOG_D("Texture parameters changed but storage is not dirty, skipping mipmap sync for texture ID: %u",
m_backendTextureId);
return;
}
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
DebugImpl::ErrorLopper errorLopper;
MGLOG_D("Syncing texture mipmaps with backend ID %u to backend for state ID %u", m_backendTextureId,
stateTextureObject->GetExternalIndex()); stateTextureObject->GetExternalIndex());
GLenum target = MG_Util::ConvertTextureTargetToGLEnum(stateTextureObject->GetTarget()); GLenum target = MG_Util::ConvertTextureTargetToGLEnum(stateTextureObject->GetTarget());
@@ -354,11 +361,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
return; return;
} }
// BackendTextureBindingProtector backendTextureBindingProtector(target);
Bind(target); Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
const auto baseSize = stateTextureObject->GetBaseSize(); const auto baseSize = stateTextureObject->GetBaseSize();
StateTextureBasicInfo currentTextureInfo = {stateTextureObject->GetFormat(), StateTextureBasicInfo currentTextureInfo = {stateTextureObject->GetFormat(),
static_cast<SizeT>(baseSize.x()), static_cast<SizeT>(baseSize.x()),
@@ -366,8 +370,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
static_cast<SizeT>(baseSize.z()), static_cast<SizeT>(baseSize.z()),
0, 0,
0}; 0};
if (stateTextureObject->CheckDirtyBit(MG_State::GLState::TextureDirtyBit::StorageDirtyBit)) {
switch (stateTextureObject->GetStorageType()) { switch (stateTextureObject->GetStorageType()) {
case TextureStorageType::Mipmap: { case TextureStorageType::Mipmap: {
auto* textureMipmapObject = auto* textureMipmapObject =
@@ -382,8 +384,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str()); MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str());
if (needsRegeneration) { if (needsRegeneration) {
MGLOG_D( MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
"Texture state changed significantly or not initialized, regenerating texture with ID: %u",
m_backendTextureId); m_backendTextureId);
// Regenerate all mipmap levels // Regenerate all mipmap levels
@@ -403,9 +404,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
: nullptr; : nullptr;
MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p, " MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p, "
"levelDirty = %s", "levelDirty = %s",
__func__, MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), __func__, MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level,
level, levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData,
levelByteSize, pData, levelDirty ? "true" : "false"); levelDirty ? "true" : "false");
errorLopper.Clear(); errorLopper.Clear();
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
@@ -416,15 +417,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
case TextureTarget::TextureCubeMap: { case TextureTarget::TextureCubeMap: {
MG_External::GLES::glTexImage2D( MG_External::GLES::glTexImage2D(
glUploadTarget, static_cast<GLint>(level), glInternalFormat, glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType, pData); 0, glFormat, glType, pData);
break; break;
} }
case TextureTarget::Texture3D: { case TextureTarget::Texture3D: {
MG_External::GLES::glTexImage3D( MG_External::GLES::glTexImage3D(
glUploadTarget, static_cast<GLint>(level), glInternalFormat, glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData); static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData);
break; break;
} }
@@ -435,8 +435,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, glUploadTarget, errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, glUploadTarget,
glInternalFormat, glFormat, glType, pData](GLenum err) { glInternalFormat, glFormat, glType, pData](GLenum err) {
MGLOG_D( MGLOG_D("%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, "
"%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, "
"type=%s, pixels=%p", "type=%s, pixels=%p",
func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(), func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(),
MG_Util::ConvertGLEnumToString(glUploadTarget).c_str(), MG_Util::ConvertGLEnumToString(glUploadTarget).c_str(),
@@ -444,8 +443,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertGLEnumToString(glFormat).c_str(), MG_Util::ConvertGLEnumToString(glFormat).c_str(),
MG_Util::ConvertGLEnumToString(glType).c_str(), pData); MG_Util::ConvertGLEnumToString(glType).c_str(), pData);
}); });
MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId);
m_backendTextureId);
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
} }
} }
@@ -485,10 +483,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertGLEnumToString(err).c_str()); MG_Util::ConvertGLEnumToString(err).c_str());
}); });
auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
MG_External::GLES::glTexSubImage2D( MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0,
glUploadTarget, static_cast<GLint>(level), 0, 0, static_cast<GLsizei>(texelSize.x()),
static_cast<GLsizei>(texelSize.x()), static_cast<GLsizei>(texelSize.y()), glFormat, static_cast<GLsizei>(texelSize.y()), glFormat, glType,
glType, textureMipmapObject->MapMipmapData(uploadTarget, level)); textureMipmapObject->MapMipmapData(uploadTarget, level));
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
} }
} }
@@ -526,8 +524,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto backendId = backendBufferObject->GetBackendBufferId(); auto backendId = backendBufferObject->GetBackendBufferId();
GLenum glInternalFormat, glType, glFormat; GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat,
&glFormat, &glType); &glType);
MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId); MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId);
@@ -537,9 +535,44 @@ namespace MobileGL::MG_Backend::DirectGLES {
default: default:
THROW_UNIMPL_EXCEPTION; THROW_UNIMPL_EXCEPTION;
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
m_prevTextureInfo = currentTextureInfo;
} }
{ // Update built-in sampler parameters void BackendTextureObject::SyncBuiltinSamplerToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend.");
return;
}
MGLOG_D("Syncing texture built-in sampler with backend ID %u to backend for state ID %u",
m_backendTextureId, stateTextureObject->GetExternalIndex());
GLenum target = MG_Util::ConvertTextureTargetToGLEnum(stateTextureObject->GetTarget());
auto targetInternal = stateTextureObject->GetTarget();
MGLOG_D(" Texture target for syncing is %s",
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
if (!IsSupportedTextureTarget(targetInternal)) {
MGLOG_E(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
return;
}
Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
// Update built-in sampler parameters
MGLOG_D("Updating sampler parameters for texture with ID: %u", m_backendTextureId); MGLOG_D("Updating sampler parameters for texture with ID: %u", m_backendTextureId);
const auto& samplerParams = stateTextureObject->GetSamplerObject()->GetAllSamplerParameters(); const auto& samplerParams = stateTextureObject->GetSamplerObject()->GetAllSamplerParameters();
@@ -592,22 +625,49 @@ namespace MobileGL::MG_Backend::DirectGLES {
#undef SYNC_TEX_SAMPLER_PARAM_IF_CHANGED #undef SYNC_TEX_SAMPLER_PARAM_IF_CHANGED
} }
{ // Update texture parameters void BackendTextureObject::SyncTextureParamsToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend.");
return;
}
MGLOG_D("Syncing texture params with backend ID %u to backend for state ID %u", m_backendTextureId,
stateTextureObject->GetExternalIndex());
GLenum target = MG_Util::ConvertTextureTargetToGLEnum(stateTextureObject->GetTarget());
auto targetInternal = stateTextureObject->GetTarget();
MGLOG_D(" Texture target for syncing is %s",
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
if (!IsSupportedTextureTarget(targetInternal)) {
MGLOG_E(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
return;
}
Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
// Update texture parameters
MGLOG_D("Updating texture parameters for texture with ID: %u", m_backendTextureId); MGLOG_D("Updating texture parameters for texture with ID: %u", m_backendTextureId);
const auto& levelRange = stateTextureObject->GetLevelRange(); const auto& levelRange = stateTextureObject->GetLevelRange();
if (m_cacheLodRange.x() != levelRange.x()) { if (m_cacheLodRange.x() != levelRange.x()) {
MG_External::GLES::glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, MG_External::GLES::glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast<GLint>(levelRange.x()));
static_cast<GLint>(levelRange.x()));
m_cacheLodRange.x() = levelRange.x(); m_cacheLodRange.x() = levelRange.x();
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
if (m_cacheLodRange.y() != levelRange.y()) { if (m_cacheLodRange.y() != levelRange.y()) {
MG_External::GLES::glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, MG_External::GLES::glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(levelRange.y()));
static_cast<GLint>(levelRange.y()));
m_cacheLodRange.y() = levelRange.y(); m_cacheLodRange.y() = levelRange.y();
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
@@ -644,13 +704,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
m_prevTextureInfo = currentTextureInfo;
}
UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>> UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>>
g_backendTextureObjects; g_backendTextureObjects;
} // namespace TextureImpl } // namespace TextureImpl
+3 -1
View File
@@ -86,7 +86,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
class BackendTextureObject { class BackendTextureObject {
public: public:
BackendTextureObject(); BackendTextureObject();
void SyncToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject); void SyncMipmapsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncBuiltinSamplerToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncTextureParamsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void Bind(GLenum target); void Bind(GLenum target);
Uint GetBackendTextureId(); Uint GetBackendTextureId();