Add paint feedback strategy planner
This commit is contained in:
@@ -823,6 +823,65 @@ pp::foundation::Status validate_blit_descs(TextureDesc source, TextureDesc desti
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<PaintFeedbackPlan> plan_paint_feedback(
|
||||
RenderDeviceFeatures features,
|
||||
TextureDesc target_desc,
|
||||
bool complex_blend) noexcept
|
||||
{
|
||||
const auto target_status = validate_texture_desc(target_desc);
|
||||
if (!target_status.ok()) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::failure(target_status);
|
||||
}
|
||||
|
||||
if (!has_texture_usage(target_desc.usage, TextureUsage::render_target)) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::failure(
|
||||
pp::foundation::Status::invalid_argument("paint feedback target must allow render_target usage"));
|
||||
}
|
||||
|
||||
if (target_desc.format == TextureFormat::depth24_stencil8) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::failure(
|
||||
pp::foundation::Status::invalid_argument("paint feedback target must be a color texture"));
|
||||
}
|
||||
|
||||
const auto target_bytes = texture_byte_size(target_desc);
|
||||
if (!target_bytes.ok()) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::failure(target_bytes.status());
|
||||
}
|
||||
|
||||
PaintFeedbackPlan plan;
|
||||
plan.target_desc = target_desc;
|
||||
plan.target_bytes = target_bytes.value();
|
||||
plan.complex_blend = complex_blend;
|
||||
if (!complex_blend) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::success(plan);
|
||||
}
|
||||
|
||||
plan.reads_destination_color = true;
|
||||
if (features.framebuffer_fetch) {
|
||||
plan.path = PaintFeedbackPath::framebuffer_fetch;
|
||||
plan.requires_explicit_transition = features.explicit_texture_transitions;
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::success(plan);
|
||||
}
|
||||
|
||||
const bool can_ping_pong = has_texture_usage(target_desc.usage, TextureUsage::sampled)
|
||||
&& has_texture_usage(target_desc.usage, TextureUsage::copy_source)
|
||||
&& has_texture_usage(target_desc.usage, TextureUsage::copy_destination)
|
||||
&& (features.texture_copy || features.render_target_blit);
|
||||
if (!can_ping_pong) {
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::failure(
|
||||
pp::foundation::Status::invalid_argument(
|
||||
"complex paint feedback requires framebuffer fetch or sampled copy-capable render targets"));
|
||||
}
|
||||
|
||||
plan.path = PaintFeedbackPath::ping_pong_textures;
|
||||
plan.requires_auxiliary_texture = true;
|
||||
plan.requires_texture_copy = features.texture_copy;
|
||||
plan.requires_render_target_blit = !features.texture_copy && features.render_target_blit;
|
||||
plan.requires_explicit_transition = features.explicit_texture_transitions;
|
||||
plan.auxiliary_desc = target_desc;
|
||||
return pp::foundation::Result<PaintFeedbackPlan>::success(plan);
|
||||
}
|
||||
|
||||
const char* texture_format_name(TextureFormat format) noexcept
|
||||
{
|
||||
switch (format) {
|
||||
@@ -887,6 +946,20 @@ const char* blit_filter_name(BlitFilter filter) noexcept
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const char* paint_feedback_path_name(PaintFeedbackPath path) noexcept
|
||||
{
|
||||
switch (path) {
|
||||
case PaintFeedbackPath::none:
|
||||
return "none";
|
||||
case PaintFeedbackPath::framebuffer_fetch:
|
||||
return "framebuffer_fetch";
|
||||
case PaintFeedbackPath::ping_pong_textures:
|
||||
return "ping_pong_textures";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const char* blend_factor_name(BlendFactor factor) noexcept
|
||||
{
|
||||
switch (factor) {
|
||||
|
||||
Reference in New Issue
Block a user