[Fix] (MG_Backend/DirectVulkan): support Voxy rendering

Implemented:

- Advertise Voxy-required DirectVulkan extensions without raising the reported OpenGL version.

- Add DirectVulkan compute, indirect draw count, DSA, readback, and buffer state paths needed by Voxy.

Fixed:

- Enable Vulkan shaderInt64 and drawIndirectFirstInstance so Voxy baseInstance-driven LOD draws address the correct section data.

- Fix DirectVulkan synchronization, framebuffer, texture readback, and shader interface handling used by Voxy and Minecraft screenshots.

Tests:

- Add MG_Test coverage for DirectVulkan extension advertising, DSA buffer/texture/framebuffer/vertex-array behavior, persistent mapped readback, and shader/program paths.
This commit is contained in:
2026-06-09 00:37:37 +08:00
parent ab9db43599
commit cf165c0db5
65 changed files with 3724 additions and 239 deletions
@@ -25,6 +25,7 @@ namespace MobileGL {
AtomicCounter,
DispatchIndirect,
DrawIndirect,
Parameter,
ShaderStorage,
BufferTargetCount,
Unknown = -1
@@ -16,7 +16,7 @@ namespace MobileGL::MG_State::GLState {
ToArray(BufferTarget::Vertex, BufferTarget::Uniform, BufferTarget::CopyRead, BufferTarget::CopyWrite,
BufferTarget::PixelPack, BufferTarget::PixelUnpack, BufferTarget::Query, BufferTarget::Texture,
BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::DispatchIndirect,
BufferTarget::DrawIndirect, BufferTarget::ShaderStorage);
BufferTarget::DrawIndirect, BufferTarget::Parameter, BufferTarget::ShaderStorage);
constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback,
BufferTarget::AtomicCounter, BufferTarget::ShaderStorage);
+8
View File
@@ -413,6 +413,14 @@ namespace MobileGL::MG_State {
return m_renderState.GetFrontFaceMode();
}
void GLContext::SetProvokingVertexMode(ProvokingVertexMode mode) {
m_renderState.SetProvokingVertexMode(mode);
}
ProvokingVertexMode GLContext::GetProvokingVertexMode() const {
return m_renderState.GetProvokingVertexMode();
}
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
+2
View File
@@ -136,6 +136,8 @@ namespace MobileGL {
CullFaceMode GetCullFaceMode() const;
void SetFrontFaceMode(FrontFaceMode mode);
FrontFaceMode GetFrontFaceMode() const;
void SetProvokingVertexMode(ProvokingVertexMode mode);
ProvokingVertexMode GetProvokingVertexMode() const;
void SetScissorBox(IntVec4 box); // x, y, width, height
const IntVec4& GetScissorBox() const; // x, y, width, height
@@ -299,6 +299,27 @@ namespace MobileGL::MG_State::GLState {
}
}
for (int i = 0; i < m_activeUniformCount; i++) {
auto& uniform = m_program->getUniform(i);
const auto locationIt = m_uniformLocations.find(uniform.name);
if (locationIt == m_uniformLocations.end()) {
continue;
}
const Uint location = locationIt->second;
if (location >= m_uniformSamplerOrImageUnitIndex.size() || uniform.getType() == nullptr ||
!uniform.getType()->isOpaque() || (!uniform.getType()->isTexture() && !uniform.getType()->isImage())) {
continue;
}
const int binding = uniform.getBinding();
if (binding >= 0 && binding != static_cast<int>(glslang::TQualifier::layoutBindingEnd)) {
m_uniformSamplerOrImageUnitIndex[location] = binding;
MGLOG_D("ProgramObject %u: Reflection - opaque uniform '%s' location=%u initialUnit=%d",
m_externalIndex, uniform.name.c_str(), location, binding);
}
}
// ------------ attributes (vertex in) ---------------
Int inCount = m_program->getNumPipeInputs();
MGLOG_D("ProgramObject %u: Reflection - pipe input count (attributes) = %d", m_externalIndex, inCount);
@@ -360,6 +360,17 @@ namespace MobileGL {
return m_parameters.FrontFaceModeSetting;
}
void RenderState::SetProvokingVertexMode(ProvokingVertexMode mode) {
if (m_parameters.ProvokingVertexModeSetting == mode) return;
m_parameters.ProvokingVertexModeSetting = mode;
++m_version;
}
ProvokingVertexMode RenderState::GetProvokingVertexMode() const {
return m_parameters.ProvokingVertexModeSetting;
}
// --------------------- Scissor ---------------------
void RenderState::SetScissorBox(IntVec4 box) {
if (m_parameters.ScissorBox == box) return;
@@ -94,6 +94,13 @@ namespace MobileGL {
Unknown = -1
};
enum class ProvokingVertexMode {
FirstVertex,
LastVertex,
ProvokingVertexModeCount,
Unknown = -1
};
enum class CapabilityInput {
Blend,
ClipDistance0,
@@ -179,6 +186,7 @@ namespace MobileGL {
Bool CullFaceEnabled = false;
CullFaceMode CullFaceModeSetting = CullFaceMode::Back;
FrontFaceMode FrontFaceModeSetting = FrontFaceMode::CounterClockwise;
ProvokingVertexMode ProvokingVertexModeSetting = ProvokingVertexMode::LastVertex;
// Scissor
Bool ScissorTestEnabled = false;
@@ -245,6 +253,8 @@ namespace MobileGL {
CullFaceMode GetCullFaceMode() const;
void SetFrontFaceMode(FrontFaceMode mode);
FrontFaceMode GetFrontFaceMode() const;
void SetProvokingVertexMode(ProvokingVertexMode mode);
ProvokingVertexMode GetProvokingVertexMode() const;
// Scissor
void SetScissorBox(IntVec4 box); // x, y, width, height