Add renderer draw descriptor contract
This commit is contained in:
@@ -316,7 +316,7 @@ pp::foundation::Status RecordingCommandContext::bind_mesh(IMesh& mesh) noexcept
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status RecordingCommandContext::draw() noexcept
|
||||
pp::foundation::Status RecordingCommandContext::draw(DrawDesc desc) noexcept
|
||||
{
|
||||
if (!in_render_pass_) {
|
||||
return pp::foundation::Status::invalid_argument("render pass has not begun");
|
||||
@@ -328,9 +328,15 @@ pp::foundation::Status RecordingCommandContext::draw() noexcept
|
||||
return pp::foundation::Status::invalid_argument("mesh must be bound before draw");
|
||||
}
|
||||
|
||||
const auto draw_status = validate_draw_desc(active_mesh_, desc);
|
||||
if (!draw_status.ok()) {
|
||||
return draw_status;
|
||||
}
|
||||
|
||||
push_command(commands_, RecordedRenderCommand {
|
||||
.kind = RecordedRenderCommandKind::draw,
|
||||
.mesh_desc = active_mesh_,
|
||||
.draw_desc = desc,
|
||||
});
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ struct RecordedRenderCommand {
|
||||
BlendState blend_state {};
|
||||
DepthState depth_state {};
|
||||
MeshDesc mesh_desc {};
|
||||
DrawDesc draw_desc {};
|
||||
TextureDesc texture_desc {};
|
||||
std::uint32_t texture_slot = 0;
|
||||
SamplerDesc sampler_desc {};
|
||||
@@ -128,7 +129,7 @@ public:
|
||||
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 draw(DrawDesc desc) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status read_texture(
|
||||
ITexture2D& texture,
|
||||
ReadbackRegion region,
|
||||
|
||||
@@ -337,6 +337,40 @@ pp::foundation::Status validate_mesh_desc(MeshDesc desc) noexcept
|
||||
return pp::foundation::Status::invalid_argument("mesh topology is not supported");
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_draw_desc(MeshDesc mesh, DrawDesc draw) noexcept
|
||||
{
|
||||
const auto mesh_status = validate_mesh_desc(mesh);
|
||||
if (!mesh_status.ok()) {
|
||||
return mesh_status;
|
||||
}
|
||||
|
||||
if (draw.instance_count == 0) {
|
||||
return pp::foundation::Status::invalid_argument("draw instance count must be greater than zero");
|
||||
}
|
||||
|
||||
if (draw.vertex_count == 0 && draw.index_count == 0) {
|
||||
return pp::foundation::Status::invalid_argument("draw must include vertices or indices");
|
||||
}
|
||||
|
||||
if (draw.index_count > 0) {
|
||||
if (mesh.index_count == 0) {
|
||||
return pp::foundation::Status::invalid_argument("indexed draw requires an indexed mesh");
|
||||
}
|
||||
|
||||
if (draw.first_index > mesh.index_count || draw.index_count > mesh.index_count - draw.first_index) {
|
||||
return pp::foundation::Status::out_of_range("draw index range exceeds the bound mesh");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
if (draw.first_vertex > mesh.vertex_count || draw.vertex_count > mesh.vertex_count - draw.first_vertex) {
|
||||
return pp::foundation::Status::out_of_range("draw vertex range exceeds the bound mesh");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_texture_slot(std::uint32_t slot) noexcept
|
||||
{
|
||||
if (slot >= max_texture_slots) {
|
||||
|
||||
@@ -157,6 +157,14 @@ struct MeshDesc {
|
||||
PrimitiveTopology topology = PrimitiveTopology::triangles;
|
||||
};
|
||||
|
||||
struct DrawDesc {
|
||||
std::uint32_t first_vertex = 0;
|
||||
std::uint32_t vertex_count = 0;
|
||||
std::uint32_t first_index = 0;
|
||||
std::uint32_t index_count = 0;
|
||||
std::uint32_t instance_count = 1;
|
||||
};
|
||||
|
||||
struct ShaderStageSource {
|
||||
const char* entry_point = "main";
|
||||
const char* source = nullptr;
|
||||
@@ -226,7 +234,7 @@ public:
|
||||
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 draw(DrawDesc desc) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status read_texture(
|
||||
ITexture2D& texture,
|
||||
ReadbackRegion region,
|
||||
@@ -279,6 +287,7 @@ public:
|
||||
[[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_draw_desc(MeshDesc mesh, DrawDesc draw) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_texture_slot(std::uint32_t slot) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_shader_program_desc(ShaderProgramDesc desc) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_shader_uniform_write(
|
||||
|
||||
Reference in New Issue
Block a user