diff --git a/docs/modernization/capability-map.md b/docs/modernization/capability-map.md index 866c9e3..d454f03 100644 --- a/docs/modernization/capability-map.md +++ b/docs/modernization/capability-map.md @@ -17,6 +17,7 @@ and validation command. | Version metadata | `scripts/pre-build.py`, `version.*` | build system, `pp_foundation` | Generated header smoke test, missing-tag behavior | | Thumbnail generation/read | `Canvas`, `Image` | `pp_assets`, `pp_paint_renderer` | Golden thumbnail, corrupt input, destination-feedback copy/fetch gate | | Save-as, overwrite prompts | App/dialogs | `pp_app_core`, `pp_panopainter_ui`, `pp_platform_*` | Decision tests, UI automation, and platform smoke | +| App status and renderer diagnostics | App title/status widgets, extension indicators | `pp_app_core`, `pp_renderer_api`, `pp_panopainter_ui` | Title/status text tests, renderer diagnostic indicator tests, CLI status smoke, live layout adapter smoke | ## Image And Export diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 5125263..4a54ce9 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -22,7 +22,7 @@ agent or engineer to remove them without reconstructing context from chat. | --- | --- | --- | --- | --- | --- | --- | | DEBT-0001 | Open | Modernization | Existing platform build files remain alongside new CMake | Required for incremental migration without losing platform coverage | Existing platform builds plus new CMake configure | Remove after all platform builds consume shared CMake targets | | DEBT-0002 | Open | Modernization | Vendored SDK and patched libraries retained initially | Some dependencies are SDK-only, patched, or have platform-specific binaries | Dependency inventory and platform build smoke tests | Replace with vcpkg packages or document permanent vendored status after triplet evaluation | -| DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, file-menu save actions, `NodeCanvas` save hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, status/display UI rendering, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4 execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | +| DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, file-menu save actions, `NodeCanvas` save hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display and renderer diagnostic decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, status/display UI rendering, renderer diagnostic capability adaptation, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4 execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12 --framebuffer-fetch --float32 --float32-linear --float16`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | | DEBT-0004 | Open | Modernization | Android, Linux, WebGL, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them | Prevent platform regressions during incremental migration; raw Windows `.sln/.vcxproj` files were removed on 2026-05-31 by user decision | `cmake --preset windows-msvc-default`; platform-specific configure/build smoke checks as each platform is migrated | Root CMake owns every platform source list and package path | | DEBT-0005 | Open | Modernization | Temporary local CTest harness is used before Catch2 is wired through vcpkg | `vcpkg` is not currently on PATH, but headless tests need to run now | `ctest --preset desktop-fast --build-config Debug` | Replace `tests/test_harness.h` tests with Catch2 tests once vcpkg toolchain/presets are validated | | DEBT-0007 | Open | Modernization | `vcpkg.json` and `windows-msvc-vcpkg-headless` are validated for the headless Windows component matrix, but app targets still use vendored libraries and Android/Apple triplets are not proven | Dependency migration must stay incremental while SDK/patched/vendor dependencies remain in use | `$env:VCPKG_ROOT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg"; cmake --preset windows-msvc-vcpkg-headless`; `ctest --preset desktop-fast-vcpkg --build-config Debug` | Component targets consume vcpkg packages where reliable and desktop app, Android, and Apple triplets are validated or explicitly documented as permanent vendor exceptions | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 9b87f67..b77eb68 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -182,9 +182,11 @@ the live tools/options menu and `pano_cli plan-app-preferences` consume those contracts while legacy widgets and settings persistence execute them. It also owns tested app status/display plans for document title text, resolution mapping/labels, DPI text, history-memory text, and recording-frame -status text; `App::title_update`, `App::update_memory_usage`, -`App::update_rec_frames`, resolution helpers, and `pano_cli plan-app-status` -consume those contracts while legacy UI nodes still render the strings. +status text, plus renderer diagnostic indicator labels for framebuffer fetch +and floating-point render targets; `App::title_update`, +`App::update_memory_usage`, `App::update_rec_frames`, resolution helpers, +`App::initLayout`, and `pano_cli plan-app-status` consume those contracts while +legacy UI nodes still render the strings and status lights. `panopainter_app` is now a real static target that owns app orchestration sources, app version metadata, and version-header generation. `pp_panopainter_ui` now owns app-specific modal, dialog, panel, canvas, diff --git a/src/app_core/app_status.h b/src/app_core/app_status.h index 3b57338..403991d 100644 --- a/src/app_core/app_status.h +++ b/src/app_core/app_status.h @@ -33,6 +33,23 @@ struct RecordingFrameLabel { std::string text; }; +struct RendererDiagnosticsInput { + bool framebuffer_fetch = false; + bool float32_render_targets = false; + bool float32_linear_filtering = false; + bool float16_render_targets = false; +}; + +struct RendererDiagnosticIndicator { + bool supported = false; + std::string_view label; +}; + +struct RendererDiagnosticsPlan { + RendererDiagnosticIndicator framebuffer_fetch; + RendererDiagnosticIndicator floating_point_targets; +}; + [[nodiscard]] inline pp::foundation::Result display_resolution_from_index(int index) { if (index < 0 || static_cast(index) >= document_resolution_values.size()) { @@ -116,4 +133,38 @@ struct RecordingFrameLabel { }; } +[[nodiscard]] inline RendererDiagnosticsPlan plan_renderer_diagnostics( + RendererDiagnosticsInput input) noexcept +{ + RendererDiagnosticsPlan plan; + plan.framebuffer_fetch = { + input.framebuffer_fetch, + "FBF", + }; + + if (input.float32_linear_filtering) { + plan.floating_point_targets = { + true, + "F32L", + }; + } else if (input.float32_render_targets) { + plan.floating_point_targets = { + true, + "F32", + }; + } else if (input.float16_render_targets) { + plan.floating_point_targets = { + true, + "F16", + }; + } else { + plan.floating_point_targets = { + false, + "", + }; + } + + return plan; +} + } diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 3b7ddbf..8aa748d 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -2179,23 +2179,28 @@ void App::initLayout() version_label->set_text(g_version); } + const auto renderer_features = ShaderManager::render_device_features(); + const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({ + .framebuffer_fetch = renderer_features.framebuffer_fetch, + .float32_render_targets = renderer_features.float32_render_targets, + .float32_linear_filtering = ShaderManager::ext_float32_linear, + .float16_render_targets = renderer_features.float16_render_targets, + }); + if (auto x = layout[main_id]->find("ext-fbf")) { - x->m_color = ShaderManager::ext_framebuffer_fetch ? glm::vec4(0, 1, 0, 1) : glm::vec4(1, 0, 0, 1); + x->m_color = renderer_diagnostics.framebuffer_fetch.supported ? + glm::vec4(0, 1, 0, 1) : + glm::vec4(1, 0, 0, 1); } if (auto x = layout[main_id]->find("ext-flt")) { - if (ShaderManager::ext_float32 || ShaderManager::ext_float16) + if (renderer_diagnostics.floating_point_targets.supported) { if (auto t = x->find("ext-flt-text")) { - if (ShaderManager::ext_float32_linear) - t->set_text("F32L"); - else if (ShaderManager::ext_float32) - t->set_text("F32"); - else if (ShaderManager::ext_float16) - t->set_text("F16"); + t->set_text(std::string(renderer_diagnostics.floating_point_targets.label)); } x->m_color = glm::vec4(0, 1, 0, 1); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b1db48e..9693394 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -905,16 +905,20 @@ if(TARGET pano_cli) --history-bytes 1572864 --recording-running --encoder-available - --encoded-frames 12) + --encoded-frames 12 + --framebuffer-fetch + --float32 + --float32-linear + --float16) set_tests_properties(pano_cli_plan_app_status_smoke PROPERTIES LABELS "app;integration;desktop-fast" - PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo\\* \\(8K\\)\".*\"dpi\":\"1.3x-dpi\".*\"memory\":\"History memory: 1.50 Mb\".*\"recording\":\\{\"visible\":true,\"text\":\"Recorded 12 frames\"\\}.*\"fromIndexValid\":true.*\"fromIndex\":2048.*\"toIndexValid\":true.*\"toIndex\":3.*\"labelValid\":true.*\"label\":\"8K\"") + PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo\\* \\(8K\\)\".*\"dpi\":\"1.3x-dpi\".*\"memory\":\"History memory: 1.50 Mb\".*\"recording\":\\{\"visible\":true,\"text\":\"Recorded 12 frames\"\\}.*\"rendererDiagnostics\":\\{\"framebufferFetch\":\\{\"supported\":true,\"label\":\"FBF\"\\},\"floatingPointTargets\":\\{\"supported\":true,\"label\":\"F32L\"\\}\\}.*\"fromIndexValid\":true.*\"fromIndex\":2048.*\"toIndexValid\":true.*\"toIndex\":3.*\"labelValid\":true.*\"label\":\"8K\"") add_test(NAME pano_cli_plan_app_status_unknown_resolution_smoke COMMAND pano_cli plan-app-status --doc-name demo --resolution 1234 --resolution-index 9 --recording-running) set_tests_properties(pano_cli_plan_app_status_unknown_resolution_smoke PROPERTIES LABELS "app;integration;desktop-fast;fuzz" - PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo \\(unknown\\)\".*\"recording\":\\{\"visible\":false,\"text\":\"\"\\}.*\"fromIndexValid\":false.*\"toIndexValid\":false.*\"labelValid\":false.*\"label\":\"\"") + PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-status\".*\"title\":\"Panodoc: demo \\(unknown\\)\".*\"recording\":\\{\"visible\":false,\"text\":\"\"\\}.*\"rendererDiagnostics\":\\{\"framebufferFetch\":\\{\"supported\":false,\"label\":\"FBF\"\\},\"floatingPointTargets\":\\{\"supported\":false,\"label\":\"\"\\}\\}.*\"fromIndexValid\":false.*\"toIndexValid\":false.*\"labelValid\":false.*\"label\":\"\"") add_test(NAME pano_cli_plan_document_resize_smoke COMMAND pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4) diff --git a/tests/app_core/app_status_tests.cpp b/tests/app_core/app_status_tests.cpp index 4affe0f..ad2b7ca 100644 --- a/tests/app_core/app_status_tests.cpp +++ b/tests/app_core/app_status_tests.cpp @@ -71,6 +71,47 @@ void recording_label_only_shows_when_recording_with_encoder(pp::tests::Harness& PP_EXPECT(harness, active.text == "Recorded 12 frames"); } +void renderer_diagnostics_report_framebuffer_fetch(pp::tests::Harness& harness) +{ + const auto unsupported = pp::app::plan_renderer_diagnostics({}); + PP_EXPECT(harness, !unsupported.framebuffer_fetch.supported); + PP_EXPECT(harness, unsupported.framebuffer_fetch.label == "FBF"); + + const auto supported = pp::app::plan_renderer_diagnostics({ + .framebuffer_fetch = true, + }); + PP_EXPECT(harness, supported.framebuffer_fetch.supported); + PP_EXPECT(harness, supported.framebuffer_fetch.label == "FBF"); +} + +void renderer_diagnostics_prefer_highest_float_capability_label(pp::tests::Harness& harness) +{ + const auto none = pp::app::plan_renderer_diagnostics({}); + PP_EXPECT(harness, !none.floating_point_targets.supported); + PP_EXPECT(harness, none.floating_point_targets.label.empty()); + + const auto float16 = pp::app::plan_renderer_diagnostics({ + .float16_render_targets = true, + }); + PP_EXPECT(harness, float16.floating_point_targets.supported); + PP_EXPECT(harness, float16.floating_point_targets.label == "F16"); + + const auto float32 = pp::app::plan_renderer_diagnostics({ + .float32_render_targets = true, + .float16_render_targets = true, + }); + PP_EXPECT(harness, float32.floating_point_targets.supported); + PP_EXPECT(harness, float32.floating_point_targets.label == "F32"); + + const auto float32_linear = pp::app::plan_renderer_diagnostics({ + .float32_render_targets = true, + .float32_linear_filtering = true, + .float16_render_targets = true, + }); + PP_EXPECT(harness, float32_linear.floating_point_targets.supported); + PP_EXPECT(harness, float32_linear.floating_point_targets.label == "F32L"); +} + } int main() @@ -82,5 +123,7 @@ int main() harness.run("document title survives unknown resolution", document_title_survives_unknown_resolution); harness.run("status labels match legacy text", status_labels_match_legacy_text); harness.run("recording label only shows when recording with encoder", recording_label_only_shows_when_recording_with_encoder); + harness.run("renderer diagnostics report framebuffer fetch", renderer_diagnostics_report_framebuffer_fetch); + harness.run("renderer diagnostics prefer highest float capability label", renderer_diagnostics_prefer_highest_float_capability_label); return harness.finish(); } diff --git a/tools/pano_cli/main.cpp b/tools/pano_cli/main.cpp index f336d0f..4d48e15 100644 --- a/tools/pano_cli/main.cpp +++ b/tools/pano_cli/main.cpp @@ -236,6 +236,10 @@ struct PlanAppStatusArgs { bool recording_running = false; bool encoder_available = false; std::uint32_t encoded_frames = 0; + bool framebuffer_fetch = false; + bool float32_render_targets = false; + bool float32_linear_filtering = false; + bool float16_render_targets = false; }; struct PlanDocumentResizeArgs { @@ -1766,7 +1770,7 @@ void print_help() << " plan-cloud-upload-all [--file-count N] [--no-progress-ui]\n" << " plan-recording-session [--running] [--frame-count N] [--platform-deletes-recorded-files]\n" << " plan-app-preferences [--ui-scale N] [--display-density N] [--current-scale N] [--scale-option N] [--viewport-scale N] [--rtl] [--timelapse-disabled] [--recording-running] [--vr-controllers-disabled] [--cursor-mode N]\n" - << " plan-app-status [--doc-name NAME] [--unsaved] [--resolution N] [--resolution-index N] [--zoom N] [--history-bytes N] [--recording-running] [--encoder-available] [--encoded-frames N]\n" + << " plan-app-status [--doc-name NAME] [--unsaved] [--resolution N] [--resolution-index N] [--zoom N] [--history-bytes N] [--recording-running] [--encoder-available] [--encoded-frames N] [--framebuffer-fetch] [--float32] [--float32-linear] [--float16]\n" << " plan-tools-menu --command panels|options|clear-grids|reset-camera|shortcuts|sonarpen [--sonarpen-available]\n" << " plan-tools-panel --panel presets|color|color-advanced|layers|brush|grids|animation [--already-visible]\n" << " plan-about-menu --command help|about|news|crash|performance [--version-major N] [--version-minor N] [--version-fix N] [--no-diagnostics] [--no-canvas]\n" @@ -3558,6 +3562,14 @@ pp::foundation::Status parse_plan_app_status_args( args.recording_running = true; } else if (key == "--encoder-available") { args.encoder_available = true; + } else if (key == "--framebuffer-fetch") { + args.framebuffer_fetch = true; + } else if (key == "--float32") { + args.float32_render_targets = true; + } else if (key == "--float32-linear") { + args.float32_linear_filtering = true; + } else if (key == "--float16") { + args.float16_render_targets = true; } else { return pp::foundation::Status::invalid_argument("unknown option"); } @@ -3582,6 +3594,12 @@ int plan_app_status(int argc, char** argv) args.recording_running, args.encoder_available, static_cast(args.encoded_frames)); + const auto diagnostics = pp::app::plan_renderer_diagnostics({ + .framebuffer_fetch = args.framebuffer_fetch, + .float32_render_targets = args.float32_render_targets, + .float32_linear_filtering = args.float32_linear_filtering, + .float16_render_targets = args.float16_render_targets, + }); std::cout << "{\"ok\":true,\"command\":\"plan-app-status\"" << ",\"state\":{\"documentName\":\"" << json_escape(args.document_name) @@ -3593,6 +3611,10 @@ int plan_app_status(int argc, char** argv) << ",\"recordingRunning\":" << json_bool(args.recording_running) << ",\"encoderAvailable\":" << json_bool(args.encoder_available) << ",\"encodedFrames\":" << args.encoded_frames + << ",\"framebufferFetch\":" << json_bool(args.framebuffer_fetch) + << ",\"float32\":" << json_bool(args.float32_render_targets) + << ",\"float32Linear\":" << json_bool(args.float32_linear_filtering) + << ",\"float16\":" << json_bool(args.float16_render_targets) << "},\"title\":\"" << json_escape(pp::app::make_document_title( args.document_name, args.unsaved, @@ -3601,7 +3623,13 @@ int plan_app_status(int argc, char** argv) << "\",\"memory\":\"" << json_escape(pp::app::make_history_memory_label(args.history_bytes)) << "\",\"recording\":{\"visible\":" << json_bool(recording_label.visible) << ",\"text\":\"" << json_escape(recording_label.text) - << "\"},\"resolutionMap\":{\"fromIndexValid\":" << json_bool(static_cast(resolution_from_index)) + << "\"},\"rendererDiagnostics\":{\"framebufferFetch\":{\"supported\":" + << json_bool(diagnostics.framebuffer_fetch.supported) + << ",\"label\":\"" << json_escape(std::string(diagnostics.framebuffer_fetch.label)) + << "\"},\"floatingPointTargets\":{\"supported\":" + << json_bool(diagnostics.floating_point_targets.supported) + << ",\"label\":\"" << json_escape(std::string(diagnostics.floating_point_targets.label)) + << "\"}},\"resolutionMap\":{\"fromIndexValid\":" << json_bool(static_cast(resolution_from_index)) << ",\"fromIndex\":" << (resolution_from_index ? resolution_from_index.value() : 0) << ",\"toIndexValid\":" << json_bool(static_cast(resolution_index)) << ",\"toIndex\":" << (resolution_index ? resolution_index.value() : 0)