[Chore] (MG_Backend/DirectVulkan): refactor draw cmds

This commit is contained in:
2026-03-17 15:10:17 +08:00
parent 8b9adc5121
commit 87122973be
3 changed files with 94 additions and 63 deletions
@@ -17,10 +17,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {}
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {}
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {}
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) {}
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
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) {}
@@ -47,65 +43,78 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {}
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {}
void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElements called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawElements called with null GL context");
Vector<DrawElementCmd> cmds;
cmds.reserve(static_cast<SizeT>(drawcount));
for (GLsizei i = 0; i < drawcount; ++i) {
if (count[i] == 0) {
continue;
}
DrawElementCmd payload{};
payload.mode = mode;
payload.first = 0;
payload.count = count[i];
payload.indexType = type;
payload.indexByteOffset = reinterpret_cast<SizeT>(indices[i]);
cmds.push_back(payload);
}
if (cmds.empty()) {
return;
}
pVulkanRenderer->MultiDrawElements(cmds);
}
void Clear(GLbitfield mask) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::Clear called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::Clear called with null GL context");
pVulkanRenderer->Clear(mask);
}
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElements called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawElements called with null GL context");
DrawElementCmd payload{};
payload.mode = mode;
payload.first = 0;
payload.count = count;
payload.indexType = type;
payload.indexByteOffset = reinterpret_cast<SizeT>(indices);
pVulkanRenderer->DrawElements(payload);
}
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArrays called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawArrays called with null GL context");
DrawArrayCmd payload{};
DrawCmd payload{};
payload.mode = mode;
payload.first = first;
payload.count = count;
payload.firstVertex = first;
payload.vertexCount = count;
pVulkanRenderer->DrawArrays(payload);
}
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElements called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawElements called with null GL context");
DrawIndexedCmd payload{};
payload.mode = mode;
payload.indexType = type;
payload.indexByteOffset = reinterpret_cast<SizeT>(indices);
payload.indexCount = count;
payload.instanceCount = 1;
pVulkanRenderer->DrawElements(payload);
}
void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElements called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawElements called with null GL context");
// Vector<DrawElementCmd> cmds;
// cmds.reserve(static_cast<SizeT>(drawcount));
// for (GLsizei i = 0; i < drawcount; ++i) {
// if (count[i] == 0) {
// continue;
// }
//
// DrawElementCmd payload{};
// payload.mode = mode;
// payload.firstVertex = 0;
// payload.indexCount = count[i];
// payload.indexType = type;
// payload.indexByteOffset = reinterpret_cast<SizeT>(indices[i]);
// cmds.push_back(payload);
// }
//
// if (cmds.empty()) {
// return;
// }
// pVulkanRenderer->MultiDrawElements(cmds);
}
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsBaseVertex called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawElementsBaseVertex called with null GL context");
}
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount, const GLint* basevertex) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElements called with null VulkanRenderer");
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawElements called with null GL context");
}
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
GLint dstY1, GLbitfield mask, GLenum filter) {
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::BlitFramebuffer called with null VulkanRenderer");
@@ -1191,7 +1191,7 @@ void main() {
1, &blitRegion, filter == GL_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST);
}
void VulkanRenderer::DrawArrays(const DrawArrayCmd& payload) {
void VulkanRenderer::DrawArrays(const DrawCmd& payload) {
auto& frame = m_frameContext.GetCurrent();
SetupDraw(frame, payload.mode, 0);
@@ -1200,10 +1200,14 @@ void main() {
VkCommandBuffer& commandBuffer = frame.commandBuffer;
vkCmdDraw(commandBuffer, static_cast<Uint32>(payload.count), 1, static_cast<Uint32>(payload.first), 0);
vkCmdDraw(commandBuffer,
payload.vertexCount,
payload.instanceCount,
payload.firstVertex,
payload.firstInstance);
}
void VulkanRenderer::DrawElements(const DrawElementCmd& payload) {
void VulkanRenderer::DrawElements(const DrawIndexedCmd& payload) {
auto& frame = m_frameContext.GetCurrent();
SetupDraw(frame, payload.mode, 0);
@@ -1231,7 +1235,7 @@ void main() {
const auto indexData = indexBuffer->GetDataReadOnly();
MOBILEGL_ASSERT(indexData != nullptr && !indexData->empty(), "DrawElements requires non-empty EBO data");
const SizeT indexSize = (payload.indexType == GL_UNSIGNED_SHORT) ? sizeof(Uint16) : sizeof(Uint32);
const SizeT indexDataSizeBytes = static_cast<SizeT>(payload.count) * indexSize;
const SizeT indexDataSizeBytes = static_cast<SizeT>(payload.indexCount) * indexSize;
MOBILEGL_ASSERT(payload.indexByteOffset + indexDataSizeBytes <= indexBuffer->GetSize(),
"DrawElements index range out of bounds");
@@ -1256,11 +1260,15 @@ void main() {
VkCommandBuffer& commandBuffer = frame.commandBuffer;
vkCmdBindIndexBuffer(commandBuffer, frameIndexUploadBuffer.GetHandle(), writeOffset, vkIndexType);
vkCmdDrawIndexed(commandBuffer, static_cast<Uint32>(payload.count), 1, 0,
static_cast<Int32>(payload.baseVertex), 0);
vkCmdDrawIndexed(commandBuffer,
payload.indexCount,
payload.instanceCount,
payload.firstIndex,
payload.vertexOffset,
payload.firstInstance);
}
void VulkanRenderer::MultiDrawElements(const Vector<DrawElementCmd>& payloads) {
void VulkanRenderer::MultiDrawElements(const Vector<DrawIndexedCmd>& payloads) {
}
@@ -43,16 +43,30 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Scissor = 1 << 6,
};
struct DrawArrayCmd {
struct DrawBaseCmd {
GLenum mode = GL_TRIANGLES;
GLint first = 0;
GLsizei count = 0;
};
struct DrawElementCmd: public DrawArrayCmd {
struct DrawCmd: public DrawBaseCmd {
Uint32 vertexCount = 0;
Uint32 instanceCount = 1;
Uint32 firstVertex = 0;
Uint32 firstInstance = 0;
};
struct DrawIndexedCmd: public DrawBaseCmd {
GLenum indexType = GL_UNSIGNED_SHORT;
SizeT indexByteOffset = 0;
GLint baseVertex = 0;
Uint32 indexCount = 0;
Uint32 instanceCount = 1;
Uint32 firstIndex = 0;
Int32 vertexOffset = 0;
Int32 firstInstance = 0;
};
struct MultiDrawElementsCmd {
};
struct QueueFamilyIndices {
@@ -86,9 +100,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void DrawArrays(const DrawArrayCmd& payload);
void DrawElements(const DrawElementCmd& payload);
void MultiDrawElements(const Vector<DrawElementCmd>& payloads);
void DrawArrays(const DrawCmd& payload);
void DrawElements(const DrawIndexedCmd& payload);
void MultiDrawElements(const Vector<DrawIndexedCmd>& payloads);
void Present();
const PhysicalDevice& GetPhysicalDevice() const;