Clangd not working correctly with emacs+eglot

Hello everyone,

I am new to clangd but not new to language servers. I experimented lsp using emacs with the backends such as cquery and ccls. This time I tried clangd. However, after setup following your documentation Getting started it does not work as the documentation described.

I tried both lsp and eglot, but there are some issues.

I am using emacs in Ubuntu, which is a Windows Subsystem for Linux. I installed clangd-10 using the package management system, apt. After the eglot is enabled, there is no diagnostics and fixes. Finding definitions and hover information does not behave correctly.

I was experimenting with one simple cpp code file. For example, I defined an int variable x. I wrote another line of code which assigns a string literal to the variable x. There is no diagnostics and if I invoke x-ref-find-definitions on x in this line there is a message “No definitions found for: LSP identifier at point.” in the mini buffer. Finally the hover information does not show up as well.

Could I get any help about this here?

Did you also follow the instructions for setting up a project? Getting started What does your compile_commands.json look like?

Actually I was doing experiment using a single cpp file. So I did not have a compile_commands.json at first. After you mentioned that, I tried use CMake to generate one.

Here is my compile_commands.json

[
{
  "directory": "/home/drcxd/test_proj/build",
  "command": "/usr/bin/c++      -o CMakeFiles/Tutorial.dir/test.cpp.o -c /home/drcxd/test_proj/test.cpp",
  "file": "/home/drcxd/test_proj/test.cpp"
}
]

This is my source code, could you try this in your environment and tell me if it works correctly?

#include <vector>
#include <string>

int main() {
    int i = 0;

    i = 1;
    i = "string";

    return void;

}

Just try to jump to definition on the second assignment of i.

I’m not an emacs person, so can’t help you with why the diagnostics aren’t showing up. It sounds to me like things are working apart from that though.

As of clangd-10 this is expected behaviour: after emitting an error (wrong type) we don’t “recover” so the whole line is discarded from the AST and operations like hover, go-to-definition, find-refs won’t work.

Clangd 11 (due in August or so) will have a fix for this called “recovery AST”. You can try it out by using a recent snapshot of clangd and passing -recovery-ast.

(Do cquery and ccls really handle this case? Maybe they’re using heuristics, I don’t know how you can handle this correctly without hooking into the guts of clang, which we only added recently)

While, actually ccls could not handle this correctly in this case. But if I define a variable of type std::string and assign a integer to it, ccls could find the correct definition. Well, clangd could also handle this case correctly.

That’s (surprisingly) valid code: it converts the integer to a char and calls the operator= overload which sets the string to a single char. So that’s why it’s different.

Well, then I guess it is working correctly. Although emacs does not show the diagnostics, the server actually knows where the error is. I just have to invoke a command to manually find that error.

But for some larger project, like DOOM-3, I found that clangd has some problem parsing the template classes. ccls could find the definition but could not show the hover info. What is more strange is, the server could find definition of a symbol but it still report an syntax error on it. These things are too complicated for me. I almost going to give up using these language servers with emacs…

This part is definitely not working correctly! Errors should be marked inline somehow, with details when you place the point there. I just don’t know enough about emacs/eglot to know the details, others might (or could ask an eglot support channel)

Are you on windows by any chance? We’re fixed some windows template problems recently. But it’ll be easier to understand what’s going on once diagnostics are shown.

Yes, I am on windows. But I am using emacs and all these things in Windows Subsystem for Linux(WSL). So you can consider it as a Linux environment? Well, by manually checking the errors prompted by the language server, I could not find anything useful. All it said were something like you can’t assign a variable of one type to one of another type.

Do you know any video/blog having an successful example using clangd/ccls with emacs on a reasonably complicated project? I saw many people in some forums said they could use those things. However, I have been trying to set these up for about two years and I never succeeded. I also never saw anyone gives instruction or example of using lsp on a real c++ project.

For me, it is really difficult to use these tools.

This is an old thread, and I’m not sure whether I should open a new one, but I’m also having problems with emacs and clangd together with eglot so I thought I’d start here.

As a learning experience I wanted to launch clangd through the emacs package eglot on the following repo from github:

I followed the repo installation instructions, and successfully compiled it on my Fedora box with cmake and ninja. This is a moderately sized repo with about 10 external dependencies and ninja reports a total of 536 files. After successful compilation, without any additional flags for LSP I tried eglot as follows:

  1. Load (as an example) the file Chapter4/VK01_DemoApp/src/main.cpp
  2. Start eglot

eglot then started and launched clangd as expected by the configuration. However, eglot started in an unusable state with lots of marked errors. Examining the “EGLOT events” showed lots of errors. Here are few selected lines from the *EGLOT (3D-Graphics-Rendering-Cookbook/c++-mode) events* buffer:

[stderr] I[21:46:22.672] Loaded compilation database from /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build/compile_commands.json
[stderr] I[21:46:22.672] Enqueueing 99 commands for indexing
:
           [(:code "pp_file_not_found" :message "'imgui/imgui.h' file not found" :range
                   (:end
                    (:character 24 :line 3)
                    :start
                    (:character 9 :line 3))
                   :severity 1 :source "clang")
            (:code "unknown_typename_suggest" :message "Unknown type name 'VulkanInstance'; did you mean 'VkInstance'? (fix available)\n\n:100:18:\nnote: 'VkInstance' declared here" :range
                   (:end
                    (:character 14 :line 42)
                    :start
                    (:character 0 :line 42))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'VulkanRenderDevice'" :range
                   (:end
                    (:character 18 :line 43)
                    :start
                    (:character 0 :line 43))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'ImGuiRenderer'" :range
                   (:end
                    (:character 29 :line 45)
                    :start
                    (:character 16 :line 45))
                   :severity 1 :source "clang")
:
            (:code "fatal_too_many_errors" :message "Too many errors emitted, stopping now" :range
                   (:end
                    (:character 0 :line 0)
                    :start
                    (:character 0 :line 0))

Some of the missing symbols are in the “missing files”, but there are also lots of symbols from other include files that are not found, but don’t have any “missing file” error.

So my questions are:

  • What can I do to make clangd find the missing include files? I unsuccesfully tried adding a .clangd in the top repo directory include file with the following contents:
CompileFlags: # Tweak the parse settings
  Add: 
    - "-I=/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/deps/src/"
  • Is the problem related to eglot and can someone using a different front end see if they can get a working clangd LSP for this repo?

Thanks in advance and if this is not the right forum, please let me know if you have a better suggestion.

Hi @dov, I’d guess your build system isn’t producing compile_commands.json so we don’t have the right set of flags to parse the file. This is generally much easier than trying to piece together the right -I flags by hand.

CMake can produce this, take a look at Getting started

Hi @sam-mccall . Thanks for answering. Actually it does, if I’m not mistaken ninja creates compile_commands.json by default. In any case, after compilation, I do get a compile_commands.json file in my build directory, and you can also see that from the first line of the *EGLOT... buffer that I included in my previous message.

But indeed in compile_commands.json there are no references to the dependent header files, nor any include paths. (Does compile_command.json support include paths?) How do I add include paths to clangd?

Oops, sorry for missing that line indeed.

compile_commands.json should include full compile flags, including any -I flags needed to find the headers you’re depending on. clangd should be able to understand them if standard clang can compile your code with those flags. Generally clang does a good job of emulating gcc, so flags that work with standard gcc should also work.

If the headers are still not found it could be:

  • the headers are under a path that your compiler is searching by default but clangd (which uses clang’s driver) is not. --query-driver or adding -I flags manually can help.
  • the compile_commands.json is incomplete for some build-system related reason

How do I add include paths to clangd?

You had this almost right above, but there’s no = in the flag, so you were adding a path “=/terra/space/…” instead of “/terra/space/…”.

Did you run

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .

?

Thanks for the suggestions.

I added an additional include path to my CMakeLists.txt and was then able to get around the include problem. I still don’t understand why g++ found the path to #include <imgui/imgui.h> when the search path (at least according to compile_commands.h) only pointed to src/imgui, i.e. one directory “too deep”.

But now I’m passed that, but instead get lots of other errors:

[stderr] /usr/bin/c++ --driver-mode=g++ -DENABLE_OPT=0 -DGLSLANG_OSINCLUDE_UNIX -I/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build/include -g -fPIC -Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions -Wno-reorder -fno-rtti -Werror=deprecated-copy -Winvalid-pch -include /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build/deps/src/glslang/glslang/CMakeFiles/MachineIndependent.dir/cmake_pch.hxx -c -x c-header -std=c++11 -I/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/deps/src/ -resource-dir=/usr/lib64/clang/14.0.0 -- /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/shared/Utils.h
[stderr] I[22:45:46.841] --> textDocument/publishDiagnostics
[server-notification] Wed Oct  5 22:45:46 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
          (:diagnostics
           [(:code "drv_argument_not_allowed_with" :message "Invalid argument '-std=c++11' not allowed with 'C'" :range
                   (:end
                    (:character 0 :line 0)
                    :start
                    (:character 0 :line 0))
                   :severity 1 :source "clang")
            (:code "pp_file_not_found" :message "'algorithm' file not found" :range
                   (:end
                    (:character 20 :line 8)
                    :start
                    (:character 9 :line 8))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'std'" :range
                   (:end
                    (:character 3 :line 14)
                    :start
                    (:character 0 :line 14))
                   :severity 1 :source "clang")

What happened? How did I suddenly move from C++ to C? Perhaps I should try compiling the project with clang++ instead of g++, but I would expect both to work.

Let me try this again:

rm CMakeCache.txt
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .
make

Then the json file should faithfully reflect how your project was build.

Are you able to provide the clangd logs? The snippets marked with [stderr] don’t have enough information to diagnose the problem.

My guess: you’re editing a header file, compile_commands.json doesn’t have commands to parse the header file (this is typical) so it’s being inferred based on the commands for one of the other files, and a C file is being chosen for some reason (this is not typical).

Ok, thanks. @tschuett I tried rebuilding everything. But I still get the same C++ vs C error.

@sam-mccall, I added the following arguments to clang: -j 1 --log=verbose and I’m including the entire contents from the communication between emacs (eglot) and clangd. I hope this is what you meant by clangd logs. If not, please let me know how to produce them.

I’m including the entire file inline as I as a new user don’t have enough privilege to upload files:

[internal] Wed Oct  5 23:20:01 2022:
(:message "Running language server: (clangd -j 1 --log=verbose)")
[client-request] (id:1) Wed Oct  5 23:20:01 2022:
(:jsonrpc "2.0" :id 1 :method "initialize" :params
          (:processId 16719 :rootPath "/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/" :rootUri "file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
                                                                                                                                                                                                                                            ())
                      :capabilities
                      (:workspace
                       (:applyEdit t :executeCommand
                                   (:dynamicRegistration :json-false)
                                   :workspaceEdit
                                   (:documentChanges t)
                                   :didChangeWatchedFiles
                                   (:dynamicRegistration t)
                                   :symbol
                                   (:dynamicRegistration :json-false)
                                   :configuration t :workspaceFolders t)
                       :textDocument
                       (:synchronization
                        (:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
                        :completion
                        (:dynamicRegistration :json-false :completionItem
                                              (:snippetSupport :json-false :deprecatedSupport t :tagSupport
                                                               (:valueSet
                                                                [1]))
                                              :contextSupport t)
                        :hover
                        (:dynamicRegistration :json-false :contentFormat
                                              ["markdown" "plaintext"])
                        :signatureHelp
                        (:dynamicRegistration :json-false :signatureInformation
                                              (:parameterInformation
                                               (:labelOffsetSupport t)
                                               :activeParameterSupport t))
                        :references
                        (:dynamicRegistration :json-false)
                        :definition
                        (:dynamicRegistration :json-false :linkSupport t)
                        :declaration
                        (:dynamicRegistration :json-false :linkSupport t)
                        :implementation
                        (:dynamicRegistration :json-false :linkSupport t)
                        :typeDefinition
                        (:dynamicRegistration :json-false :linkSupport t)
                        :documentSymbol
                        (:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind
                                              (:valueSet
                                               [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))
                        :documentHighlight
                        (:dynamicRegistration :json-false)
                        :codeAction
                        (:dynamicRegistration :json-false :codeActionLiteralSupport
                                              (:codeActionKind
                                               (:valueSet
                                                ["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"]))
                                              :isPreferredSupport t)
                        :formatting
                        (:dynamicRegistration :json-false)
                        :rangeFormatting
                        (:dynamicRegistration :json-false)
                        :rename
                        (:dynamicRegistration :json-false)
                        :publishDiagnostics
                        (:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport
                                             (:valueSet
                                              [1 2])))
                       :experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
                                                   ()))
                      :workspaceFolders
                      [(:uri "file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook" :name "/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/")]))
[stderr] I[23:20:01.239] clangd version 14.0.0 (Fedora 14.0.0-1.fc36)
[stderr] I[23:20:01.239] Features: linux
[stderr] I[23:20:01.239] PID: 17184
[stderr] I[23:20:01.239] Working directory: /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook
[stderr] I[23:20:01.239] argv[0]: /usr/bin/clangd
[stderr] I[23:20:01.239] argv[1]: -j
[stderr] I[23:20:01.239] argv[2]: 1
[stderr] I[23:20:01.239] argv[3]: --log=verbose
[stderr] V[23:20:01.239] User config file is /home/dov/.config/clangd/config.yaml
[stderr] I[23:20:01.239] Starting LSP over stdin/stdout
[server-reply] (id:1) Wed Oct  5 23:20:01 2022:
(:id 1 :jsonrpc "2.0" :result
     (:capabilities
      (:astProvider t :callHierarchyProvider t :clangdInlayHintsProvider t :codeActionProvider
                    (:codeActionKinds
                     ["quickfix" "refactor" "info"])
                    :compilationDatabase
                    (:automaticReload t)
                    :completionProvider
                    (:allCommitCharacters
                     [" " "	" "(" ")" "[" "]" "{" "}" "<" ">" ":" ";" "," "+" "-" "/" "*" "%" "^" "&" "#" "?" "." "=" "\"" "'" "|"]
                     :resolveProvider :json-false :triggerCharacters
                     ["." "<" ">" ":" "\"" "/" "*"])
                    :declarationProvider t :definitionProvider t :documentFormattingProvider t :documentHighlightProvider t :documentLinkProvider
                    (:resolveProvider :json-false)
                    :documentOnTypeFormattingProvider
                    (:firstTriggerCharacter "\n" :moreTriggerCharacter
                                            [])
                    :documentRangeFormattingProvider t :documentSymbolProvider t :executeCommandProvider
                    (:commands
                     ["clangd.applyFix" "clangd.applyTweak"])
                    :hoverProvider t :implementationProvider t :memoryUsageProvider t :referencesProvider t :renameProvider t :selectionRangeProvider t :semanticTokensProvider
                    (:full
                     (:delta t)
                     :legend
                     (:tokenModifiers
                      ["declaration" "deprecated" "deduced" "readonly" "static" "abstract" "virtual" "dependentName" "defaultLibrary" "usedAsMutableReference" "functionScope" "classScope" "fileScope" "globalScope"]
                      :tokenTypes
                      ["variable" "variable" "parameter" "function" "method" "function" "property" "variable" "class" "interface" "enum" "enumMember" "type" "type" "unknown" "namespace" "typeParameter" "concept" "type" "macro" "comment"])
                     :range :json-false)
                    :signatureHelpProvider
                    (:triggerCharacters
                     ["(" ")" "{" "}" "<" ">" ","])
                    :textDocumentSync
                    (:change 2 :openClose t :save t)
                    :typeDefinitionProvider t :typeHierarchyProvider t :workspaceSymbolProvider t)
      :serverInfo
      (:name "clangd" :version "clangd version 14.0.0 (Fedora 14.0.0-1.fc36) linux x86_64-unknown-linux-gnu; target=x86_64-redhat-linux-gnu")))
[client-notification] Wed Oct  5 23:20:01 2022:
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
                                                            ()))
[client-notification] Wed Oct  5 23:20:01 2022:
(:jsonrpc "2.0" :method "textDocument/didOpen" :params
          (:textDocument
           (:uri "file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp" :version 0 :languageId "c++" :text "#define VK_NO_PROTOTYPES\n#define GLFW_INCLUDE_VULKAN\n#include <GLFW/glfw3.h>\n#include <imgui/imgui.h>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <chrono>\n#include <deque>\n#include <memory>\n#include <limits>\n#include <string>\n\n#include \"shared/Utils.h\"\n#include \"shared/UtilsMath.h\"\n#include \"shared/UtilsFPS.h\"\n#include \"shared/UtilsVulkan.h\"\n#include \"shared/vkRenderers/VulkanCanvas.h\"\n#include \"shared/vkRenderers/VulkanCube.h\"\n#include \"shared/vkRenderers/VulkanImGui.h\"\n#include \"shared/vkRenderers/VulkanClear.h\"\n#include \"shared/vkRenderers/VulkanFinish.h\"\n#include \"shared/vkRenderers/VulkanModelRenderer.h\"\n#include \"shared/Camera.h\"\n#include \"shared/SGI_Trackball.h\"\n#include \"shared/EasyProfilerWrapper.h\"\n#include \"shared/Graph.h\"\n\n#include <glm/glm.hpp>\n#include <glm/ext.hpp>\nusing glm::mat4;\nusing glm::vec3;\nusing glm::vec4;\n\nconst uint32_t kScreenWidth = 1280;\nconst uint32_t kScreenHeight = 720;\n\nconstexpr float DEG_2_RAD=float(M_PI / 180.0);\nconstexpr float RAD_2_DEG=float(180.0 / M_PI);\n\nGLFWwindow* window;\n\nVulkanInstance vk;\nVulkanRenderDevice vkDev;\n\nstd::unique_ptr<ImGuiRenderer> imgui;\nstd::unique_ptr<ModelRenderer> modelRenderer;\nstd::unique_ptr<CubeRenderer> cubeRenderer;\nstd::unique_ptr<VulkanCanvas> canvas;\nstd::unique_ptr<VulkanCanvas> canvas2d;\nstd::unique_ptr<VulkanClear> clear;\nstd::unique_ptr<VulkanFinish> finish;\n\nFramesPerSecondCounter fpsCounter(0.02f);\nLinearGraph fpsGraph;\nLinearGraph sineGraph(4096);\n\nstruct MouseState\n{\n	glm::vec2 pos = glm::vec2(0.0f);\n	bool pressedLeft = false;\n} mouseState;\n\nglm::vec3 cameraPos(0.0f, 0.0f, 0.0f);\nglm::vec3 cameraAngles(-45.0f, 0.0f, 0.0f);\n\nCameraPositioner_FirstPerson positioner_firstPerson(cameraPos, vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 1.0f, 0.0f));\nCameraPositioner_MoveTo      positioner_moveTo(cameraPos, cameraAngles);\nCameraPositioner_Trackball positioner_trackball((int)kScreenWidth, (int)kScreenHeight);\nCamera camera = Camera(positioner_firstPerson);\n\n// ImGUI stuff\nconst char* cameraType = \"FirstPerson\";\nconst char* comboBoxItems[] = { \"FirstPerson\", \"MoveTo\", \"Trackball\" };\nconst char* currentComboBoxItem = cameraType;\n\nbool initVulkan()\n{\n	EASY_FUNCTION();\n\n	createInstance(&vk.instance);\n\n	if (!setupDebugCallbacks(vk.instance, &vk.messenger, &vk.reportCallback))\n		exit(EXIT_FAILURE);\n\n	if (glfwCreateWindowSurface(vk.instance, window, nullptr, &vk.surface))\n		exit(EXIT_FAILURE);\n\n	if (!initVulkanRenderDevice(vk, vkDev, kScreenWidth, kScreenHeight, isDeviceSuitable, { .geometryShader = VK_TRUE }))\n		exit(EXIT_FAILURE);\n\n  // Build all the renderers\n	imgui = std::make_unique<ImGuiRenderer>(vkDev);\n	modelRenderer = std::make_unique<ModelRenderer>(vkDev, \"data/rubber_duck/scene.gltf\", \"data/ch2_sample3_STB.jpg\", (uint32_t)sizeof(glm::mat4));\n	cubeRenderer = std::make_unique<CubeRenderer>(vkDev, modelRenderer->getDepthTexture(), \"data/piazza_bologni_1k.hdr\");\n	clear = std::make_unique<VulkanClear>(vkDev, modelRenderer->getDepthTexture());\n	finish = std::make_unique<VulkanFinish>(vkDev, modelRenderer->getDepthTexture());\n	canvas2d = std::make_unique<VulkanCanvas>(vkDev, VulkanImage{ .image = VK_NULL_HANDLE, .imageView = VK_NULL_HANDLE });\n	canvas = std::make_unique<VulkanCanvas>(vkDev, modelRenderer->getDepthTexture());\n\n	return true;\n}\n\nvoid terminateVulkan()\n{\n	canvas = nullptr;\n	canvas2d = nullptr;\n	finish = nullptr;\n	clear = nullptr;\n	cubeRenderer = nullptr;\n	modelRenderer = nullptr;\n	imgui = nullptr;\n	destroyVulkanRenderDevice(vkDev);\n	destroyVulkanInstance(vk);\n}\n\nvoid reinitCamera()\n{\n	if (!strcmp(cameraType, \"FirstPerson\"))\n	{\n		camera = Camera(positioner_firstPerson);\n	}\n	else if (!strcmp(cameraType, \"MoveTo\"))\n  {\n    positioner_moveTo.setDesiredPosition(cameraPos);\n    positioner_moveTo.setDesiredAngles(cameraAngles.x, cameraAngles.y, cameraAngles.z);\n    camera = Camera(positioner_moveTo);\n	}\n  else if ((std::string)cameraType == \"Trackball\")\n    camera = Camera(positioner_trackball);\n}\n\nvoid renderGUI(uint32_t imageIndex)\n{\n	EASY_FUNCTION();\n\n	int width, height;\n	glfwGetFramebufferSize(window, &width, &height);\n\n	ImGuiIO& io = ImGui::GetIO();\n	io.DisplaySize = ImVec2((float)width, (float)height);\n	ImGui::NewFrame();\n\n	const ImGuiWindowFlags flags =\n		ImGuiWindowFlags_NoTitleBar |\n		ImGuiWindowFlags_NoResize |\n		ImGuiWindowFlags_NoMove |\n		ImGuiWindowFlags_NoScrollbar |\n		ImGuiWindowFlags_NoSavedSettings |\n		ImGuiWindowFlags_NoInputs |\n		ImGuiWindowFlags_NoBackground;\n\n	ImGui::SetNextWindowPos(ImVec2(0, 0));\n	ImGui::Begin(\"Statistics\", nullptr, flags);\n	ImGui::Text(\"FPS: %.2f\", fpsCounter.getFPS());\n	ImGui::End();\n\n	ImGui::Begin(\"Camera Control\", nullptr);\n	{\n		if (ImGui::BeginCombo(\"##combo\", currentComboBoxItem)) // The second parameter is the label previewed before opening the combo.\n		{\n			for (int n = 0; n < IM_ARRAYSIZE(comboBoxItems); n++)\n			{\n				const bool isSelected = (currentComboBoxItem == comboBoxItems[n]);\n\n				if (ImGui::Selectable(comboBoxItems[n], isSelected))\n					currentComboBoxItem = comboBoxItems[n];\n\n				if (isSelected) {\n					ImGui::SetItemDefaultFocus();   // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support)\n        }\n			}\n			ImGui::EndCombo();\n		}\n\n		if (!strcmp(cameraType, \"MoveTo\"))\n		{\n			if (ImGui::SliderFloat3(\"Position\", glm::value_ptr(cameraPos), -10.0f, +10.0f))\n				positioner_moveTo.setDesiredPosition(cameraPos);\n			if (ImGui::SliderFloat3(\"Pitch/Pan/Roll\", glm::value_ptr(cameraAngles), -90.0f, +90.0f))\n				positioner_moveTo.setDesiredAngles(cameraAngles);\n		}\n\n		if (currentComboBoxItem && strcmp(currentComboBoxItem, cameraType))\n		{\n			printf(\"Selected new camera type: %s\\n\", currentComboBoxItem);\n			cameraType = currentComboBoxItem;\n			reinitCamera();\n		}\n	}\n	ImGui::End();\n	ImGui::Render();\n\n	imgui->updateBuffers(vkDev, imageIndex, ImGui::GetDrawData());\n}\n\n// Build the uniforms with the model view matrices.\nvoid update3D(uint32_t imageIndex)\n{\n	int width, height;\n	glfwGetFramebufferSize(window, &width, &height);\n	const float ratio = width / (float)height;\n\n	const mat4 m1 = \n    glm::rotate(glm::translate(mat4(1.0f), vec3(0.f, 0.5f, -1.5f))\n                * glm::rotate(mat4(1.f), glm::pi<float>(), vec3(1, 0, 0)),\n                (float)glfwGetTime(),\n                vec3(0.0f, 1.0f, 0.0f));\n	mat4 view = camera.getViewMatrix();\n\n	const mat4 p = glm::perspective(45.0f, ratio, 0.1f, 1000.0f);\n\n	const mat4 mtx = p * view * m1;\n\n	{\n		EASY_BLOCK(\"UpdateUniformBuffers\");\n		modelRenderer->updateUniformBuffer(vkDev, imageIndex, glm::value_ptr(mtx), sizeof(mat4));\n		canvas->updateUniformBuffer(vkDev, p * view, 0.0f, imageIndex);\n		canvas2d->updateUniformBuffer(vkDev, glm::ortho(0, 1, 1, 0), 0.0f, imageIndex);\n		cubeRenderer->updateUniformBuffer(vkDev, imageIndex, p * view * m1);\n		EASY_END_BLOCK;\n	}\n}\n\nvoid update2D(uint32_t imageIndex)\n{\n	canvas2d->clear();\n	sineGraph.renderGraph(*canvas2d.get(), vec4(0.0f, 1.0f, 0.0f, 1.0f));\n	fpsGraph.renderGraph(*canvas2d.get());\n	canvas2d->updateBuffer(vkDev, imageIndex);\n}\n\n// Loop over all the renderers and have each one add its contents to the\n// command buffer.\nvoid composeFrame(uint32_t imageIndex, const std::vector<RendererBase*>& renderers)\n{\n	update3D(imageIndex);\n	renderGUI(imageIndex);\n	update2D(imageIndex);\n\n	EASY_BLOCK(\"FillCommandBuffers\");\n\n	VkCommandBuffer commandBuffer = vkDev.commandBuffers[imageIndex];\n\n	const VkCommandBufferBeginInfo bi =\n	{\n		.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,\n		.pNext = nullptr,\n		.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,\n		.pInheritanceInfo = nullptr\n	};\n\n	VK_CHECK(vkBeginCommandBuffer(commandBuffer, &bi));\n\n	for (auto& r : renderers)\n		r->fillCommandBuffer(commandBuffer, imageIndex);\n\n	VK_CHECK(vkEndCommandBuffer(commandBuffer));\n\n	EASY_END_BLOCK;\n}\n\nbool drawFrame(const std::vector<RendererBase*>& renderers)\n{\n	EASY_FUNCTION();\n\n	uint32_t imageIndex = 0;\n	VkResult result = vkAcquireNextImageKHR(vkDev.device, vkDev.swapchain, 0, vkDev.semaphore, VK_NULL_HANDLE, &imageIndex);\n	VK_CHECK(vkResetCommandPool(vkDev.device, vkDev.commandPool, 0));\n\n	if (result != VK_SUCCESS) return false;\n\n	composeFrame(imageIndex, renderers);\n\n	const VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // or even VERTEX_SHADER_STAGE\n\n	const VkSubmitInfo si =\n	{\n		.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,\n		.pNext = nullptr,\n		.waitSemaphoreCount = 1,\n		.pWaitSemaphores = &vkDev.semaphore,\n		.pWaitDstStageMask = waitStages,\n		.commandBufferCount = 1,\n		.pCommandBuffers = &vkDev.commandBuffers[imageIndex],\n		.signalSemaphoreCount = 1,\n		.pSignalSemaphores = &vkDev.renderSemaphore\n	};\n\n	{\n		EASY_BLOCK(\"vkQueueSubmit\", profiler::colors::Magenta);\n		VK_CHECK(vkQueueSubmit(vkDev.graphicsQueue, 1, &si, nullptr));\n		EASY_END_BLOCK;\n	}\n\n	const VkPresentInfoKHR pi =\n	{\n		.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,\n		.pNext = nullptr,\n		.waitSemaphoreCount = 1,\n		.pWaitSemaphores = &vkDev.renderSemaphore,\n		.swapchainCount = 1,\n		.pSwapchains = &vkDev.swapchain,\n		.pImageIndices = &imageIndex\n	};\n\n	{\n		EASY_BLOCK(\"vkQueuePresentKHR\", profiler::colors::Magenta);\n		VK_CHECK(vkQueuePresentKHR(vkDev.graphicsQueue, &pi));\n		EASY_END_BLOCK;\n	}\n\n	{\n		EASY_BLOCK(\"vkDeviceWaitIdle\", profiler::colors::Red);\n		VK_CHECK(vkDeviceWaitIdle(vkDev.device));\n		EASY_END_BLOCK;\n	}\n\n	return true;\n}\n\nint main()\n{\n	EASY_PROFILER_ENABLE;\n	EASY_MAIN_THREAD;\n\n	glslang_initialize_process();\n\n	volkInitialize();\n\n	if (!glfwInit())\n		exit(EXIT_FAILURE);\n\n	if (!glfwVulkanSupported())\n		exit(EXIT_FAILURE);\n\n	glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);\n	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);\n\n	ImGui::CreateContext();\n	ImGuiIO& io = ImGui::GetIO();\n\n	window = glfwCreateWindow(kScreenWidth, kScreenHeight, \"VulkanApp\", nullptr, nullptr);\n	if (!window)\n	{\n		glfwTerminate();\n		exit(EXIT_FAILURE);\n	}\n\n	glfwSetCursorPosCallback(\n		window,\n		[](auto* window, double x, double y)\n		{\n			ImGui::GetIO().MousePos = ImVec2((float)x, (float)y);\n      mouseState.pos = glm::vec2({(float)x,(float)y});\n		}\n	);\n\n	glfwSetMouseButtonCallback(\n		window,\n		[](auto* window, int button, int action, int mods)\n		{\n			auto& io = ImGui::GetIO();\n			const int idx = button == GLFW_MOUSE_BUTTON_LEFT ? 0 : button == GLFW_MOUSE_BUTTON_RIGHT ? 2 : 1;\n			io.MouseDown[idx] = action == GLFW_PRESS;\n\n			if (button == GLFW_MOUSE_BUTTON_LEFT)\n      {\n#if 0\n        if (!mouseState.pressedLeft)\n          trackballPos = mouseState.pos;\n#endif\n  \n				mouseState.pressedLeft = action == GLFW_PRESS;\n      }\n		}\n	);\n\n	glfwSetKeyCallback(\n		window,\n		[](GLFWwindow* window, int key, int scancode, int action, int mods)\n		{\n			const bool pressed = action != GLFW_RELEASE;\n			if (key == GLFW_KEY_ESCAPE && pressed)\n				glfwSetWindowShouldClose(window, GLFW_TRUE);\n			if (key == GLFW_KEY_W)\n				positioner_firstPerson.movement_.forward_ = pressed;\n			if (key == GLFW_KEY_S)\n				positioner_firstPerson.movement_.backward_ = pressed;\n			if (key == GLFW_KEY_A)\n				positioner_firstPerson.movement_.left_ = pressed;\n			if (key == GLFW_KEY_D)\n				positioner_firstPerson.movement_.right_ = pressed;\n			if (key == GLFW_KEY_SPACE)\n				positioner_firstPerson.setUpVector(vec3(0.0f, 1.0f, 0.0f));\n		}\n	);\n\n	initVulkan();\n\n	{\n		canvas->plane3d(vec3(0,+1.5,0), vec3(1,0,0), vec3(0,0,1), 40, 40, 10.0f, 10.0f, vec4(1,0,0,1), vec4(0,1,0,1));\n\n		for(size_t i = 0 ; i < vkDev.swapchainImages.size() ; i++)\n			canvas->updateBuffer(vkDev, i);\n	}\n\n	double timeStamp = glfwGetTime();\n	float deltaSeconds = 0.0f;\n\n  // List of all the renderers (in order?) for a single frame\n	const std::vector<RendererBase*> renderers = {\n    clear.get(),\n    //    cubeRenderer.get(),   // The \"inside cube\" renderer\n    modelRenderer.get(), \n    canvas.get(),\n    canvas2d.get(),  // What does this due?\n    imgui.get(), \n    finish.get()\n  };\n\n	while (!glfwWindowShouldClose(window))\n	{\n		{\n			EASY_BLOCK(\"UpdateCameraPositioners\");\n\n      // something is not dealt with correctly with the mouse state!\n      positioner_firstPerson.update(deltaSeconds, 0.0f*mouseState.pos, mouseState.pressedLeft);\n      positioner_moveTo.update(deltaSeconds, 0.0f*mouseState.pos, mouseState.pressedLeft);\n      // Only operate on the trackball if it is in use\n      if ((std::string)cameraType == \"Trackball\")\n        positioner_trackball.update(deltaSeconds, mouseState.pos, mouseState.pressedLeft);\n			EASY_END_BLOCK;\n		}\n\n		const double newTimeStamp = glfwGetTime();\n		deltaSeconds = static_cast<float>(newTimeStamp - timeStamp);\n		timeStamp = newTimeStamp;\n\n		const bool frameRendered = drawFrame(renderers);\n\n		if (fpsCounter.tick(deltaSeconds, frameRendered))\n		{\n			fpsGraph.addPoint(fpsCounter.getFPS());\n		}\n		sineGraph.addPoint((float)sin(glfwGetTime() * 10.0));\n\n		{\n			EASY_BLOCK(\"PollEvents\");\n			glfwPollEvents();\n			EASY_END_BLOCK;\n		}\n	}\n\n	ImGui::DestroyContext();\n\n	terminateVulkan();\n	glfwTerminate();\n	glslang_finalize_process();\n\n	PROFILER_DUMP(\"profiling.prof\");\n\n	return 0;\n}\n")))
[client-notification] Wed Oct  5 23:20:01 2022:
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params
          (:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
                                   ())))
[server-notification] Wed Oct  5 23:20:01 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
          (:diagnostics
           []
           :uri "file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.clangd"))
[stderr] V[23:20:01.239] <<< {"id":1,"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"experimental":{},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dynamicRegistration":false,"isPreferredSupport":true},"completion":{"completionItem":{"deprecatedSupport":true,"snippetSupport":false,"tagSupport":{"valueSet":[1]}},"contextSupport":true,"dynamicRegistration":false},"declaration":{"dynamicRegistration":false,"linkSupport":true},"definition":{"dynamicRegistration":false,"linkSupport":true},"documentHighlight":{"dynamicRegistration":false},"documentSymbol":{"dynamicRegistration":false,"hierarchicalDocumentSymbolSupport":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"formatting":{"dynamicRegistration":false},"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":false},"implementation":{"dynamicRegistration":false,"linkSupport":true},"publishDiagnostics":{"codeDescriptionSupport":false,"relatedInformation":false,"tagSupport":{"valueSet":[1,2]}},"rangeFormatting":{"dynamicRegistration":false},"references":{"dynamicRegistration":false},"rename":{"dynamicRegistration":false},"signatureHelp":{"dynamicRegistration":false,"signatureInformation":{"activeParameterSupport":true,"parameterInformation":{"labelOffsetSupport":true}}},"synchronization":{"didSave":true,"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":true},"typeDefinition":{"dynamicRegistration":false,"linkSupport":true}},"workspace":{"applyEdit":true,"configuration":true,"didChangeWatchedFiles":{"dynamicRegistration":true},"executeCommand":{"dynamicRegistration":false},"symbol":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true},"workspaceFolders":true}},"initializationOptions":{},"processId":16719,"rootPath":"/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/","rootUri":"file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook","workspaceFolders":[{"name":"/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/","uri":"file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook"}]}}
[stderr] 
[stderr] I[23:20:01.239] <-- initialize(1)
[stderr] I[23:20:01.240] --> reply:initialize(1) 0 ms
[stderr] I[23:20:01.240] --> reply:initialize(1) 0 ms
[stderr] V[23:20:01.240] >>> {"id":1,"jsonrpc":"2.0","result":{"capabilities":{"astProvider":true,"callHierarchyProvider":true,"clangdInlayHintsProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix","refactor","info"]},"compilationDatabase":{"automaticReload":true},"completionProvider":{"allCommitCharacters":[" ","\t","(",")","[","]","{","}","<",">",":",";",",","+","-","/","*","%","^","&","#","?",".","=","\"","'","|"],"resolveProvider":false,"triggerCharacters":[".","<",">",":","\"","/","*"]},"declarationProvider":true,"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentLinkProvider":{"resolveProvider":false},"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"\n","moreTriggerCharacter":[]},"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"executeCommandProvider":{"commands":["clangd.applyFix","clangd.applyTweak"]},"hoverProvider":true,"implementationProvider":true,"memoryUsageProvider":true,"referencesProvider":true,"renameProvider":true,"selectionRangeProvider":true,"semanticTokensProvider":{"full":{"delta":true},"legend":{"tokenModifiers":["declaration","deprecated","deduced","readonly","static","abstract","virtual","dependentName","defaultLibrary","usedAsMutableReference","functionScope","classScope","fileScope","globalScope"],"tokenTypes":["variable","variable","parameter","function","method","function","property","variable","class","interface","enum","enumMember","type","type","unknown","namespace","typeParameter","concept","type","macro","comment"]},"range":false},"signatureHelpProvider":{"triggerCharacters":["(",")","{","}","<",">",","]},"textDocumentSync":{"change":2,"openClose":true,"save":true},"typeDefinitionProvider":true,"typeHierarchyProvider":true,"workspaceSymbolProvider":true},"serverInfo":{"name":"clangd","version":"clangd version 14.0.0 (Fedora 14.0.0-1.fc36) linux x86_64-unknown-linux-gnu; target=x86_64-redhat-linux-gnu"}}}
[stderr] 
[stderr] V[23:20:01.241] <<< {"jsonrpc":"2.0","method":"initialized","params":{}}
[stderr] 
[stderr] I[23:20:01.241] <-- initialized
[stderr] I[23:20:01.241] <-- initialized
[stderr] nil
[stderr] nil
[stderr] V[23:20:01.243] <<< {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"c++","text":"#define VK_NO_PROTOTYPES\n#define GLFW_INCLUDE_VULKAN\n#include <GLFW/glfw3.h>\n#include <imgui/imgui.h>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <chrono>\n#include <deque>\n#include <memory>\n#include <limits>\n#include <string>\n\n#include \"shared/Utils.h\"\n#include \"shared/UtilsMath.h\"\n#include \"shared/UtilsFPS.h\"\n#include \"shared/UtilsVulkan.h\"\n#include \"shared/vkRenderers/VulkanCanvas.h\"\n#include \"shared/vkRenderers/VulkanCube.h\"\n#include \"shared/vkRenderers/VulkanImGui.h\"\n#include \"shared/vkRenderers/VulkanClear.h\"\n#include \"shared/vkRenderers/VulkanFinish.h\"\n#include \"shared/vkRenderers/VulkanModelRenderer.h\"\n#include \"shared/Camera.h\"\n#include \"shared/SGI_Trackball.h\"\n#include \"shared/EasyProfilerWrapper.h\"\n#include \"shared/Graph.h\"\n\n#include <glm/glm.hpp>\n#include <glm/ext.hpp>\nusing glm::mat4;\nusing glm::vec3;\nusing glm::vec4;\n\nconst uint32_t kScreenWidth = 1280;\nconst uint32_t kScreenHeight = 720;\n\nconstexpr float DEG_2_RAD=float(M_PI / 180.0);\nconstexpr float RAD_2_DEG=float(180.0 / M_PI);\n\nGLFWwindow* window;\n\nVulkanInstance vk;\nVulkanRenderDevice vkDev;\n\nstd::unique_ptr<ImGuiRenderer> imgui;\nstd::unique_ptr<ModelRenderer> modelRenderer;\nstd::unique_ptr<CubeRenderer> cubeRenderer;\nstd::unique_ptr<VulkanCanvas> canvas;\nstd::unique_ptr<VulkanCanvas> canvas2d;\nstd::unique_ptr<VulkanClear> clear;\nstd::unique_ptr<VulkanFinish> finish;\n\nFramesPerSecondCounter fpsCounter(0.02f);\nLinearGraph fpsGraph;\nLinearGraph sineGraph(4096);\n\nstruct MouseState\n{\n\tglm::vec2 pos = glm::vec2(0.0f);\n\tbool pressedLeft = false;\n} mouseState;\n\nglm::vec3 cameraPos(0.0f, 0.0f, 0.0f);\nglm::vec3 cameraAngles(-45.0f, 0.0f, 0.0f);\n\nCameraPositioner_FirstPerson positioner_firstPerson(cameraPos, vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 1.0f, 0.0f));\nCameraPositioner_MoveTo      positioner_moveTo(cameraPos, cameraAngles);\nCameraPositioner_Trackball positioner_trackball((int)kScreenWidth, (int)kScreenHeight);\nCamera camera = Camera(positioner_firstPerson);\n\n// ImGUI stuff\nconst char* cameraType = \"FirstPerson\";\nconst char* comboBoxItems[] = { \"FirstPerson\", \"MoveTo\", \"Trackball\" };\nconst char* currentComboBoxItem = cameraType;\n\nbool initVulkan()\n{\n\tEASY_FUNCTION();\n\n\tcreateInstance(&vk.instance);\n\n\tif (!setupDebugCallbacks(vk.instance, &vk.messenger, &vk.reportCallback))\n\t\texit(EXIT_FAILURE);\n\n\tif (glfwCreateWindowSurface(vk.instance, window, nullptr, &vk.surface))\n\t\texit(EXIT_FAILURE);\n\n\tif (!initVulkanRenderDevice(vk, vkDev, kScreenWidth, kScreenHeight, isDeviceSuitable, { .geometryShader = VK_TRUE }))\n\t\texit(EXIT_FAILURE);\n\n  // Build all the renderers\n\timgui = std::make_unique<ImGuiRenderer>(vkDev);\n\tmodelRenderer = std::make_unique<ModelRenderer>(vkDev, \"data/rubber_duck/scene.gltf\", \"data/ch2_sample3_STB.jpg\", (uint32_t)sizeof(glm::mat4));\n\tcubeRenderer = std::make_unique<CubeRenderer>(vkDev, modelRenderer->getDepthTexture(), \"data/piazza_bologni_1k.hdr\");\n\tclear = std::make_unique<VulkanClear>(vkDev, modelRenderer->getDepthTexture());\n\tfinish = std::make_unique<VulkanFinish>(vkDev, modelRenderer->getDepthTexture());\n\tcanvas2d = std::make_unique<VulkanCanvas>(vkDev, VulkanImage{ .image = VK_NULL_HANDLE, .imageView = VK_NULL_HANDLE });\n\tcanvas = std::make_unique<VulkanCanvas>(vkDev, modelRenderer->getDepthTexture());\n\n\treturn true;\n}\n\nvoid terminateVulkan()\n{\n\tcanvas = nullptr;\n\tcanvas2d = nullptr;\n\tfinish = nullptr;\n\tclear = nullptr;\n\tcubeRenderer = nullptr;\n\tmodelRenderer = nullptr;\n\timgui = nullptr;\n\tdestroyVulkanRenderDevice(vkDev);\n\tdestroyVulkanInstance(vk);\n}\n\nvoid reinitCamera()\n{\n\tif (!strcmp(cameraType, \"FirstPerson\"))\n\t{\n\t\tcamera = Camera(positioner_firstPerson);\n\t}\n\telse if (!strcmp(cameraType, \"MoveTo\"))\n  {\n    positioner_moveTo.setDesiredPosition(cameraPos);\n    positioner_moveTo.setDesiredAngles(cameraAngles.x, cameraAngles.y, cameraAngles.z);\n    camera = Camera(positioner_moveTo);\n\t}\n  else if ((std::string)cameraType == \"Trackball\")\n    camera = Camera(positioner_trackball);\n}\n\nvoid renderGUI(uint32_t imageIndex)\n{\n\tEASY_FUNCTION();\n\n\tint width, height;\n\tglfwGetFramebufferSize(window, &width, &height);\n\n\tImGuiIO& io = ImGui::GetIO();\n\tio.DisplaySize = ImVec2((float)width, (float)height);\n\tImGui::NewFrame();\n\n\tconst ImGuiWindowFlags flags =\n\t\tImGuiWindowFlags_NoTitleBar |\n\t\tImGuiWindowFlags_NoResize |\n\t\tImGuiWindowFlags_NoMove |\n\t\tImGuiWindowFlags_NoScrollbar |\n\t\tImGuiWindowFlags_NoSavedSettings |\n\t\tImGuiWindowFlags_NoInputs |\n\t\tImGuiWindowFlags_NoBackground;\n\n\tImGui::SetNextWindowPos(ImVec2(0, 0));\n\tImGui::Begin(\"Statistics\", nullptr, flags);\n\tImGui::Text(\"FPS: %.2f\", fpsCounter.getFPS());\n\tImGui::End();\n\n\tImGui::Begin(\"Camera Control\", nullptr);\n\t{\n\t\tif (ImGui::BeginCombo(\"##combo\", currentComboBoxItem)) // The second parameter is the label previewed before opening the combo.\n\t\t{\n\t\t\tfor (int n = 0; n < IM_ARRAYSIZE(comboBoxItems); n++)\n\t\t\t{\n\t\t\t\tconst bool isSelected = (currentComboBoxItem == comboBoxItems[n]);\n\n\t\t\t\tif (ImGui::Selectable(comboBoxItems[n], isSelected))\n\t\t\t\t\tcurrentComboBoxItem = comboBoxItems[n];\n\n\t\t\t\tif (isSelected) {\n\t\t\t\t\tImGui::SetItemDefaultFocus();   // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support)\n        }\n\t\t\t}\n\t\t\tImGui::EndCombo();\n\t\t}\n\n\t\tif (!strcmp(cameraType, \"MoveTo\"))\n\t\t{\n\t\t\tif (ImGui::SliderFloat3(\"Position\", glm::value_ptr(cameraPos), -10.0f, +10.0f))\n\t\t\t\tpositioner_moveTo.setDesiredPosition(cameraPos);\n\t\t\tif (ImGui::SliderFloat3(\"Pitch/Pan/Roll\", glm::value_ptr(cameraAngles), -90.0f, +90.0f))\n\t\t\t\tpositioner_moveTo.setDesiredAngles(cameraAngles);\n\t\t}\n\n\t\tif (currentComboBoxItem && strcmp(currentComboBoxItem, cameraType))\n\t\t{\n\t\t\tprintf(\"Selected new camera type: %s\\n\", currentComboBoxItem);\n\t\t\tcameraType = currentComboBoxItem;\n\t\t\treinitCamera();\n\t\t}\n\t}\n\tImGui::End();\n\tImGui::Render();\n\n\timgui->updateBuffers(vkDev, imageIndex, ImGui::GetDrawData());\n}\n\n// Build the uniforms with the model view matrices.\nvoid update3D(uint32_t imageIndex)\n{\n\tint width, height;\n\tglfwGetFramebufferSize(window, &width, &height);\n\tconst float ratio = width / (float)height;\n\n\tconst mat4 m1 = \n    glm::rotate(glm::translate(mat4(1.0f), vec3(0.f, 0.5f, -1.5f))\n                * glm::rotate(mat4(1.f), glm::pi<float>(), vec3(1, 0, 0)),\n                (float)glfwGetTime(),\n                vec3(0.0f, 1.0f, 0.0f));\n\tmat4 view = camera.getViewMatrix();\n\n\tconst mat4 p = glm::perspective(45.0f, ratio, 0.1f, 1000.0f);\n\n\tconst mat4 mtx = p * view * m1;\n\n\t{\n\t\tEASY_BLOCK(\"UpdateUniformBuffers\");\n\t\tmodelRenderer->updateUniformBuffer(vkDev, imageIndex, glm::value_ptr(mtx), sizeof(mat4));\n\t\tcanvas->updateUniformBuffer(vkDev, p * view, 0.0f, imageIndex);\n\t\tcanvas2d->updateUniformBuffer(vkDev, glm::ortho(0, 1, 1, 0), 0.0f, imageIndex);\n\t\tcubeRenderer->updateUniformBuffer(vkDev, imageIndex, p * view * m1);\n\t\tEASY_END_BLOCK;\n\t}\n}\n\nvoid update2D(uint32_t imageIndex)\n{\n\tcanvas2d->clear();\n\tsineGraph.renderGraph(*canvas2d.get(), vec4(0.0f, 1.0f, 0.0f, 1.0f));\n\tfpsGraph.renderGraph(*canvas2d.get());\n\tcanvas2d->updateBuffer(vkDev, imageIndex);\n}\n\n// Loop over all the renderers and have each one add its contents to the\n// command buffer.\nvoid composeFrame(uint32_t imageIndex, const std::vector<RendererBase*>& renderers)\n{\n\tupdate3D(imageIndex);\n\trenderGUI(imageIndex);\n\tupdate2D(imageIndex);\n\n\tEASY_BLOCK(\"FillCommandBuffers\");\n\n\tVkCommandBuffer commandBuffer = vkDev.commandBuffers[imageIndex];\n\n\tconst VkCommandBufferBeginInfo bi =\n\t{\n\t\t.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,\n\t\t.pNext = nullptr,\n\t\t.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,\n\t\t.pInheritanceInfo = nullptr\n\t};\n\n\tVK_CHECK(vkBeginCommandBuffer(commandBuffer, &bi));\n\n\tfor (auto& r : renderers)\n\t\tr->fillCommandBuffer(commandBuffer, imageIndex);\n\n\tVK_CHECK(vkEndCommandBuffer(commandBuffer));\n\n\tEASY_END_BLOCK;\n}\n\nbool drawFrame(const std::vector<RendererBase*>& renderers)\n{\n\tEASY_FUNCTION();\n\n\tuint32_t imageIndex = 0;\n\tVkResult result = vkAcquireNextImageKHR(vkDev.device, vkDev.swapchain, 0, vkDev.semaphore, VK_NULL_HANDLE, &imageIndex);\n\tVK_CHECK(vkResetCommandPool(vkDev.device, vkDev.commandPool, 0));\n\n\tif (result != VK_SUCCESS) return false;\n\n\tcomposeFrame(imageIndex, renderers);\n\n\tconst VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // or even VERTEX_SHADER_STAGE\n\n\tconst VkSubmitInfo si =\n\t{\n\t\t.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,\n\t\t.pNext = nullptr,\n\t\t.waitSemaphoreCount = 1,\n\t\t.pWaitSemaphores = &vkDev.semaphore,\n\t\t.pWaitDstStageMask = waitStages,\n\t\t.commandBufferCount = 1,\n\t\t.pCommandBuffers = &vkDev.commandBuffers[imageIndex],\n\t\t.signalSemaphoreCount = 1,\n\t\t.pSignalSemaphores = &vkDev.renderSemaphore\n\t};\n\n\t{\n\t\tEASY_BLOCK(\"vkQueueSubmit\", profiler::colors::Magenta);\n\t\tVK_CHECK(vkQueueSubmit(vkDev.graphicsQueue, 1, &si, nullptr));\n\t\tEASY_END_BLOCK;\n\t}\n\n\tconst VkPresentInfoKHR pi =\n\t{\n\t\t.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,\n\t\t.pNext = nullptr,\n\t\t.waitSemaphoreCount = 1,\n\t\t.pWaitSemaphores = &vkDev.renderSemaphore,\n\t\t.swapchainCount = 1,\n\t\t.pSwapchains = &vkDev.swapchain,\n\t\t.pImageIndices = &imageIndex\n\t};\n\n\t{\n\t\tEASY_BLOCK(\"vkQueuePresentKHR\", profiler::colors::Magenta);\n\t\tVK_CHECK(vkQueuePresentKHR(vkDev.graphicsQueue, &pi));\n\t\tEASY_END_BLOCK;\n\t}\n\n\t{\n\t\tEASY_BLOCK(\"vkDeviceWaitIdle\", profiler::colors::Red);\n\t\tVK_CHECK(vkDeviceWaitIdle(vkDev.device));\n\t\tEASY_END_BLOCK;\n\t}\n\n\treturn true;\n}\n\nint main()\n{\n\tEASY_PROFILER_ENABLE;\n\tEASY_MAIN_THREAD;\n\n\tglslang_initialize_process();\n\n\tvolkInitialize();\n\n\tif (!glfwInit())\n\t\texit(EXIT_FAILURE);\n\n\tif (!glfwVulkanSupported())\n\t\texit(EXIT_FAILURE);\n\n\tglfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);\n\tglfwWindowHint(GLFW_RESIZABLE, GL_FALSE);\n\n\tImGui::CreateContext();\n\tImGuiIO& io = ImGui::GetIO();\n\n\twindow = glfwCreateWindow(kScreenWidth, kScreenHeight, \"VulkanApp\", nullptr, nullptr);\n\tif (!window)\n\t{\n\t\tglfwTerminate();\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tglfwSetCursorPosCallback(\n\t\twindow,\n\t\t[](auto* window, double x, double y)\n\t\t{\n\t\t\tImGui::GetIO().MousePos = ImVec2((float)x, (float)y);\n      mouseState.pos = glm::vec2({(float)x,(float)y});\n\t\t}\n\t);\n\n\tglfwSetMouseButtonCallback(\n\t\twindow,\n\t\t[](auto* window, int button, int action, int mods)\n\t\t{\n\t\t\tauto& io = ImGui::GetIO();\n\t\t\tconst int idx = button == GLFW_MOUSE_BUTTON_LEFT ? 0 : button == GLFW_MOUSE_BUTTON_RIGHT ? 2 : 1;\n\t\t\tio.MouseDown[idx] = action == GLFW_PRESS;\n\n\t\t\tif (button == GLFW_MOUSE_BUTTON_LEFT)\n      {\n#if 0\n        if (!mouseState.pressedLeft)\n          trackballPos = mouseState.pos;\n#endif\n  \n\t\t\t\tmouseState.pressedLeft = action == GLFW_PRESS;\n      }\n\t\t}\n\t);\n\n\tglfwSetKeyCallback(\n\t\twindow,\n\t\t[](GLFWwindow* window, int key, int scancode, int action, int mods)\n\t\t{\n\t\t\tconst bool pressed = action != GLFW_RELEASE;\n\t\t\tif (key == GLFW_KEY_ESCAPE && pressed)\n\t\t\t\tglfwSetWindowShouldClose(window, GLFW_TRUE);\n\t\t\tif (key == GLFW_KEY_W)\n\t\t\t\tpositioner_firstPerson.movement_.forward_ = pressed;\n\t\t\tif (key == GLFW_KEY_S)\n\t\t\t\tpositioner_firstPerson.movement_.backward_ = pressed;\n\t\t\tif (key == GLFW_KEY_A)\n\t\t\t\tpositioner_firstPerson.movement_.left_ = pressed;\n\t\t\tif (key == GLFW_KEY_D)\n\t\t\t\tpositioner_firstPerson.movement_.right_ = pressed;\n\t\t\tif (key == GLFW_KEY_SPACE)\n\t\t\t\tpositioner_firstPerson.setUpVector(vec3(0.0f, 1.0f, 0.0f));\n\t\t}\n\t);\n\n\tinitVulkan();\n\n\t{\n\t\tcanvas->plane3d(vec3(0,+1.5,0), vec3(1,0,0), vec3(0,0,1), 40, 40, 10.0f, 10.0f, vec4(1,0,0,1), vec4(0,1,0,1));\n\n\t\tfor(size_t i = 0 ; i < vkDev.swapchainImages.size() ; i++)\n\t\t\tcanvas->updateBuffer(vkDev, i);\n\t}\n\n\tdouble timeStamp = glfwGetTime();\n\tfloat deltaSeconds = 0.0f;\n\n  // List of all the renderers (in order?) for a single frame\n\tconst std::vector<RendererBase*> renderers = {\n    clear.get(),\n    //    cubeRenderer.get(),   // The \"inside cube\" renderer\n    modelRenderer.get(), \n    canvas.get(),\n    canvas2d.get(),  // What does this due?\n    imgui.get(), \n    finish.get()\n  };\n\n\twhile (!glfwWindowShouldClose(window))\n\t{\n\t\t{\n\t\t\tEASY_BLOCK(\"UpdateCameraPositioners\");\n\n      // something is not dealt with correctly with the mouse state!\n      positioner_firstPerson.update(deltaSeconds, 0.0f*mouseState.pos, mouseState.pressedLeft);\n      positioner_moveTo.update(deltaSeconds, 0.0f*mouseState.pos, mouseState.pressedLeft);\n      // Only operate on the trackball if it is in use\n      if ((std::string)cameraType == \"Trackball\")\n        positioner_trackball.update(deltaSeconds, mouseState.pos, mouseState.pressedLeft);\n\t\t\tEASY_END_BLOCK;\n\t\t}\n\n\t\tconst double newTimeStamp = glfwGetTime();\n\t\tdeltaSeconds = static_cast<float>(newTimeStamp - timeStamp);\n\t\ttimeStamp = newTimeStamp;\n\n\t\tconst bool frameRendered = drawFrame(renderers);\n\n\t\tif (fpsCounter.tick(deltaSeconds, frameRendered))\n\t\t{\n\t\t\tfpsGraph.addPoint(fpsCounter.getFPS());\n\t\t}\n\t\tsineGraph.addPoint((float)sin(glfwGetTime() * 10.0));\n\n\t\t{\n\t\t\tEASY_BLOCK(\"PollEvents\");\n\t\t\tglfwPollEvents();\n\t\t\tEASY_END_BLOCK;\n\t\t}\n\t}\n\n\tImGui::DestroyContext();\n\n\tterminateVulkan();\n\tglfwTerminate();\n\tglslang_finalize_process();\n\n\tPROFILER_DUMP(\"profiling.prof\");\n\n\treturn 0;\n}\n","uri":"file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp","version":0}}}
[stderr] 
[stderr] I[23:20:01.243] <-- textDocument/didOpen
[stderr] V[23:20:01.243] config note at /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.clangd:1:0: Parsing config fragment
[stderr] V[23:20:01.243] config note at /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.clangd:1:0: Parsed 1 fragments from file
[stderr] V[23:20:01.243] Config fragment: compiling /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.clangd:1 -> 0x00007FEA04003390 (trusted=false)
[stderr] I[23:20:01.243] --> textDocument/publishDiagnostics
[stderr] V[23:20:01.243] >>> {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[],"uri":"file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.clangd"}}
[stderr] 
[stderr] I[23:20:01.244] Loaded compilation database from /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/compile_commands.json
[stderr] V[23:20:01.244] Broadcasting compilation database from /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook
[stderr] I[23:20:01.244] ASTWorker building file /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp version 0 with command inferred from /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/deps/src/glslang/OGLCompilersDLL/InitializeDll.cpp
[stderr] [/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build]
[stderr] [/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build]
[stderr] /usr/bin/c++ --driver-mode=g++ -DENABLE_OPT=0 -DGLSLANG_OSINCLUDE_UNIX -g -fPIC -Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions -Wno-reorder -fno-rtti -Werror=deprecated-copy -c -std=c++11 -I/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/deps/src/ -resource-dir=/usr/lib64/clang/14.0.0 -- /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp
[stderr] V[23:20:01.245] Driver produced command: cc1 -cc1 -triple x86_64-redhat-linux-gnu -fsyntax-only -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build -resource-dir /usr/lib64/clang/14.0.0 -D ENABLE_OPT=0 -D GLSLANG_OSINCLUDE_UNIX -I /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/deps/src/ -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/backward -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-reorder -Werror=deprecated-copy -std=c++11 -fdeprecated-macro -fdebug-compilation-dir=/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp
[stderr] V[23:20:01.245] Building first preamble for /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp version 0
[stderr] V[23:20:01.246] Ignored diagnostic. unknown warning option '-Wmaybe-uninitialized'; did you mean '-Wuninitialized'?
[stderr] V[23:20:01.247] Ignored diagnostic. unknown warning option '-Wmaybe-uninitialized'; did you mean '-Wuninitialized'?
[stderr] V[23:20:01.247] <<< {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}
[stderr] 
[stderr] I[23:20:01.247] <-- workspace/didChangeConfiguration
[stderr] I[23:20:01.249] Loaded compilation database from /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/build/compile_commands.json
[stderr] I[23:20:01.249] Enqueueing 99 commands for indexing
[stderr] V[23:20:01.328] BackgroundIndex: building version 1 after loading index from disk
[stderr] V[23:20:01.440] BackgroundIndex: serving version 1 (27058366 bytes)
[stderr] V[23:20:02.019] indexed preamble AST for /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp version 0:
[stderr]   symbol slab: 30294 symbols, 8542736 bytes
[stderr]   ref slab: 0 symbols, 0 refs, 128 bytes
[stderr]   relations slab: 249 relations, 4376 bytes
[stderr] V[23:20:02.181] Build dynamic index for header symbols with estimated memory usage of 18267984 bytes
[stderr] V[23:20:02.185] Built preamble of size 11040892 for file /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp version 0
[stderr] V[23:20:02.190] Ignored diagnostic. unknown warning option '-Wmaybe-uninitialized'; did you mean '-Wuninitialized'?
[stderr] V[23:20:02.200] Trying to fix unresolved name "VulkanInstance" in scopes: []
[stderr] V[23:20:02.200] Dex query tree: (LIMIT 10000 (& T=kan T=lka T=ulk T=vul T=ani T=anc T=tan T=nin T=nce T=ins T=nst T=sta S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.200] Dex query tree: (LIMIT 10000 (& T=lka T=kan T=vul T=ani T=ulk T=anc T=nce T=tan T=ins T=nin T=sta T=nst S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.207] Trying to fix unresolved name "VulkanRenderDevice" in scopes: []
[stderr] V[23:20:02.207] Dex query tree: (LIMIT 10000 (& T=anr T=lka T=ulk T=vul T=kan T=nre T=erd T=rde T=end T=ren T=nde T=dev T=ice T=vic T=evi T=der S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.207] Dex query tree: (LIMIT 10000 (& T=lka T=kan T=anr T=vic T=vul T=dev T=ulk T=ice T=evi T=nre T=erd T=end T=ren T=rde T=nde T=der S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.210] Trying to fix unresolved name "ImGuiRenderer" in scopes: []
[stderr] V[23:20:02.210] Dex query tree: (LIMIT 10000 (& T=uir T=rer T=mgu T=img T=ire T=gui T=end T=ren T=nde T=ere T=der S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.210] Dex query tree: (LIMIT 10000 (& T=mgu T=gui T=img T=uir T=rer T=ire T=end T=ren T=nde T=der T=ere S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.213] Trying to fix unresolved name "ModelRenderer" in scopes: []
[stderr] V[23:20:02.213] Dex query tree: (LIMIT 10000 (& T=elr T=del T=rer T=lre T=mod T=ode T=end T=ren T=nde T=ere T=der S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.213] Dex query tree: (LIMIT 10000 (& T=elr T=lre T=rer T=del T=end T=mod T=ren T=nde T=der T=ere T=ode S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.216] Trying to fix unresolved name "CubeRenderer" in scopes: []
[stderr] V[23:20:02.216] Dex query tree: (LIMIT 10000 (& T=ber T=cub T=ube T=rer T=end T=ren T=nde T=ere T=der S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.216] Dex query tree: (LIMIT 10000 (& T=ber T=cub T=ube T=rer T=end T=ren T=nde T=der T=ere S= ?=Restricted For Code Completion))
[stderr] V[23:20:02.218] Trying to fix unresolved name "VulkanCanvas" in scopes: []
[stderr] V[23:20:02.221] Trying to fix unresolved name "VulkanCanvas" in scopes: []
[stderr] V[23:20:02.223] Trying to fix unresolved name "VulkanClear" in scopes: []
[stderr] V[23:20:02.225] Trying to fix unresolved name "VulkanFinish" in scopes: []
[stderr] V[23:20:02.235] Trying to fix unresolved name "FramesPerSecondCounter" in scopes: []
[stderr] V[23:20:02.237] Trying to fix unresolved name "LinearGraph" in scopes: []
[stderr] V[23:20:02.239] Trying to fix unresolved name "LinearGraph" in scopes: []
[stderr] V[23:20:02.258] Trying to fix unresolved name "CameraPositioner_FirstPerson" in scopes: []
[stderr] V[23:20:02.268] Trying to fix unresolved name "CameraPositioner_MoveTo" in scopes: []
[stderr] V[23:20:02.280] Trying to fix unresolved name "CameraPositioner_Trackball" in scopes: []
[stderr] V[23:20:02.281] Trying to fix unresolved name "Camera" in scopes: []
[stderr] V[23:20:02.284] Trying to fix unresolved name "EASY_FUNCTION" in scopes: []
[stderr] V[23:20:02.284] Trying to fix include for incomplete type VkInstance_T
[stderr] V[23:20:02.296] indexed file AST for /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp version 0:
[stderr]   symbol slab: 44 symbols, 14424 bytes
[stderr]   ref slab: 133 symbols, 223 refs, 14464 bytes
[stderr]   relations slab: 0 relations, 24 bytes
[stderr] V[23:20:02.296] Build dynamic index for main-file symbols with estimated memory usage of 53400 bytes
[stderr] I[23:20:02.297] --> textDocument/publishDiagnostics
[stderr] I[23:20:02.297] --> textDocument/publishDiagnostics
[server-notification] Wed Oct  5 23:20:02 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
          (:diagnostics
           [(:code "pp_file_not_found" :message "'shared/Utils.h' file not found" :range
                   (:end
                    (:character 25 :line 13)
                    :start
                    (:character 9 :line 13))
                   :severity 1 :source "clang")
            (:code "unknown_typename_suggest" :message "Unknown type name 'VulkanInstance'; did you mean 'VkInstance'? (fix available)\n\n:100:18:\nnote: 'VkInstance' declared here" :range
                   (:end
                    (:character 14 :line 42)
                    :start
                    (:character 0 :line 42))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'VulkanRenderDevice'" :range
                   (:end
                    (:character 18 :line 43)
                    :start
                    (:character 0 :line 43))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'ImGuiRenderer'" :range
                   (:end
                    (:character 29 :line 45)
                    :start
                    (:character 16 :line 45))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'ModelRenderer'" :range
                   (:end
                    (:character 29 :line 46)
                    :start
                    (:character 16 :line 46))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use_suggest" :message "Use of undeclared identifier 'CubeRenderer'; did you mean 'modelRenderer'? (fix available)\n\nmain.cpp:47:32: note: 'modelRenderer' declared here" :range
                   (:end
                    (:character 28 :line 47)
                    :start
                    (:character 16 :line 47))
                   :severity 1 :source "clang")
            (:message "'modelRenderer' declared here\n\nmain.cpp:48:17: error: use of undeclared identifier 'CubeRenderer'; did you mean 'modelRenderer'?" :range
                      (:end
                       (:character 44 :line 46)
                       :start
                       (:character 31 :line 46))
                      :severity 3)
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'VulkanCanvas'" :range
                   (:end
                    (:character 28 :line 48)
                    :start
                    (:character 16 :line 48))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'VulkanCanvas'" :range
                   (:end
                    (:character 28 :line 49)
                    :start
                    (:character 16 :line 49))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'VulkanClear'" :range
                   (:end
                    (:character 27 :line 50)
                    :start
                    (:character 16 :line 50))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'VulkanFinish'" :range
                   (:end
                    (:character 28 :line 51)
                    :start
                    (:character 16 :line 51))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'FramesPerSecondCounter'" :range
                   (:end
                    (:character 22 :line 53)
                    :start
                    (:character 0 :line 53))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'LinearGraph'" :range
                   (:end
                    (:character 11 :line 54)
                    :start
                    (:character 0 :line 54))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'LinearGraph'" :range
                   (:end
                    (:character 11 :line 55)
                    :start
                    (:character 0 :line 55))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'CameraPositioner_FirstPerson'" :range
                   (:end
                    (:character 28 :line 66)
                    :start
                    (:character 0 :line 66))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'CameraPositioner_MoveTo'" :range
                   (:end
                    (:character 23 :line 67)
                    :start
                    (:character 0 :line 67))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'CameraPositioner_Trackball'" :range
                   (:end
                    (:character 26 :line 68)
                    :start
                    (:character 0 :line 68))
                   :severity 1 :source "clang")
            (:code "unknown_typename" :message "Unknown type name 'Camera'" :range
                   (:end
                    (:character 6 :line 69)
                    :start
                    (:character 0 :line 69))
                   :severity 1 :source "clang")
            (:code "undeclared_var_use" :message "Use of undeclared identifier 'EASY_FUNCTION'" :range
                   (:end
                    (:character 14 :line 78)
                    :start
                    (:character 1 :line 78))
                   :severity 1 :source "clang")
            (:code "typecheck_member_reference_suggestion" :message "Member reference type 'VkInstance' (aka 'VkInstance_T *') is a pointer; did you mean to use '->'? (fix available)" :range
                   (:end
                    (:character 20 :line 80)
                    :start
                    (:character 19 :line 80))
                   :severity 1 :source "clang")
            (:code "typecheck_incomplete_tag" :message "Incomplete definition of type 'VkInstance_T'\n\n:100:1:\nnote: forward declaration of 'VkInstance_T'" :range
                   (:end
                    (:character 20 :line 80)
                    :start
                    (:character 19 :line 80))
                   :severity 1 :source "clang")
            (:code "fatal_too_many_errors" :message "Too many errors emitted, stopping now" :range
                   (:end
                    (:character 0 :line 0)
                    :start
                    (:character 0 :line 0))
                   :severity 1 :source "clang")]
           :uri "file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp" :version 0))
[stderr] V[23:20:02.297] >>> {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"code":"pp_file_not_found","message":"'shared/Utils.h' file not found","range":{"end":{"character":25,"line":13},"start":{"character":9,"line":13}},"severity":1,"source":"clang"},{"code":"unknown_typename_suggest","message":"Unknown type name 'VulkanInstance'; did you mean 'VkInstance'? (fix available)\n\n:100:18:\nnote: 'VkInstance' declared here","range":{"end":{"character":14,"line":42},"start":{"character":0,"line":42}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'VulkanRenderDevice'","range":{"end":{"character":18,"line":43},"start":{"character":0,"line":43}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'ImGuiRenderer'","range":{"end":{"character":29,"line":45},"start":{"character":16,"line":45}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'ModelRenderer'","range":{"end":{"character":29,"line":46},"start":{"character":16,"line":46}},"severity":1,"source":"clang"},{"code":"undeclared_var_use_suggest","message":"Use of undeclared identifier 'CubeRenderer'; did you mean 'modelRenderer'? (fix available)\n\nmain.cpp:47:32: note: 'modelRenderer' declared here","range":{"end":{"character":28,"line":47},"start":{"character":16,"line":47}},"severity":1,"source":"clang"},{"message":"'modelRenderer' declared here\n\nmain.cpp:48:17: error: use of undeclared identifier 'CubeRenderer'; did you mean 'modelRenderer'?","range":{"end":{"character":44,"line":46},"start":{"character":31,"line":46}},"severity":3},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'VulkanCanvas'","range":{"end":{"character":28,"line":48},"start":{"character":16,"line":48}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'VulkanCanvas'","range":{"end":{"character":28,"line":49},"start":{"character":16,"line":49}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'VulkanClear'","range":{"end":{"character":27,"line":50},"start":{"character":16,"line":50}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'VulkanFinish'","range":{"end":{"character":28,"line":51},"start":{"character":16,"line":51}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'FramesPerSecondCounter'","range":{"end":{"character":22,"line":53},"start":{"character":0,"line":53}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'LinearGraph'","range":{"end":{"character":11,"line":54},"start":{"character":0,"line":54}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'LinearGraph'","range":{"end":{"character":11,"line":55},"start":{"character":0,"line":55}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'CameraPositioner_FirstPerson'","range":{"end":{"character":28,"line":66},"start":{"character":0,"line":66}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'CameraPositioner_MoveTo'","range":{"end":{"character":23,"line":67},"start":{"character":0,"line":67}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'CameraPositioner_Trackball'","range":{"end":{"character":26,"line":68},"start":{"character":0,"line":68}},"severity":1,"source":"clang"},{"code":"unknown_typename","message":"Unknown type name 'Camera'","range":{"end":{"character":6,"line":69},"start":{"character":0,"line":69}},"severity":1,"source":"clang"},{"code":"undeclared_var_use","message":"Use of undeclared identifier 'EASY_FUNCTION'","range":{"end":{"character":14,"line":78},"start":{"character":1,"line":78}},"severity":1,"source":"clang"},{"code":"typecheck_member_reference_suggestion","message":"Member reference type 'VkInstance' (aka 'VkInstance_T *') is a pointer; did you mean to use '->'? (fix available)","range":{"end":{"character":20,"line":80},"start":{"character":19,"line":80}},"severity":1,"source":"clang"},{"code":"typecheck_incomplete_tag","message":"Incomplete definition of type 'VkInstance_T'\n\n:100:1:\nnote: forward declaration of 'VkInstance_T'","range":{"end":{"character":20,"line":80},"start":{"character":19,"line":80}},"severity":1,"source":"clang"},{"code":"fatal_too_many_errors","message":"Too many errors emitted, stopping now","range":{"end":{"character":0,"line":0},"start":{"character":0,"line":0}},"severity":1,"source":"clang"}],"uri":"file:///terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/Chapter4/VK01_DemoApp/src/main.cpp","version":0}}
[stderr] 

Here’s the full log. As a new user I don’t have privileges to attach files. And trying to inline it, my post was caught in the spam filter and quarantined. Hopefully a github gist won’t be caught…

I added a gist for the compile_commands.json as well at Continue debugging clang and eglot · GitHub .

In it can be seen than the compilation of main.cpp contains the include path:

-I/terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/.

but still, in the error messages from clang I get the error message:

"code":"pp_file_not_found","message":"'shared/Utils.h' file not found",

But the file does exist:

$ ls -l /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/./shared/Utils.h
-rw-r--r--. 1 dov dov 1755 Oct  2 10:35 /terra/space/pub-repos/PacktPublishing/3D-Graphics-Rendering-Cookbook/./shared/Utils.h

So it seems that clang is missing it somehow.

My version of clangd is:

clangd version 14.0.0 (Fedora 14.0.0-1.fc36)
Features: linux
Platform: x86_64-unknown-linux-gnu; target=x86_64-redhat-linux-gnu