Repository navigation
OpenGL PVIDEO GPU Conversion
Lifecycle: Performance - Unproven · Type: Resource reuse and GPU conversion
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: The CPU conversion and full texture redefinition are source-confirmed. No PVIDEO-active benchmark has measured their cost.
OpenGL candidate directory · OpenGL Renderer · Vulkan PVIDEO Resource Lifetime
The OpenGL display path converts packed CR8YB8CB8YA8/YUY2-style guest video bytes into a newly allocated RGBA CPU buffer every time the overlay is rendered, uploads the converted image with glTexImage2D(), then samples it during display composition.
The candidate has two independently testable stages:
- Retain compatible PVIDEO texture storage and use subimage updates instead of redefining storage every refresh.
- Upload the packed guest representation and perform YUV-to-RGB conversion during GPU composition.
The second stage can remove both the CPU conversion loop and the 2-byte-to-4-byte upload expansion.
-
hw/xbox/nv2a/pgraph/gl/display.cconvert_texture_data__CR8YB8CB8YA8()render_display_pvideo_overlay()-
glTexImage2D()onr->disp_rndr.pvideo_tex - PVIDEO crop, pitch, scale, position, and color-key handling
- Display shader and texture-unit state.
- Guest VRAM freshness/dirty tracking for overlay bytes.
flowchart TD
A[PVIDEO enabled] --> B[Read base/offset/pitch/size/crop registers]
B --> C[Allocate width x height x 4 CPU buffer]
C --> D[Loop over every output pixel]
D --> E[Convert packed YUV pair to RGB]
E --> F[glTexImage2D redefines RGBA texture]
F --> G[Display shader samples RGBA overlay]
G --> H[Apply crop/scale/color key composition]
H --> I[Free temporary CPU buffer]
flowchart TD
A[PVIDEO enabled] --> B{Packed texture storage compatible?}
B -->|No| C[Allocate/resize packed resource]
B -->|Yes| D[Reuse storage]
C --> E[Upload packed guest rows]
D --> E
E --> F[Display shader fetches packed YUV samples]
F --> G[Convert to RGB in shader]
G --> H[Apply crop/scale/color key]
H --> I[Compose display]
J[Unsupported format/capability] --> K[Reference CPU conversion route]
if (pvideo_width != cache.width ||
pvideo_height != cache.height ||
cache.internal_format != GL_RGBA8) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
pvideo_width, pvideo_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
cache.width = pvideo_width;
cache.height = pvideo_height;
}
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
pvideo_width, pvideo_height,
GL_RGBA, GL_UNSIGNED_BYTE, converted);This removes storage redefinition but retains CPU conversion and expanded transfer bytes.
The exact OpenGL representation depends on supported formats. One possible model uses a two-byte texel or integer texture and decodes the shared chroma pair in the display shader.
Illustrative shader logic:
uvec4 pair = texelFetch(packed_video, ivec2(pixel.x >> 1, pixel.y), 0);
uint y = ((pixel.x & 1) == 0) ? pair.r : pair.b;
uint cb = pair.g;
uint cr = pair.a;
vec3 rgb = convert_ycbcr_to_rgb(y, cb, cr);The actual channel packing must match the guest format exactly; this snippet is not an accepted layout declaration.
Current code converts/uploads the full admitted input region on each composition. A complete route should track:
- PVIDEO register generation;
- guest byte dirtiness for the active base/offset/pitch/height range;
- input crop and output rectangle;
- texture storage dimensions and format;
- last uploaded content generation.
If registers and bytes are unchanged, the existing packed texture can be reused without another upload. This reuse is separate from Completed Display Reuse, which can avoid the entire display composition.
The GPU route must reproduce:
- luma/chroma byte pairing;
- limited/full range behavior used by current conversion helpers;
- channel coefficients and integer rounding;
- odd-pixel handling;
- pitch and row padding;
- input crop (
POINT_IN); - output scale and coordinate origin;
- color-key comparison interaction;
- alpha value.
A visually similar conversion is not sufficient where color-key equality or pixel hashing matters.
The PVIDEO texture should have a stable storage key:
typedef struct GLPvideoStorageKey {
unsigned input_width;
unsigned input_height;
unsigned packed_row_texels;
GLenum internal_format;
GLenum upload_format;
GLenum upload_type;
} GLPvideoStorageKey;Sampling parameters should be set only when the storage/resource is created or when effective filtering changes. A future OpenGL Sampler Objects route can isolate overlay filtering from image storage.
- Per-frame temporary RGBA allocation/free.
- CPU per-pixel YUV-to-RGB conversion.
- Repeated texture storage redefinition.
- Expanded four-byte-per-pixel upload when packed data is used.
- Uploads when both overlay state and active guest bytes are unchanged.
- Correct PVIDEO enable/disable behavior.
- Crop, pitch, scale, output position, and interlace behavior.
- Color-key and channel conversion semantics.
- Fresh guest bytes before upload.
- Texture lifetime across display-context use.
- Reference route for unsupported formats/capabilities.
- Correct invalidation on reset, snapshot restore, or resource recreation.
- Sharply bounded to PVIDEO-active workloads.
- Stage 1 is low risk and independently measurable.
- Stage 2 removes CPU arithmetic and halves source upload bytes for the packed format.
- Reuses the existing display shader/composition stage.
- Has pixel-level correctness fixtures.
- PVIDEO may be uncommon in many benchmark scenes.
- GPU conversion can differ at rounding/color-key boundaries.
- Packed texture support and row layout vary by host capability.
- Dirty tracking for pitched overlay data must be complete.
- Shader conversion increases display-pass GPU work.
- Combining resource reuse, dirty tracking, and GPU conversion in one patch would obscure results.
pvideo_active_frames
pvideo_uploads
pvideo_storage_allocations
pvideo_storage_reuses
pvideo_storage_resizes
pvideo_CPU_conversion_pixels
pvideo_CPU_conversion_us
pvideo_packed_upload_bytes
pvideo_RGBA_upload_bytes
pvideo_uploads_skipped_unchanged
pvideo_GPU_conversion_frames
pvideo_display_GPU_us
| Scenario | Required result |
|---|---|
| Long constant-resolution video | One storage allocation, repeated updates |
| Unchanged bytes/registers | Upload can be skipped |
| Resolution/pitch change | One safe storage replacement |
| Odd width and padded pitch | Correct luma/chroma pairing |
| Input crop and output scale | Same selected source pixels |
| Color-key boundary colors | Same overlay decision |
| Enable/disable/teardown | No stale overlay |
| Snapshot/reset/context recreation | Cache invalidated correctly |
| CPU versus GPU conversion image diff | Declared exact or bounded result |
| PVIDEO-heavy Release workload | Lower CPU/upload/tail cost |
Promote stable storage reuse separately when object/storage churn is reduced with identical output. Promote GPU conversion only after pixel-level comparison establishes the admitted conversion contract and Release measurements improve PVIDEO-active workloads.
Reject GPU conversion if numerical differences break color keying or if the display GPU cost exceeds the removed CPU/upload cost. Do not generalize a PVIDEO result to ordinary game rendering.
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