Files
panopainter/src/renderer_api/recording_renderer.h

230 lines
8.1 KiB
C++

#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,
set_scissor,
set_blend_state,
set_depth_state,
bind_shader,
set_shader_uniform,
bind_texture,
bind_sampler,
bind_mesh,
draw,
upload_texture,
generate_mipmaps,
transition_texture,
copy_texture,
read_texture,
capture_frame,
blit_render_target,
end_render_pass,
trace_marker,
trace_begin_scope,
trace_end_scope,
};
struct RecordedRenderCommand {
RecordedRenderCommandKind kind = RecordedRenderCommandKind::draw;
TextureDesc target_desc {};
bool clear_color_enabled = false;
ClearColor clear_color {};
bool clear_depth_enabled = false;
float clear_depth = 1.0F;
bool clear_stencil_enabled = false;
std::uint8_t clear_stencil = 0;
Viewport viewport {};
ScissorRect scissor {};
BlendState blend_state {};
DepthState depth_state {};
MeshDesc mesh_desc {};
DrawDesc draw_desc {};
TextureDesc texture_desc {};
std::uint32_t texture_slot = 0;
SamplerDesc sampler_desc {};
std::uint32_t sampler_slot = 0;
TextureDesc source_desc {};
TextureDesc destination_desc {};
TextureState before_state = TextureState::undefined;
TextureState after_state = TextureState::undefined;
ReadbackRegion readback_region {};
ReadbackRegion source_region {};
ReadbackRegion destination_region {};
BlitFilter blit_filter = BlitFilter::nearest;
std::uint64_t upload_bytes = 0;
std::uint32_t generated_mip_levels = 0;
std::uint64_t generated_mip_bytes = 0;
std::uint64_t copy_source_bytes = 0;
std::uint64_t copy_destination_bytes = 0;
std::uint64_t readback_bytes = 0;
std::uint64_t capture_bytes = 0;
std::uint64_t blit_source_bytes = 0;
std::uint64_t blit_destination_bytes = 0;
std::uint64_t uniform_bytes = 0;
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,
RenderPassDesc desc) noexcept override;
[[nodiscard]] pp::foundation::Status set_viewport(Viewport viewport) noexcept override;
[[nodiscard]] pp::foundation::Status set_scissor(ScissorRect scissor) noexcept override;
[[nodiscard]] pp::foundation::Status set_blend_state(BlendState state) noexcept override;
[[nodiscard]] pp::foundation::Status set_depth_state(DepthState state) noexcept override;
[[nodiscard]] pp::foundation::Status bind_shader(IShaderProgram& shader) noexcept override;
[[nodiscard]] pp::foundation::Status set_shader_uniform(
const char* name,
std::span<const std::byte> bytes) noexcept override;
[[nodiscard]] pp::foundation::Status bind_texture(
std::uint32_t slot,
ITexture2D& texture) noexcept override;
[[nodiscard]] pp::foundation::Status bind_sampler(
std::uint32_t slot,
SamplerDesc sampler) noexcept override;
[[nodiscard]] pp::foundation::Status bind_mesh(IMesh& mesh) noexcept override;
[[nodiscard]] pp::foundation::Status draw(DrawDesc desc) noexcept override;
[[nodiscard]] pp::foundation::Status read_texture(
ITexture2D& texture,
ReadbackRegion region,
IReadbackBuffer& destination) noexcept override;
[[nodiscard]] pp::foundation::Status upload_texture(
ITexture2D& texture,
ReadbackRegion region,
std::span<const std::byte> rgba_or_channel_bytes) noexcept override;
[[nodiscard]] pp::foundation::Status generate_mipmaps(
ITexture2D& texture) noexcept override;
[[nodiscard]] pp::foundation::Status transition_texture(
ITexture2D& texture,
TextureState before,
TextureState after) noexcept override;
[[nodiscard]] pp::foundation::Status copy_texture(
ITexture2D& source,
ReadbackRegion source_region,
ITexture2D& destination,
ReadbackRegion destination_region) noexcept override;
[[nodiscard]] pp::foundation::Status capture_frame(
IRenderTarget& target,
IReadbackBuffer& destination) noexcept override;
[[nodiscard]] pp::foundation::Status blit_render_target(
IRenderTarget& source,
ReadbackRegion source_region,
IRenderTarget& destination,
ReadbackRegion destination_region,
BlitFilter filter) noexcept override;
void end_render_pass() noexcept override;
[[nodiscard]] bool in_render_pass() const noexcept;
void reset() noexcept;
private:
std::vector<RecordedRenderCommand>* commands_ = nullptr;
TextureDesc active_target_ {};
MeshDesc active_mesh_ {};
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;
[[nodiscard]] pp::foundation::Status marker(const char* component, const char* name) noexcept override;
[[nodiscard]] pp::foundation::Status begin_scope(const char* component, const char* name) noexcept override;
[[nodiscard]] pp::foundation::Status end_scope() noexcept override;
void reset() noexcept;
private:
std::vector<RecordedRenderCommand>* commands_ = nullptr;
std::uint32_t scope_depth_ = 0;
};
class RecordingRenderDevice final : public IRenderDevice {
public:
RecordingRenderDevice() noexcept;
[[nodiscard]] const char* backend_name() const noexcept override;
[[nodiscard]] RenderDeviceFeatures features() const noexcept override;
[[nodiscard]] pp::foundation::Result<std::unique_ptr<ITexture2D>> create_texture(
TextureDesc desc) noexcept override;
[[nodiscard]] pp::foundation::Result<std::unique_ptr<IRenderTarget>> create_render_target(
TextureDesc color_desc) noexcept override;
[[nodiscard]] pp::foundation::Result<std::unique_ptr<IShaderProgram>> create_shader_program(
ShaderProgramDesc desc) noexcept override;
[[nodiscard]] pp::foundation::Result<std::unique_ptr<IMesh>> create_mesh(
MeshDesc desc) noexcept override;
[[nodiscard]] pp::foundation::Result<std::unique_ptr<IReadbackBuffer>> create_readback_buffer(
std::uint64_t size_bytes) 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;
}