Add stroke composite feedback planner
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "foundation/parse.h"
|
||||
#include "foundation/result.h"
|
||||
#include "paint/blend.h"
|
||||
#include "paint_renderer/compositor.h"
|
||||
#include "paint/stroke.h"
|
||||
#include "paint/stroke_script.h"
|
||||
#include "renderer_api/recording_renderer.h"
|
||||
@@ -347,6 +348,21 @@ struct PlanPaintFeedbackArgs {
|
||||
bool depth_target = false;
|
||||
};
|
||||
|
||||
struct PlanStrokeCompositeArgs {
|
||||
int width = 64;
|
||||
int height = 32;
|
||||
int layer_blend_mode = 0;
|
||||
int stroke_blend_mode = 0;
|
||||
bool dual_brush_blend = false;
|
||||
bool pattern_blend = false;
|
||||
bool framebuffer_fetch = false;
|
||||
bool explicit_texture_transitions = false;
|
||||
bool texture_copy = false;
|
||||
bool render_target_blit = false;
|
||||
bool render_only_target = false;
|
||||
bool depth_target = false;
|
||||
};
|
||||
|
||||
struct PlanGridOperationArgs {
|
||||
std::string kind = "pick";
|
||||
std::string path;
|
||||
@@ -1766,6 +1782,7 @@ void print_help()
|
||||
<< " plan-brush-texture-list --kind add|remove|move [--dir NAME] [--data-path DIR] [--source FILE] [--item-count N] [--current-index N] [--offset N] [--user-texture]\n"
|
||||
<< " plan-brush-stroke-control --kind float|bool|blend|tip-aspect-reset|default-reset [--setting NAME] [--value N] [--enabled|--disabled] [--blend-mode N]\n"
|
||||
<< " plan-paint-feedback [--width N] [--height N] [--simple|--complex] [--framebuffer-fetch] [--texture-copy] [--blit] [--explicit-transitions] [--render-only] [--depth]\n"
|
||||
<< " plan-stroke-composite [--width N] [--height N] [--layer-blend N] [--stroke-blend N] [--dual-blend] [--pattern-blend] [--framebuffer-fetch] [--texture-copy] [--blit] [--explicit-transitions] [--render-only] [--depth]\n"
|
||||
<< " plan-canvas-tool --kind draw|erase|line|camera|grid|copy|cut|fill|mask-free|mask-line|bucket|pick|touch-lock [--current-mode-draw]\n"
|
||||
<< " plan-canvas-tool-state [--mode draw|erase|line|camera|grid|copy|cut|fill|mask-free|mask-line|bucket] [--picking] [--touch-lock]\n"
|
||||
<< " plan-grid-operation --kind pick|load|reload|clear|render|commit [--path FILE] [--no-heightmap] [--no-canvas] [--float32] [--float16] [--texture-resolution N] [--samples N]\n"
|
||||
@@ -4933,6 +4950,137 @@ int plan_paint_feedback(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_stroke_composite_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
PlanStrokeCompositeArgs& args)
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
const std::string_view key(argv[i]);
|
||||
if (key == "--width" || key == "--height" || key == "--layer-blend" || key == "--stroke-blend") {
|
||||
if (i + 1 >= argc) {
|
||||
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||
}
|
||||
const auto value = parse_i32_arg(argv[++i]);
|
||||
if (!value) {
|
||||
return value.status();
|
||||
}
|
||||
if (key == "--width" || key == "--height") {
|
||||
if (value.value() <= 0) {
|
||||
return pp::foundation::Status::invalid_argument("stroke composite extent must be greater than zero");
|
||||
}
|
||||
if (key == "--width") {
|
||||
args.width = value.value();
|
||||
} else {
|
||||
args.height = value.value();
|
||||
}
|
||||
} else if (key == "--layer-blend") {
|
||||
args.layer_blend_mode = value.value();
|
||||
} else {
|
||||
args.stroke_blend_mode = value.value();
|
||||
}
|
||||
} else if (key == "--dual-blend") {
|
||||
args.dual_brush_blend = true;
|
||||
} else if (key == "--pattern-blend") {
|
||||
args.pattern_blend = true;
|
||||
} else if (key == "--framebuffer-fetch") {
|
||||
args.framebuffer_fetch = true;
|
||||
} else if (key == "--explicit-transitions") {
|
||||
args.explicit_texture_transitions = true;
|
||||
} else if (key == "--texture-copy") {
|
||||
args.texture_copy = true;
|
||||
} else if (key == "--blit") {
|
||||
args.render_target_blit = true;
|
||||
} else if (key == "--render-only") {
|
||||
args.render_only_target = true;
|
||||
} else if (key == "--depth") {
|
||||
args.depth_target = true;
|
||||
} else {
|
||||
return pp::foundation::Status::invalid_argument("unknown option");
|
||||
}
|
||||
}
|
||||
|
||||
if (args.layer_blend_mode < 0 || args.layer_blend_mode > 4) {
|
||||
return pp::foundation::Status::out_of_range("layer blend mode must be in the range [0, 4]");
|
||||
}
|
||||
if (args.stroke_blend_mode < 0 || args.stroke_blend_mode > 10) {
|
||||
return pp::foundation::Status::out_of_range("stroke blend mode must be in the range [0, 10]");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
int plan_stroke_composite(int argc, char** argv)
|
||||
{
|
||||
PlanStrokeCompositeArgs args;
|
||||
const auto status = parse_plan_stroke_composite_args(argc, argv, args);
|
||||
if (!status.ok()) {
|
||||
print_error("plan-stroke-composite", status.message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pp::renderer::TextureUsage usage = pp::renderer::TextureUsage::render_target;
|
||||
if (!args.render_only_target) {
|
||||
usage |= pp::renderer::TextureUsage::sampled;
|
||||
usage |= pp::renderer::TextureUsage::copy_source;
|
||||
usage |= pp::renderer::TextureUsage::copy_destination;
|
||||
}
|
||||
|
||||
const pp::paint_renderer::StrokeCompositeRequest request {
|
||||
.extent = pp::renderer::Extent2D {
|
||||
.width = static_cast<std::uint32_t>(args.width),
|
||||
.height = static_cast<std::uint32_t>(args.height),
|
||||
},
|
||||
.target_format = args.depth_target
|
||||
? pp::renderer::TextureFormat::depth24_stencil8
|
||||
: pp::renderer::TextureFormat::rgba8,
|
||||
.target_usage = usage,
|
||||
.layer_blend_mode = static_cast<pp::paint::BlendMode>(args.layer_blend_mode),
|
||||
.stroke_blend_mode = static_cast<pp::paint::StrokeBlendMode>(args.stroke_blend_mode),
|
||||
.dual_brush_blend = args.dual_brush_blend,
|
||||
.pattern_blend = args.pattern_blend,
|
||||
};
|
||||
const pp::renderer::RenderDeviceFeatures features {
|
||||
.framebuffer_fetch = args.framebuffer_fetch,
|
||||
.explicit_texture_transitions = args.explicit_texture_transitions,
|
||||
.texture_copy = args.texture_copy,
|
||||
.render_target_blit = args.render_target_blit,
|
||||
};
|
||||
const auto plan = pp::paint_renderer::plan_stroke_composite(features, request);
|
||||
if (!plan) {
|
||||
print_error("plan-stroke-composite", plan.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto& value = plan.value();
|
||||
std::cout << "{\"ok\":true,\"command\":\"plan-stroke-composite\""
|
||||
<< ",\"state\":{\"width\":" << args.width
|
||||
<< ",\"height\":" << args.height
|
||||
<< ",\"layerBlend\":\"" << pp::paint::blend_mode_name(request.layer_blend_mode)
|
||||
<< "\",\"strokeBlend\":\"" << pp::paint::stroke_blend_mode_name(request.stroke_blend_mode)
|
||||
<< "\",\"dualBrushBlend\":" << json_bool(args.dual_brush_blend)
|
||||
<< ",\"patternBlend\":" << json_bool(args.pattern_blend)
|
||||
<< ",\"framebufferFetch\":" << json_bool(args.framebuffer_fetch)
|
||||
<< ",\"explicitTransitions\":" << json_bool(args.explicit_texture_transitions)
|
||||
<< ",\"textureCopy\":" << json_bool(args.texture_copy)
|
||||
<< ",\"blit\":" << json_bool(args.render_target_blit)
|
||||
<< ",\"renderOnlyTarget\":" << json_bool(args.render_only_target)
|
||||
<< ",\"depthTarget\":" << json_bool(args.depth_target)
|
||||
<< "},\"plan\":{\"path\":\"" << pp::paint_renderer::stroke_composite_path_name(value.path)
|
||||
<< "\",\"feedbackPath\":\"" << pp::renderer::paint_feedback_path_name(value.feedback.path)
|
||||
<< "\",\"targetBytes\":" << value.target_bytes
|
||||
<< ",\"auxiliaryBytes\":" << value.auxiliary_bytes
|
||||
<< ",\"estimatedWorkingBytes\":" << value.estimated_working_bytes
|
||||
<< ",\"complexBlend\":" << json_bool(value.complex_blend)
|
||||
<< ",\"readsDestinationColor\":" << json_bool(value.reads_destination_color)
|
||||
<< ",\"requiresAuxiliaryTexture\":" << json_bool(value.requires_auxiliary_texture)
|
||||
<< ",\"requiresTextureCopy\":" << json_bool(value.requires_texture_copy)
|
||||
<< ",\"requiresRenderTargetBlit\":" << json_bool(value.requires_render_target_blit)
|
||||
<< ",\"requiresExplicitTransition\":" << json_bool(value.requires_explicit_transition)
|
||||
<< "}}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_canvas_tool_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
@@ -8067,6 +8215,10 @@ int main(int argc, char** argv)
|
||||
return plan_paint_feedback(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-stroke-composite") {
|
||||
return plan_stroke_composite(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-canvas-tool") {
|
||||
return plan_canvas_tool(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user