Add renderer scissor state contract

This commit is contained in:
2026-06-02 15:46:03 +02:00
parent 5226746c1a
commit 9a7e1c4def
9 changed files with 215 additions and 65 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_scissor(ScissorRect scissor) noexcept
{
if (!in_render_pass_) {
return pp::foundation::Status::invalid_argument("render pass has not begun");
}
const auto status = validate_scissor(scissor, active_target_.extent);
if (!status.ok()) {
return status;
}
push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::set_scissor,
.scissor = scissor,
});
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::set_blend_state(BlendState state) noexcept
{
if (!in_render_pass_) {
@@ -418,6 +436,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_scissor:
return "set_scissor";
case RecordedRenderCommandKind::set_blend_state:
return "set_blend_state";
case RecordedRenderCommandKind::bind_shader:

View File

@@ -10,6 +10,7 @@ namespace pp::renderer {
enum class RecordedRenderCommandKind : std::uint8_t {
begin_render_pass,
set_viewport,
set_scissor,
set_blend_state,
bind_shader,
bind_texture,
@@ -28,6 +29,7 @@ struct RecordedRenderCommand {
TextureDesc target_desc {};
ClearColor clear_color {};
Viewport viewport {};
ScissorRect scissor {};
BlendState blend_state {};
MeshDesc mesh_desc {};
TextureDesc texture_desc {};
@@ -100,6 +102,7 @@ public:
IRenderTarget& target,
ClearColor clear_color) 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 bind_shader(IShaderProgram& shader) noexcept override;
[[nodiscard]] pp::foundation::Status bind_texture(

View File

@@ -131,6 +131,38 @@ pp::foundation::Status validate_viewport(Viewport viewport, Extent2D target_exte
return pp::foundation::Status::success();
}
pp::foundation::Status validate_scissor(ScissorRect scissor, Extent2D target_extent) noexcept
{
const auto extent_status = validate_extent(target_extent);
if (!extent_status.ok()) {
return extent_status;
}
if (!scissor.enabled) {
return pp::foundation::Status::success();
}
if (scissor.x < 0 || scissor.y < 0) {
return pp::foundation::Status::invalid_argument("scissor origin must be non-negative");
}
if (scissor.width == 0 || scissor.height == 0) {
return pp::foundation::Status::invalid_argument("scissor size must be greater than zero");
}
const auto x = static_cast<std::uint32_t>(scissor.x);
const auto y = static_cast<std::uint32_t>(scissor.y);
if (x > target_extent.width || y > target_extent.height) {
return pp::foundation::Status::out_of_range("scissor origin is outside the render target");
}
if (scissor.width > target_extent.width - x || scissor.height > target_extent.height - y) {
return pp::foundation::Status::out_of_range("scissor exceeds render target bounds");
}
return pp::foundation::Status::success();
}
pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept
{
switch (factor) {

View File

@@ -47,6 +47,14 @@ struct Viewport {
float max_depth = 1.0F;
};
struct ScissorRect {
bool enabled = false;
std::int32_t x = 0;
std::int32_t y = 0;
std::uint32_t width = 0;
std::uint32_t height = 0;
};
struct ClearColor {
float r = 0.0F;
float g = 0.0F;
@@ -155,6 +163,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_scissor(ScissorRect scissor) 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(
@@ -193,6 +202,7 @@ 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_scissor(ScissorRect scissor, 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;