mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (DirectVulkan, MG_State): give each transform feedback object its own capture counters
The frontend half of ARB_transform_feedback2 landed for both backends, but Magma's capture was still written for the one implicit span GL 3.3 has: - A paused span kept capturing. VK_EXT_transform_feedback's counter buffers already make consecutive draws append, so pausing is simply "do not wrap this draw" - the counters keep their values and the next resumed draw carries on where the last captured one stopped. - Those counter buffers were context-wide. Transform feedback objects can each hold an open, paused span at the same time - KHR-GL40.transform_feedback.draw_xfb_test keeps three - and they were all appending through one set of four slots. Each object now gets its own group, handed out on first use; past sixteen objects they share group 0, which only matters for concurrently-paused spans. - The generation that identifies a span is what a backend keys its append state on, so it is now part of the per-object state the frontend saves and restores. Without that, resuming an object that was paused before another one began looked like a new span and restarted its counters at zero. GL_PRIMITIVES_GENERATED needed one more thing. It counts what the last vertex processing stage emitted whether or not anything is being captured, but VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT only counts what the capture saw - so a draw made while the span was paused is invisible to it. The frontend now tallies those draws, and the Vulkan query adds the delta at result time. The correction lives in the backend that needs it: an ES driver's GL_PRIMITIVES_GENERATED counts them by itself, and adding it there too would double them. transform_feedback* on Magma: 4 failures -> 3. Espryt stays at 38/38.
This commit is contained in:
@@ -764,6 +764,7 @@ namespace MobileGL::MG_State {
|
||||
object.paused = m_transformFeedbackPaused;
|
||||
object.primitiveMode = m_transformFeedbackPrimitiveMode;
|
||||
object.program = m_transformFeedbackProgram;
|
||||
object.generation = m_transformFeedbackGeneration;
|
||||
object.capturedVertices = m_transformFeedbackCapturedVertices;
|
||||
object.inputPrimitives = m_transformFeedbackInputPrimitives;
|
||||
}
|
||||
@@ -783,6 +784,10 @@ namespace MobileGL::MG_State {
|
||||
m_transformFeedbackPaused = object.paused;
|
||||
m_transformFeedbackPrimitiveMode = object.primitiveMode;
|
||||
m_transformFeedbackProgram = object.program;
|
||||
// The generation identifies one capture span, and a span belongs to the object
|
||||
// that opened it - a backend keys its append state on it, so switching objects
|
||||
// has to bring the right one back.
|
||||
m_transformFeedbackGeneration = object.generation;
|
||||
m_transformFeedbackCapturedVertices = object.capturedVertices;
|
||||
m_transformFeedbackInputPrimitives = object.inputPrimitives;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace MobileGL {
|
||||
m_transformFeedbackPaused = false;
|
||||
m_transformFeedbackPrimitiveMode = primitiveMode;
|
||||
m_transformFeedbackProgram = program;
|
||||
++m_transformFeedbackGeneration;
|
||||
m_transformFeedbackGeneration = ++m_transformFeedbackNextGeneration;
|
||||
m_transformFeedbackCapturedVertices = 0;
|
||||
m_transformFeedbackInputPrimitives = 0;
|
||||
}
|
||||
@@ -251,6 +251,15 @@ namespace MobileGL {
|
||||
m_transformFeedbackPrimitiveCounter += primitives;
|
||||
}
|
||||
Uint64 GetTransformFeedbackPrimitiveCounter() const { return m_transformFeedbackPrimitiveCounter; }
|
||||
// Primitives a draw assembled while the capture was paused. GL counts those in
|
||||
// PRIMITIVES_GENERATED, but a backend that answers the query with its own
|
||||
// transform feedback counter cannot see them - nothing was being captured.
|
||||
void AddTransformFeedbackPausedPrimitives(Uint64 primitives) {
|
||||
m_transformFeedbackPausedPrimitiveCounter += primitives;
|
||||
}
|
||||
Uint64 GetTransformFeedbackPausedPrimitiveCounter() const {
|
||||
return m_transformFeedbackPausedPrimitiveCounter;
|
||||
}
|
||||
// Vertices already captured since BeginTransformFeedback (drives the
|
||||
// buffer-capacity clamp on the primitives-written accounting).
|
||||
void AddTransformFeedbackCapturedVertices(Uint64 vertices) {
|
||||
@@ -327,9 +336,12 @@ namespace MobileGL {
|
||||
GLenum m_transformFeedbackPrimitiveMode = GL_POINTS;
|
||||
SharedPtr<ProgramObject> m_transformFeedbackProgram;
|
||||
Uint64 m_transformFeedbackGeneration = 0;
|
||||
// Source of the per-span ids above; never rolls back with an object switch.
|
||||
Uint64 m_transformFeedbackNextGeneration = 0;
|
||||
// Not object state: the transform feedback queries snapshot it at BeginQuery
|
||||
// and take the delta at EndQuery, which spans whatever objects were used.
|
||||
Uint64 m_transformFeedbackPrimitiveCounter = 0;
|
||||
Uint64 m_transformFeedbackPausedPrimitiveCounter = 0;
|
||||
Uint64 m_transformFeedbackCapturedVertices = 0;
|
||||
Uint64 m_transformFeedbackInputPrimitives = 0;
|
||||
|
||||
@@ -345,6 +357,7 @@ namespace MobileGL {
|
||||
Bool paused = false;
|
||||
GLenum primitiveMode = GL_POINTS;
|
||||
SharedPtr<ProgramObject> program;
|
||||
Uint64 generation = 0;
|
||||
Uint64 capturedVertices = 0;
|
||||
Uint64 inputPrimitives = 0;
|
||||
Uint64 recordedVertices = 0;
|
||||
|
||||
Reference in New Issue
Block a user