在 VR 开发中使用 Nsight Visual Studio Edition 阎安 图形工具 QA 经理 1
Nvidia 图形工具的最新更新 Nsight VSE 图形调试入门 错误的 Geometry 显示 目录 调试 VR 程序 针对 GPU 的 Range Profiling 2
Nvidia 图形工具的最新更新 3
NSIGHT VISUAL STUDIO EDITION 在 Visual Studio 中进行图形调试和剖析 图形 API 调试图形性能剖析系统跟踪分析 DX9/DX11/DX12*/OpenGL/Vulkan** 支持 Visual Studio 2012, 2013, 2015 4
Nsight VSE 5.3 支持 DX12 和 VR 开发调试 完全支持 DirectX 12 的调试 The New Razer Blade Pro Powered by NVIDIA GeForce GTX 1080 支持 VR APIs 支持在 Win10 Hybrid 笔记本上的调试体验支持显示着色器的统计信息对 Range profiler 的优化更智能的 memory viewer 配置支持对 Vulkan 程序进行帧截取并串行化为源代码 5
支持 VR API Oculus SDK OpenVR & HTC Vive NVAPI 直接模式 6
Range Profiler 的改进 7
Shader 统计信息 ShaderPerf 的回归 8
更智能的 MEMORY VIEW 9
LINUX GRAPHICS DEBUGGER 针对 Linux 平台的图形调试器 帧截取 帧串行化为源代码工程 Range Profiler 支持 10
Nsight VSE PRO 显示 SASS 指令 高级 Performance Metrics (future) 着色器剖析 (future) 11
对微软 PIX 工具的支持 GPU Performance Metrics 插件 在 PIX 的 Event list 里面显示 GPU 性能计数器 选择不同的 NVIDIA GPU 性能计数器 12
CodeWorks 为游戏开发者提供 Android 开发支持 简化 Android 开发环境设置支持 Visual Studio 上的交叉编译和远程调试系统跟踪和多核 CPU 剖析图形调试和剖析和 Unreal Engine 4 Mobile 一起发布可以在 Tegra 和非 Tegra 设备上工作 * 在 SHIELD 设备上体验最好 不需要 rooted OS Image 13
CODEWORKS 1r6 Android N/7.x, Android SDK 24.4, NDK r12b SHIELD TV OTA 5.x 支持 Nsight Tegra VSE 3.4 Tegra Graphics Debugger 2.4 Tegra System Profiler 3.7 14
Nsight Tegra VSE 3.4 支持非 Tegra 的 Android 设备支持 GDB Native C/C++ 的远程调试单独的 C++ 工程支持交叉编译的配置支持 Incredibuild 和 CMake 支持 Unreal Engine 4 native game project 15
TEGRA SYSTEM PROFILER 3.7 多核 CPU 的性能采样剖析系统范围的内核, 进程, 线程的跟踪多进程的 API 级的 CPU/GPU 跟踪支持 OpenGL/ES 和 NVTX 多窗口支持 16
Tegra GRAPHICS DEBUGGER 2.4 帧截取同时串行化为源代码 Range Profiler 支持非 root 系统支持非 Tegra 的 Android 设备 17
入门 18
入门 配置你工程的 Nsight User Settings 点击 VS 中的 Nsight 菜单, 选择 Start Graphics Debugging 程序启动后, 可以看到 Nsight 的 HUD 状态, FPS GPU 性能图示使用快捷键 Ctrl-Z 可以移动, 缩放 HUD 内的元素 19
入门 按下空格键, 捕捉当前帧实时捕捉, 程序依旧运行, 只是被暂停了 HUD 允许你 : 查看当前场景的 Drawcall 查看贴图和 Render Target 以上功能可以脱离 Visual Studio 使用可以序列化当前的一帧, 并生成 C++ 的源代码和工程, 支持 VR API! 20
入门 转到 Visual Studio Scrubber 视图 允许你查看当前的所有 Drawcall, 从 Perf Markers 上获得当前 Drawcall 的上下文信息 Event 视图 显示所有的 API 调用, 附带参数信息 和 Scrubber 视图同步 根据关键字过滤 draw pssetshader\( 如果使用了现成的中间件或者引擎, 开发者可能没有办法选择需要的 Perfmarker API. Nsight 允许显示指定的 Perfmarker, 开发者可以混用不同的 API Current Targets 视图 显示当前 Drawcall 绑定的所有 RTV 和 DSV 21
选中某一个 Drawcall, 打开 API Inspector 视图 视图左边显示了基本的 GPU 管线, 分为一个个 Stage 每个 Stage 表示当前 Drawcall 在对应管线的 Stage 上的状态 IA: 渲染管线的输入状态设置 VS, HS, DS, PS, CS: shader 状态 SO Raster OM 入门 22
入门 打开 API Statistics 视图, 有一千左右的 Draws, 但有三万九千多的其他类型的 API 调用 其中有 AddRef/Release 调用大概一万三千左右 如果你过滤 GetDesc, 会发现有大约六百个, 但是 Desc 是不可更改的, 可以缓存下来 根据 GetDesc 的 Object 排序 可以发现有一些 Texture Object 被调用了 GetDesc 大约 8-12 次 但是缓存一个 D3D11_TEXTURE2D_DESC 只需要 44 字节! 23
入门 其他 Nsight 的功能也对 VR 程序的调试有所帮助 Scrubber 视图新功能 : 根据 Drawcall 不同的特性添加不同的 Scrubber 的 Range 选择 + 按钮, 选择 viewport, 提供针对双眼的各自 Drawcall 的 Range 当你没有配置自定义的 Perfmarker 的时候, 特别有用 24
欢迎使用 Nsight HUD 显示的 performance 图表和 Drawcall scrubbing 入门 Visual Studio 集成的视图 Scrubber, Events & Current Target API Inspector & API Statistics Geometry & Resources 使用基本视图功能来定位潜在的 CPU 性能问题 25
错误的 Geometry 26
通过 Nsight 来启动对应的程序 错误的 Geometry 仅仅用来模拟 Nsight 用户曾遇到过的一类问题 : 我的渲染结果为什么变成这样了? 27
错误的 Geometry 暂停并截取一帧, 拖动 HUD 上的 scrubber 到错误的 Drawcall 问题的根源可能有很多, 使用 Nsight 来逐一检查 API Inspector VS stage Vertex Shader 出问题了? API Inspector RS stage 光栅化设置出问题了? Etc. 28
错误的 Geometry API Inspector VS stage, 展开所有的项, 检查各个 buffer, 有地方不对劲么? 29
错误的 Geometry API Inspector RS stage, 光栅化里面的 cull mode 设置, fill mode 设置, depth bias 设置, 等等, 有地方不对劲么? 30
错误的 Geometry 看上去渲染管线的设置都没问题, 可能是数据的问题? 打开 Geometry 视图 31
打开 Geometry View [Nsight 5.1 新功能 ] Nsight 已经检测到一些浮点数异常 : Floating Point Specials Detected In Vertex Data! Graphical 子视图 新的 Geometry View 可以映射任何顶点属性为渲染需要的位置 / 颜色 / 法线信息 显示法线或者 UV 信息为颜色 一直维持顶点属性的设置, 直到 vertex layout 改变 Memory 子视图 错误的 Geometry 每一个顶点为一行, 列为顶点对应的各个属性 可以以 index buffer order 或者 vertex buffer order 显示 数据显示已经考虑到了对应的 offset 32
错误的 Geometry 进一步查看 Float Point Special Detected In Vertex Data! 还可以使用 Resource 视图中的 tag 功能来显示场景中所有使用了这个 buffer 的 Drawcall. 不仅仅标记 vertex buffer, 还支持任意资源, 例如 texture 资源 33
顶点数据错误 错误的 GEOMETRY API Inspector 视图帮助检查渲染管线设置 Geometry 视图帮助检查变形前的数据 Resources 视图 + tag 来显示何处使用了资源 34
VR 但不那么立体 35
视差和双目视觉 看向前方, 选择一个物体作为前景, 例如你的手指, 或者某个人的头部交替的遮住你的左右眼睛当你切换遮住的眼睛的时候, 注意到你选择的物体相对于背景是移动的这个叫做视差, 是人类双目视觉系统本能的一部分赋予我们感知深度的能力, 同时 VR 利用其来实现更加沉浸式的体验 36
视差和双目视觉 37
VR 但不那么立体 有些时候, VR 渲染的立体感被破坏, 进而影响体验 看到过立体场景里面的物体像是若干个不同深度的 billboard? 注意下面场景截图中飞在半空的水泥块 如果是在实际的 VR 头戴显示器上观察, 就会发现这些物体不正常的贴在半空, 就像一个 UI 或者狙击枪的十字标线一样 38
1.VR Not R 39
VR 但不那么立体 通过 Nsight 来启动对应的程序截取当前帧 (Ctrl-Z + Space 作为快捷键 ) 打开 Resources 视图, 来看看水泥块对应的深度是否会导致这个问题首先, 找到导致 不那么立体 效果的水泥块的 Drawcall 40
VR 但不那么立体 找到渲染左眼 Render Target 的 Drawcall 在 Event 视图中按下 Ctrl+F2 来收藏这个 event 找到渲染右眼 Render Target 的 Drawcall 在 Event 视图中按下 Ctrl+F2 来收藏这个 event 如果你没有自定义 PerfMarker, 可以使用 Scrubber 视图中自定义的 Viewport 项添加新的一行 Range 集合, 进而确认这些 Drawcall 对应不同的眼睛 打开 Current Target 视图, 选择并点击当前的深度图, 来打开 Resources 视图, 进而检查对应深度贴图的详细信息 41
42
VR 但不那么立体 在 Resources 视图中检查当前的 DSV 注意, 你可能只能看到全黑或者全白的图像 打开 histogram and renormalize (texture 图片右下角的小箭头 ), 拖动 max 箭头来调整当前显示值的范围, 这样就可以看到深度贴图的细节信息 注意水泥块在每个眼睛下的深度信息 43
44
VR 但不那么立体 使用 API Inspector 视图来确认渲染管线的设置, 看上去都没问题还有其他因素可能影响么? 我们需要查看 VR 的设置! 打开 VR Inspector 视图可以查看 Swap Chains, Mirror Textures, Render Desc Queries, HMD 信息 45
46
VR 但不那么立体 点击其中的 Show API Usage 可以在 Events 视图中显示所有的 VR API 调用 47
VR 但不那么立体 仔细查看 VR Inspector 视图里面的 Render Desc Queries VR 程序 query 了左眼的状态两次这可能是在 copy-paste 的时候, 忘记更改右眼的状态了 改回左右眼 query 各一次, 重新启动, 问题解决了! 48
VR 但不那么立体 在 Events 视图中收藏特定的 Drawcall 在 Resources 视图中查看贴图图像的柱状图查看器及重映射在 API Inspector 视图中检查渲染管线的设置在 VR Inspector 视图中检查 VR 的设置 49
瓶颈在哪儿? 50
瓶颈在哪儿? 通过 Nsight 来启动对应的程序 如果是 GPU bound 的话, 你希望使用 profiler 来定位渲染管线的那一部分是瓶颈, 会导致程序性能下降 在 Scrubber 视图上右键单击, 选择 Profile Frame 来打开新的 Range Profiler 视图 传统的 Profiler 是以 Drawcall 为中心, 允许按照管线状态来分类 Drawcall 新的 Profiler 是以 Range 为中心 : 一系列的 Drawcall 定义了一个 Range. 51
瓶颈在哪儿? 新的范式是 Range, 基于渲染管线的状态定义通过 Perf Markers 来定义 Range 通过 Shader Program 来定义 Range ( 支持所有 6 种 Shader) 通过 Viewport 来定义 Range ( 适用于 VR 程序 ) 通过 Render Target 来定义 Range ( 显示那一组 RTV, DSV 使用时间最长 ) 用户自定义的 Range 通过拖动来创建一个 Range 52
瓶颈在哪儿? Range Profiler 在 Range Scrubber 下面提供了 3 个面板以提供更加详细的信息 Range Info Summary 显示当前 Range 的基本信息 ( 图元, 像素, compute shader, 等等 ) 右上方的组合框里还提供 Action Details, 允许你查看每个 Drawdcall 或者 Dispatch call 的信息 Range Profiler 相较于以前的一项关键性改进是可以有选择的获取性能剖析所需要的数据. 这对于现代的图形程序十分有用, 因为 Drawcall 的个数已经从几千个增长到以万为单位! 53
瓶颈在哪儿? Pipeline Overview Summary, 显示效率最低的前 4 个 stage Range Details, 显示传统的管线示意图, 可以看到每个 stage 的瓶颈是多少 Action Details, 显示每个 Drawcall 对应管线单元的详细信息 54
瓶颈在哪儿? Memory Summary, 显示基本的 memory 使用统计信息, 例如 L2, Framebuffer 等等 Range Details, 显示管线里面每个使用 memory 的 stage 之间的 request 和 bytes Action Details, 显示对应每个 Drawcall 的更加详细的信息 55
瓶颈在哪儿? Range Profiler 和 Dynamic Shader Edit 在 Profiler 视图中选取一个真正耗时的 Drawcall, 创建一个 User Range, 并选中转到 API Inspector 视图点击 Shader 的链接, 打开 Shader 源代码在 Shader 源码中点击右键, 选择 Shader Edit, 对代码进行一些优化点击 Profiler 视图上的 Lock 按钮, 并点击 Clone 按钮, 打开一个新的 Profiler 视图在新的 Profiler 视图中重新运行 profiler, 确认你的修改确实让性能得到提升 56
Range Profiler Scrubber 和 Ranges 瓶颈在哪儿? 新的数据视图 可以一边优化一边重跑 Profiler 动态的编辑 Shader, 对其进行优化 重跑 Profiler, 确认优化确实起作用了 57
Questions? Nsight 支持论坛 : https://devtalk.nvidia.com/default/board/84/nsight-visual-studio-edition/ 开发工具支持邮箱 : devtools-support@nvidia.com 欢迎进行询问, 讨论和建议 58
谢谢! 59