Files
panopainter/docs/modernization/renderer_api_contract.md

4.6 KiB

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.
  1. 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.
  1. 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.
  1. 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.