mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (DirectVulkan): GPU transform feedback capture via VK_EXT_transform_feedback
Second stage of GL 3.0 transform feedback: captured draws now write real data. - Device setup enables the VK_EXT_transform_feedback feature when present and loads the bind/begin/end entry points. - Captured draws compile an XfbCapture program variant whose last vertex-processing stage gets XfbBuffer/XfbStride/Offset decorations from the program's resolved varyings (a new spirv-opt pass). A captured gl_Position is mirrored into a dedicated output written before every OpReturn - or before every OpEmitVertex in a geometry stage - ahead of the position fixup, so the captured value is the shader's own pre-remap position. - DrawArrays/DrawElements wrap the draw in Begin/EndTransformFeedbackEXT; a small counter buffer resumes the append position across draws within one glBeginTransformFeedback (fresh Begin starts at the bound offsets). - Capture targets are promoted to persistently-mapped host-coherent GPU storage (persistent-map storage now also carries the transform feedback usage), so MapBuffer/GetBufferSubData read the captured bytes after the fence wait glEndTransformFeedback now performs. - Draw-mode/feedback-mode validation defers to the geometry shader's output primitive when one is present, and glGetBooleanv reports GL_TRANSFORM_FEEDBACK_ACTIVE/PAUSED so dEQP's per-case state reset can unwind an active capture. KHR-GL33: transform_feedback capture_vertex_*/capture_geometry_*/ discard_*/draw_xfb and clip_distance.coverage now pass; queries (PRIMITIVES_WRITTEN) and gl_ClipDistance capture remain.
This commit is contained in:
@@ -231,6 +231,21 @@ namespace MobileGL::MG_State::GLState {
|
||||
return m_resource.Bytes();
|
||||
}
|
||||
|
||||
Bool BufferObject::EnsureGpuResidentStorage() {
|
||||
if (m_resource.IsGpuResident()) {
|
||||
return true;
|
||||
}
|
||||
if (m_size == 0 || g_bufferBackendOps == nullptr || g_bufferBackendOps->AcquirePersistentMap == nullptr) {
|
||||
return false;
|
||||
}
|
||||
void* base = g_bufferBackendOps->AcquirePersistentMap(*this);
|
||||
if (base == nullptr) {
|
||||
return false;
|
||||
}
|
||||
m_resource.AdoptPersistentMap(base);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* BufferObject::AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access) {
|
||||
MOBILEGL_ASSERT(range.end <= m_size && range.start <= range.end,
|
||||
"AcquireMemoryRange out of bounds: range (%zu, %zu) exceeds m_size (%zu)", range.start,
|
||||
|
||||
@@ -133,6 +133,11 @@ namespace MobileGL {
|
||||
|
||||
void* AcquireMemory(Bool markMapped, Bool read, Bool write);
|
||||
void* AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access);
|
||||
// Adopt backend host-visible coherent GPU storage as the source of truth
|
||||
// (used for GPU-written targets like transform feedback capture, so
|
||||
// MapBuffer/GetBufferSubData read real GPU results). No-op when already
|
||||
// resident or when the backend declines.
|
||||
Bool EnsureGpuResidentStorage();
|
||||
void ReleaseMemory();
|
||||
void FlushMemoryRange(SizeT offset, SizeT length);
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ namespace MobileGL {
|
||||
m_transformFeedbackActive = true;
|
||||
m_transformFeedbackPrimitiveMode = primitiveMode;
|
||||
m_transformFeedbackProgram = program;
|
||||
++m_transformFeedbackGeneration;
|
||||
}
|
||||
void EndTransformFeedback() {
|
||||
m_transformFeedbackActive = false;
|
||||
@@ -226,6 +227,9 @@ namespace MobileGL {
|
||||
const SharedPtr<ProgramObject>& GetTransformFeedbackProgram() const {
|
||||
return m_transformFeedbackProgram;
|
||||
}
|
||||
// Bumped on every BeginTransformFeedback; the backend uses it to
|
||||
// distinguish "resume appending" from "fresh capture".
|
||||
Uint64 GetTransformFeedbackGeneration() const { return m_transformFeedbackGeneration; }
|
||||
|
||||
// Framebuffer
|
||||
void GenFramebufferNames(Uint number, Vector<Uint>& framebuffers);
|
||||
@@ -262,6 +266,7 @@ namespace MobileGL {
|
||||
Bool m_transformFeedbackActive = false;
|
||||
GLenum m_transformFeedbackPrimitiveMode = GL_POINTS;
|
||||
SharedPtr<ProgramObject> m_transformFeedbackProgram;
|
||||
Uint64 m_transformFeedbackGeneration = 0;
|
||||
TextureState m_textureState;
|
||||
ProgramState m_programState;
|
||||
RenderState m_renderState;
|
||||
|
||||
Reference in New Issue
Block a user