[Fix] (DirectGLES): exact transform feedback primitive queries

Two leftovers from the capture passthrough, both only observable with a
geometry shader in the pipeline:

- GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN / GL_PRIMITIVES_GENERATED fell back
  to the frontend's CPU accounting, which counts the primitives the draw call
  assembles and so cannot see a geometry stage's amplification. Both are core ES
  query targets (GL_PRIMITIVES_GENERATED from 3.2 on, gated accordingly so an
  older driver doesn't get a stray GL_INVALID_ENUM), so they now go straight to
  the driver's own counters. Generalized the occlusion-query handle's isOcclusion
  flag into the glBeginQuery target it already had to remember for glEndQuery,
  which is what tells the result read to use the core 32-bit getter.

- FixupGsStripCaptureOrder rewrites captured strip triangles from Vulkan's
  (i, i+1, i+2) order into GL's (i+1, i, i+2). A driver-side capture already
  emits GL order, so the rewrite corrupted it - KHR-GL33.transform_feedback
  .geometry read back the odd triangle rotated one vertex. Skipped when the
  backend owns the capture span.

KHR-GL3{0,1,2,3}.transform_feedback is now 21/21 on Espryt; DirectVulkan
(lavapipe) re-verified at 21/21 for the shared frontend change.
This commit is contained in:
BZLZHH
2026-08-01 11:57:18 -04:00
parent df7d1edeca
commit e9382f5329
4 changed files with 63 additions and 20 deletions
@@ -135,6 +135,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
// flow through GetQueryResult64/DeleteBackendQuery like the timer queries above.
BackendQueryHandle BeginOcclusionQuery();
void EndOcclusionQuery(BackendQueryHandle query);
// GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN / GL_PRIMITIVES_GENERATED, also core ES
// (GL_PRIMITIVES_GENERATED from ES 3.2 on). Null when the target is unavailable, in
// which case the frontend falls back to counting primitives from the draw calls.
BackendQueryHandle BeginXfbPrimitivesQuery(Bool generated);
void EndXfbPrimitivesQuery(BackendQueryHandle query);
Bool IsQueryResultAvailable(BackendQueryHandle query);
// Returns true when a final value landed in *outNanoseconds (a zero for
// null or stale-generation handles IS final: the frontend may cache it