Repository navigation
OpenGL Direct Surface Binding
Lifecycle: Performance - Unproven · Type: Copy-bypass and aliasing shortcut
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: The current backend materializes a separate texture version. Direct aliasing is not implemented and has substantial ordering hazards.
OpenGL candidate directory · Copy-image surface transfer · OpenGL Renderer
When a render surface is later sampled as a texture, xemu currently copies or renders the surface into a separate texture object. That independent destination freezes a version: later rendering to the original surface does not change the already-materialized texture.
Direct surface binding removes the copy entirely for states where the surface image itself can be sampled with the required interpretation. The challenge is not creating a view—it is preserving guest ordering, texture-version identity, and feedback behavior.
This is intentionally a separate experiment from glCopyImageSubData():
- Copy-image transfer retains an independent texture version.
- Direct binding aliases the producer resource and must prove that later writes cannot change earlier consumers.
-
hw/xbox/nv2a/pgraph/gl/texture.c- surface lookup during texture binding
-
pgraph_gl_render_surface_to_texture()call - texture binding
draw_timeand scale tracking
-
hw/xbox/nv2a/pgraph/gl/surface.c- surface/texture compatibility checks
- render-copy and CPU fallback routes
- Surface cache lifetime, draw version, upload/download, and framebuffer attachment handling.
flowchart TD
A[Texture stage points into active render-surface range] --> B{Surface/texture compatible?}
B -->|No| C[Download/convert/upload texture]
B -->|Yes| D{Texture binding older than surface draw_time?}
D -->|No| E[Reuse independent texture]
D -->|Yes| F[Materialize new independent texture version]
F --> G[Bind copied texture for guest draw]
E --> G
C --> G
The independent texture object is a version barrier.
flowchart TD
A[Texture stage references render surface] --> B{Direct-view eligibility proven?}
B -->|No| C[Reference copy/materialization route]
B -->|Yes| D[Create/reuse sample-compatible view state]
D --> E{Feedback or later-write hazard?}
E -->|Yes| C
E -->|No| F[Retain surface version reference]
F --> G[Bind surface image directly]
G --> H[Draw samples exact retained version]
H --> I[Release version after GPU completion]
Possible binding record:
typedef struct GLDirectSurfaceTexture {
SurfaceBinding *surface;
uint64_t surface_lifetime_id;
uint64_t content_version;
GLenum target;
GLenum sampling_format;
unsigned base_level;
unsigned width;
unsigned height;
uint32_t scale;
} GLDirectSurfaceTexture;A raw pointer to SurfaceBinding is insufficient if the cache can destroy and reuse the allocation.
- Color surface; depth/stencil requires separate research.
- Sampleable OpenGL texture target exists for the surface storage.
- Guest texture format can be represented without copy-time conversion.
- Dimensions, scale, mip level, and border semantics match.
- Channel/alpha interpretation matches shader expectations.
- The surface producer is complete before the sampling draw.
- The surface is not simultaneously attached for a prohibited feedback loop.
- Later writes cannot mutate the version needed by already-recorded/issued draws.
- Surface recreation at the same guest address produces a new lifetime ID.
- Sampler state can be applied without mutating the surface in a way that breaks its rendering role; sampler objects are preferable.
- Texture cache/refcount/lifetime rules retain the surface until the last sampling draw completes.
- CPU upload/download authority changes invalidate the direct view.
Consider:
1. Render red into surface A.
2. Draw B while sampling A.
3. Render blue into A.
4. Draw C while sampling A.
Correct output:
B observes red.
C observes blue.
If the host executes work asynchronously and both draws sample the same mutable texture storage, B can incorrectly observe blue unless command ordering and resource hazards guarantee the earlier sample completes before the later write.
OpenGL command ordering in one context may protect some sequences, but cross-context work, FBO reattachment, driver reordering, and shared-resource ownership still require an explicit model. A shortcut must document which ordering guarantee it relies on.
Sampling from a texture that is simultaneously attached to the active framebuffer can be undefined or require a specific texture-barrier strategy. The initial route should reject:
- same surface as active color target;
- same surface as active depth/stencil target;
- overlapping regions with unresolved write/read order;
- guest patterns requiring feedback semantics not proven by the backend.
A texture barrier is not a universal permission to ignore feedback restrictions.
- Destination texture allocation/redefinition.
- Copy-image or full-screen render-copy work.
- Additional texture memory for the copied representation.
- Version-copy latency on repeated render-to-texture use.
- Some cache lookup and upload work.
- Exact guest sampling representation.
- Independent version behavior when later writes would otherwise change earlier observations.
- Correct surface-to-texture ordering.
- Feedback-loop rejection or proven handling.
- Correct scale, border, mip, format, and alpha behavior.
- CPU visibility/readback when requested.
- Copy fallback for unsupported or unsafe states.
The current backend applies filter/wrap/border parameters to texture objects. Applying guest sampling state directly to a render-surface texture can alter state used by other consumers. A robust direct-binding route should depend on OpenGL Sampler Objects or maintain separate safe texture state.
This dependency does not mean sampler objects must be implemented first for all textures, but the direct route must not mutate shared surface storage unpredictably.
- Removes the entire copy/materialization step on a hit.
- Reduces host image memory and bandwidth.
- High potential in render-to-texture-heavy games.
- Can use existing surface lifetime and draw-version concepts as a foundation.
- Maintains a complete copy fallback.
- Most dangerous OpenGL surface optimization in this set.
- Missing version ownership causes nondeterministic stale/future data.
- Feedback behavior can become undefined.
- Surface and texture lifetimes become coupled.
- Scale/format compatibility may leave a narrow hit rate.
- Driver/context differences can expose hidden synchronization assumptions.
- Direct aliasing may worsen cache behavior despite removing copies.
surface_texture_requests
direct_binding_eligible
direct_binding_hits
direct_binding_fallbacks{reason}
copy_materializations_avoided
bytes_avoided
surface_versions_retained
surface_version_reuse_waits
feedback_blocks
lifetime_mismatch_blocks
format_or_scale_blocks
GPU time for materialization versus direct route
| Scenario | Required result |
|---|---|
| Render red → sample → render blue → sample | First consumer red, second blue |
| Several draws sample one stable surface | Direct reuse without copies |
| Source reused at same guest address | New lifetime prevents old alias |
| Surface attached while sampled | Rejected or proven safe route |
| Multiple texture stages sample source | Correct sampler/state separation |
| Scale/format/border mismatch | Copy fallback |
| CPU upload overwrites guest range | Direct view invalidated |
| CPU readback after direct use | Correct guest bytes |
| Context reset/snapshot/eviction | No dangling surface reference |
| Artificial GPU delay | No early destruction or mutation |
Promote to Researched only after versioned red/blue ordering fixtures, feedback rejection, lifetime stress, and output comparisons pass, and real workloads show enough avoided materialization to improve Release performance.
Reject or restrict the route if safe version retention effectively requires making a copy anyway, if feedback/format constraints make coverage negligible, or if cross-context ownership cannot be proven.
DSP tooling guide and navigation updated November 2, 2026 for experimental PR #384, source 8f51d237. Capture/replay usage and limits.
The earlier wiki-wide review was published November 1, 2026. Emulator source: b7140848. Reviewed wiki content: 1d2b671. Current status · Release availability · Publication process.
- Home
- Current status
- Stable versus main
- Implemented mechanisms
- Controls and defaults
- Measured results and limits
- Complete change register
- System
- CPU and vCPU
- Memory and DMA
- Graphics / NV2A
- APU and audio
- Timing and timers
- Platform and I/O
- Hardware observations
- Fidelity boundaries
- Methodology
- PGR2 routes
- Debugging lag / hot paths
- Tools and commands
- DSP capture, replay and fuzzing
- HLE readiness and public XISO proof
- Concurrent DSP shadow and OpenAL proof
- DSP HLE operation inventory
- DSP HLE fix examples and testing
- Development
- Upstream shortlist
- Wiki maintenance
- Research / retired work
- Optimization catalog
- Hot-path shortcuts
- Researched experiments
- Unproven proposal directory
- PR lessons
- September26 snapshot
Repository · PRs · Issues