Add headless recording renderer api

This commit is contained in:
2026-06-02 09:44:04 +02:00
parent 61f86f5aae
commit 1d44036933
6 changed files with 503 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
#pragma once
#include "renderer_api/renderer_api.h"
#include <span>
#include <vector>
namespace pp::renderer {
enum class RecordedRenderCommandKind : std::uint8_t {
begin_render_pass,
set_viewport,
bind_shader,
bind_mesh,
draw,
end_render_pass,
trace_marker,
};
struct RecordedRenderCommand {
RecordedRenderCommandKind kind = RecordedRenderCommandKind::draw;
TextureDesc target_desc {};
ClearColor clear_color {};
Viewport viewport {};
MeshDesc mesh_desc {};
const char* component = "";
const char* name = "";
};
class RecordingTexture2D final : public ITexture2D {
public:
explicit RecordingTexture2D(TextureDesc desc) noexcept;
[[nodiscard]] TextureDesc desc() const noexcept override;
private:
TextureDesc desc_ {};
};
class RecordingRenderTarget final : public IRenderTarget {
public:
explicit RecordingRenderTarget(TextureDesc color_desc) noexcept;
[[nodiscard]] TextureDesc color_desc() const noexcept override;
private:
TextureDesc color_desc_ {};
};
class RecordingShaderProgram final : public IShaderProgram {
public:
explicit RecordingShaderProgram(const char* debug_name) noexcept;
[[nodiscard]] const char* debug_name() const noexcept override;
private:
const char* debug_name_ = "";
};
class RecordingMesh final : public IMesh {
public:
explicit RecordingMesh(MeshDesc desc) noexcept;
[[nodiscard]] MeshDesc desc() const noexcept override;
private:
MeshDesc desc_ {};
};
class RecordingReadbackBuffer final : public IReadbackBuffer {
public:
explicit RecordingReadbackBuffer(std::uint64_t size_bytes) noexcept;
[[nodiscard]] std::uint64_t size_bytes() const noexcept override;
private:
std::uint64_t size_bytes_ = 0;
};
class RecordingCommandContext final : public ICommandContext {
public:
explicit RecordingCommandContext(std::vector<RecordedRenderCommand>& commands) noexcept;
[[nodiscard]] pp::foundation::Status begin_render_pass(
IRenderTarget& target,
ClearColor clear_color) noexcept override;
[[nodiscard]] pp::foundation::Status set_viewport(Viewport viewport) noexcept override;
[[nodiscard]] pp::foundation::Status bind_shader(IShaderProgram& shader) noexcept override;
[[nodiscard]] pp::foundation::Status bind_mesh(IMesh& mesh) noexcept override;
[[nodiscard]] pp::foundation::Status draw() noexcept override;
void end_render_pass() noexcept override;
[[nodiscard]] bool in_render_pass() const noexcept;
private:
std::vector<RecordedRenderCommand>* commands_ = nullptr;
TextureDesc active_target_ {};
bool in_render_pass_ = false;
bool shader_bound_ = false;
bool mesh_bound_ = false;
};
class RecordingRenderTrace final : public IRenderTrace {
public:
explicit RecordingRenderTrace(std::vector<RecordedRenderCommand>& commands) noexcept;
void marker(const char* component, const char* name) noexcept override;
private:
std::vector<RecordedRenderCommand>* commands_ = nullptr;
};
class RecordingRenderDevice final : public IRenderDevice {
public:
RecordingRenderDevice() noexcept;
[[nodiscard]] const char* backend_name() const noexcept override;
[[nodiscard]] ICommandContext& immediate_context() noexcept override;
[[nodiscard]] IRenderTrace* trace() noexcept override;
[[nodiscard]] std::span<const RecordedRenderCommand> commands() const noexcept;
void clear() noexcept;
private:
std::vector<RecordedRenderCommand> commands_;
RecordingCommandContext context_;
RecordingRenderTrace trace_;
};
[[nodiscard]] const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) noexcept;
}