[Feat] (MG_Impl, MG_State): implement the direct state access transform feedback API

glCreateTransformFeedbacks, glTransformFeedbackBufferBase, glTransformFeedbackBufferRange
and the three glGetTransformFeedback* queries were all stubs, so a transform feedback
object could only be configured and inspected by binding it first - the exact thing
direct state access exists to avoid. The queries were the worse half: they returned
nothing and raised no error, so an application could not tell that it had learned
nothing.

glCreateTransformFeedbacks creates the objects outright. glGenTransformFeedbacks only
reserves names, and a reserved name becomes an object when it is first bound
(GL 4.6 core 13.2.1); the DSA form has no bind step to create them from.

The queries and the buffer bindings read and write a named object's state. That state
lives in two places: the context keeps one live copy of the capture bindings and the
active/paused flags for whichever object is bound, and every other object's copy sits in
its saved state until a bind swaps it in. The by-name accessors added to the context
resolve that, so a query for the bound object reads the live copy rather than a stale
save.

GL_TRANSFORM_FEEDBACK_BUFFER_START and _SIZE are answered as zero unless the binding was
made by the range form, matching what the buffer object binding points already do.

Takes direct_state_access.xfb_* from 0 to 4 of 5 on both backends; xfb_functional still
fails on the capture itself, which is a separate defect.
This commit is contained in:
BZLZHH
2026-08-05 02:16:48 +00:00
parent 42fd02d82f
commit dac02ca044
6 changed files with 258 additions and 6 deletions
@@ -16,7 +16,13 @@ namespace MobileGL::MG_Impl::GLImpl {
void PauseTransformFeedback(void);
void ResumeTransformFeedback(void);
void GenTransformFeedbacks(GLsizei n, GLuint* ids);
void CreateTransformFeedbacks(GLsizei n, GLuint* ids);
void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids);
void TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer);
void TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
void GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint* param);
void GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint* param);
void GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64* param);
void BindTransformFeedback(GLenum target, GLuint id);
GLboolean IsTransformFeedback(GLuint id);
void DrawTransformFeedback(GLenum mode, GLuint id);