From fb95285ca147ba49c90cf17bcbf6fd1a9810bf33 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 1 Jun 2021 13:29:09 +0100 Subject: [PATCH] Put all annotation docs into the same 'how do I' page. Refs #2285 * This page now documents both how to annotate things from code in the application, as well as at runtime in the UI. --- docs/how/how_annotate_capture.rst | 167 +++++++++++++++++- docs/how/how_view_texture.rst | 73 +------- docs/imgs/Screenshots/EventBrowserRegions.png | Bin 0 -> 20349 bytes docs/renderdoc.hhk | 8 +- docs/window/event_browser.rst | 62 +------ 5 files changed, 179 insertions(+), 131 deletions(-) create mode 100644 docs/imgs/Screenshots/EventBrowserRegions.png diff --git a/docs/how/how_annotate_capture.rst b/docs/how/how_annotate_capture.rst index 4c1740f0c..ea5ad812e 100644 --- a/docs/how/how_annotate_capture.rst +++ b/docs/how/how_annotate_capture.rst @@ -1,9 +1,172 @@ How do I annotate a capture? ============================ -RenderDoc allows some annotation of capture files, meaning that you can make notes and bookmark important events, then save your changes within the capture itself for sharing with other people. This can be useful for example when investigating a bug or repro case and passing on your findings natively to someone else, instead of having to include additional text like 'texture 148 is the buggy texture'. +RenderDoc allows annotation of captures in two ways - annotations that you provide from your application along with the other graphics API calls that you make, and annotations that are made in the UI while analysing a capture and can be saved with it. -All of these modifications can be saved with a capture. Pressing :kbd:`Ctrl-S` or :guilabel:`File` → :guilabel:`Save` will save the capture with any changes that have been made to it in the UI. If you haven't already saved a temporary capture, or the capture is on a remote context, this will need to you save it to a local path. +The annotations provided with the graphics API calls from your application vary by the particular API and are documented below. + +Annotations made in the UI are also described below. These can be useful for example when investigating a bug or repro case and passing on your findings natively to someone else, instead of having to include additional text like 'texture 148 is the buggy texture' you can directly mark up the capture. + +All of the UI modifications can be saved with a capture. Pressing :kbd:`Ctrl-S` or :guilabel:`File` → :guilabel:`Save` will save the capture with any changes that have been made to it in the UI. If you haven't already saved a temporary capture, or the capture is on a remote context, this will need to you save it to a local path. + +Application provided marker regions +----------------------------------- + +When calling graphics API functions from your code you can provide annotations to group regions of the frame under names, with a nested hierarchy. + +These markers are provided in an API specific way: D3D11 uses the ``D3DPERF`` or ``ID3DUserDefinedAnnotation`` APIs, D3D12 uses ``SetMarker``/``BeginEvent``/``EndEvent`` on lists or queues, OpenGL has many extensions but ``KHR_debug`` is guaranteed to always be available, and Vulkan uses ``VK_EXT_debug_utils``. + +In APIs such as D3D12 and Vulkan with queues and command buffers, the markers are processed in submission order and are allowed to cross primary command buffers, so a single region can cross several command buffers. Secondary command buffers or bundles can contain markers but they must be self-contained and not imbalanced. + +Some of the APIs add the ability to provide a colour for a marker region, these colours are displayed in the :doc:`../window/event_browser` window. + +.. figure:: ../imgs/Screenshots/EventBrowserRegions.png + + Marker Regions: The Event browser showing several coloured marker regions. + +Example code for D3D11: + +.. highlight:: c++ +.. code:: c++ + + // The ``D3DPERF`` APIs are exported by ``d3d9.dll``, but can still be used in D3D11 + // for compatibility reasons + + D3DPERF_BeginEvent(0xffffffff, L"Start of example"); + + D3DPERF_BeginEvent(0xff00ff00, L"Sub section"); + // events inside the subsection + D3DPERF_EndEvent(); + + // events outside the subsection + D3DPERF_EndEvent(); + + // the newer ID3DUserDefinedAnnotation API is also supported + ID3DUserDefinedAnnotation *annot; + immediateContext->QueryInterface(__uuidof(ID3DUserDefinedAnnotation), (void **)&annot); + + annot->BeginEvent(L"Sub section 2") + + annot->EndEvent(); + +Example code for D3D12: + +.. highlight:: c++ +.. code:: c++ + + // 1 for the first parameter means the data is an ANSI string. Pass 0 for a wchar string. + // the length should include the NULL terminator + list->BeginEvent(1, "Begin Section", sizeof("Begin Section")); + + list->EndEvent(); + + // queue-level markers can be provided similarly. + +Example code for OpenGL using the ``KHR_debug`` extension. Many other extensions exist in GL to provide markers and will be made available by RenderDoc too. + +.. highlight:: c++ +.. code:: c++ + + // omitted code to initialise the extension function pointers + + glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "Begin Section"); + + // contents of section here + + glPopDebugGroupKHR(); + +Example code for Vulkan using the ``VK_EXT_debug_utils`` extension: + +.. highlight:: c++ +.. code:: c++ + + // omitted code to initialise the extension + + VkCommandBuffer cmd = ...; + + VkDebugUtilsLabelEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + markerInfo.pLabelName = "Begin Section"; + vkCmdBeginDebugUtilsLabelEXT(cmd, &markerInfo); + + // contents of section here + + vkCmdEndDebugUtilsLabelEXT(cmd); + + // queue-level markers can be provided similarly. + +Application provided object names +--------------------------------- + +Similar to the marker regions above, it is possible to give objects names via the graphics APIs and they will be displayed with those human-readable names instead of auto-generated names. + +When a resource with a custom name is bound to the pipeline it will be listed like so: + +.. figure:: ../imgs/Screenshots/NamedTex.png + + Named Texture: The example texture bound with name displayed. + +In a similar way any other resource can be named and this will be useful throughout the rest of the analysis. If a custom name is not provided, a default name will be generated - as seen above with the Render Pass and Framebuffer objects. + +Again the exact method varies by API, as given in the examples below. + +.. note:: + + RenderDoc does not support names that change within a capture. A resource only has one name, which is the most recent one set. + +Example code for D3D11 using the ``SetPrivateData`` function: + +.. highlight:: c++ +.. code:: c++ + + // Creating an example resource - a 2D Texture. + ID3D11Texture2D *tex2d = NULL; + d3dDevice->CreateTexture2D(&descriptor, NULL, &tex2d); + + // Give the texture a useful name + tex2d->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Example Texture"), "Example Texture"); + +With D3D12 you can use the ``SetName`` function: + +.. highlight:: c++ +.. code:: c++ + + // Creating an example resource - a 2D Texture. + ID3D12Resource *tex2d = NULL; + d3dDevice->CreateCommittedResource(&heapProps, heapFlags, &descriptor, initState, &clearValue, __uuidof(ID3D12Resource), (void **)&tex2d); + + // Give the texture a useful name + tex2d->SetName(L"Example Texture"); + +In OpenGL this can be done with ``GL_KHR_debug`` with the function ``glObjectLabel``. + +.. highlight:: c++ +.. code:: c++ + + // Creating an example resource - a 2D Texture. + GLuint tex2d = 0; + glGenTextures(1, &tex2d); + glBindTexture(GL_TEXTURE_2D, tex2d); + + // apply the name, -1 means NULL terminated + glObjectLabel(GL_TEXTURE, tex2d, -1, "Example Texture"); + +In Vulkan you can enable the ``VK_EXT_debug_utils`` extension, which is provided by RenderDoc, and use the ``vkSetDebugUtilsObjectNameEXT`` function. + +.. highlight:: c++ +.. code:: c++ + + // create the image + VkImage tex2d; + vkCreateImage(device, &createInfo, NULL, &tex2d); + + // set the name + VkDebugUtilsObjectNameInfoEXT nameInfo = {}; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.objectType = VK_OBJECT_TYPE_IMAGE; + nameInfo.objectHandle = (uint64_t)tex2d; // this cast may vary by platform/compiler + nameInfo.pObjectName = "Off-screen color framebuffer"; + vkSetDebugUtilsObjectNameEXT(device, &nameInfo); Bookmarks --------- diff --git a/docs/how/how_view_texture.rst b/docs/how/how_view_texture.rst index cd0c3ae9d..d74d661e8 100644 --- a/docs/how/how_view_texture.rst +++ b/docs/how/how_view_texture.rst @@ -1,77 +1,7 @@ How do I view a specific texture? ================================= -This page documents how to annotate your resources with user-friendly names to make it easier to follow use of them throughout the frame, as well as the functions for finding and following textures by name rather than by usage. - -Annotating resources with names -------------------------------- - -It is much easier to browse and debug frames when the resources are given meaningful names - along with including :doc:`debugging information in shaders ` and marking up the frame with :doc:`hierarchical user-defined regions <../window/event_browser>`. - -The way this is done varies by API. In D3D11 the resource is named using the ``SetPrivateData`` function: - -.. highlight:: c++ -.. code:: c++ - - // Creating an example resource - a 2D Texture. - ID3D11Texture2D *tex2d = NULL; - d3dDevice->CreateTexture2D(&descriptor, NULL, &tex2d); - - // Give the buffer a useful name - tex2d->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Example Texture"), "Example Texture"); - -With D3D12 you can use the ``SetName`` function: - -.. highlight:: c++ -.. code:: c++ - - // Creating an example resource - a 2D Texture. - ID3D12Resource *tex2d = NULL; - d3dDevice->CreateCommittedResource(&heapProps, heapFlags, &descriptor, initState, &clearValue, __uuidof(ID3D12Resource), (void **)&tex2d); - - // Give the buffer a useful name - tex2d->SetName(L"Example Texture"); - -In OpenGL this can be done with ``GL_KHR_debug`` - ``glObjectLabel``. - -.. highlight:: c++ -.. code:: c++ - - // Creating an example resource - a 2D Texture. - GLuint tex2d = 0; - glGenTextures(1, &tex2d); - glBindTexture(GL_TEXTURE_2D, tex2d); - - // apply the name, -1 means NULL terminated - glObjectLabel(GL_TEXTURE, tex2d, -1, "Example Texture"); - -In Vulkan you can enable the ``VK_EXT_debug_utils`` extension, which is provided by RenderDoc, and use the ``vkSetDebugUtilsObjectNameEXT`` function. - -.. highlight:: c++ -.. code:: c++ - - // At instance creation time, request the VK_EXT_debug_utils extension and - // use vkGetInstanceProcAddr to obtain vkSetDebugUtilsObjectNameEXT - - // create the image - VkImage tex2d; - vkCreateImage(device, &createInfo, NULL, &tex2d); - - // set the name - VkDebugUtilsObjectNameInfoEXT nameInfo = {}; - nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; - nameInfo.objectType = VK_OBJECT_TYPE_IMAGE; - nameInfo.objectHandle = (uint64_t)tex2d; // this cast may vary by platform/compiler - nameInfo.pObjectName = "Off-screen color framebuffer"; - vkSetDebugUtilsObjectNameEXT(device, &nameInfo); - -When this texture is bound to the pipeline it will be listed like so: - -.. figure:: ../imgs/Screenshots/NamedTex.png - - Named Texture: The example texture bound with name displayed. - -In a similar way any other resource can be named and this will be useful throughout the rest of the analysis. If a custom name is not provided, a default name will be generated - as seen above with the Render Pass and Framebuffer objects. +This page documents how to open a specific texture by name, without needing to find it via a current resource binding. Texture list in Texture Viewer ------------------------------ @@ -111,4 +41,5 @@ Opening a texture from the pipeline state viewer (:doc:`how_object_details`) wil See Also -------- +* :doc:`../how/how_annotate_capture` * :doc:`../window/texture_viewer` diff --git a/docs/imgs/Screenshots/EventBrowserRegions.png b/docs/imgs/Screenshots/EventBrowserRegions.png new file mode 100644 index 0000000000000000000000000000000000000000..05d029bd11a00f5eead2bc8f4c2f2e8ead2d5b10 GIT binary patch literal 20349 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
  • - - + +
  • - - + +
  • diff --git a/docs/window/event_browser.rst b/docs/window/event_browser.rst index 3c4153012..c57694350 100644 --- a/docs/window/event_browser.rst +++ b/docs/window/event_browser.rst @@ -8,60 +8,9 @@ Annotating your frame The Event Browser becomes most useful when the application has user-defined annotations of sections and subsections of the frames, to allow for a more logical and ordered browsing of the frame. -Doing this is API and platform specific. Example code for D3D11 is included below, using the ``D3DPERF`` library that is exported by ``d3d9.dll``, which can still be used in D3D11: +Doing this is API and platform specific. More information on how to do it can be found in :doc:`../how/how_annotate_capture`. -.. highlight:: c++ -.. code:: c++ - - D3DPERF_BeginEvent(0xffffffff, L"Start of example"); - - D3DPERF_BeginEvent(0xff00ff00, L"Sub section"); - // events inside the subsection - D3DPERF_EndEvent(); - - // events outside the subsection - D3DPERF_EndEvent(); - - // the newer ID3DUserDefinedAnnotation API is also supported - ID3DUserDefinedAnnotation *annot; - immediateContext->QueryInterface(__uuidof(ID3DUserDefinedAnnotation), (void **)&annot); - - annot->BeginEvent(L"Sub section 2") - - annot->EndEvent(); - -This will generate a section of the frame with a subsection that includes some events, and then some further events that are siblings of the subsection. - -OpenGL can make use of the ``KHR_debug`` extension: - -.. highlight:: c++ -.. code:: c++ - - // omitted code to initialise the extension - - glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "Begin Section"); - - // contents of section here - - glPopDebugGroupKHR(); - -Vulkan can use the ``VK_EXT_debug_utils`` extension: - -.. highlight:: c++ -.. code:: c++ - - // omitted code to initialise the extension - - VkCommandBuffer cmd = ...; - - VkDebugUtilsLabelEXT markerInfo = {}; - markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; - markerInfo.pLabelName = "Begin Section"; - vkCmdBeginDebugUtilsLabelEXT(cmd, &markerInfo); - - // contents of section here - - vkCmdEndDebugUtilsLabelEXT(cmd); +The colours of any marker regions provided by these API functions will be used to markup the row for the region as well as showing a bar along the left side of the tree showing which regions an event is in. Selecting available columns --------------------------- @@ -98,7 +47,7 @@ The event browser is the primary way to browse through the frame. Events are lis The currently selected event is highlighted and indicated with a green flag |flag_green|. This is the event that RenderDoc is inspecting and is reflected in all the other windows of the UI. -.. figure:: ../imgs/QuickStart/QuickStart4.png +.. figure:: ../imgs/Screenshots/EventBrowserRegions.png Current Event: The Event browser showing several sections and the current event. @@ -163,3 +112,8 @@ When you hit enter to jump to an EID, the toolbar closes and if you wish to jump .. figure:: ../imgs/Screenshots/JumpEID.png Jumping around: The jump-to-EID toolbar prompting for an event. + +See Also +-------- + +* :doc:`../how/how_annotate_capture`