Add renderer sampler state contract

This commit is contained in:
2026-06-02 15:56:26 +02:00
parent b68ddc42c6
commit 952a00e7d3
9 changed files with 322 additions and 53 deletions

View File

@@ -217,6 +217,32 @@ pp::foundation::Status RecordingCommandContext::bind_texture(
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::bind_sampler(
std::uint32_t slot,
SamplerDesc sampler) noexcept
{
if (!in_render_pass_) {
return pp::foundation::Status::invalid_argument("render pass has not begun");
}
const auto slot_status = validate_texture_slot(slot);
if (!slot_status.ok()) {
return slot_status;
}
const auto sampler_status = validate_sampler_desc(sampler);
if (!sampler_status.ok()) {
return sampler_status;
}
push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::bind_sampler,
.sampler_desc = sampler,
.sampler_slot = slot,
});
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::bind_mesh(IMesh& mesh) noexcept
{
if (!in_render_pass_) {
@@ -464,6 +490,8 @@ const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) no
return "bind_shader";
case RecordedRenderCommandKind::bind_texture:
return "bind_texture";
case RecordedRenderCommandKind::bind_sampler:
return "bind_sampler";
case RecordedRenderCommandKind::bind_mesh:
return "bind_mesh";
case RecordedRenderCommandKind::draw:

View File

@@ -15,6 +15,7 @@ enum class RecordedRenderCommandKind : std::uint8_t {
set_depth_state,
bind_shader,
bind_texture,
bind_sampler,
bind_mesh,
draw,
upload_texture,
@@ -36,6 +37,8 @@ struct RecordedRenderCommand {
MeshDesc mesh_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 {};
ReadbackRegion readback_region {};
@@ -111,6 +114,9 @@ public:
[[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() noexcept override;
[[nodiscard]] pp::foundation::Status read_texture(

View File

@@ -242,6 +242,60 @@ pp::foundation::Status validate_depth_state(DepthState state) noexcept
return validate_compare_op(state.compare);
}
pp::foundation::Status validate_sampler_filter(SamplerFilter filter) noexcept
{
switch (filter) {
case SamplerFilter::nearest:
case SamplerFilter::linear:
return pp::foundation::Status::success();
}
return pp::foundation::Status::invalid_argument("sampler filter is not supported");
}
pp::foundation::Status validate_sampler_address_mode(SamplerAddressMode mode) noexcept
{
switch (mode) {
case SamplerAddressMode::clamp_to_edge:
case SamplerAddressMode::repeat:
case SamplerAddressMode::mirrored_repeat:
case SamplerAddressMode::clamp_to_border:
return pp::foundation::Status::success();
}
return pp::foundation::Status::invalid_argument("sampler address mode is not supported");
}
pp::foundation::Status validate_sampler_desc(SamplerDesc desc) noexcept
{
const auto min_filter = validate_sampler_filter(desc.min_filter);
if (!min_filter.ok()) {
return min_filter;
}
const auto mag_filter = validate_sampler_filter(desc.mag_filter);
if (!mag_filter.ok()) {
return mag_filter;
}
const auto mip_filter = validate_sampler_filter(desc.mip_filter);
if (!mip_filter.ok()) {
return mip_filter;
}
const auto address_u = validate_sampler_address_mode(desc.address_u);
if (!address_u.ok()) {
return address_u;
}
const auto address_v = validate_sampler_address_mode(desc.address_v);
if (!address_v.ok()) {
return address_v;
}
return validate_sampler_address_mode(desc.address_w);
}
pp::foundation::Status validate_mesh_desc(MeshDesc desc) noexcept
{
if (desc.vertex_count == 0) {
@@ -493,4 +547,32 @@ const char* compare_op_name(CompareOp op) noexcept
return "unknown";
}
const char* sampler_filter_name(SamplerFilter filter) noexcept
{
switch (filter) {
case SamplerFilter::nearest:
return "nearest";
case SamplerFilter::linear:
return "linear";
}
return "unknown";
}
const char* sampler_address_mode_name(SamplerAddressMode mode) noexcept
{
switch (mode) {
case SamplerAddressMode::clamp_to_edge:
return "clamp_to_edge";
case SamplerAddressMode::repeat:
return "repeat";
case SamplerAddressMode::mirrored_repeat:
return "mirrored_repeat";
case SamplerAddressMode::clamp_to_border:
return "clamp_to_border";
}
return "unknown";
}
}

View File

@@ -99,6 +99,18 @@ enum class CompareOp : std::uint8_t {
always,
};
enum class SamplerFilter : std::uint8_t {
nearest,
linear,
};
enum class SamplerAddressMode : std::uint8_t {
clamp_to_edge,
repeat,
mirrored_repeat,
clamp_to_border,
};
struct BlendState {
bool enabled = false;
BlendFactor source_color = BlendFactor::one;
@@ -119,6 +131,15 @@ struct DepthState {
CompareOp compare = CompareOp::less_or_equal;
};
struct SamplerDesc {
SamplerFilter min_filter = SamplerFilter::linear;
SamplerFilter mag_filter = SamplerFilter::linear;
SamplerFilter mip_filter = SamplerFilter::linear;
SamplerAddressMode address_u = SamplerAddressMode::clamp_to_edge;
SamplerAddressMode address_v = SamplerAddressMode::clamp_to_edge;
SamplerAddressMode address_w = SamplerAddressMode::clamp_to_edge;
};
struct MeshDesc {
std::uint32_t vertex_count = 0;
std::uint32_t index_count = 0;
@@ -187,6 +208,9 @@ public:
[[nodiscard]] virtual pp::foundation::Status bind_texture(
std::uint32_t slot,
ITexture2D& texture) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status bind_sampler(
std::uint32_t slot,
SamplerDesc sampler) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status bind_mesh(IMesh& mesh) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status draw() noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status read_texture(
@@ -226,6 +250,9 @@ public:
[[nodiscard]] pp::foundation::Status validate_blend_state(BlendState state) noexcept;
[[nodiscard]] pp::foundation::Status validate_compare_op(CompareOp op) noexcept;
[[nodiscard]] pp::foundation::Status validate_depth_state(DepthState state) noexcept;
[[nodiscard]] pp::foundation::Status validate_sampler_filter(SamplerFilter filter) noexcept;
[[nodiscard]] pp::foundation::Status validate_sampler_address_mode(SamplerAddressMode mode) noexcept;
[[nodiscard]] pp::foundation::Status validate_sampler_desc(SamplerDesc desc) 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;
@@ -245,5 +272,7 @@ public:
[[nodiscard]] const char* blend_factor_name(BlendFactor factor) noexcept;
[[nodiscard]] const char* blend_op_name(BlendOp op) noexcept;
[[nodiscard]] const char* compare_op_name(CompareOp op) noexcept;
[[nodiscard]] const char* sampler_filter_name(SamplerFilter filter) noexcept;
[[nodiscard]] const char* sampler_address_mode_name(SamplerAddressMode mode) noexcept;
}