mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (MG_Backend/DirectGLES): Correct MRT sync.
This commit is contained in:
@@ -398,113 +398,101 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
MGLOG_E("State FBO object is null, cannot sync to backend.");
|
MGLOG_E("State FBO object is null, cannot sync to backend.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MGLOG_D("Syncing FBO with backend ID %u to backend for state ID %u, as %s FBO", m_backendFBOId,
|
MGLOG_D("Syncing FBO with backend ID %u to backend for state ID %u, as %s FBO", m_backendFBOId,
|
||||||
stateFBOObject->GetExternalIndex(), (asTarget == FramebufferTarget::Draw ? "DRAW" : "READ"));
|
stateFBOObject->GetExternalIndex(), (asTarget == FramebufferTarget::Draw ? "DRAW" : "READ"));
|
||||||
|
|
||||||
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
||||||
BackendFramebufferBindingProtector backendFBOBindingProtector(glFBOTarget);
|
BackendFramebufferBindingProtector backendFBOBindingProtector(glFBOTarget);
|
||||||
|
|
||||||
Bind(asTarget);
|
Bind(asTarget);
|
||||||
|
|
||||||
if (asTarget == FramebufferTarget::Draw) {
|
// Handle all attachments
|
||||||
int nBuffers = 0;
|
const auto& attachments = stateFBOObject->GetAllAttachments();
|
||||||
// Attach attachment to FBO, realize `glDrawBuffers`
|
for (SizeT i = 0; i < attachments.size(); ++i) {
|
||||||
if (stateFBOObject->DrawBuffersIsDirty()) {
|
const auto& attachment = attachments[i];
|
||||||
std::fill(m_frontendBuffers,
|
if (!attachment.IsValid() || attachment.IsEmpty()) {
|
||||||
m_frontendBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
continue;
|
||||||
std::fill(m_backendBuffers,
|
|
||||||
m_backendBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
|
||||||
auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
|
||||||
for (GLint i = 0; i < stateDrawBuffers.size(); ++i) {
|
|
||||||
m_frontendBuffers[i] = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(stateDrawBuffers[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
MGLOG_D("%s: mapping draw buffers gl -> es:", __func__);
|
|
||||||
for (int i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
|
||||||
if (m_frontendBuffers[i] == GL_NONE) {
|
|
||||||
MGLOG_D("(m_frontendBuffers[%d] = GL_NONE), skipped", i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_backendBuffers[nBuffers] = GL_COLOR_ATTACHMENT0 + nBuffers;
|
|
||||||
m_compactedFrontendBuffers[nBuffers] = m_frontendBuffers[i];
|
|
||||||
MGLOG_D("(m_frontendBuffers[%d] = %s) -> %s", i,
|
|
||||||
MG_Util::ConvertGLEnumToString(m_frontendBuffers[i]).c_str(),
|
|
||||||
MG_Util::ConvertGLEnumToString(m_backendBuffers[nBuffers]).c_str());
|
|
||||||
nBuffers++;
|
|
||||||
}
|
|
||||||
|
|
||||||
MG_External::GLES::glDrawBuffers(nBuffers, m_backendBuffers);
|
|
||||||
|
|
||||||
stateFBOObject->ClearDrawBuffersDirtyState();
|
|
||||||
}
|
}
|
||||||
|
FramebufferAttachmentType type = static_cast<FramebufferAttachmentType>(i);
|
||||||
// Sync all attachments
|
GLenum glAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(type);
|
||||||
const auto& attachments = stateFBOObject->GetAllAttachments();
|
if (attachment.IsTexture()) {
|
||||||
for (SizeT i = 0; i < nBuffers; ++i) {
|
const auto& textureObject = attachment.GetTexture();
|
||||||
FramebufferAttachmentType frontendAttachmentType =
|
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
||||||
MG_Util::ConvertGLEnumToFramebufferAttachmentType(m_compactedFrontendBuffers[i]);
|
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
||||||
GLenum glBackendAttachmentType = m_backendBuffers[i];
|
MGLOG_E("No backend texture found for FBO attachment, cannot bind texture.");
|
||||||
|
continue;
|
||||||
const auto& attachment = attachments[(SizeT)frontendAttachmentType];
|
}
|
||||||
if (!attachment.IsComplete()) {
|
const auto& backendTextureObject = backendTextureIt->second;
|
||||||
|
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
||||||
|
backendTextureObject->Bind(glTextureTarget);
|
||||||
|
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glAttachment, glTextureTarget,
|
||||||
|
backendTextureObject->GetBackendTextureId(),
|
||||||
|
static_cast<GLint>(attachment.GetTextureLevel()));
|
||||||
|
} else if (attachment.IsRenderbuffer()) {
|
||||||
|
// TODO: renderbuffer support
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Handle draw buffers for DRAW_FRAMEBUFFER
|
||||||
|
if (asTarget == FramebufferTarget::Draw) {
|
||||||
|
// Create mappings for draw buffers
|
||||||
|
int nBuffers = 0;
|
||||||
|
std::fill(m_frontendBuffers, m_frontendBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
||||||
|
GL_NONE);
|
||||||
|
std::fill(m_backendBuffers, m_backendBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
||||||
|
GL_NONE);
|
||||||
|
std::fill(m_compactedFrontendBuffers,
|
||||||
|
m_compactedFrontendBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
||||||
|
auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
||||||
|
for (GLint i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
||||||
|
if (stateDrawBuffers[i] == FramebufferAttachmentType::None) {
|
||||||
|
m_frontendBuffers[i] = GL_NONE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment.IsTexture()) {
|
m_frontendBuffers[i] = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(stateDrawBuffers[i]);
|
||||||
const auto& textureObject = attachment.GetTexture();
|
|
||||||
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
// Create compacted mapping
|
||||||
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
m_backendBuffers[nBuffers] = GL_COLOR_ATTACHMENT0 + nBuffers;
|
||||||
MGLOG_E("No backend texture found for FBO attachment, cannot bind texture.");
|
m_compactedFrontendBuffers[nBuffers] = m_frontendBuffers[i];
|
||||||
continue;
|
nBuffers++;
|
||||||
}
|
|
||||||
const auto& backendTextureObject = backendTextureIt->second;
|
|
||||||
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
|
||||||
backendTextureObject->Bind(glTextureTarget);
|
|
||||||
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glBackendAttachmentType, glTextureTarget,
|
|
||||||
backendTextureObject->GetBackendTextureId(),
|
|
||||||
static_cast<GLint>(attachment.GetTextureLevel()));
|
|
||||||
} else if (attachment.IsRenderbuffer()) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Attach attachment to FBO, realize `glReadBuffer`
|
MG_External::GLES::glDrawBuffers(nBuffers, m_backendBuffers);
|
||||||
// TODO: do we actually need "virtualization" here? I assume not?
|
|
||||||
GLenum frontendAtt = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(stateFBOObject->GetReadBuffer());
|
// Attach textures for compacted draw buffers
|
||||||
|
for (int i = 0; i < nBuffers; ++i) {
|
||||||
|
FramebufferAttachmentType frontendAttachmentType =
|
||||||
|
MG_Util::ConvertGLEnumToFramebufferAttachmentType(m_compactedFrontendBuffers[i]);
|
||||||
|
GLenum backendAttachment = m_backendBuffers[i];
|
||||||
|
const auto& attachment = attachments[static_cast<SizeT>(frontendAttachmentType)];
|
||||||
|
if (!attachment.IsTexture()) continue;
|
||||||
|
const auto& textureObject = attachment.GetTexture();
|
||||||
|
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
||||||
|
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
|
||||||
|
const auto& backendTextureObject = backendTextureIt->second;
|
||||||
|
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
||||||
|
backendTextureObject->Bind(glTextureTarget);
|
||||||
|
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, backendAttachment, glTextureTarget,
|
||||||
|
backendTextureObject->GetBackendTextureId(),
|
||||||
|
static_cast<GLint>(attachment.GetTextureLevel()));
|
||||||
|
}
|
||||||
|
|
||||||
|
stateFBOObject->ClearDrawBuffersDirtyState();
|
||||||
|
}
|
||||||
|
// Handle read buffer for READ_FRAMEBUFFER
|
||||||
|
else if (asTarget == FramebufferTarget::Read) {
|
||||||
|
FramebufferAttachmentType readBufferType = stateFBOObject->GetReadBuffer();
|
||||||
|
GLenum frontendAtt = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(readBufferType);
|
||||||
GLenum backendAtt = GL_NONE;
|
GLenum backendAtt = GL_NONE;
|
||||||
// Attach attachment to FBO, fast path
|
// Find corresponding backend attachment in compacted draw buffers
|
||||||
for (SizeT i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
for (SizeT i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
||||||
if (m_compactedFrontendBuffers[i] == frontendAtt) backendAtt = m_backendBuffers[i];
|
if (m_compactedFrontendBuffers[i] == frontendAtt) {
|
||||||
|
backendAtt = m_backendBuffers[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (backendAtt != GL_NONE) {
|
if (backendAtt != GL_NONE) {
|
||||||
MG_External::GLES::glReadBuffer(backendAtt);
|
MG_External::GLES::glReadBuffer(backendAtt);
|
||||||
} else {
|
} else {
|
||||||
// Maybe we should properly do `glFramebufferTexture2D` here
|
|
||||||
// don't need remap / virtualization
|
|
||||||
MG_External::GLES::glReadBuffer(frontendAtt);
|
MG_External::GLES::glReadBuffer(frontendAtt);
|
||||||
const auto& attachments = stateFBOObject->GetAllAttachments();
|
|
||||||
const auto& attachment = attachments[(SizeT)frontendAtt];
|
|
||||||
if (!attachment.IsComplete()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachment.IsTexture()) {
|
|
||||||
const auto& textureObject = attachment.GetTexture();
|
|
||||||
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
|
||||||
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
|
||||||
MGLOG_E("No backend texture found for FBO attachment, cannot bind texture.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto& backendTextureObject = backendTextureIt->second;
|
|
||||||
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
|
||||||
backendTextureObject->Bind(glTextureTarget);
|
|
||||||
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, frontendAtt, glTextureTarget,
|
|
||||||
backendTextureObject->GetBackendTextureId(),
|
|
||||||
static_cast<GLint>(attachment.GetTextureLevel()));
|
|
||||||
} else if (attachment.IsRenderbuffer()) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,15 +579,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
auto& spirvCode = shaderSpirvs[index];
|
auto& spirvCode = shaderSpirvs[index];
|
||||||
|
|
||||||
MG_Util::ShaderTranspiler::SpvcSession spvcSession(spirvCode);
|
MG_Util::ShaderTranspiler::SpvcSession spvcSession(spirvCode);
|
||||||
// if (glShaderType == GL_VERTEX_SHADER) {
|
|
||||||
// if (stateProgramObject->GetAttribLocationMap().empty())
|
|
||||||
// MGLOG_D("%s: no explicitly set vertex in location", __func__);
|
|
||||||
// for (auto& [name, loc]: stateProgramObject->GetAttribLocationMap()) {
|
|
||||||
// MGLOG_D("%s: got explicitly set - layout(location = %d) %s;", __func__, loc,
|
|
||||||
// name.c_str());
|
|
||||||
// }
|
|
||||||
//// spvcSession.SetVertexAttribLocation(stateProgramObject->GetAttribLocationMap());
|
|
||||||
// }
|
|
||||||
|
|
||||||
spvc_compiler_options options;
|
spvc_compiler_options options;
|
||||||
spvcSession.CreateOptions(&options);
|
spvcSession.CreateOptions(&options);
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
class BackendFramebufferObject {
|
class BackendFramebufferObject {
|
||||||
public:
|
public:
|
||||||
BackendFramebufferObject();
|
BackendFramebufferObject();
|
||||||
void SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget);
|
void SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject,
|
||||||
|
FramebufferTarget asTarget);
|
||||||
Uint GetBackendFramebufferId() { return m_backendFBOId; }
|
Uint GetBackendFramebufferId() { return m_backendFBOId; }
|
||||||
void Bind(FramebufferTarget target);
|
void Bind(FramebufferTarget target);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user