1. Overview
Yes: APU/DSP calculations can be executed by GPU compute shaders through PHLEGM’s graphics backends. This would extend the proposed graphics-backend micro-code architecture to a third execution target: GPU Compute. The approach is technically feasible, but not every APU operation would benefit.
For the SNES, the best initial candidates are selected S-DSP signal-processing tasks; the sequential S-SMP / SPC700 processor should initially continue executing on the host CPU using the existing data-driven micro-code runtime.
This is an architecture proposal, not a statement that GPU APU micro-codes or a cross-backend compute IR already exist in PHLEGM v9.
2. Why graphics backends can handle audio
General-purpose GPU compute dispatches parallel shader invocations over buffers of data. Audio algorithms often contain arithmetic that can be expressed as reusable operations: decoding, interpolation, mixing and filtering.
| PHLEGM backend | Potential compute mechanism | Requirement / caveat |
|---|---|---|
gfx_opengl.lib | GLSL compute shaders | Normally OpenGL 4.3+ or a suitable extension; older contexts require CPU fallback. |
gfx_d3d11.lib | HLSL compute shaders | Requires supported D3D11 compute capabilities and compatible device feature level. |
gfx_vulkan.lib | SPIR-V compute pipelines | Requires a compute-capable Vulkan device/queue and suitable memory/synchronization support. |
GPU compute can be excellent for large buffers, but the SNES audio workload is small. Kernel launches, state transfers, fences, and readback may cost more than the audio math itself. Availability does not guarantee a speedup.
3. Proposed PHLEGM execution architecture
.phlegm definitions (CPU / PPU / APU / DSP)microcode.lib compiler / validator / intermediate representationcompute.lib generic interface → gfx_opengl.lib / gfx_d3d11.lib / gfx_vulkan.libcompute.lib is a suggested abstraction for dispatching backend-neutral computation—not an existing required PHLEGM library. The compute IR expresses operations in hardware-independent terms; backends supply shader compilation, resource allocation, dispatch, and synchronization.
CPU target
Instruction execution, timing-sensitive hardware state, port handshakes, sequential DSP operations, and deterministic fallback.
GPU Graphics target
PPU rendering: tile fetch, compositing, sprites, SNES Mode 7 and other raster tasks.
GPU Compute target
Optional batch-oriented general computation such as DSP sample processing when benchmarking justifies offload.
4. SNES S-SMP / S-DSP suitability
SNES audio combines the S-SMP (SPC700) control processor, the S-DSP audio processor, and CPU↔APU communication ports. These parts have very different parallelism and synchronization requirements.
| Component / operation | GPU fit | Why |
|---|---|---|
| S-SMP / SPC700 instruction stream | Low | Sequential, branch-heavy control flow and timing-sensitive port interaction. |
| S-DSP voice generation | Conditional | Up to eight voice paths can provide some parallelism, but each voice carries state between samples. |
| BRR decoding | Conditional | Independent voices/blocks may batch well; predictor history makes samples within a block dependent. |
| Gaussian interpolation | Promising primitive | Arithmetic is regular, but exact integer behavior, clipping and source sample state must match hardware. |
| ADSR / gain envelopes | Limited | Small workload, timing and state dependencies. |
| Eight-voice mixing | Promising primitive | Parallel per-voice contributions; reduction overhead can outweigh savings for only eight voices. |
| Echo / FIR filtering | Conditional | Tap operations can be parallel; echo-feedback history imposes dependencies across output samples. |
| APU I/O-port handshake | Keep on CPU | Main-CPU-visible synchronization should not depend on asynchronous GPU completion. |
The S-DSP’s nominal output stream is approximately 32 kHz. This is a relatively modest workload by modern host CPU standards, so the default should remain CPU execution until measurements show otherwise.
5. Candidate audio micro-code primitives
The names below are illustrative proposals for a generic audio/compute instruction vocabulary; they are not existing PHLEGM opcodes or finalized .phlegm syntax.
AUDIO_BRR_DECODE
Decode compressed sample data using supplied predictor and range rules.
AUDIO_SAMPLE_INTERPOLATE
Interpolate sample positions using a definition-selected integer kernel.
AUDIO_ENVELOPE_UPDATE
Advance envelope state according to supplied schedules and modes.
AUDIO_VOICE_MIX
Accumulate multiple voice contributions with explicit width and clipping rules.
AUDIO_FIR_FILTER
Apply finite-impulse-response filtering over a declared sample history.
AUDIO_ECHO_FEEDBACK
Combine filtered signals with a feedback buffer and configured arithmetic.
AUDIO_SAMPLE_OUTPUT
Write bounded PCM samples to a host-consumable output buffer.
COMPUTE_BARRIER
Express data dependencies across stages when required by a validated schedule.
Each primitive needs well-defined operand widths, signedness, rounding, saturation, latency, buffer ownership, and state-update ordering. Accuracy must not depend on subtle differences between shader compilers.
6. Keep audio behavior data-driven
The emulated device definitions should determine what the APU does; generic execution engines determine how to execute it efficiently.
| Responsibility | Ownership |
|---|---|
| S-SMP opcode behavior and CPU/APU port semantics | Machine/chipset .phlegm micro-codes and register definitions. |
| DSP registers, envelopes, interpolation tables, filtering rules | Machine/chipset .phlegm definitions. |
| Generic audio arithmetic, buffers, scheduling abstractions | microcode.lib plus proposed reusable audio/compute primitives. |
| Shader translation, compute dispatch, GPU memory and fences | compute.lib contract with the existing gfx_*.lib backends. |
| DAC/PCM submission to the user’s audio device | Host audio output implementation, independent of the graphics backend. |
Illustrative definition-driven pipeline
// Conceptual program only — NOT valid .phlegm syntax
APU_AUDIO_BLOCK:
for each emulated DSP sample time:
AUDIO_ENVELOPE_UPDATE(voice_state)
AUDIO_BRR_DECODE(sample_state)
AUDIO_SAMPLE_INTERPOLATE(voice_sample)
AUDIO_VOICE_MIX(voice_samples)
AUDIO_FIR_FILTER(echo_history)
AUDIO_ECHO_FEEDBACK(echo_state)
AUDIO_SAMPLE_OUTPUT(pcm_buffer)
// Execution policy:
// CPU_reference by default; GPU_compute only if verified
// and profitable for a suitably sized workload.
A real implementation may need to fuse stages or execute some of them serially to preserve authentic DSP ordering. The pseudocode specifies the concept, not a claim that the steps are freely parallelizable.
7. Compilation and execution lifecycle
PHLEGM’s existing micro-code rule remains unchanged: compile the applicable machine-specific definitions at machine load, and recompile when a session restore requires it. Do not generate machine micro-codes during native build, distribution packaging, or bootstrap execution.
- Load the machine. Resolve active chipset, support-chip and audio definitions.
- Compile and validate. Build an architecture-neutral audio/compute IR from the active definitions.
- Inspect capabilities. Determine whether the chosen graphics backend has suitable compute support and integer precision.
- Select an execution target. Use the deterministic CPU path by default; optionally enable a verified GPU implementation.
- Compile GPU programs once per active definition state. Prepare shaders, buffers and dispatch plans, not one shader per sample or frame.
- Schedule blocks safely. Produce exactly the samples allowed by elapsed emulated DSP time; return ordered PCM buffers to the host audio output.
- On machine change/restore. Invalidate old compiled machine-specific programs and reconstruct them from the currently active definitions.
8. Timing, buffering and synchronization
Audio is low-latency and strongly ordered. An efficient compute shader that finishes too late, uses stale port state, or changes sample ordering is an incorrect emulation result.
Emulated clock
Drive DSP sample production from emulated timing, not wall-clock draw calls or host GPU frame rate.
Batch size
Batch enough samples to amortize dispatch/readback while keeping audio latency and responsiveness acceptable.
Deterministic state
Preserve feedback buffers, per-voice history, envelope transitions and integer arithmetic in exact order.
Port handshake
Leave CPU↔S-SMP communication and IPL/upload handshakes on the timing-aware host-side execution path.
Host output
Transfer generated PCM through an audio queue/ring buffer; never route sound through a framebuffer.
Failure recovery
On unsupported compute, GPU loss, timeout or mismatch, transition safely to the CPU implementation.
Because DSP operations maintain history across samples, naively processing an entire block in parallel can change results. Any parallel implementation must either respect dependency order or prove an equivalent transformation.
9. Backend and CPU fallback contract
| Execution path | Role | Fallback behavior |
|---|---|---|
| CPU interpreter/reference | Canonical, diagnosable audio behavior and regression oracle. | Always available; required for unsupported GPU paths. |
| CPU optimized | Fast native execution of validated generic primitives. | Preferred when GPU dispatch is slower or less deterministic. |
| OpenGL compute | Optional GLSL compute execution in capable contexts. | CPU for contexts without compute or needed integer features. |
| D3D11 compute | Optional HLSL compute execution. | CPU on insufficient feature level/capability. |
| Vulkan compute | Optional SPIR-V compute dispatch. | CPU if compute queues/resources are unavailable. |
Backends should expose shared feature/capability queries and return the same observable emulated audio behavior. No game should require a GPU, and the same APU definitions should run on different host graphics backends.
10. Correctness and performance validation
Begin with a deterministic CPU implementation. Then compare audio sample streams and internal DSP-state transitions against GPU execution using the same emulated register writes and sample-clock schedule.
| Test group | Acceptance criteria |
|---|---|
| Instruction & register fidelity | S-SMP execution, DSP register effects, envelopes and port reads/writes match the verified reference. |
| DSP arithmetic | BRR history, Gaussian interpolation, mixing, echo FIR/feedback and clipping match the chosen accuracy target. |
| Backend parity | PCM output and state transitions match across CPU, OpenGL, D3D11 and Vulkan where GPU compute is enabled. |
| Timing | Correct sample counts, latency boundaries and register changes within a block. |
| Stress | GPU saturation, backend reset, long sessions, suspend/resume and transitions back to CPU. |
| Performance | Measure CPU processing time, GPU dispatch time, data transfer, synchronization, latency, underruns and power use. |
| Game regressions | Revisit ActRaiser and Mystic Quest startup behavior; audio offload must not hide broken SPC700/APU handshakes. |
Suggested diagnostics: emulated DSP sample counter, S-SMP instruction count, CPU↔APU port state, audio IR hash, selected execution target, per-block samples, dispatch duration, readback duration, underrun count, and CPU/GPU sample checksum.
11. Recommended implementation sequence
- Complete functional SNES audio accuracy first. Validate S-SMP IPL/upload flow, CPU↔APU synchronization and S-DSP output using CPU execution.
- Define reusable audio IR. Specify typed operations, integer widths, saturation, buffer access, state hazards and deterministic ordering.
- Build the CPU reference executor. Ensure every proposed primitive produces a testable and correct result.
- Prototype an optional compute interface. Let graphics backends advertise compute capabilities without embedding SNES-specific DSP code.
- Offload one benchmarked kernel. Begin with a bounded, testable workload such as batched interpolation or mixing; do not migrate the whole APU blindly.
- Prove backend parity. Add OpenGL, then D3D11 and Vulkan implementations as appropriate, with exactness tests and automatic fallback.
- Expand selectively. Consider BRR decode and filtering only where real profiling shows a sustained improvement after transfer costs.
- Reuse across systems. Apply generic audio operations to other emulated machines without adding machine-specific branches to native libraries.
12. Scope, cautions and conclusion
- Not a replacement for APU hardware emulation: GPU compute only accelerates selected calculations; S-SMP, S-DSP and port semantics still need correct definitions and timing.
- Not guaranteed faster: For eight SNES voices at ~32 kHz, a well-written CPU implementation may remain the best choice.
- Not tied to display refresh: Audio must run from the emulated audio clock, not the PPU’s frame presentation.
- Not hard-coded machine logic: Avoid SNES-specific branches inside
compute.libor backend libraries. - Not proprietary firmware distribution: The design does not require shipping an S-SMP IPL ROM image; existing explicit firmware-source rules remain in force.
- Not currently implemented: Names, IR stages and APIs in this document are proposals requiring development and benchmarking.