[Feat] (MG_Backend/DirectGLES): Implement more draw funcs. Add DrawSyncBit.

This commit is contained in:
BZLZHH
2025-12-07 10:50:13 +08:00
parent 1da2550774
commit b3824c871c
2 changed files with 169 additions and 30 deletions
+152 -30
View File
@@ -13,6 +13,22 @@
#include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h> #include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h>
namespace MobileGL::MG_Backend::DirectGLES { namespace MobileGL::MG_Backend::DirectGLES {
enum class DrawSyncBit : Uint32 {
None = 0,
IndexBuffer = 1 << 0,
IndirectBuffer = 1 << 1,
Instancing = 1 << 2
};
inline DrawSyncBit operator|(DrawSyncBit a, DrawSyncBit b) {
return static_cast<DrawSyncBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
}
inline DrawSyncBit& operator|=(DrawSyncBit& a, DrawSyncBit b) {
a = a | b;
return a;
}
namespace DebugImpl { namespace DebugImpl {
void ErrorLopper::Loop(std::function<void(GLenum)> func) { void ErrorLopper::Loop(std::function<void(GLenum)> func) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
@@ -45,9 +61,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
// TODO: deletion for deleted objects // TODO: deletion for deleted objects
namespace BufferImpl { namespace BufferImpl {
void SyncNeccessaryBuffers() { void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) {
// All buffers we need are: // All buffers we need are:
// 1.VBO 2.IBO 3.UBO 4.PBO 5.SSBO (TODO) // 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed) 5.SSBO (TODO)
// PBO is not needed since it should be handled in frontend
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync; Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray(); const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
@@ -69,11 +86,25 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
// IBO // IBO
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject(); if (includeIBO) {
if (possibleIBO) { const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
const auto& end = buffersToSync.end(); if (possibleIBO) {
if (std::find(buffersToSync.begin(), end, possibleIBO) == end) { const auto& end = buffersToSync.end();
buffersToSync.push_back(possibleIBO); if (std::find(buffersToSync.begin(), end, possibleIBO) == end) {
buffersToSync.push_back(possibleIBO);
}
}
}
// Indirect Buffer Object
if (includeIndirectBuffer) {
const auto& possibleIndirectBuffer =
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject();
if (possibleIndirectBuffer) {
const auto& end = buffersToSync.end();
if (std::find(buffersToSync.begin(), end, possibleIndirectBuffer) == end) {
buffersToSync.push_back(possibleIndirectBuffer);
}
} }
} }
@@ -323,9 +354,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void PrepareForDraw() { void PrepareForDraw(DrawSyncBit syncBit) {
BufferImpl::SyncNeccessaryBuffers(); BufferImpl::SyncNeccessaryBuffers(syncBit & DrawSyncBit::IndexBuffer, syncBit & DrawSyncBit::IndirectBuffer);
VertexArrayImpl::SyncCurrentVAO(); VertexArrayImpl::SyncCurrentVAO(); // TODO: instancing
TextureImpl::SyncNeccessaryTextures(); TextureImpl::SyncNeccessaryTextures();
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
PrgramImpl::SyncCurrentProgram(); PrgramImpl::SyncCurrentProgram();
@@ -474,16 +505,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
PrepareForDraw();
MG_External::GLES::glDrawArrays(mode, first, count);
}
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
PrepareForDraw();
MG_External::GLES::glDrawElements(mode, count, type, indices);
}
void Clear(GLbitfield mask) { void Clear(GLbitfield mask) {
TextureImpl::SyncNeccessaryTextures(); TextureImpl::SyncNeccessaryTextures();
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
@@ -494,27 +515,128 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_External::GLES::glClear(mask); MG_External::GLES::glClear(mask);
} }
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint baseVertex) { void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
PrepareForDraw(); DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
MG_External::GLES::glDrawElementsBaseVertex(mode, count, type, indices, baseVertex); PrepareForDraw(syncBit);
MG_External::GLES::glDrawElements(mode, count, type, indices);
} }
void MultiDrawElements(GLenum mode, const GLsizei* counts, GLenum type, const void* const* indices, void DrawArrays(GLenum mode, GLint first, GLsizei count) {
DrawSyncBit syncBit = DrawSyncBit::None;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawArrays(mode, first, count);
}
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
}
void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount) { GLsizei drawcount) {
PrepareForDraw(); DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
PrepareForDraw(syncBit);
for (GLsizei i = 0; i < drawcount; ++i) { for (GLsizei i = 0; i < drawcount; ++i) {
MG_External::GLES::glDrawElements(mode, counts[i], type, indices[i]); MG_External::GLES::glDrawElements(mode, count[i], type, indices[i]);
} }
} }
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* counts, GLenum type, const void* const* indices, void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount, const GLint* baseVertices) { GLsizei drawcount, const GLint* basevertex) {
PrepareForDraw(); DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
PrepareForDraw(syncBit);
for (GLsizei i = 0; i < drawcount; ++i) { for (GLsizei i = 0; i < drawcount; ++i) {
MG_External::GLES::glDrawElementsBaseVertex(mode, counts[i], type, indices[i], baseVertices[i]); MG_External::GLES::glDrawElementsBaseVertex(mode, count[i], type, indices[i], basevertex[i]);
} }
} }
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::IndirectBuffer;
PrepareForDraw(syncBit);
for (GLsizei i = 0; i < drawcount; ++i) {
const GLvoid* cmd = reinterpret_cast<const GLvoid*>(reinterpret_cast<const uint8_t*>(indirect) +
i * (stride ? stride : sizeof(GLsizei) * 4));
MG_External::GLES::glDrawElementsIndirect(mode, type, cmd);
}
}
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) {
DrawSyncBit syncBit = DrawSyncBit::IndirectBuffer;
PrepareForDraw(syncBit);
for (GLsizei i = 0; i < drawcount; ++i) {
const GLvoid* cmd = reinterpret_cast<const GLvoid*>(reinterpret_cast<const uint8_t*>(indirect) +
i * (stride ? stride : sizeof(GLsizei) * 4));
MG_External::GLES::glDrawArraysIndirect(mode, cmd);
}
}
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const void* indices, GLint basevertex) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex);
}
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawRangeElements(mode, start, end, count, type, indices);
}
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex, GLuint baseinstance) {
// Not supported in OpenGL ES
MGLOG_W("DrawElementsInstancedBaseVertexBaseInstance is not supported in OpenGL ES.");
}
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex);
}
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLuint baseinstance) {
// Not supported in OpenGL ES
MGLOG_W("DrawElementsInstancedBaseInstance is not supported in OpenGL ES.");
}
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawElementsInstanced(mode, count, type, indices, instancecount);
}
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) {
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::IndirectBuffer;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawElementsIndirect(mode, type, indirect);
}
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
GLuint baseinstance) {
// Not supported in OpenGL ES
MGLOG_W("DrawArraysInstancedBaseInstance is not supported in OpenGL ES.");
}
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
DrawSyncBit syncBit = DrawSyncBit::Instancing;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawArraysInstanced(mode, first, count, instancecount);
}
void DrawArraysIndirect(GLenum mode, const void* indirect) {
DrawSyncBit syncBit = DrawSyncBit::IndirectBuffer;
PrepareForDraw(syncBit);
MG_External::GLES::glDrawArraysIndirect(mode, indirect);
}
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
GLint dstY1, GLbitfield mask, GLenum filter) { GLint dstY1, GLbitfield mask, GLenum filter) {
DebugImpl::ErrorLopper errorLopper; DebugImpl::ErrorLopper errorLopper;
@@ -14,6 +14,23 @@ namespace MobileGL::MG_Backend::DirectGLES {
GLsizei drawcount); GLsizei drawcount);
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount, const GLint* basevertex); GLsizei drawcount, const GLint* basevertex);
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride);
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride);
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const void* indices, GLint basevertex);
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex, GLuint baseinstance);
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex);
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLuint baseinstance);
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount);
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect);
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
GLuint baseinstance);
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
void DrawArraysIndirect(GLenum mode, const void* indirect);
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
GLint dstY1, GLbitfield mask, GLenum filter); GLint dstY1, GLbitfield mask, GLenum filter);
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,