Repository navigation
OpenGL Copy Image Surface Transfer
Lifecycle: Performance - Unproven · Type: Exact copy subset
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: The current compatible surface-to-texture route is source-confirmed. The exactglCopyImageSubData()eligibility subset has not been qualified.
OpenGL candidate directory · Direct surface binding · OpenGL Renderer
When a newer compatible render surface must update a texture, the current OpenGL fast route does not copy image storage directly. It redefines destination texture storage, attaches the destination to an FBO, changes substantial OpenGL state, clears the destination, and draws a full-screen triangle that samples the source surface.
The candidate keeps destination storage alive and uses glCopyImageSubData() for the subset where source and destination representations are copy compatible.
This is narrower and safer than direct surface binding. It still creates an independent texture version; it only replaces the way that version is materialized.
-
hw/xbox/nv2a/pgraph/gl/surface.csurface_to_texture_can_fastpath()render_surface_to()pgraph_gl_render_surface_to_texture()- slow readback/upload fallback
-
hw/xbox/nv2a/pgraph/gl/texture.c- surface-to-texture compatibility and binding lifetime
- Texture storage allocation/reallocation and OpenGL capability discovery.
flowchart TD
A[Surface newer than texture binding] --> B{Current compatibility check passes?}
B -->|No| C[Download surface and upload texture]
B -->|Yes| D[glTexImage2D NULL redefines destination]
D --> E[Attach destination texture to temporary FBO]
E --> F[Bind source surface as texture]
F --> G[Change viewport/masks/tests/program/VAO]
G --> H[Clear destination]
H --> I[Draw full-screen triangle]
I --> J[Restore selected GL state]
J --> K[Publish texture draw_time]
This avoids a CPU round trip, but it still performs rendering work and disturbs global OpenGL state.
flowchart TD
A[Surface newer than texture binding] --> B{Copy-image compatibility key matches?}
B -->|No| C[Current render-copy or slow fallback]
B -->|Yes| D{Destination storage already compatible?}
D -->|No| E[Allocate/redefine destination once]
D -->|Yes| F[Keep existing storage]
E --> G[glCopyImageSubData]
F --> G
G --> H[Publish independent texture version]
Illustrative call:
glCopyImageSubData(
surface->gl_buffer, GL_TEXTURE_2D, 0,
0, 0, 0,
texture->gl_texture, texture->gl_target, 0,
0, 0, 0,
copy_width, copy_height, 1);The actual target, mip level, face/layer, dimensions, internal formats, scaling, and border rules must be included in the guard.
A safe first subset should require:
- source is a color surface;
- destination is a 2D texture, not a cubemap face or 3D layer;
- one mip level is being updated;
- source and destination dimensions match after the already-selected scale policy;
- no filtering, scaling, swizzle conversion, border insertion, color remap, or alpha synthesis is required;
- OpenGL internal formats are copy compatible according to the API rules;
- source and destination are distinct objects or a proven legal non-overlapping region;
- destination storage exists with the correct immutable/mutable representation;
- no feedback loop or pending write/read hazard exists.
The existing surface_to_texture_can_fastpath() format pairs are a starting point, not a complete glCopyImageSubData() contract.
The current route calls glTexImage2D(..., NULL) before every compatible copy. The candidate needs a storage descriptor on the texture binding:
typedef struct GLCopyStorageKey {
GLenum target;
GLenum internal_format;
unsigned width;
unsigned height;
unsigned levels;
unsigned layers;
} GLCopyStorageKey;If the key matches, retain storage. If it changes, reallocate before the copy. Storage identity must also reset when the texture object is recreated or evicted.
- Repeated destination storage redefinition on same-shape updates.
- FBO attachment and completeness work.
- Destination clear.
- Full-screen vertex/fragment execution.
- Temporary shader/VAO/program binding.
- Most render-state disturbance and restoration.
- Independent destination image version.
- Correct format/alpha/channel representation.
- Correct dimensions and selected mip/layer.
- Ordering from surface producer to copy and from copy to texture consumer.
- Reference route for conversion/scaling/border/swizzle cases.
- Storage recreation when the representation changes.
- Texture-cache and draw-time/version updates.
The current shader route can perform effects that a raw image copy cannot:
- sampling/filtering;
- channel interpretation through the texture format;
- scaling;
- handling a destination with different representation;
- border or coordinate behavior.
glCopyImageSubData() copies image data. It does not run the current conversion shader. Eligibility must prove that no conversion is needed.
This candidate reduces state mutation, but the fallback render-copy path remains. A future OpenGL Render-State Shadow must account for both:
- copy-image path, which should not disturb ordinary draw state;
- render-copy path, which deliberately changes many states and restores only selected values.
- Exact for a well-defined representation-compatible subset.
- Removes a complete internal draw and clear.
- Reduces global state churn.
- Retains independent texture lifetime, avoiding alias/version hazards.
- Has clear output/version fixtures.
- Compatibility rules are stricter than the current visual fast path.
- Driver support/capability must be checked.
- Incorrect format compatibility can silently reorder channels or alpha.
- Destination storage caching adds another lifetime key.
- Copy may still serialize if source/destination hazards are not ordered efficiently.
- The route may have low coverage if games frequently require conversion or scaling.
surface_to_texture_requests
copy_image_eligible
copy_image_calls
copy_image_bytes
render_copy_fallbacks{reason}
slow_CPU_fallbacks{reason}
destination_storage_reuses
destination_storage_reallocations
internal_draws_avoided
FBO_setups_avoided
copy_image_us
render_copy_us
| Scenario | Required result |
|---|---|
| Exact same-format/same-size color copy | Byte/pixel-identical result |
| XRGB/ARGB and channel-order pairs | Only admitted pairs copy exactly |
| Scaled source or destination | Reference route unless exact rule proven |
| Border/cubemap/mipmap case | Reference route |
| Source red then blue, copies to B and C | B remains red; C becomes blue |
| Destination reused with new representation | Storage reallocated safely |
| Source modified after copy | Destination retains independent older version |
| Multiple texture stages | Each binding sees correct copied version |
| Context reset/cache eviction | Storage key invalidated |
| Multiple drivers | Capability and correctness recorded |
Promote to Researched when a declared format/shape subset is pixel exact, route counters show useful coverage, and Release measurements reduce surface-to-texture CPU/GPU work or frame tails.
Reject or narrow the route if compatibility checks become driver-specific and unreliable, if exact-copy coverage is negligible, or if the driver’s copy path is slower than the current full-screen draw in representative workloads.
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