mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Backend/DirectGLES): direct draw buffer mapping, fix up simple case
This commit is contained in:
@@ -850,116 +850,31 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
||||||
Bind(asTarget);
|
Bind(asTarget);
|
||||||
|
|
||||||
FramebufferAttachmentType* frontendAttachmentToSync = nullptr;
|
// connect attachments (set buffers)
|
||||||
GLenum* backendAttachmentToSync = nullptr;
|
// TODO: remapping
|
||||||
Int frontendAttachmentToSyncCount = 0;
|
auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
||||||
switch (asTarget) {
|
Bool drawBufferDirty = false;
|
||||||
case FramebufferTarget::Draw: {
|
for (GLint i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
||||||
auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
auto currentBuf = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(stateDrawBuffers[i]);
|
||||||
|
if (m_backendDrawBuffers[i] != currentBuf)
|
||||||
// Check if still clean, skip if clean
|
drawBufferDirty = true;
|
||||||
if (memcmp(m_frontendDrawBuffers, stateDrawBuffers.data(),
|
m_backendDrawBuffers[i] = currentBuf;
|
||||||
FramebufferObject::MAX_DRAW_BUFFERS * sizeof(FramebufferAttachmentType)) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create mappings for draw buffers
|
|
||||||
int nBuffers = 0;
|
|
||||||
std::fill(m_frontendDrawBuffers, m_frontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
|
|
||||||
FramebufferAttachmentType::None);
|
|
||||||
std::fill(m_compactedFrontendDrawBuffers,
|
|
||||||
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
|
|
||||||
FramebufferAttachmentType::None);
|
|
||||||
std::fill(m_backendDrawBuffers, m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
|
||||||
for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
|
||||||
if (stateDrawBuffers[i] == FramebufferAttachmentType::None) {
|
|
||||||
m_frontendDrawBuffers[i] = FramebufferAttachmentType::None;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_frontendDrawBuffers[i] = stateDrawBuffers[i];
|
|
||||||
|
|
||||||
// Create compacted mapping
|
|
||||||
m_backendDrawBuffers[nBuffers] = GL_COLOR_ATTACHMENT0 + nBuffers;
|
|
||||||
m_compactedFrontendDrawBuffers[nBuffers] = m_frontendDrawBuffers[i];
|
|
||||||
nBuffers++;
|
|
||||||
}
|
|
||||||
MG_External::GLES::glDrawBuffers(nBuffers, m_backendDrawBuffers);
|
|
||||||
|
|
||||||
frontendAttachmentToSync = m_compactedFrontendDrawBuffers;
|
|
||||||
backendAttachmentToSync = m_backendDrawBuffers;
|
|
||||||
frontendAttachmentToSyncCount = nBuffers;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case FramebufferTarget::Read: {
|
if (drawBufferDirty)
|
||||||
auto frontendReadBuf = stateFBOObject->GetReadBuffer();
|
MG_External::GLES::glDrawBuffers(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS, m_backendDrawBuffers);
|
||||||
if (frontendReadBuf == m_frontendReadBuffer) break;
|
|
||||||
m_frontendReadBuffer = frontendReadBuf;
|
|
||||||
|
|
||||||
// For consistency, we need to find the compacted attachment index of this read buffer
|
auto currentReadBuf = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(stateFBOObject->GetReadBuffer());
|
||||||
auto it = std::find(m_compactedFrontendDrawBuffers,
|
if (m_backendReadBuffer != currentReadBuf)
|
||||||
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, frontendReadBuf);
|
MG_External::GLES::glReadBuffer(m_backendReadBuffer);
|
||||||
|
|
||||||
// TODO: what if sync ReadBuffer first then DrawBuffer?
|
// attach texture to fbo
|
||||||
GLenum glBackendReadBuffer = GL_NONE;
|
// TODO: attach according to remapped
|
||||||
Bool notFound = (it == m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS);
|
const auto& attachments = stateFBOObject->GetAllAttachmentObjects();
|
||||||
if (notFound) {
|
for (SizeT i = 0; i < attachments.size(); ++i) {
|
||||||
MGLOG_D("%s: read buffer not found in draw buffer, use as in frontend", __func__);
|
const auto& attachmentObject = attachments[i];
|
||||||
glBackendReadBuffer = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(frontendReadBuf);
|
FramebufferAttachmentType type = static_cast<FramebufferAttachmentType>(i);
|
||||||
} else {
|
GLenum glBackendAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(type);
|
||||||
MGLOG_D("%s: read buffer found in draw buffer, keep it consistent as in read buffers", __func__);
|
|
||||||
auto index = std::distance(m_compactedFrontendDrawBuffers, it);
|
|
||||||
glBackendReadBuffer = m_backendDrawBuffers[index];
|
|
||||||
}
|
|
||||||
if (m_backendReadBuffer == glBackendReadBuffer) break;
|
|
||||||
m_backendReadBuffer = glBackendReadBuffer;
|
|
||||||
MG_External::GLES::glReadBuffer(glBackendReadBuffer);
|
|
||||||
|
|
||||||
frontendAttachmentToSync = &m_frontendReadBuffer;
|
|
||||||
backendAttachmentToSync = &m_backendReadBuffer;
|
|
||||||
frontendAttachmentToSyncCount = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
MOBILEGL_ASSERT(false, "%s: Unreachable!", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync texture/buffer to attachment
|
|
||||||
const auto& attachmentObjects = stateFBOObject->GetAllAttachmentObjects();
|
|
||||||
auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions();
|
|
||||||
for (Int i = 0; i < frontendAttachmentToSyncCount; ++i) {
|
|
||||||
auto frontendAttachment = frontendAttachmentToSync[i];
|
|
||||||
if (attachmentVersions[(SizeT)frontendAttachment] ==
|
|
||||||
m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
|
|
||||||
|
|
||||||
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendAttachment);
|
|
||||||
if (!attachmentObject.IsValid() || attachmentObject.IsEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto glBackendAttachment = backendAttachmentToSync[i];
|
|
||||||
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
|
|
||||||
}
|
|
||||||
|
|
||||||
FramebufferAttachmentType auxAtt[] = {FramebufferAttachmentType::Depth, FramebufferAttachmentType::Stencil};
|
|
||||||
for (auto& att : auxAtt) {
|
|
||||||
auto frontendAttachment = att;
|
|
||||||
if (attachmentVersions[(SizeT)frontendAttachment] ==
|
|
||||||
m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
|
|
||||||
|
|
||||||
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendAttachment);
|
|
||||||
if (!attachmentObject.IsValid() || attachmentObject.IsEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto glBackendAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(att);
|
|
||||||
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
|
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user