Add renderer blend state contract

This commit is contained in:
2026-06-02 15:40:43 +02:00
parent 5dbeb0504d
commit 5226746c1a
9 changed files with 326 additions and 60 deletions

View File

@@ -122,6 +122,24 @@ pp::foundation::Status RecordingCommandContext::set_viewport(Viewport viewport)
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::set_blend_state(BlendState state) noexcept
{
if (!in_render_pass_) {
return pp::foundation::Status::invalid_argument("render pass has not begun");
}
const auto status = validate_blend_state(state);
if (!status.ok()) {
return status;
}
push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::set_blend_state,
.blend_state = state,
});
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::bind_shader(IShaderProgram& shader) noexcept
{
if (!in_render_pass_) {
@@ -400,6 +418,8 @@ const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) no
return "begin_render_pass";
case RecordedRenderCommandKind::set_viewport:
return "set_viewport";
case RecordedRenderCommandKind::set_blend_state:
return "set_blend_state";
case RecordedRenderCommandKind::bind_shader:
return "bind_shader";
case RecordedRenderCommandKind::bind_texture:

View File

@@ -10,6 +10,7 @@ namespace pp::renderer {
enum class RecordedRenderCommandKind : std::uint8_t {
begin_render_pass,
set_viewport,
set_blend_state,
bind_shader,
bind_texture,
bind_mesh,
@@ -27,6 +28,7 @@ struct RecordedRenderCommand {
TextureDesc target_desc {};
ClearColor clear_color {};
Viewport viewport {};
BlendState blend_state {};
MeshDesc mesh_desc {};
TextureDesc texture_desc {};
std::uint32_t texture_slot = 0;
@@ -98,6 +100,7 @@ public:
IRenderTarget& target,
ClearColor clear_color) noexcept override;
[[nodiscard]] pp::foundation::Status set_viewport(Viewport viewport) noexcept override;
[[nodiscard]] pp::foundation::Status set_blend_state(BlendState state) noexcept override;
[[nodiscard]] pp::foundation::Status bind_shader(IShaderProgram& shader) noexcept override;
[[nodiscard]] pp::foundation::Status bind_texture(
std::uint32_t slot,

View File

@@ -131,6 +131,63 @@ pp::foundation::Status validate_viewport(Viewport viewport, Extent2D target_exte
return pp::foundation::Status::success();
}
pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept
{
switch (factor) {
case BlendFactor::zero:
case BlendFactor::one:
case BlendFactor::source_alpha:
case BlendFactor::one_minus_source_alpha:
case BlendFactor::destination_alpha:
case BlendFactor::one_minus_destination_alpha:
return pp::foundation::Status::success();
}
return pp::foundation::Status::invalid_argument("blend factor is not supported");
}
pp::foundation::Status validate_blend_op(BlendOp op) noexcept
{
switch (op) {
case BlendOp::add:
case BlendOp::subtract:
case BlendOp::reverse_subtract:
return pp::foundation::Status::success();
}
return pp::foundation::Status::invalid_argument("blend operation is not supported");
}
pp::foundation::Status validate_blend_state(BlendState state) noexcept
{
const auto source_color = validate_blend_factor(state.source_color);
if (!source_color.ok()) {
return source_color;
}
const auto destination_color = validate_blend_factor(state.destination_color);
if (!destination_color.ok()) {
return destination_color;
}
const auto color_op = validate_blend_op(state.color_op);
if (!color_op.ok()) {
return color_op;
}
const auto source_alpha = validate_blend_factor(state.source_alpha);
if (!source_alpha.ok()) {
return source_alpha;
}
const auto destination_alpha = validate_blend_factor(state.destination_alpha);
if (!destination_alpha.ok()) {
return destination_alpha;
}
return validate_blend_op(state.alpha_op);
}
pp::foundation::Status validate_mesh_desc(MeshDesc desc) noexcept
{
if (desc.vertex_count == 0) {
@@ -324,4 +381,38 @@ const char* blit_filter_name(BlitFilter filter) noexcept
return "unknown";
}
const char* blend_factor_name(BlendFactor factor) noexcept
{
switch (factor) {
case BlendFactor::zero:
return "zero";
case BlendFactor::one:
return "one";
case BlendFactor::source_alpha:
return "source_alpha";
case BlendFactor::one_minus_source_alpha:
return "one_minus_source_alpha";
case BlendFactor::destination_alpha:
return "destination_alpha";
case BlendFactor::one_minus_destination_alpha:
return "one_minus_destination_alpha";
}
return "unknown";
}
const char* blend_op_name(BlendOp op) noexcept
{
switch (op) {
case BlendOp::add:
return "add";
case BlendOp::subtract:
return "subtract";
case BlendOp::reverse_subtract:
return "reverse_subtract";
}
return "unknown";
}
}

View File

@@ -65,6 +65,35 @@ enum class BlitFilter : std::uint8_t {
linear,
};
enum class BlendFactor : std::uint8_t {
zero,
one,
source_alpha,
one_minus_source_alpha,
destination_alpha,
one_minus_destination_alpha,
};
enum class BlendOp : std::uint8_t {
add,
subtract,
reverse_subtract,
};
struct BlendState {
bool enabled = false;
BlendFactor source_color = BlendFactor::one;
BlendFactor destination_color = BlendFactor::zero;
BlendOp color_op = BlendOp::add;
BlendFactor source_alpha = BlendFactor::one;
BlendFactor destination_alpha = BlendFactor::zero;
BlendOp alpha_op = BlendOp::add;
bool write_r = true;
bool write_g = true;
bool write_b = true;
bool write_a = true;
};
struct MeshDesc {
std::uint32_t vertex_count = 0;
std::uint32_t index_count = 0;
@@ -126,6 +155,7 @@ public:
IRenderTarget& target,
ClearColor clear_color) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status set_viewport(Viewport viewport) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status set_blend_state(BlendState state) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status bind_shader(IShaderProgram& shader) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status bind_texture(
std::uint32_t slot,
@@ -163,6 +193,9 @@ public:
[[nodiscard]] std::uint32_t bytes_per_pixel(TextureFormat format) noexcept;
[[nodiscard]] pp::foundation::Status validate_extent(Extent2D extent) noexcept;
[[nodiscard]] pp::foundation::Status validate_viewport(Viewport viewport, Extent2D target_extent) noexcept;
[[nodiscard]] pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept;
[[nodiscard]] pp::foundation::Status validate_blend_op(BlendOp op) noexcept;
[[nodiscard]] pp::foundation::Status validate_blend_state(BlendState state) noexcept;
[[nodiscard]] pp::foundation::Status validate_mesh_desc(MeshDesc desc) noexcept;
[[nodiscard]] pp::foundation::Status validate_texture_slot(std::uint32_t slot) noexcept;
[[nodiscard]] pp::foundation::Status validate_shader_program_desc(ShaderProgramDesc desc) noexcept;
@@ -179,5 +212,7 @@ public:
[[nodiscard]] const char* texture_format_name(TextureFormat format) noexcept;
[[nodiscard]] const char* primitive_topology_name(PrimitiveTopology topology) noexcept;
[[nodiscard]] const char* blit_filter_name(BlitFilter filter) noexcept;
[[nodiscard]] const char* blend_factor_name(BlendFactor factor) noexcept;
[[nodiscard]] const char* blend_op_name(BlendOp op) noexcept;
}