Files
panopainter/docs/modernization/renderer_api_contract.md

116 lines
4.6 KiB
Markdown

# Renderer API Backend-Neutral Contract
## Purpose
`pp_renderer_api` defines the backend-neutral rendering contract used by `pp_paint_renderer`
and the higher-level app core. This document captures the minimum behavior that any
concrete backend (`pp_renderer_gl` today, Vulkan/Metal later) must preserve.
## Contract Scope
- Public interfaces:
- `pp::renderer::IRenderDevice`
- `pp::renderer::ICommandContext`
- `pp::renderer::ITexture2D`
- `pp::renderer::IRenderTarget`
- `pp::renderer::IShaderProgram`
- `pp::renderer::IMesh`
- `pp::renderer::IReadbackBuffer`
- `pp::renderer::IRenderTrace`
- `pp::renderer::Recording*` helpers in `renderer_api/recording_renderer.*`
- Validation helpers in `renderer_api.h` and shader catalog helpers in
`renderer_api/shader_catalog.*`
## Behavioral Invariants
- No exceptions are part of API control flow; failures are reported through
`pp::foundation::Status` / `pp::foundation::Result`.
- Object lifetimes remain backend-owned; API consumers pass references/handles only.
- Resource descriptors and command/state descriptors must be validated and constrained by the
helper functions.
- Backends may reject unsupported operations via explicit non-OK status but must not mutate
visible program state before reporting failure.
- Error codes and debug names are deterministic and backend-neutral (human-readable and
test-stable where feasible).
## Surface Contracts
1. `IRenderDevice`
- `backend_name()` identifies backend family.
- `features()` returns capability bits used for planner decisions.
- Resource creation methods return `Result` and report allocation/validation failures.
- `immediate_context()` is stable for the lifetime of the device object.
- `trace()` may return `nullptr`; callers must tolerate no trace provider.
2. `ICommandContext`
- State mutation (`set_viewport`, `set_scissor`, blend/depth/shader/sampler/mesh/program binds) is
explicit and backend-agnostic.
- Command methods that can fail must return status.
- `end_render_pass()` is always side-effect safe and non-throwing.
- `read_texture` / `capture_frame` readback contracts are byte-sized and descriptor-driven.
- Texture upload/copy/readback/transition methods must respect descriptor bounds and ordering rules.
3. Resource descriptors and helpers
- `TextureDesc`, `Extent2D`, `Viewport`, `ScissorRect`, `RenderPassDesc`,
`TextureUsage`, `TextureState`, `BlendState`, `DepthState`, sampler/topology enums
are shared semantic vocabulary across backends.
- Validation helpers (`validate_*`) are the compatibility fence for contract behavior.
- `PaintFeedbackPlan` and `plan_paint_feedback(...)` are the feature/algorithm decision seam
for framebuffer feedback vs ping-pong workflows.
4. Trace and recording
- `IRenderTrace` is optional and may be elided, but implementations should support scoped markers
and markers where used.
- Recording backend (`RecordingRenderDevice`, `RecordingCommandContext`) must preserve command
order and reject invalid sequences through status/command visibility.
## Feature semantics
Backends are expected to honor all feature bits consistently:
- `framebuffer_fetch`
- `explicit_texture_transitions`
- `texture_copy`
- `render_target_blit`
- `frame_capture`
- `float16_render_targets`
- `float32_render_targets`
- `float32_linear_filtering`
Feature gates must be enforced by planners before issuing backend commands.
## Existing conformance coverage
Current renderer-api conformance tests (non-backend):
- `pp_renderer_api_tests`
- `pp_renderer_api` test cases:
- `validates_texture_usage_contract`
- `validates_texture_transition_contract`
- `validates_mipmap_generation_contract`
- `validates_texture_copy_contract`
- `validates_blit_contract`
- `plans_paint_feedback_paths`
- `renderer_interfaces_support_backend_neutral_dispatch`
- `recording_renderer_*` command-sequence and validation tests
OpenGL-specific conformance remains in `pp_renderer_gl` suites:
- `pp_renderer_gl_capabilities_tests`
- `pp_renderer_gl_command_plan_tests`
- `pp_renderer_gl_gpu_readback_tests` (where GPU context is available)
- `panopainter_renderer_conformance_matrix_self_test`
- `ctest --preset renderer-conformance`
- `panopainter_renderer_api_contract_self_test` (tooling guard for renderer API and paint renderer
backend-neutral contract source purity).
## Open items for RND-007
- Ensure Vulkan/Metal planning/lifecycle tests run the same contract surfaces without backend leakage.
- Keep `pp_renderer_api` implementation/usage free from backend-only headers and raw platform state.
- Keep new backend labs opt-in until this contract and conformance matrix are complete.