116 lines
4.6 KiB
Markdown
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.
|