Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Yes—but it would be closer to a Vita-specific API trace recorder than RenderDoc. A useful first version is feasible, especially for your own Unity Vita build, but complete GPU-state capture and accurate per-draw GPU timing would be substantially harder.
- What is realistically possible
- A taiHEN user plugin could be loaded into the game process and hook the exported SceGxm functions used by Unity. taiHEN explicitly supports function replacement and hooks inside applications and system modules.
- The plugin could watch calls such as:
- * sceGxmBeginScene / sceGxmEndScene
- * sceGxmDraw and sceGxmDrawPrecomputed
- * sceGxmSetVertexProgram
- * sceGxmSetFragmentProgram
- * texture bindings
- * vertex and index stream bindings
- * uniform-buffer reservations and updates
- * blend, depth, stencil, culling and viewport state
- * render-target and depth-surface selection
- * display-queue submission
- The public VitaSDK headers expose a large portion of this GXM API, including draw calls, shader selection, render state, texture formats and surface layouts.
- On a requested frame, the recorder would serialize the state seen at every draw into a capture file:
- Frame
- ├── Render target information
- ├── Depth/stencil information
- ├── Draw 0
- │ ├── vertex program
- │ ├── fragment program
- │ ├── textures
- │ ├── vertex/index buffers
- │ ├── uniforms
- │ ├── render state
- │ └── primitive and index count
- ├── Draw 1
- └── ...
- A PC viewer could then present a draw-call timeline and aggregate useful statistics.
- What you could obtain reliably
- A first-generation tool could give us:
- Information Feasibility
- Final displayed color buffer High
- Draw-call count High
- Triangle/index count High
- Shader/program changes High
- Texture binding changes High
- Render-target changes High
- Blend/depth/cull state High
- Texture dimensions and formats High
- Vertex/index-buffer sizes Medium–high
- Uniform data at each draw Medium–high
- Estimated texture and buffer bandwidth Medium
- CPU time spent submitting each draw High
- Total frame GPU completion time Medium–high
- Exact GPU duration per draw Low
- Hardware utilization counters Unknown/low
- Fragment count or overdraw directly from GPU Low
- Perfect standalone replay on a PC Very low
- This alone would be valuable for your project. It could answer questions such as:
- * Which shader produced the most draws?
- * How many triangles were submitted for each pass?
- * How often did textures, shaders or blend states change?
- * How much texture data was potentially sampled?
- * Which draws used alpha test or blending?
- * Which render targets were active?
- * How many objects were rendered more than once?
- * How much CPU time was spent inside GXM submission?
- * Which frame stages were separated by BeginScene, EndScene, flushes or synchronization?
- The important limitation: GXM is tile-based
- The Vita’s SGX543MP4+ is a PowerVR tile-based renderer. The framebuffer after an individual sceGxmDraw call is not necessarily sitting in memory as a completed image. Much of the fragment work may remain deferred until the tile is processed or the scene ends.
- Consequently, hooking this sequence:
- sceGxmDraw(...);
- copyFramebuffer();
- would not reliably produce the visual result “after that draw.”
- That is one of the largest differences from a desktop immediate-mode frame debugger.
- To inspect individual draw output, we would need one of these approaches:
- 1. Capture and replay the frame one draw at a time.
- Record every call and resource, then replay draw 0, draws 0–1, draws 0–2, and so forth into a diagnostic render target.
- 2. Recapture the same deterministic frame repeatedly.
- On capture pass 1, stop after draw 1; on pass 2, stop after draw 2; and so on.
- 3. Instrument the game itself.
- Unity-side code supplies object, material, pass and camera names while the native plugin captures the lower-level GXM activity.
- The third option would be particularly effective for your project.
- “Attach” versus loading a plugin
- Attaching to an already-running process after it has started is more difficult and unnecessary for the initial implementation.
- The cleaner design is:
- taiHEN loads FrameCapture.suprx with the game
- ↓
- plugin installs GXM hooks
- ↓
- game runs normally with capture disabled
- ↓
- button combination or network command arms capture
- ↓
- next complete frame is recorded
- ↓
- capture is written or sent to PC
- The plugin remains mostly dormant until capture is requested. That avoids needing a conventional debugger-style process attachment mechanism.
- It could be controlled by:
- * a Vita button combination;
- * a small TCP command from the PC;
- * a file placed in a known directory;
- * a Unity FrameCapture.Trigger() native-plugin call.
- For development, I would use both a Unity call and a button fallback.
- How I would design it
- Vita component
- A user-mode taiHEN plugin:
- vita-framecapture.suprx
- Responsibilities:
- * Hook GXM entry points.
- * Maintain a shadow copy of the current GXM state.
- * Assign stable IDs to programs, textures, buffers and surfaces.
- * Start a frame at sceGxmBeginScene.
- * Emit a draw record at each sceGxmDraw.
- * Finish capture at sceGxmEndScene or display submission.
- * Wait for GPU completion before copying final surfaces.
- * Write a binary capture to ux0:data/framecapture/.
- * Optionally stream captures over TCP.
- sceGxmFinish is documented as blocking CPU execution until the GPU has completed rendering, so it can provide a reliable synchronization point for an explicitly requested capture, although it would intentionally stall that frame.
- PC component
- A desktop application that reads the capture and provides:
- * event browser;
- * per-draw state;
- * texture viewer;
- * vertex/index statistics;
- * shader/program grouping;
- * render-pass grouping;
- * state-change analysis;
- * estimated bandwidth;
- * final color-buffer viewer;
- * export to CSV or JSON.
- Initially, this could be a C# desktop application because the difficult part is the Vita plugin, not the viewer.
- Unity integration
- For your Unity project, a managed component could add semantic metadata:
- VitaFrameCapture.BeginMarker("Camera.Main");
- VitaFrameCapture.BeginMarker("Building Exterior");
- VitaFrameCapture.SetObjectInfo(
- renderer.GetInstanceID(),
- renderer.name,
- material.name,
- shader.name);
- Graphics.DrawMesh(...);
- VitaFrameCapture.EndMarker();
- GXM itself exposes user-marker functions such as sceGxmPushUserMarker, sceGxmPopUserMarker and sceGxmSetUserMarker.
- Unity may not emit those automatically, but we can introduce markers around your custom managers, shadow pass, camera stages and important render groups. That would turn anonymous GXM draws into something much more understandable:
- Camera.Main
- ShadowMap.PlayerSpotlight
- Building_17_Walls
- Building_17_Trim
- ForwardBase.Opaque
- Road_Section_04
- Building_17_Walls
- AlphaTest
- Tree_03_Leaves
- GrassShell_04
- Transparent
- Puddle_02
- GPU timing
- This is where expectations need to be controlled.
- Feasible
- We can measure:
- * total CPU frame duration;
- * CPU time spent in each hooked function;
- * CPU submission duration;
- * time between end-of-scene and completed GPU synchronization;
- * total synchronized GPU workload for the frame;
- * the cost difference between two captures with selected draws disabled.
- Probably not feasible initially
- Without access to undocumented PowerVR performance counters or Sony’s official development profiling interfaces, we probably cannot directly report:
- Draw 128: vertex stage 34 µs
- Draw 128: fragment stage 241 µs
- Draw 128: 38,200 shader invocations
- Draw 128: 82% texture-unit utilization
- A useful substitute is differential timing:
- 1. Capture a repeatable frame.
- 2. Measure its total GPU-completion time.
- 3. Disable a draw group.
- 4. Measure it again.
- 5. Attribute the difference approximately to that group.
- For your project, grouping by shader, building section, alpha-tested grass, trees, shadows and transparency would make this surprisingly useful.
- Resource capture complications
- A draw record contains pointers to resources, not necessarily self-contained assets. During capture we would need to determine the allocations behind:
- * textures;
- * vertex buffers;
- * index buffers;
- * uniform buffers;
- * shader programs;
- * render targets.
- The most robust approach is to hook resource creation and mapping functions from process startup, rather than trying to discover everything only when the capture button is pressed.
- That allows the plugin to build a registry:
- GPU address → allocation ID, CPU address, size, type and format
- When capture begins, resources referenced by the captured frame can then be copied into the capture file.
- Without this registry, we could still collect draw statistics, but standalone resource inspection and replay would be unreliable.
- Recommended development stages
- Stage 1: frame event analyzer
- Capture only:
- * begin/end scene;
- * draw calls;
- * primitive type;
- * index count;
- * active shader pointers;
- * textures and state pointers;
- * render-state changes;
- * CPU timestamps;
- * final screenshot.
- This would already expose draw count, approximate triangles, state churn and pass structure.
- Stage 2: resource descriptions
- Track:
- * texture format, dimensions, mip count and memory location;
- * vertex/index allocation sizes;
- * render-target formats;
- * depth formats;
- * shader program identifiers;
- * memory estimates.
- Stage 3: resource snapshots
- Copy:
- * textures;
- * vertex data;
- * indices;
- * uniforms;
- * final color and depth surfaces where readable.
- Stage 4: Unity-assisted labels
- Add object, material, shader, pass and LOD metadata from your Unity code.
- Stage 5: diagnostic replay
- Replay captured commands on the Vita itself, initially only for:
- * draw suppression;
- * wireframe substitutions;
- * texture replacement;
- * overdraw visualization;
- * shader-cost grouping;
- * cumulative draw output.
- A full desktop replay backend should not be the initial objective. Vita GXM shader binaries and hardware behavior do not map directly onto desktop graphics APIs.
- My overall assessment
- A tool that captures everything Sony’s official GPU debugger would have exposed is probably unrealistic without proprietary SDK/debug interfaces and substantial reverse engineering.
- A tool that captures:
- * frame structure;
- * all GXM draw calls;
- * pipeline state;
- * resources;
- * final framebuffer;
- * Unity object labels;
- * approximate memory and bandwidth costs;
- * total and differential GPU timing;
- is absolutely plausible.
- For your Vita project, that narrower tool could still be extremely useful. In fact, because we control the Unity-side code, a hybrid Unity instrumentation + native GXM hook system would likely provide more actionable information than attempting a completely generic black-box debugger.
Advertisement
Add Comment
Please, Sign In to add comment