From 03213a99f6362a066976ad6c588b44d79d1aaf34 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 17 Dec 2023 17:36:54 +0000 Subject: [PATCH 01/14] Added vsgtracyinstrumentation example to demonstrate use of Tracy + sg:TracyInstrumentation usage --- CMakeLists.txt | 2 + examples/utils/CMakeLists.txt | 4 + .../vsgtracyinstrumentation/CMakeLists.txt | 14 + .../vsgtracyinstrumentation.cpp | 284 ++++++++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 examples/utils/vsgtracyinstrumentation/CMakeLists.txt create mode 100644 examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b03a3e8e..e033a96c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,8 @@ find_package(vsgXchange 1.0.5 QUIET) # find the optional vsgImGui that can be used for GUI elements added into graphics windows. find_package(vsgImGui QUIET) +find_package(Tracy QUIET) + # set the use of C++17 globally as all examples require it set(CMAKE_CXX_STANDARD 17) diff --git a/examples/utils/CMakeLists.txt b/examples/utils/CMakeLists.txt index e5cf8c4c..7e82dfaa 100644 --- a/examples/utils/CMakeLists.txt +++ b/examples/utils/CMakeLists.txt @@ -4,3 +4,7 @@ add_subdirectory(vsgshaderset) add_subdirectory(vsgintersection) add_subdirectory(vsgstoragebuffer) add_subdirectory(vsgcustomshaderset) + +if (Tracy_FOUND) + add_subdirectory(vsgtracyinstrumentation) +endif() diff --git a/examples/utils/vsgtracyinstrumentation/CMakeLists.txt b/examples/utils/vsgtracyinstrumentation/CMakeLists.txt new file mode 100644 index 00000000..43352c34 --- /dev/null +++ b/examples/utils/vsgtracyinstrumentation/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SOURCES + vsgtracyinstrumentation.cpp +) + +add_executable(vsgtracyinstrumentation ${SOURCES}) + +target_link_libraries(vsgtracyinstrumentation vsg::vsg Tracy::TracyClient) + +if (vsgXchange_FOUND) + target_compile_definitions(vsgtracyinstrumentation PRIVATE vsgXchange_FOUND) + target_link_libraries(vsgtracyinstrumentation vsgXchange::vsgXchange) +endif() + +install(TARGETS vsgtracyinstrumentation RUNTIME DESTINATION bin) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp new file mode 100644 index 00000000..60215966 --- /dev/null +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -0,0 +1,284 @@ +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +#include + +#include +#include +#include +#include + +vsg::ref_ptr createTextureQuad(vsg::ref_ptr sourceData, vsg::ref_ptr options) +{ + auto builder = vsg::Builder::create(); + builder->options = options; + + vsg::StateInfo state; + state.image = sourceData; + state.lighting = false; + + vsg::GeometryInfo geom; + geom.dy.set(0.0f, 0.0f, 1.0f); + geom.dz.set(0.0f, -1.0f, 0.0f); + + return builder->createQuad(geom, state); +} + +void enableGenerateDebugInfo(vsg::ref_ptr options) +{ + auto shaderHints = vsg::ShaderCompileSettings::create(); + shaderHints->generateDebugInfo = true; + + auto& text = options->shaderSets["text"] = vsg::createTextShaderSet(options); + text->defaultShaderHints = shaderHints; + + auto& flat = options->shaderSets["flat"] = vsg::createFlatShadedShaderSet(options); + flat->defaultShaderHints = shaderHints; + + auto& phong = options->shaderSets["phong"] = vsg::createPhongShaderSet(options); + phong->defaultShaderHints = shaderHints; + + auto& pbr = options->shaderSets["pbr"] = vsg::createPhysicsBasedRenderingShaderSet(options); + pbr->defaultShaderHints = shaderHints; +} + +int main(int argc, char** argv) +{ + try + { + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + // set up vsg::Options to pass in filepaths, ReaderWriters and other IO related options to use when reading and writing files. + auto options = vsg::Options::create(); + options->sharedObjects = vsg::SharedObjects::create(); + options->fileCache = vsg::getEnv("VSG_FILE_CACHE"); + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + +#ifdef vsgXchange_all + // add vsgXchange's support for reading and writing 3rd party file formats + options->add(vsgXchange::all::create()); +#endif + + arguments.read(options); + + auto windowTraits = vsg::WindowTraits::create(); + windowTraits->windowTitle = "vsgviewer"; + windowTraits->debugLayer = arguments.read({"--debug", "-d"}); + windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); + windowTraits->synchronizationLayer = arguments.read("--sync"); + bool reportAverageFrameRate = arguments.read("--fps"); + if (int mt = 0; arguments.read({"--memory-tracking", "--mt"}, mt)) vsg::Allocator::instance()->setMemoryTracking(mt); + if (arguments.read("--double-buffer")) windowTraits->swapchainPreferences.imageCount = 2; + if (arguments.read("--triple-buffer")) windowTraits->swapchainPreferences.imageCount = 3; // default + if (arguments.read("--IMMEDIATE")) { windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; } + if (arguments.read("--FIFO")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_FIFO_KHR; + if (arguments.read("--FIFO_RELAXED")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; + if (arguments.read("--MAILBOX")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_MAILBOX_KHR; + if (arguments.read({"-t", "--test"})) + { + windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + windowTraits->fullscreen = true; + reportAverageFrameRate = true; + } + if (arguments.read({"--st", "--small-test"})) + { + windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + windowTraits->width = 192, windowTraits->height = 108; + windowTraits->decoration = false; + reportAverageFrameRate = true; + } + + if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true; + if (arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height)) { windowTraits->fullscreen = false; } + if (arguments.read({"--no-frame", "--nf"})) windowTraits->decoration = false; + if (arguments.read("--or")) windowTraits->overrideRedirect = true; + if (arguments.read("--d32")) windowTraits->depthFormat = VK_FORMAT_D32_SFLOAT; + arguments.read("--screen", windowTraits->screenNum); + arguments.read("--display", windowTraits->display); + arguments.read("--samples", windowTraits->samples); + auto numFrames = arguments.value(-1, "-f"); + auto pathFilename = arguments.value("", "-p"); + auto loadLevels = arguments.value(0, "--load-levels"); + auto maxPagedLOD = arguments.value(0, "--maxPagedLOD"); + auto horizonMountainHeight = arguments.value(0.0, "--hmh"); + auto nearFarRatio = arguments.value(0.001, "--nfr"); + if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; + + if (arguments.read({"--shader-debug-info", "--sdi"})) + { + enableGenerateDebugInfo(options); + windowTraits->deviceExtensionNames.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); + } + + if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); + + if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); + + if (argc <= 1) + { + std::cout << "Please specify a 3d model or image file on the command line." << std::endl; + return 1; + } + + auto group = vsg::Group::create(); + + vsg::Path path; + + // read any vsg files + for (int i = 1; i < argc; ++i) + { + vsg::Path filename = arguments[i]; + path = vsg::filePath(filename); + + auto object = vsg::read(filename, options); + if (auto node = object.cast()) + { + group->addChild(node); + } + else if (auto data = object.cast()) + { + if (auto textureGeometry = createTextureQuad(data, options)) + { + group->addChild(textureGeometry); + } + } + else if (object) + { + std::cout << "Unable to view object of type " << object->className() << std::endl; + } + else + { + std::cout << "Unable to load file " << filename << std::endl; + } + } + + if (group->children.empty()) + { + return 1; + } + + vsg::ref_ptr vsg_scene; + if (group->children.size() == 1) + vsg_scene = group->children[0]; + else + vsg_scene = group; + + // create the viewer and assign window(s) to it + auto viewer = vsg::Viewer::create(); + auto window = vsg::Window::create(windowTraits); + if (!window) + { + std::cout << "Could not create window." << std::endl; + return 1; + } + + viewer->addWindow(window); + + // compute the bounds of the scene graph to help position camera + vsg::ComputeBounds computeBounds; + vsg_scene->accept(computeBounds); + vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; + double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.6; + + // set up the camera + auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); + + vsg::ref_ptr perspective; + auto ellipsoidModel = vsg_scene->getRefObject("EllipsoidModel"); + if (ellipsoidModel) + { + perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio, horizonMountainHeight); + } + else + { + perspective = vsg::Perspective::create(30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 4.5); + } + + auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D())); + + // add close handler to respond to the close window button and pressing escape + viewer->addEventHandler(vsg::CloseHandler::create(viewer)); + + auto animationPathHandler = vsg::RecordAnimationPathHandler::create(camera, pathFilename, options); + animationPathHandler->printFrameStatsToConsole = true; + viewer->addEventHandler(animationPathHandler); + + viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + + // if required preload specific number of PagedLOD levels. + if (loadLevels > 0) + { + vsg::LoadPagedLOD loadPagedLOD(camera, loadLevels); + + auto startTime = vsg::clock::now(); + + vsg_scene->accept(loadPagedLOD); + + auto time = std::chrono::duration(vsg::clock::now() - startTime).count(); + std::cout << "No. of tiles loaded " << loadPagedLOD.numTiles << " in " << time << "ms." << std::endl; + } + + auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); + viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + + vsg::ref_ptr instrumentation; + +#if 0 + instrumentation = vsg::TracyInstrumentation::create(); + viewer->assignInstrumentation(instrumentation); +#endif + + viewer->compile(); + + if (maxPagedLOD > 0) + { + // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required. + for(auto& task : viewer->recordAndSubmitTasks) + { + if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD; + } + } + + viewer->start_point() = vsg::clock::now(); + + // rendering main loop + while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) + { + if (!instrumentation && GetProfiler().IsConnected()) + { + vsg::info("Need to assign TracyInstrumentation on the fly"); + instrumentation = vsg::TracyInstrumentation::create(); + viewer->assignInstrumentation(instrumentation); + } + + // pass any events into EventHandlers assigned to the Viewer + viewer->handleEvents(); + + viewer->update(); + + viewer->recordAndSubmit(); + + viewer->present(); + } + + if (reportAverageFrameRate) + { + auto fs = viewer->getFrameStamp(); + double fps = static_cast(fs->frameCount) / std::chrono::duration(vsg::clock::now() - viewer->start_point()).count(); + std::cout<<"Average frame rate = "<assignInstrumentation(instrumentation); #endif @@ -248,12 +249,14 @@ int main(int argc, char** argv) // rendering main loop while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) { +#ifdef TRACY_ON_DEMAND if (!instrumentation && GetProfiler().IsConnected()) { - vsg::info("Need to assign TracyInstrumentation on the fly"); + vsg::info("Tracy profile is now connected, assigning TracyInstrumentation."); instrumentation = vsg::TracyInstrumentation::create(); viewer->assignInstrumentation(instrumentation); } +#endif // pass any events into EventHandlers assigned to the Viewer viewer->handleEvents(); From 2e43bdb43a67d2fd7a3206683e1ff1f0cc6fda0f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Dec 2023 17:45:58 +0000 Subject: [PATCH 03/14] Added --cpu and --gpu command line controls to vsgtracyinstrumentation --- .../vsgtracyinstrumentation.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 3d9b855b..11e8a62a 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -108,6 +108,11 @@ int main(int argc, char** argv) auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; + // set TracyInstrumentation options + auto instrumentation = vsg::TracyInstrumentation::create(); + arguments.read("--cpu", instrumentation->cpu_instumentation_level); + arguments.read("--gpu", instrumentation->gpu_instumentation_level); + if (arguments.read({"--shader-debug-info", "--sdi"})) { enableGenerateDebugInfo(options); @@ -225,11 +230,8 @@ int main(int argc, char** argv) auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); - vsg::ref_ptr instrumentation; - #ifndef TRACY_ON_DEMAND vsg::info("TRACY_ON_DEMAND not enabled so assigning TracyInstrumentation by default."); - instrumentation = vsg::TracyInstrumentation::create(); viewer->assignInstrumentation(instrumentation); #endif @@ -250,10 +252,9 @@ int main(int argc, char** argv) while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) { #ifdef TRACY_ON_DEMAND - if (!instrumentation && GetProfiler().IsConnected()) + if (!viewer->instrumentation && GetProfiler().IsConnected()) { vsg::info("Tracy profile is now connected, assigning TracyInstrumentation."); - instrumentation = vsg::TracyInstrumentation::create(); viewer->assignInstrumentation(instrumentation); } #endif From be7c1885efd021b7a83e2fb572970d55ca618f75 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Dec 2023 09:42:00 +0000 Subject: [PATCH 04/14] Added runtime adjustment of cpu and gpu_instrumentation_levels --- .../vsgtracyinstrumentation.cpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 11e8a62a..8b4118f2 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -45,6 +45,37 @@ void enableGenerateDebugInfo(vsg::ref_ptr options) pbr->defaultShaderHints = shaderHints; } +class InstrumentationHandler : public vsg::Inherit +{ +public: + + vsg::ref_ptr instrumentation; + + InstrumentationHandler(vsg::ref_ptr in_instrumentation) : instrumentation(in_instrumentation) {} + + void apply(vsg::KeyPressEvent& keyPress) override + { + if (keyPress.keyModified == 'c') + { + if (instrumentation->cpu_instumentation_level > 0) --instrumentation->cpu_instumentation_level; + } + else if (keyPress.keyModified == 'C') + { + if (instrumentation->cpu_instumentation_level < 3) ++instrumentation->cpu_instumentation_level; + } + if (keyPress.keyModified == 'g') + { + if (instrumentation->gpu_instumentation_level > 0) --instrumentation->gpu_instumentation_level; + } + else if (keyPress.keyModified == 'G') + { + if (instrumentation->gpu_instumentation_level < 3) ++instrumentation->gpu_instumentation_level; + } + } +}; + + + int main(int argc, char** argv) { try @@ -214,6 +245,9 @@ int main(int argc, char** argv) viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + // add event handler to control the cpu and gpu_instrumentation_level using the 'c', 'g' keys to reduce the cpu and gpu instruemntation level, and 'C' and 'G' to increase them respectively. + viewer->addEventHandler(InstrumentationHandler::create(instrumentation)); + // if required preload specific number of PagedLOD levels. if (loadLevels > 0) { From d689eea8c4cfc333f393d5ff9ce1c6bb4da1a249 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Dec 2023 12:09:37 +0000 Subject: [PATCH 05/14] Updates to work with latest vsg::TracyInstrumentation changes and enabling of the calibrated timestamps. --- .../vsgtracyinstrumentation.cpp | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 8b4118f2..29c39582 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -57,19 +57,19 @@ class InstrumentationHandler : public vsg::Inheritcpu_instumentation_level > 0) --instrumentation->cpu_instumentation_level; + if (instrumentation->settings->cpu_instumentation_level > 0) --instrumentation->settings->cpu_instumentation_level; } else if (keyPress.keyModified == 'C') { - if (instrumentation->cpu_instumentation_level < 3) ++instrumentation->cpu_instumentation_level; + if (instrumentation->settings->cpu_instumentation_level < 3) ++instrumentation->settings->cpu_instumentation_level; } if (keyPress.keyModified == 'g') { - if (instrumentation->gpu_instumentation_level > 0) --instrumentation->gpu_instumentation_level; + if (instrumentation->settings->gpu_instumentation_level > 0) --instrumentation->settings->gpu_instumentation_level; } else if (keyPress.keyModified == 'G') { - if (instrumentation->gpu_instumentation_level < 3) ++instrumentation->gpu_instumentation_level; + if (instrumentation->settings->gpu_instumentation_level < 3) ++instrumentation->settings->gpu_instumentation_level; } } }; @@ -141,8 +141,8 @@ int main(int argc, char** argv) // set TracyInstrumentation options auto instrumentation = vsg::TracyInstrumentation::create(); - arguments.read("--cpu", instrumentation->cpu_instumentation_level); - arguments.read("--gpu", instrumentation->gpu_instumentation_level); + arguments.read("--cpu", instrumentation->settings->cpu_instumentation_level); + arguments.read("--gpu", instrumentation->settings->gpu_instumentation_level); if (arguments.read({"--shader-debug-info", "--sdi"})) { @@ -150,6 +150,10 @@ int main(int argc, char** argv) windowTraits->deviceExtensionNames.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); } + // TODO: need to check for VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME support? + // enable calibrated timestamps. + windowTraits->deviceExtensionNames.push_back(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); + if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); @@ -160,6 +164,10 @@ int main(int argc, char** argv) return 1; } + // assign instrumentation to vsg::Options to enable read/write functions to provide instrumentation + options->instrumentation = instrumentation; + + auto group = vsg::Group::create(); vsg::Path path; From d33eafbfdec2d32759ebb5857ee1f0ff2ef527c6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2023 09:03:21 +0000 Subject: [PATCH 06/14] Added support for building against Tracy version without TRACY_ENABLE --- .../vsgtracyinstrumentation.cpp | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 29c39582..65ba657b 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -102,7 +102,7 @@ int main(int argc, char** argv) windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); windowTraits->synchronizationLayer = arguments.read("--sync"); bool reportAverageFrameRate = arguments.read("--fps"); - if (int mt = 0; arguments.read({"--memory-tracking", "--mt"}, mt)) vsg::Allocator::instance()->setMemoryTracking(mt); + bool multiThreading = arguments.read("--mt"); if (arguments.read("--double-buffer")) windowTraits->swapchainPreferences.imageCount = 2; if (arguments.read("--triple-buffer")) windowTraits->swapchainPreferences.imageCount = 3; // default if (arguments.read("--IMMEDIATE")) { windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; } @@ -133,8 +133,6 @@ int main(int argc, char** argv) arguments.read("--samples", windowTraits->samples); auto numFrames = arguments.value(-1, "-f"); auto pathFilename = arguments.value("", "-p"); - auto loadLevels = arguments.value(0, "--load-levels"); - auto maxPagedLOD = arguments.value(0, "--maxPagedLOD"); auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; @@ -150,6 +148,14 @@ int main(int argc, char** argv) windowTraits->deviceExtensionNames.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); } +#ifndef TRACY_ON_DEMAND + vsg::info("TRACY_ON_DEMAND not enabled so assigning TracyInstrumentation by default."); + bool assignInstrumentationBeforeMainLoop = true; +#else + bool assignInstrumentationBeforeMainLoop = arguments.read("--always"); +#endif + + // TODO: need to check for VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME support? // enable calibrated timestamps. windowTraits->deviceExtensionNames.push_back(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); @@ -256,44 +262,27 @@ int main(int argc, char** argv) // add event handler to control the cpu and gpu_instrumentation_level using the 'c', 'g' keys to reduce the cpu and gpu instruemntation level, and 'C' and 'G' to increase them respectively. viewer->addEventHandler(InstrumentationHandler::create(instrumentation)); - // if required preload specific number of PagedLOD levels. - if (loadLevels > 0) - { - vsg::LoadPagedLOD loadPagedLOD(camera, loadLevels); - - auto startTime = vsg::clock::now(); - - vsg_scene->accept(loadPagedLOD); - - auto time = std::chrono::duration(vsg::clock::now() - startTime).count(); - std::cout << "No. of tiles loaded " << loadPagedLOD.numTiles << " in " << time << "ms." << std::endl; - } - auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); -#ifndef TRACY_ON_DEMAND - vsg::info("TRACY_ON_DEMAND not enabled so assigning TracyInstrumentation by default."); - viewer->assignInstrumentation(instrumentation); -#endif - - viewer->compile(); + if (assignInstrumentationBeforeMainLoop) + { + viewer->assignInstrumentation(instrumentation); + } - if (maxPagedLOD > 0) + if (multiThreading) { - // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required. - for(auto& task : viewer->recordAndSubmitTasks) - { - if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD; - } + viewer->setupThreading(); } + viewer->compile(); + viewer->start_point() = vsg::clock::now(); // rendering main loop while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) { -#ifdef TRACY_ON_DEMAND +#if defined(TRACY_ENABLE) && defined(TRACY_ON_DEMAND) if (!viewer->instrumentation && GetProfiler().IsConnected()) { vsg::info("Tracy profile is now connected, assigning TracyInstrumentation."); From 5b18c37dc3efa4947e1838ae2bc46d68a5f7a675 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2023 12:41:41 +0000 Subject: [PATCH 07/14] Added GpuAnnotation support to vsgviewer --- examples/app/vsgviewer/vsgviewer.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/app/vsgviewer/vsgviewer.cpp b/examples/app/vsgviewer/vsgviewer.cpp index b1d32269..c158261f 100644 --- a/examples/app/vsgviewer/vsgviewer.cpp +++ b/examples/app/vsgviewer/vsgviewer.cpp @@ -114,6 +114,14 @@ int main(int argc, char** argv) if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); + vsg::ref_ptr instrumentation; + if (arguments.read({"--gpu-annotation", "--ga"}) && vsg::isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) + { + windowTraits->debugUtils = true; + instrumentation = vsg::GpuAnnotation::create(); + } + + if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); if (argc <= 1) @@ -223,6 +231,8 @@ int main(int argc, char** argv) auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + if (instrumentation) viewer->assignInstrumentation(instrumentation); + viewer->compile(); if (maxPagedLOD > 0) From e3813395388c1325be16f732c8c28bf756b8f9b1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2023 15:41:28 +0000 Subject: [PATCH 08/14] Added support for selecting SourceLocation::function as the label for vsg::GpuAnnotation --- examples/app/vsgviewer/vsgviewer.cpp | 6 +++++- .../vsgtracyinstrumentation/vsgtracyinstrumentation.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/app/vsgviewer/vsgviewer.cpp b/examples/app/vsgviewer/vsgviewer.cpp index c158261f..55b6cebd 100644 --- a/examples/app/vsgviewer/vsgviewer.cpp +++ b/examples/app/vsgviewer/vsgviewer.cpp @@ -118,7 +118,11 @@ int main(int argc, char** argv) if (arguments.read({"--gpu-annotation", "--ga"}) && vsg::isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { windowTraits->debugUtils = true; - instrumentation = vsg::GpuAnnotation::create(); + + auto gpu_instrumentation = vsg::GpuAnnotation::create(); + if (arguments.read("--func")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; + + instrumentation = gpu_instrumentation; } diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 65ba657b..9cb54382 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -97,7 +97,7 @@ int main(int argc, char** argv) arguments.read(options); auto windowTraits = vsg::WindowTraits::create(); - windowTraits->windowTitle = "vsgviewer"; + windowTraits->windowTitle = "vsgtracyinstrumentation"; windowTraits->debugLayer = arguments.read({"--debug", "-d"}); windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); windowTraits->synchronizationLayer = arguments.read("--sync"); From 16b21c161a8ef7d13c42f7aed6b5e15f6ebe9a3d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2023 16:26:51 +0000 Subject: [PATCH 09/14] Added TracyInstrumentation and GpuAnnoation support to vsgshadow --- examples/nodes/vsgshadow/CMakeLists.txt | 5 +++++ examples/nodes/vsgshadow/vsgshadow.cpp | 26 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/examples/nodes/vsgshadow/CMakeLists.txt b/examples/nodes/vsgshadow/CMakeLists.txt index be8ecf92..8314b41b 100644 --- a/examples/nodes/vsgshadow/CMakeLists.txt +++ b/examples/nodes/vsgshadow/CMakeLists.txt @@ -11,4 +11,9 @@ if (vsgXchange_FOUND) target_link_libraries(vsgshadow vsgXchange::vsgXchange) endif() +if (Tracy_FOUND) + target_compile_definitions(vsgshadow PRIVATE Tracy_FOUND) + target_link_libraries(vsgshadow Tracy::TracyClient) +endif() + install(TARGETS vsgshadow RUNTIME DESTINATION bin) diff --git a/examples/nodes/vsgshadow/vsgshadow.cpp b/examples/nodes/vsgshadow/vsgshadow.cpp index 2c837992..e676ead5 100644 --- a/examples/nodes/vsgshadow/vsgshadow.cpp +++ b/examples/nodes/vsgshadow/vsgshadow.cpp @@ -4,6 +4,10 @@ # include #endif +#ifdef Tracy_FOUND +# include +#endif + #include struct ModelSettings @@ -210,6 +214,26 @@ int main(int argc, char** argv) windowTraits->decoration = false; } + vsg::ref_ptr instrumentation; + if (arguments.read({"--gpu-annotation", "--ga"}) && vsg::isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) + { + windowTraits->debugUtils = true; + + auto gpu_instrumentation = vsg::GpuAnnotation::create(); + if (arguments.read("--func")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; + + instrumentation = gpu_instrumentation; + } +#ifdef Tracy_FOUND + else if (arguments.read("--tracy")) + { + auto tracy_instrumentation = vsg::TracyInstrumentation::create(); + arguments.read("--cpu", tracy_instrumentation->settings->cpu_instumentation_level); + arguments.read("--gpu", tracy_instrumentation->settings->gpu_instumentation_level); + instrumentation = tracy_instrumentation; + } +#endif + double maxShadowDistance = arguments.value(1e8, "--sd"); double shadowMapBias = arguments.value(0.005, "--sb"); double lambda = arguments.value(0.5, "--lambda"); @@ -523,6 +547,8 @@ int main(int argc, char** argv) auto commandGraph = vsg::CommandGraph::create(window, renderGraph); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + if (instrumentation) viewer->assignInstrumentation(instrumentation); + viewer->compile(resourceHints); auto startTime = vsg::clock::now(); From cf7c261ae6e5fe0c28ae41236c4d57fe2edbe892 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2023 16:39:58 +0000 Subject: [PATCH 10/14] Added TracyInstrumentation and GpuAnnoation to vsgshadow --- examples/nodes/vsgshadow/vsgshadow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/nodes/vsgshadow/vsgshadow.cpp b/examples/nodes/vsgshadow/vsgshadow.cpp index e676ead5..f4bd4925 100644 --- a/examples/nodes/vsgshadow/vsgshadow.cpp +++ b/examples/nodes/vsgshadow/vsgshadow.cpp @@ -227,6 +227,8 @@ int main(int argc, char** argv) #ifdef Tracy_FOUND else if (arguments.read("--tracy")) { + windowTraits->deviceExtensionNames.push_back(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); + auto tracy_instrumentation = vsg::TracyInstrumentation::create(); arguments.read("--cpu", tracy_instrumentation->settings->cpu_instumentation_level); arguments.read("--gpu", tracy_instrumentation->settings->gpu_instumentation_level); From cc8444cd8cf18407bc428dbac0950f236fd01874 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 4 Jan 2024 14:28:04 +0000 Subject: [PATCH 11/14] Bumped version to 1.1.1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac6f67da..ad7b2261 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7) project(vsgExamples - VERSION 1.1.0 + VERSION 1.1.1 DESCRIPTION "Set of example programs that test and illustrate how to use the VulkanSceneGraph" LANGUAGES CXX C ) @@ -21,7 +21,7 @@ if (VULKAN_SDK) set(ENV{VULKAN_SDK} ${VULKAN_SDK}) endif() -find_package(vsg 1.1.0) +find_package(vsg 1.1.1) vsg_setup_dir_vars() vsg_setup_build_vars() From 212308f149add05a3076adb5e855e4baa8719784 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 5 Jan 2024 19:06:51 +0000 Subject: [PATCH 12/14] Added --calibrated command line parameter and setup of required extension. --- .../vsgtracyinstrumentation.cpp | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 9cb54382..4566c43b 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -137,11 +137,15 @@ int main(int argc, char** argv) auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; + // set whether calibrated timestamp extension should be enabled. + bool calibrated = arguments.read("--calibrated"); + // set TracyInstrumentation options auto instrumentation = vsg::TracyInstrumentation::create(); arguments.read("--cpu", instrumentation->settings->cpu_instumentation_level); arguments.read("--gpu", instrumentation->settings->gpu_instumentation_level); + if (arguments.read({"--shader-debug-info", "--sdi"})) { enableGenerateDebugInfo(options); @@ -155,10 +159,21 @@ int main(int argc, char** argv) bool assignInstrumentationBeforeMainLoop = arguments.read("--always"); #endif + auto window = vsg::Window::create(windowTraits); + if (!window) + { + std::cout << "Could not create window." << std::endl; + return 1; + } - // TODO: need to check for VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME support? - // enable calibrated timestamps. - windowTraits->deviceExtensionNames.push_back(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); + if (calibrated) + { + auto physicalDevice = window->getOrCreatePhysicalDevice(); + if (physicalDevice->supportsDeviceExtension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME)) + { + windowTraits->deviceExtensionNames.push_back(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); + } + } if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); @@ -219,13 +234,6 @@ int main(int argc, char** argv) // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); - auto window = vsg::Window::create(windowTraits); - if (!window) - { - std::cout << "Could not create window." << std::endl; - return 1; - } - viewer->addWindow(window); // compute the bounds of the scene graph to help position camera From 5a7e25a644f9e8b4fcbb6c85c57c1345cd86da9e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 8 Jan 2024 14:10:04 +0000 Subject: [PATCH 13/14] Added support for vsg::InstrumentationNode --- examples/app/vsgviewer/vsgviewer.cpp | 3 +- .../vsgtracyinstrumentation.cpp | 36 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/examples/app/vsgviewer/vsgviewer.cpp b/examples/app/vsgviewer/vsgviewer.cpp index fb47149b..7aa92bb8 100644 --- a/examples/app/vsgviewer/vsgviewer.cpp +++ b/examples/app/vsgviewer/vsgviewer.cpp @@ -124,7 +124,8 @@ int main(int argc, char** argv) windowTraits->debugUtils = true; auto gpu_instrumentation = vsg::GpuAnnotation::create(); - if (arguments.read("--func")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; + if (arguments.read("--className")) gpu_instrumentation->labelType = vsg::GpuAnnotation::Object_className; + else if (arguments.read("--func")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; instrumentation = gpu_instrumentation; } diff --git a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp index 4566c43b..54b8abfc 100644 --- a/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp +++ b/examples/utils/vsgtracyinstrumentation/vsgtracyinstrumentation.cpp @@ -74,7 +74,16 @@ class InstrumentationHandler : public vsg::Inherit decorateWithInstrumentationNode(vsg::ref_ptr node, const std::string& name, vsg::uint_color color) +{ + auto instrumentationNode = vsg::InstrumentationNode::create(node); + instrumentationNode->setName(name); + instrumentationNode->setColor(color); + + vsg::info("decorateWithInstrumentationNode(", node, ", ", name, ", {", int(color.r), ", ", int(color.g), ", ", int(color.b), ", ", int(color.a), "})"); + return instrumentationNode; +} int main(int argc, char** argv) { @@ -133,12 +142,14 @@ int main(int argc, char** argv) arguments.read("--samples", windowTraits->samples); auto numFrames = arguments.value(-1, "-f"); auto pathFilename = arguments.value("", "-p"); + auto outputFilename = arguments.value("", "-o"); auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; // set whether calibrated timestamp extension should be enabled. bool calibrated = arguments.read("--calibrated"); + bool decorate = arguments.read("--decorate"); // set TracyInstrumentation options auto instrumentation = vsg::TracyInstrumentation::create(); @@ -202,13 +213,27 @@ int main(int argc, char** argv) auto object = vsg::read(filename, options); if (auto node = object.cast()) { - group->addChild(node); + if (decorate) + { + group->addChild(decorateWithInstrumentationNode(node, filename.string(), vsg::uint_color(255, 255, 64, 255))); + } + else + { + group->addChild(node); + } } else if (auto data = object.cast()) { if (auto textureGeometry = createTextureQuad(data, options)) { - group->addChild(textureGeometry); + if (decorate) + { + group->addChild(decorateWithInstrumentationNode(textureGeometry, filename.string(), vsg::uint_color(255, 255, 64, 255))); + } + else + { + group->addChild(textureGeometry); + } } } else if (object) @@ -232,6 +257,13 @@ int main(int argc, char** argv) else vsg_scene = group; + + if (outputFilename) + { + vsg::write(vsg_scene, outputFilename, options); + return 1; + } + // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); viewer->addWindow(window); From 6fc5f87c3e143cfc47c00d7b9497321228b3cc16 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 8 Jan 2024 14:26:33 +0000 Subject: [PATCH 14/14] Added test of vsg::InstrumentationNode --- examples/app/vsgviewer/vsgviewer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/app/vsgviewer/vsgviewer.cpp b/examples/app/vsgviewer/vsgviewer.cpp index 7aa92bb8..e4c660d8 100644 --- a/examples/app/vsgviewer/vsgviewer.cpp +++ b/examples/app/vsgviewer/vsgviewer.cpp @@ -124,7 +124,8 @@ int main(int argc, char** argv) windowTraits->debugUtils = true; auto gpu_instrumentation = vsg::GpuAnnotation::create(); - if (arguments.read("--className")) gpu_instrumentation->labelType = vsg::GpuAnnotation::Object_className; + if (arguments.read("--name")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_name; + else if (arguments.read("--className")) gpu_instrumentation->labelType = vsg::GpuAnnotation::Object_className; else if (arguments.read("--func")) gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; instrumentation = gpu_instrumentation;