diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9173d3b..73b21fd 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -19,4 +19,4 @@ sphinx: # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html # python: # install: -# - requirements: docs/requirements.txt \ No newline at end of file +# - requirements: docs/requirements.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 849247f..515418b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,9 @@ option(NO_DEFAULT_QT "Add -DNO_DEFAULT_QT=ON to disable using default Qt package # Boolean option to enable live Vulkan mode. option(RGA_ENABLE_VULKAN "Add -DRGA_ENABLE_VULKAN=OFF to build RGA without Vulkan mode support. By default, Vulkan mode is enabled." ON) +# Boolean option to disable dx10 mode. +option(RGA_DISABLE_DX10 "Add -DRGA_DISABLE_DX10=OFF to build RGA without DX10 support. By default, DX10 support is enabled." OFF) + # Define build level here add_definitions(-DAMDT_PUBLIC -DCMAKE_BUILD) diff --git a/build/dependency_map.py b/build/dependency_map.py index baf3046..631d2b0 100644 --- a/build/dependency_map.py +++ b/build/dependency_map.py @@ -44,8 +44,8 @@ "tsingleton" : ["../external/tsingleton", "master"], "common_src_miniz" : ["../external/miniz", "master"], "dynamic_library_module" : ["../external/dynamic_library_module", "amd-rga-v2.7"], - "device_info" : ["../external/device_info", "c374c2b328bea66a92db6e49f6b32607f97b3e2c"], + "device_info" : ["../external/device_info", "rga-v2.11"], "update_check_api" : ["../external/update_check_api", "v2.1.1"], # QtCommon. - "qt_common" : ["../external/qt_common", "6377814493f6e5c97fd5c44fccdd22767bf86355"], + "qt_common" : ["../external/qt_common", "78e1cee86c75941f9936110334b9e10d1f4db869"], } diff --git a/build/pre_build.py b/build/pre_build.py index d890d56..9fbc94f 100644 --- a/build/pre_build.py +++ b/build/pre_build.py @@ -46,6 +46,8 @@ def parse_arguments(): parser.add_argument("--qt", default="6.7.0", help="specify the version of QT to be used with the script (default: 6.7.0)" ) parser.add_argument("--clean", action="store_true", help="delete any directories created by this script") parser.add_argument("--no-qt", action="store_true", help="build a headless version (not applicable for all products)") + parser.add_argument("--no-vulkan", action="store_true", help="build a version without vulkan support") + parser.add_argument("--no-dx10", action="store_true", help="build a version without dx10 support") parser.add_argument("--build-number", default="0", help="specify the build number, primarily to be used by build machines to produce versioned builds") parser.add_argument("--internal", action="store_true", help="configure internal builds of the RGA applications (only used within AMD") @@ -217,7 +219,10 @@ def generate_config(config, args): cmake_args = ["cmake", cmakelist_path, "-DCMAKE_PREFIX_PATH=" + qt_path, "-DQT_PACKAGE_ROOT=" + qt_path, "-G", cmake_generator] else: - cmake_args = ["cmake", cmakelist_path, "-DHEADLESS=TRUE"] + cmake_args = ["cmake", cmakelist_path, "-DHEADLESS=TRUE", "-DBUILD_CLI_ONLY=ON"] + + if args.no_dx10: + cmake_args.extend(["-DRGA_DISABLE_DX10=ON"]) if sys.platform == "win32": if args.vs != "2017": @@ -228,7 +233,6 @@ def generate_config(config, args): elif args.toolchain == "2017": cmake_args.extend(["-Tv141"]) - # Use build number. cmake_args.extend(["-DRGA_BUILD_NUMBER=" + str(args.build_number)]) @@ -238,6 +242,9 @@ def generate_config(config, args): if not args.vk_lib is None: cmake_args.extend(["-DVULKAN_SDK_LIB_DIR=" + str(args.vk_lib)]) + if args.no_vulkan: + cmake_args.extend(["-DRGA_ENABLE_VULKAN=OFF"]) + if sys.platform.startswith('linux'): if args.disable_extra_qt_lib_deploy: cmake_args.extend(["-DDISABLE_EXTRA_QT_LIB_DEPLOY:BOOL=TRUE"]) diff --git a/documentation/RGA_RELEASE_NOTES.docx b/documentation/RGA_RELEASE_NOTES.docx index 531ac44..208e0e2 100644 Binary files a/documentation/RGA_RELEASE_NOTES.docx and b/documentation/RGA_RELEASE_NOTES.docx differ diff --git a/documentation/RGA_RELEASE_NOTES.txt b/documentation/RGA_RELEASE_NOTES.txt index 071e643..4ff8478 100644 --- a/documentation/RGA_RELEASE_NOTES.txt +++ b/documentation/RGA_RELEASE_NOTES.txt @@ -1,14 +1,16 @@ -Radeon GPU Analyzer 2.10.0 Release Notes -======================================== +Radeon™ GPU Analyzer 2.11 Release Notes +======================================= Highlights ========== -- The RGA GUI application now handles display scaling, which allows for a better experience when working with multiple monitors or when changing display settings. -- Analyze pre-compiled HIP Code Object binaries for the MI-300 with RGA's Binary Analysis mode. -- Added support for MI-300 (gfx942) as a target in OpenCL mode. -- DX12 single shader support: compile single DX12 shaders in isolation (CS, VS or PS). When an incomplete DX12 pipeline is received (missing a shader, root signature or state subset), the tool will use reflection to auto-generate the missing pieces of the pipeline for you. No impact to the invocation command, just omit the missing pieces. -- DX12 Agility SDK updated to version v613. -- DXC updated to version v1.8.2403.2 (HLSL 2021 is now enabled by default). +- Added support for gfx1150 as a compiler target across all modes. +- DXR mode now supports AMD compiler’s raytracing updates. With Radeon Adrenalin™ driver version 24.9.1, the AMD compiler includes changes to the way raytracing state objects are being compiled. Use this new version of RGA to ensure compatibility with the new compiler. +- Dark mode: the RGA GUI application now lets you choose between Light and Dark themes or have the UI follow the OS theme. To control this behavior, visit the tool’s Settings menu. +- Updated DXC to version v1.8.2407. +- Updated the offline Vulkan and OpenGL compilers. +Notes: +• As part of adding support for AMD compiler’s raytracing updates, the DXR invocation command is now simplified, removing support for the --mode and --export command line options. Any DXR state object compilation would be considered a Pipeline compilation, and it is up to the driver to decide on the compilation type (Indirect vs. Unified). For more information and usage examples, run rga -s dxr -h. +• This release removes support for pre-RDNA targets in the Vulkan offline mode. Known Issues ============ @@ -220,6 +222,11 @@ GUI Application - Certain GDS instructions are being misclassified as SALU. - Changing disassembly columns can be sluggish on certain systems in projects with multiple .cl files. - On systems with default Unicode path for the RGA projects folder, the tool will not be able to save files. A workaround has been provided in version 2.6.1 (allowing the user to change the folder in which projects are saved). +- On Linux, if the OS color theme is updated while the RGA GUI application is running, the RGA GUI application will not immediately reflect these changes (the changes will be reflected the next time that you launch the application). + +General +- RGA compilation is not impacted by Driver Experiments. Activating driver experiments would generally have no impact on RGA’s behavior and the compiled shaders, kernels and pipelines. + Notes for OpenCL Mode Users =========================== diff --git a/documentation/source/conf.py b/documentation/source/conf.py index ddb3e48..69c88f8 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -55,9 +55,9 @@ # built documents. # # The short X.Y version. -version = '2.10.0' +version = '2.11.0' # The full version, including alpha/beta/rc tags. -release = '2.10.0' +release = '2.11.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/documentation/source/help_manual.rst b/documentation/source/help_manual.rst index 10a4b84..4c0efce 100644 --- a/documentation/source/help_manual.rst +++ b/documentation/source/help_manual.rst @@ -113,6 +113,8 @@ The Application Settings view is used to configure global application settings t * Default API on startup: RGA will always enter the selected API Mode upon startup. + * Color theme: "Detect OS" is the default. This will use the system's setting for the color theme. + * **Disassembly View** * Disassembly view columns: The set of disassembly view columns which will be visible by default. @@ -458,6 +460,8 @@ The Application Settings view is used to configure global application settings t * Default API on startup: RGA will always enter the selected API Mode upon startup. + * Color theme: "Detect OS" is the default. This will use the system's setting for the color theme. + * **Disassembly View** * Disassembly view columns: The set of disassembly view columns which will be visible by default. @@ -739,6 +743,8 @@ The Application Settings view is used to configure global application settings t * Default API on startup: RGA will always enter the selected API Mode upon startup. + * Color theme: "Detect OS" is the default. This will use the system's setting for the color theme. + * **Disassembly View** * Disassembly view columns: The set of disassembly view columns which will be visible by default. @@ -1029,6 +1035,23 @@ By default, RGA will use the compiler that is bundled with the package. You can * **Libraries folder:** Path to alternative compiler's OpenCL™ device libraries folder. The following bitcode files are expected to be in the specified folder: irif.amdgcn.bc, ockl.amdgcn.bc, oclc_correctly_rounded_sqrt_off.amdgcn.bc, oclc_correctly_rounded_sqrt_on.amdgcn.bc, oclc_daz_opt_off.amdgcn.bc, oclc_daz_opt_on.amdgcn.bc, oclc_finite_only_off.amdgcn.bc, oclc_finite_only_on.amdgcn.bc, oclc_isa_version_900.amdgcn.bc, oclc_isa_version_901.amdgcn.bc, oclc_isa_version_902.amdgcn.bc, oclc_unsafe_math_off.amdgcn.bc, oclc_unsafe_math_on.amdgcn.bc, ocml.amdgcn.bc, opencl.amdgcn.bc +Change the Color Theme +^^^^^^^^^^^^^^^^^^^^^^ + +RGA now supports switching between dark and light color themes. + +.. image:: images/2_1/rga_dark_mode_example.png + +#. Navigate to the "Application settings" section of the Settings tab and select the color theme drop down. + +.. image:: images/2_1/rga_color_theme_setting.png + +#. "Detect OS" is the default option and will use the system's setting for the color theme. "Light" theme uses light backgrounds and dark text, while in "Dark" theme RGA will have dark backgrounds with lighter colored text. + +#. After setting the color theme and saving you will be prompted to restart the application. If the application is not restarted not all ui elements will update to reflect the new color theme. + +.. image:: images/2_1/color_theme_changed_restart_application_dialog.png + Keyboard Shortcuts ------------------ RGA provides several keyboard shortcuts to facilitate mouse-free usage. diff --git a/documentation/source/images/2_1/color_theme_changed_restart_application_dialog.png b/documentation/source/images/2_1/color_theme_changed_restart_application_dialog.png new file mode 100644 index 0000000..63f157f Binary files /dev/null and b/documentation/source/images/2_1/color_theme_changed_restart_application_dialog.png differ diff --git a/documentation/source/images/2_1/rga_color_theme_setting.png b/documentation/source/images/2_1/rga_color_theme_setting.png new file mode 100644 index 0000000..4772693 Binary files /dev/null and b/documentation/source/images/2_1/rga_color_theme_setting.png differ diff --git a/documentation/source/images/2_1/rga_dark_mode_example.png b/documentation/source/images/2_1/rga_dark_mode_example.png new file mode 100644 index 0000000..697a6d3 Binary files /dev/null and b/documentation/source/images/2_1/rga_dark_mode_example.png differ diff --git a/external/amdt_os_wrappers/CMakeLists.txt b/external/amdt_os_wrappers/CMakeLists.txt index 28bafbc..3c4fc9f 100644 --- a/external/amdt_os_wrappers/CMakeLists.txt +++ b/external/amdt_os_wrappers/CMakeLists.txt @@ -184,7 +184,7 @@ endif() set_target_properties(AMDTOSWrappers PROPERTIES DEBUG_POSTFIX -d CXX_STANDARD 17) # Set Visual C++ warning level to 4 -if(MSVC) +if(MSVC AND RGA_ENABLE_VULKAN) target_compile_options(vulkan_backend PRIVATE /W4) endif() diff --git a/external/dxc/dxc.exe b/external/dxc/dxc.exe index 6f114c7..eea89b2 100644 Binary files a/external/dxc/dxc.exe and b/external/dxc/dxc.exe differ diff --git a/external/dxc/dxcompiler.dll b/external/dxc/dxcompiler.dll index 19c64e6..9f67e88 100644 --- a/external/dxc/dxcompiler.dll +++ b/external/dxc/dxcompiler.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb0e6196eae92f69f7e3a8a0bf0e35f30d7c2adad475bebbde3a41015ca0b414 -size 17802672 +oid sha256:1220478c87af97551d2342906c5a08d888ee9fa26f6f99b6072d674801f492d1 +size 17972656 diff --git a/external/dxc/dxil.dll b/external/dxc/dxil.dll index 895c4b0..db5a1ce 100644 Binary files a/external/dxc/dxil.dll and b/external/dxc/dxil.dll differ diff --git a/external/lc/disassembler/linux/amdgpu-dis b/external/lc/disassembler/linux/amdgpu-dis index 894924f..fffb272 100644 --- a/external/lc/disassembler/linux/amdgpu-dis +++ b/external/lc/disassembler/linux/amdgpu-dis @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:17eba5f1e01cf2f534116e8dbd20aab859f90bde10f289a3683152cb3f490c5d -size 13396792 +oid sha256:5321b1e5140522e0c31b2b81a2824b290f9b656bdf8647d4acf9b0ae1a660baa +size 15181096 diff --git a/external/lc/disassembler/windows/amdgpu-dis.exe b/external/lc/disassembler/windows/amdgpu-dis.exe index d50d272..d2bafb9 100644 --- a/external/lc/disassembler/windows/amdgpu-dis.exe +++ b/external/lc/disassembler/windows/amdgpu-dis.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5161862b2bc65b1a70b74886288ad08622c8553c279c7df8547bc3899390c1d5 -size 12586496 +oid sha256:4e3e78bfb33863102cf1c9b0dbe3c55d2de3e1a6f4f7237dfd0946bd9620874f +size 14981120 diff --git a/external/lc/opencl/linux/bin/clang-18 b/external/lc/opencl/linux/bin/clang-18 index 685a206..299ef1e 100644 --- a/external/lc/opencl/linux/bin/clang-18 +++ b/external/lc/opencl/linux/bin/clang-18 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2f3cafbca8d4f4840989d46882d931b0c34460f700e4fc9716216b784e497a5 -size 149846360 +oid sha256:a734d74038ba6fb802bd0d0d28c43cba3ae811e2442114567207559f04874180 +size 151017120 diff --git a/external/lc/opencl/linux/bin/lld b/external/lc/opencl/linux/bin/lld index 5903004..4ffe2d5 100644 --- a/external/lc/opencl/linux/bin/lld +++ b/external/lc/opencl/linux/bin/lld @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3786ebd2b35fdd3e749813ac2863fd1c0ad4e0569d9cefc4267c593f4aecd929 -size 83104752 +oid sha256:6656ee41c400046a2f5193bdf24d0da89c48b0b876bac1835d6df6b0780a89eb +size 83610872 diff --git a/external/lc/opencl/linux/bin/llvm-objdump b/external/lc/opencl/linux/bin/llvm-objdump index 3891d74..2ab6d92 100644 --- a/external/lc/opencl/linux/bin/llvm-objdump +++ b/external/lc/opencl/linux/bin/llvm-objdump @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6f64b83036d626a45ea6996bb5983d7873253834d67d63872c90ca0a5072b99 -size 16081136 +oid sha256:380e82148f9bb92a4c00ca96a9bd0865317c1b5b35b60b887f99c127cabf7668 +size 17175880 diff --git a/external/lc/opencl/linux/bin/llvm-readobj b/external/lc/opencl/linux/bin/llvm-readobj index f76e4db..4c877a1 100644 --- a/external/lc/opencl/linux/bin/llvm-readobj +++ b/external/lc/opencl/linux/bin/llvm-readobj @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebdbc7624fff5948095cde9ad5a573535af239314794de6719f6c8a9e5ec5634 -size 9566384 +oid sha256:5416f7db5a848478ad7bc31fe6a2ae969f2d1b1408ae89068ef8e91390d8c788 +size 9646272 diff --git a/external/lc/opencl/linux/lib/bitcode/hip.bc b/external/lc/opencl/linux/lib/bitcode/hip.bc index 8ff577e..79eae7b 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/hip.bc and b/external/lc/opencl/linux/lib/bitcode/hip.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/ockl.bc b/external/lc/opencl/linux/lib/bitcode/ockl.bc index ff5f75d..c7635a3 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/ockl.bc and b/external/lc/opencl/linux/lib/bitcode/ockl.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_400.bc b/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_400.bc index c59602f..6b58ace 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_400.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_400.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_500.bc b/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_500.bc index 759b3ca..237956f 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_500.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_abi_version_500.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc b/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc index 29fb9d7..00aa1aa 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc b/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc index 2460a9a..87c5f3c 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_off.bc b/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_off.bc index e06ba05..a0ccb56 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_off.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_off.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_on.bc b/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_on.bc index 75cbc4d..6d3c8c6 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_on.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_daz_opt_on.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_off.bc b/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_off.bc index 3b7a403..26f46be 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_off.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_off.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_on.bc b/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_on.bc index 1e7fcbc..50d9b55 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_on.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_finite_only_on.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1010.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1010.bc index 5afef0b..bdc248b 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1010.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1010.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1011.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1011.bc index b4f6e9b..ff771fc 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1011.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1011.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1012.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1012.bc index b4b996d..cff7f93 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1012.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1012.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1030.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1030.bc index 92b1c81..6be1b02 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1030.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1030.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1031.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1031.bc index 42d2550..a779492 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1031.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1031.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1032.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1032.bc index 483cd6c..13e99a3 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1032.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1032.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1034.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1034.bc index ff578a3..12f227c 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1034.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1034.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1035.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1035.bc index 8a86eed..ebd21be 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1035.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1035.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1100.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1100.bc index cb7ab01..83ba41e 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1100.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1100.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1101.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1101.bc index 4edcb77..be8769b 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1101.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1101.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1102.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1102.bc index 3b0d010..e17cd57 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1102.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1102.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1103.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1103.bc index 10eaf53..438db64 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1103.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1103.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1150.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1150.bc new file mode 100644 index 0000000..95ac10e Binary files /dev/null and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_1150.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_900.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_900.bc index d4d1078..58d1791 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_900.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_900.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_902.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_902.bc index 7c06595..ae230c3 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_902.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_902.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_904.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_904.bc index d5bd890..17d7423 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_904.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_904.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_906.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_906.bc index 70c1eb4..bd674f3 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_906.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_906.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_908.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_908.bc index a0eecb4..c26a19c 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_908.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_908.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_909.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_909.bc index ee73297..2df7835 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_909.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_909.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90a.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90a.bc index d7678d1..2d6139d 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90a.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90a.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90c.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90c.bc index 3387fac..be84639 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90c.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_90c.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_942.bc b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_942.bc index 95ea332..4548648 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_942.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_isa_version_942.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_off.bc b/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_off.bc index e60d716..a73b71e 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_off.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_off.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_on.bc b/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_on.bc index 0d5b12d..c00e87f 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_on.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_unsafe_math_on.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_off.bc b/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_off.bc index 3b6875e..dba63f5 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_off.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_off.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_on.bc b/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_on.bc index b2ae296..4189c47 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_on.bc and b/external/lc/opencl/linux/lib/bitcode/oclc_wavefrontsize64_on.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/ocml.bc b/external/lc/opencl/linux/lib/bitcode/ocml.bc index 559f2e9..ca9ce0d 100644 Binary files a/external/lc/opencl/linux/lib/bitcode/ocml.bc and b/external/lc/opencl/linux/lib/bitcode/ocml.bc differ diff --git a/external/lc/opencl/linux/lib/bitcode/opencl.bc b/external/lc/opencl/linux/lib/bitcode/opencl.bc index 1eade50..a0a1e92 100644 --- a/external/lc/opencl/linux/lib/bitcode/opencl.bc +++ b/external/lc/opencl/linux/lib/bitcode/opencl.bc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0de8a6563b40c5a28de74eb1c3f62bcdd06903a02d0b6e04a3c4699791d6c12 -size 2698472 +oid sha256:f8172464e3f551cf77ee01b917fa2785223922ecb1f5423c53568e9172bcfe54 +size 2700684 diff --git a/external/lc/opencl/windows/bin/clang.exe b/external/lc/opencl/windows/bin/clang.exe index e3c05b1..fcf66a3 100644 --- a/external/lc/opencl/windows/bin/clang.exe +++ b/external/lc/opencl/windows/bin/clang.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:113e07b52c0698d941d014202ff4e98dd1e2b5c990ee5696ec45901b425aa09b -size 85504512 +oid sha256:5d395a44d4e9fafe486f0d21589edbc79b59297665e757e5f3da469a8167c51a +size 86351872 diff --git a/external/lc/opencl/windows/bin/ld.lld.exe b/external/lc/opencl/windows/bin/ld.lld.exe index dca5c50..db1e370 100644 --- a/external/lc/opencl/windows/bin/ld.lld.exe +++ b/external/lc/opencl/windows/bin/ld.lld.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7478f4a38672dd8db25fb15c417bcc4c08955d11868b7c843411da6ef5555eac -size 50981888 +oid sha256:b533c81c4e2c58a27aafe7ec22441b443207b344a268326aee8c7e2309b51bea +size 51392512 diff --git a/external/lc/opencl/windows/bin/llvm-objdump.exe b/external/lc/opencl/windows/bin/llvm-objdump.exe index 64ccf4a..b03d7f8 100644 --- a/external/lc/opencl/windows/bin/llvm-objdump.exe +++ b/external/lc/opencl/windows/bin/llvm-objdump.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c02bc4028b40fb9ec5c03827c61d3ef9801d2d7d800bb833a4e816107751acf -size 14623744 +oid sha256:9cc22d099424a2838b772b82f89545716ebf23700d5d561bf81356d6b2c4ebf3 +size 16120320 diff --git a/external/lc/opencl/windows/bin/llvm-readobj.exe b/external/lc/opencl/windows/bin/llvm-readobj.exe index 17a88b0..fbdf6b4 100644 --- a/external/lc/opencl/windows/bin/llvm-readobj.exe +++ b/external/lc/opencl/windows/bin/llvm-readobj.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25130d837b34b387491dc57f6d9543d3d6b9d7eb83dfe4aa183904767eb23a8f -size 6884352 +oid sha256:e2e3866edae5f3c12dfa86da4814f9895c11b9ef9c4ddc71f424cc1b8eb563dc +size 6916608 diff --git a/external/lc/opencl/windows/lib/bitcode/hip.bc b/external/lc/opencl/windows/lib/bitcode/hip.bc index 9cedab7..19a063a 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/hip.bc and b/external/lc/opencl/windows/lib/bitcode/hip.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/ockl.bc b/external/lc/opencl/windows/lib/bitcode/ockl.bc index 2bf0d82..b35dec1 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/ockl.bc and b/external/lc/opencl/windows/lib/bitcode/ockl.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_400.bc b/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_400.bc index cacdc5b..dd7585b 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_400.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_400.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_500.bc b/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_500.bc index 1c0995c..d1e8a6c 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_500.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_abi_version_500.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc b/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc index 8fe17f9..cb221a5 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_off.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc b/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc index 93f6e61..e295186 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_correctly_rounded_sqrt_on.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_off.bc b/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_off.bc index c7ae6f2..d62cba6 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_off.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_off.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_on.bc b/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_on.bc index 5d96401..27c9819 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_on.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_daz_opt_on.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_off.bc b/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_off.bc index bc27510..0cb2390 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_off.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_off.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_on.bc b/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_on.bc index 7ae235a..1d7a230 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_on.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_finite_only_on.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1010.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1010.bc index 6ca3002..e01a3a6 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1010.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1010.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1011.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1011.bc index 0e720f5..539ccd1 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1011.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1011.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1012.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1012.bc index f40b571..d454a64 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1012.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1012.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1030.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1030.bc index ea7a4f1..58dd0e6 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1030.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1030.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1031.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1031.bc index cf13934..18d22b7 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1031.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1031.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1032.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1032.bc index 53ff988..c71c220 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1032.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1032.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1034.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1034.bc index 61e19e9..66e1aea 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1034.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1034.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1035.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1035.bc index e12022f..7c6e459 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1035.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1035.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1100.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1100.bc index ebe9731..40abca2 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1100.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1100.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1101.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1101.bc index 72b6999..72368de 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1101.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1101.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1102.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1102.bc index addecf2..66a85bf 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1102.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1102.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1103.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1103.bc index 12fcb13..624b3b6 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1103.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1103.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1150.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1150.bc new file mode 100644 index 0000000..42c19d6 Binary files /dev/null and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_1150.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_900.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_900.bc index 7273fd2..0525ed9 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_900.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_900.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_902.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_902.bc index ad1e833..ec88551 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_902.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_902.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_904.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_904.bc index 3803c1e..8e2c0e7 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_904.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_904.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_906.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_906.bc index dd34642..641ca3c 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_906.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_906.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_908.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_908.bc index dbb8e38..91f2f6c 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_908.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_908.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_909.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_909.bc index ddc184e..e8ecf6a 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_909.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_909.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90a.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90a.bc index a1e6887..1932946 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90a.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90a.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90c.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90c.bc index 089b9ef..83f004e 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90c.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_90c.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_942.bc b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_942.bc index 3f1ddbe..a187f2f 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_942.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_isa_version_942.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_off.bc b/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_off.bc index 113b1b4..68b0e77 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_off.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_off.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_on.bc b/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_on.bc index f7205d6..68327e5 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_on.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_unsafe_math_on.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_off.bc b/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_off.bc index 42ded7d..f8bdab6 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_off.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_off.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_on.bc b/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_on.bc index 0e67ca6..6a3a596 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_on.bc and b/external/lc/opencl/windows/lib/bitcode/oclc_wavefrontsize64_on.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/ocml.bc b/external/lc/opencl/windows/lib/bitcode/ocml.bc index 90c19e6..7e4409a 100644 Binary files a/external/lc/opencl/windows/lib/bitcode/ocml.bc and b/external/lc/opencl/windows/lib/bitcode/ocml.bc differ diff --git a/external/lc/opencl/windows/lib/bitcode/opencl.bc b/external/lc/opencl/windows/lib/bitcode/opencl.bc index 549fbf2..b7a19ce 100644 --- a/external/lc/opencl/windows/lib/bitcode/opencl.bc +++ b/external/lc/opencl/windows/lib/bitcode/opencl.bc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fde7a753d93a4c63d18549c6becf75a7d1c385f5ed8400063e6bcd7f7922bfa1 -size 2699580 +oid sha256:e488beff5d2bcfa18a3795328620bafe3114975d135f8838205739338db2a77a +size 2701784 diff --git a/external/opengl/glc/linux/glc b/external/opengl/glc/linux/glc index ed82e29..0675999 100644 --- a/external/opengl/glc/linux/glc +++ b/external/opengl/glc/linux/glc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b603dedd28de53e6dea236427bb39d14961f380c43a68f2bf005486489f9274 -size 57375312 +oid sha256:f9d114fd3c75891033e7e404b7cf062ec52e2e2225ff0964d4c2143f160a5553 +size 65878960 diff --git a/external/opengl/glc/windows/glc.exe b/external/opengl/glc/windows/glc.exe index 89166e0..969bc06 100644 --- a/external/opengl/glc/windows/glc.exe +++ b/external/opengl/glc/windows/glc.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2ff4aa9baea036afd97f7757fef83b4ab811933627721abe390515b18aa3950 -size 42457600 +oid sha256:60eefd7ee12b55efe5749abb25412809b521b3a940314331d6c71c367fc030e0 +size 43520000 diff --git a/external/vulkan_offline/linux/amdllpc b/external/vulkan_offline/linux/amdllpc index b2327d7..f83d3e3 100644 --- a/external/vulkan_offline/linux/amdllpc +++ b/external/vulkan_offline/linux/amdllpc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01e49c17f281bdf727152ec1a7d2ea001c55dae5e8b3b7d58da49344df8181d3 -size 77895664 +oid sha256:26d3192fd8284d13695127aaa6fbbfd6d89a5ec273fd87fc5983c45d4ebf19f9 +size 102076128 diff --git a/external/vulkan_offline/windows/amdllpc.exe b/external/vulkan_offline/windows/amdllpc.exe index 10007cc..10cc1d2 100644 --- a/external/vulkan_offline/windows/amdllpc.exe +++ b/external/vulkan_offline/windows/amdllpc.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4ae106c0a9af78487811aa5a52362faa7807ddc53a8fed1710b5120b06ca2d9 -size 50889216 +oid sha256:00df050146c333149735a065333b5d1795e0acf07c99eddbb4a52468c429d96e +size 64591360 diff --git a/installer/RGA-Installer.aip b/installer/RGA-Installer.aip index 8dcd3cd..3f5c72a 100755 --- a/installer/RGA-Installer.aip +++ b/installer/RGA-Installer.aip @@ -244,6 +244,7 @@ + @@ -300,7 +301,7 @@ - + @@ -325,6 +326,7 @@ + @@ -370,6 +372,8 @@ + + diff --git a/source/common/rga_sorting_utils.h b/source/common/rga_sorting_utils.h index 545882f..08bee26 100644 --- a/source/common/rga_sorting_utils.h +++ b/source/common/rga_sorting_utils.h @@ -18,6 +18,7 @@ static const char* kStrRdna2 = "RDNA2"; static const char* kStrCdna2 = "CDNA2"; static const char* kStrRdna3 = "RDNA3"; static const char* kStrCdna3 = "CDNA3"; +static const char* kStrRdna3_5 = "RDNA3.5"; enum class GpuArchitecture { @@ -30,7 +31,8 @@ enum class GpuArchitecture kGpuArchitectureRdna2, kGpuArchitectureCdna2, kGpuArchitectureRdna3, - kGpuArchitectureCdna3 + kGpuArchitectureCdna3, + kGpuArchitectureRdna3_5 }; // GPU Architectures sort priority. @@ -43,7 +45,8 @@ static const std::unordered_map kGpuSortPriority = {kStrRdna2, GpuArchitecture::kGpuArchitectureRdna2}, {kStrCdna2, GpuArchitecture::kGpuArchitectureCdna2}, {kStrRdna3, GpuArchitecture::kGpuArchitectureRdna3}, - {kStrCdna3, GpuArchitecture::kGpuArchitectureCdna3}}; + {kStrCdna3, GpuArchitecture::kGpuArchitectureCdna3}, + {kStrRdna3_5, GpuArchitecture::kGpuArchitectureRdna3_5}}; // Definition of GpuComparator template diff --git a/source/common/rga_version_info.h b/source/common/rga_version_info.h index 5cdd896..ef866a8 100644 --- a/source/common/rga_version_info.h +++ b/source/common/rga_version_info.h @@ -1,7 +1,7 @@ #pragma once #define RGA_VERSION_MAJOR 2 -#define RGA_VERSION_MINOR 10 +#define RGA_VERSION_MINOR 11 #define RGA_VERSION_UPDATE 0 #define GEN_RGA_VERSION(MAJOR, MINOR, UPDATE) MAJOR.MINOR.UPDATE #define RGA_VERSION_MAJOR_MINOR GEN_RGA_VERSION(RGA_VERSION_MAJOR, RGA_VERSION_MINOR, RGA_VERSION_UPDATE) diff --git a/source/radeon_gpu_analyzer_backend/CMakeLists.txt b/source/radeon_gpu_analyzer_backend/CMakeLists.txt index 5cd00b7..ae5b394 100755 --- a/source/radeon_gpu_analyzer_backend/CMakeLists.txt +++ b/source/radeon_gpu_analyzer_backend/CMakeLists.txt @@ -113,14 +113,18 @@ endif() # Pick up the source files that are relevant to the platform if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") add_library(radeon_gpu_analyzer_backend STATIC ${COMMON_SRC} ${WINDOWS_SRC} ${DEVICE_INFO_SRC}) - if (CMAKE_64BIT_TARGET) - find_library(DX10ASM_LIBRARY_RELEASE DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/x64/Release_Static") - find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/x64/Debug_Static") + if(NOT RGA_DISABLE_DX10) + if (CMAKE_64BIT_TARGET) + find_library(DX10ASM_LIBRARY_RELEASE DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/x64/Release_Static") + find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/x64/Debug_Static") + else() + find_library(DX10ASM_LIBRARY_RELEASE DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/Win32/Release_Static") + find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/Win32/Debug_Static") + endif() + target_link_libraries(radeon_gpu_analyzer_backend optimized ${DX10ASM_LIBRARY_RELEASE} debug ${DX10ASM_LIBRARY_DEBUG}) else() - find_library(DX10ASM_LIBRARY_RELEASE DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/Win32/Release_Static") - find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../../external/dx10_asm/lib/VS2015/Win32/Debug_Static") + add_definitions(-DDISABLE_DX10) endif() - target_link_libraries(radeon_gpu_analyzer_backend optimized ${DX10ASM_LIBRARY_RELEASE} debug ${DX10ASM_LIBRARY_DEBUG}) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") add_library(radeon_gpu_analyzer_backend STATIC ${COMMON_SRC} ${LINUX_SRC}) add_library(DeviceInfoLib OBJECT ${DEVICE_INFO_SRC}) diff --git a/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.cpp b/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.cpp index d14d1ef..6bf527e 100644 --- a/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.cpp +++ b/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.cpp @@ -234,10 +234,3 @@ bool BeDx12Utils::ParseShaderModel(const std::string& shader_model_str, ShaderMo } return ret; } - -// Returns true if this is DXR Shader mode and false otherwise. -bool BeDx12Utils::IsDxrShaderMode(const Config& config) -{ - std::string dxr_mode = RgaSharedUtils::ToLower(config.dxr_mode); - return (dxr_mode.compare(kStrDxrModeShader) == 0); -} diff --git a/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.h b/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.h index 9ddd6cc..7e7ef04 100644 --- a/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.h +++ b/source/radeon_gpu_analyzer_backend/autogen/be_utils_dx12.h @@ -15,10 +15,6 @@ // C++ #include -// Dxr string constants. -static const char* kStrDxrModeShader = "shader"; -static const char* kStrDxrModePipeline = "pipeline"; - class BeDx12Utils { public: @@ -83,9 +79,6 @@ class BeDx12Utils // In case of a failure, for example, if the shader model format is invalid, false is return. // Otherwise, true is returned. static bool ParseShaderModel(const std::string& shader_model_str, ShaderModelVersion& shader_model); - - // Returns true if this is DXR Shader mode and false otherwise. - static bool IsDxrShaderMode(const Config& config); }; #endif // RGA_RADEONGPUANALYZERBACKEND_SRC_BE_UTILS_DX12_H_ diff --git a/source/radeon_gpu_analyzer_backend/autogen/be_validator_dx12.cpp b/source/radeon_gpu_analyzer_backend/autogen/be_validator_dx12.cpp index c8c6b74..2c464f7 100644 --- a/source/radeon_gpu_analyzer_backend/autogen/be_validator_dx12.cpp +++ b/source/radeon_gpu_analyzer_backend/autogen/be_validator_dx12.cpp @@ -55,11 +55,6 @@ static const char* kStrErrorDxrStateDescAndHlslFileMix = "Error: cannot mix --state-desc and --hlsl options.If --hlsl option is used, it must contain the entire state definition in the HLSL source code."; static const char* kStrErrorDxrStateDescFileNotFoundOrEmpty = "Error: DXR state JSON file not found or empty: "; static const char* kStrErrorDxrHlslFileNotFoundOrEmpty = "Error: HLSL input file not found or empty: "; -static const char* kStrErrorDxrModeNotProvided = "Error: no DXR mode provided (use --mode with either 'pipeline' or 'shader' as the argument)."; -static const char* kStrErrorDxrModeNotRecognizedA = "Error: unrecognized DXR mode given: "; -static const char* kStrErrorDxrExportNotProvided = "Error: DXR export not provided (use --export option)."; -static const char* kStrErrorDxrExportNotSupportedInPipelineMode = "Error: --export option not supported in pipeline mode."; -static const char* kStrErrorDxrModeNotRecognizedB = ". Expected: pipeline or shader."; static const char* kStrWarningDxrBinaryExtractionNotSupportedInShaderMode = "Warning: pipeline binary extraction (-b option) " "is not supported in Shader mode."; @@ -381,49 +376,6 @@ static bool IsInputValidDxr(const Config& config) std::cout << kStrErrorDxrHlslFileNotFoundOrEmpty << config.dxr_hlsl << std::endl; ret = false; } - else if (config.dxr_mode.empty()) - { - // Mode not provided. - std::cout << kStrErrorDxrModeNotProvided << std::endl; - ret = false; - } - else if (BeDx12Utils::IsDxrShaderMode(config) && config.dxr_exports.empty()) - { - // Export not provided in Shader mode. - std::cout << kStrErrorDxrExportNotProvided << std::endl; - ret = false; - } - else if (!BeDx12Utils::IsDxrShaderMode(config) && !config.dxr_exports.empty()) - { - // Export not supported in Pipeline mode. - std::cout << kStrErrorDxrExportNotSupportedInPipelineMode << std::endl; - ret = false; - } - else - { - std::string dxr_mode = RgaSharedUtils::ToLower(config.dxr_mode); - ; - if (dxr_mode.compare(kStrDxrModePipeline) != 0 && dxr_mode.compare(kStrDxrModeShader) != 0) - { - // Unrecognized mode. - std::cout << kStrErrorDxrModeNotRecognizedA << dxr_mode << kStrErrorDxrModeNotRecognizedB << std::endl; - ret = false; - } - if (ret && dxr_mode.compare(kStrDxrModeShader) == 0 && !config.dxr_exports.empty() && - std::find_if(config.dxr_exports.begin(), config.dxr_exports.end(), [&](const std::string currExp) { - std::string curr_export_lower = RgaSharedUtils::ToLower(currExp); - return (curr_export_lower.compare("all") == 0); - }) != config.dxr_exports.end()) - { - std::cout << "Error: 'all' is not a valid argument for --export in Shader mode (only valid in Pipeline mode). Please specify a shader name." - << std::endl; - ret = false; - } - if (ret && dxr_mode.compare(kStrDxrModeShader) == 0 && !config.binary_output_file.empty()) - { - std::cout << kStrWarningDxrBinaryExtractionNotSupportedInShaderMode << std::endl; - } - } // In Offline mode, the target device must be specified. if ((config.dx12_offline_session || !config.alternative_amdxc.empty()) && config.asics.empty()) diff --git a/source/radeon_gpu_analyzer_backend/be_data_types.h b/source/radeon_gpu_analyzer_backend/be_data_types.h index 25a1634..d63c807 100644 --- a/source/radeon_gpu_analyzer_backend/be_data_types.h +++ b/source/radeon_gpu_analyzer_backend/be_data_types.h @@ -69,7 +69,8 @@ enum BeRtxPipelineStage : char kClosestHit, kMiss, kCallable, - kTraversal, + kTraversal, + kLaunchKernel, kCountRtx }; @@ -86,7 +87,8 @@ static const BeRtxPipelineFiles kStrRtxStageNames = "ClosestHit", "Miss", "Callable", - "Traversal" + "Traversal", + "LaunchKernel" }; // Rtx Suffixes for stage-specific output files. diff --git a/source/radeon_gpu_analyzer_backend/be_include.h b/source/radeon_gpu_analyzer_backend/be_include.h index b14fccc..1dfd254 100644 --- a/source/radeon_gpu_analyzer_backend/be_include.h +++ b/source/radeon_gpu_analyzer_backend/be_include.h @@ -119,10 +119,9 @@ enum beStatus kBeStatusVulkanFailedExtractValidationInfo, kBeStatusVulkanPreprocessFailed, KBeStatusVulkanMixedInputFiles, - kBeStatusVulkanCodeObjMdParsingFailed, - kBeStatusVulkanComputeCodeObjMetaDataSuccess, - kBeStatusVulkanGraphicsCodeObjMetaDataSuccess, - kBeStatusVulkanRayTracingCodeObjMetaDataSuccess, + kBeStatusComputeCodeObjMetaDataSuccess, + kBeStatusGraphicsCodeObjMetaDataSuccess, + kBeStatusRayTracingCodeObjMetaDataSuccess, kBeStatusLightningCompilerLaunchFailed, kBeStatusLightningCompilerTimeOut, kBeStatusLightningCompilerGeneratedError, @@ -140,6 +139,7 @@ enum beStatus kBeStatusLightningExtractKernelNamesFailed, kBeStatusLightningGetKernelCodeSizeFailed, kBeStatusBinaryInvalidInput, + kBeStatusCodeObjMdParsingFailed, kBeStatusWriteToFileFailed, kBeStatusFailedOutputVerification, kBeStatusShaeCannotLocateAnalyzer, diff --git a/source/radeon_gpu_analyzer_backend/be_metadata_parser.cpp b/source/radeon_gpu_analyzer_backend/be_metadata_parser.cpp new file mode 100644 index 0000000..643bfbd --- /dev/null +++ b/source/radeon_gpu_analyzer_backend/be_metadata_parser.cpp @@ -0,0 +1,361 @@ +//================================================================= +// Copyright 2024 Advanced Micro Devices, Inc. All rights reserved. +//================================================================= + +// C++. +#include +#include + +// Yaml. +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4996) +#pragma warning(disable : 4127) +#endif +#include "yaml-cpp/yaml.h" +#ifdef _WIN32 +#pragma warning(pop) +#endif + +// Local. +#include "radeon_gpu_analyzer_backend/be_metadata_parser.h" + +// Hardware Stage Dot Strings. +const std::string kStrLS = ".ls"; +const std::string kStrHS = ".hs"; +const std::string kStrES = ".es"; +const std::string kStrGS = ".gs"; +const std::string kStrVS = ".vs"; +const std::string kStrPS = ".ps"; +const std::string kStrCS = ".cs"; + +// Graphics Shader Stage Dot Strings. +const std::string kStrVertex = ".vertex"; +const std::string kStrHull = ".hull"; +const std::string kStrDomain = ".domain"; +const std::string kStrGeometry = ".geometry"; +const std::string kStrPixel = ".pixel"; +const std::string kStrCompute = ".compute"; + +// Raytracing Shader Stage Dot Strings. +const std::string kStrUnknown = "Unknown"; +const std::string kStrRayGeneration = "RayGeneration"; +const std::string kStrMiss = "Miss"; +const std::string kStrAnyHit = "AnyHit"; +const std::string kStrClosestHit = "ClosestHit"; +const std::string kStrIntersection = "Intersection"; +const std::string kStrCallable = "Callable"; +const std::string kStrTraversal = "Traversal"; +const std::string kStrLaunchKernel = "LaunchKernel"; + +// Amdgpudis dot tokens. +static const std::string kStrLcCodeObjectMetadataTokenStart = "---\n"; +static const std::string kStrLcCodeObjectMetadataTokenEnd = "\n..."; +static const std::string kStrCodeObjectMetadataKeyKernels = "amdhsa.kernels"; +static const std::string kStrCodeObjectMetadataKeyPipelines = "amdpal.pipelines"; +static const std::string kAmdgpuDisDotApiToken = ".api"; +static const std::string kAmdgpuDisDotHardwareStagesToken = ".hardware_stages"; +static const std::string kAmdgpuDisDotScratchMemorySizeToken = ".scratch_memory_size"; +static const std::string kAmdgpuDisDotSgprCountToken = ".sgpr_count"; +static const std::string kAmdgpuDisDotSgprLimitToken = ".sgpr_limit"; +static const std::string kAmdgpuDisDotVgprCountToken = ".vgpr_count"; +static const std::string kAmdgpuDisDotVgprLimitToken = ".vgpr_limit"; +static const std::string kAmdgpuDisDotShaderFunctionsToken = ".shader_functions"; +static const std::string kAmdgpuDisDotLdsSizeToken = ".lds_size"; +static const std::string kAmdgpuDisDotShaderSubtypeToken = ".shader_subtype"; +static const std::string kAmdgpuDisDotShadersToken = ".shaders"; +static const std::string kAmdgpuDisDotHardwareMappingToken = ".hardware_mapping"; +static const std::string kAmdgpuDisDxilStdManglingPrefix = "\001?"; +static const std::string kAmdgpuDisDxilStdManglingSuffix = "@@"; +static const std::string kAmdgpuDisDxilStdHexPattern = "[A-F0-9]+:"; + + +std::string BeMangledKernelUtils::DemangleShaderName(const std::string& kernel_name) +{ + std::string umangled_kernel_name{kernel_name}; + umangled_kernel_name = UnQuote(umangled_kernel_name, '\"'); + umangled_kernel_name = UnQuote(umangled_kernel_name, '\''); + try + { + umangled_kernel_name = std::regex_replace(umangled_kernel_name, std::regex(kAmdgpuDisDxilStdHexPattern), ""); + } + catch (...) + { + ; // If unrecognized mangled name patter is detected, skip demangling. + } + std::size_t prefix = umangled_kernel_name.find(kAmdgpuDisDxilStdManglingPrefix); + if (prefix != std::string::npos) + { + std::string name = umangled_kernel_name.substr(prefix + kAmdgpuDisDxilStdManglingPrefix.size()); + std::size_t suffix = name.find(kAmdgpuDisDxilStdManglingSuffix); + if (suffix != std::string::npos) + { + umangled_kernel_name = name.substr(0, suffix); + } + } + return umangled_kernel_name; +} + +std::string BeMangledKernelUtils::UnQuote(const std::string& str, char quote) +{ + std::string no_quotes{str}; + no_quotes.erase(std::remove(no_quotes.begin(), no_quotes.end(), quote), no_quotes.end()); + return no_quotes; +} + +std::string BeMangledKernelUtils::Quote(const std::string& str, char quote) +{ + return quote + str + quote; +} + +BeAmdPalMetaData::StageType BeAmdPalMetaData::GetStageType(const std::string& stage_name) +{ + static const std::unordered_map stageMap = {{kStrLS, StageType::kLS}, + {kStrHS, StageType::kHS}, + {kStrES, StageType::kES}, + {kStrGS, StageType::kGS}, + {kStrVS, StageType::kVS}, + {kStrPS, StageType::kPS}, + {kStrCS, StageType::kCS}}; + + auto it = stageMap.find(stage_name); + if (it != stageMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown stage type: " + stage_name); +} + +BeAmdPalMetaData::ShaderType BeAmdPalMetaData::GetShaderType(const std::string& shader_name) +{ + static const std::unordered_map shaderMap = {{kStrVertex, ShaderType::kVertex}, + {kStrHull, ShaderType::kHull}, + {kStrDomain, ShaderType::kDomain}, + {kStrGeometry, ShaderType::kGeometry}, + {kStrPixel, ShaderType::kPixel}, + {kStrCompute, ShaderType::kCompute}}; + + auto it = shaderMap.find(shader_name); + if (it != shaderMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown shader type: " + shader_name); +} + +BeAmdPalMetaData::ShaderSubtype BeAmdPalMetaData::GetShaderSubtype(const std::string& subtype_name) +{ + static const std::unordered_map subtypeMap = {{kStrUnknown, ShaderSubtype::kUnknown}, + {kStrRayGeneration, ShaderSubtype::kRayGeneration}, + {kStrMiss, ShaderSubtype::kMiss}, + {kStrAnyHit, ShaderSubtype::kAnyHit}, + {kStrClosestHit, ShaderSubtype::kClosestHit}, + {kStrIntersection, ShaderSubtype::kIntersection}, + {kStrCallable, ShaderSubtype::kCallable}, + {kStrTraversal, ShaderSubtype::kTraversal}, + {kStrLaunchKernel, ShaderSubtype::kLaunchKernel}}; + + auto it = subtypeMap.find(subtype_name); + if (it != subtypeMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown shader subtype: " + subtype_name); +} + +std::string BeAmdPalMetaData::GetStageName(StageType stage_type) +{ + static const std::unordered_map inverseStageMap = {{StageType::kLS, kStrLS}, + {StageType::kHS, kStrHS}, + {StageType::kES, kStrES}, + {StageType::kGS, kStrGS}, + {StageType::kVS, kStrVS}, + {StageType::kPS, kStrPS}, + {StageType::kCS, kStrCS}}; + + auto it = inverseStageMap.find(stage_type); + if (it != inverseStageMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown stage type: " + std::to_string(static_cast(stage_type))); +} + +std::string BeAmdPalMetaData::GetShaderName(ShaderType shader_type) +{ + static const std::unordered_map inverseShaderMap = {{ShaderType::kVertex, kStrVertex}, + {ShaderType::kHull, kStrHull}, + {ShaderType::kDomain, kStrDomain}, + {ShaderType::kGeometry, kStrGeometry}, + {ShaderType::kPixel, kStrPixel}, + {ShaderType::kCompute, kStrCompute}}; + + auto it = inverseShaderMap.find(shader_type); + if (it != inverseShaderMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown shader type: " + std::to_string(static_cast(shader_type))); +} + +std::string BeAmdPalMetaData::GetShaderSubtypeName(ShaderSubtype subtype) +{ + static const std::unordered_map inverseSubtypeMap = {{ShaderSubtype::kUnknown, kStrUnknown}, + {ShaderSubtype::kRayGeneration, kStrRayGeneration}, + {ShaderSubtype::kMiss, kStrMiss}, + {ShaderSubtype::kAnyHit, kStrAnyHit}, + {ShaderSubtype::kClosestHit, kStrClosestHit}, + {ShaderSubtype::kIntersection, kStrIntersection}, + {ShaderSubtype::kCallable, kStrCallable}, + {ShaderSubtype::kTraversal, kStrTraversal}, + {ShaderSubtype::kLaunchKernel, kStrLaunchKernel}}; + + auto it = inverseSubtypeMap.find(subtype); + if (it != inverseSubtypeMap.end()) + { + return it->second; + } + throw std::runtime_error("Unknown shader subtype: " + std::to_string(static_cast(subtype))); +} + +uint64_t GetHardwareStageProperty(const YAML::Node& node, const std::string& key) +{ + uint64_t ret = static_cast(-1); + if (node[key]) + { + ret = node[key].as(); + } + return ret; +} + +beKA::beStatus BeAmdPalMetaData::ParseAmdgpudisMetadata(const std::string& amdgpu_dis_output, BeAmdPalMetaData::PipelineMetaData& pipeline_md) +{ + beKA::beStatus status = beKA::beStatus::kBeStatusSuccess; + size_t start_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenStart); + size_t end_offset; + + std::vector pipelines; + while ((end_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenEnd, start_offset)) != std::string::npos) + { + // For each metadata section ... + try + { + const std::string& kernel_metadata_text = + amdgpu_dis_output.substr(start_offset, end_offset - start_offset + kStrLcCodeObjectMetadataTokenEnd.size()); + YAML::Node codeobj_metadata_node = YAML::Load(kernel_metadata_text); + + if (!codeobj_metadata_node.IsMap()) + { + status = beKA::beStatus::kBeStatusCodeObjMdParsingFailed; + break; + } + + if (codeobj_metadata_node[kStrCodeObjectMetadataKeyKernels]) + { + status = beKA::beStatus::kBeStatusComputeCodeObjMetaDataSuccess; + break; + } + + // For each pipeline ... + for (const auto& pipeline_node : codeobj_metadata_node[kStrCodeObjectMetadataKeyPipelines]) + { + // Parse api token. + BeAmdPalMetaData::PipelineMetaData pipeline; + pipeline.api = pipeline_node[kAmdgpuDisDotApiToken].as(); + + // Parse stats for each hardware stage. + for (const auto& stage_node : pipeline_node[kAmdgpuDisDotHardwareStagesToken]) + { + BeAmdPalMetaData::HardwareStageMetaData stage; + + stage.stage_type = BeAmdPalMetaData::GetStageType(stage_node.first.as()); + stage.stats.lds_size_used = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotLdsSizeToken); + stage.stats.scratch_memory_used = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotScratchMemorySizeToken); + stage.stats.num_sgprs_used = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotSgprCountToken); + stage.stats.num_sgprs_available = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotSgprLimitToken); + stage.stats.num_vgprs_used = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotVgprCountToken); + stage.stats.num_vgprs_available = GetHardwareStageProperty(stage_node.second, kAmdgpuDisDotVgprLimitToken); + + pipeline.hardware_stages.push_back(stage); + } + + if (pipeline_node[kAmdgpuDisDotShaderFunctionsToken]) + { + // Parse shader functions. + for (const auto& function_node : pipeline_node[kAmdgpuDisDotShaderFunctionsToken]) + { + BeAmdPalMetaData::ShaderFunctionMetaData function; + + function.name = BeMangledKernelUtils::DemangleShaderName(function_node.first.as()); + function.shader_subtype = BeAmdPalMetaData::GetShaderSubtype(function_node.second[kAmdgpuDisDotShaderSubtypeToken].as()); + + function.stats.lds_size_used = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotLdsSizeToken); + function.stats.scratch_memory_used = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotScratchMemorySizeToken); + function.stats.num_sgprs_used = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotSgprCountToken); + function.stats.num_sgprs_available = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotSgprLimitToken); + function.stats.num_vgprs_used = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotVgprCountToken); + function.stats.num_vgprs_available = GetHardwareStageProperty(function_node.second, kAmdgpuDisDotVgprLimitToken); + + pipeline.shader_functions.push_back(function); + } + status = beKA::beStatus::kBeStatusRayTracingCodeObjMetaDataSuccess; + } + else + { + status = beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess; + } + + // Parse shader stages. + for (const auto& shader_node : pipeline_node[kAmdgpuDisDotShadersToken]) + { + BeAmdPalMetaData::ShaderMetaData shader; + shader.shader_type = BeAmdPalMetaData::GetShaderType(shader_node.first.as()); + const YAML::Node& hardware_mapping_node = shader_node.second[kAmdgpuDisDotHardwareMappingToken]; + if (hardware_mapping_node.IsSequence() && hardware_mapping_node.size() > 0) + { + shader.hardware_mapping = BeAmdPalMetaData::GetStageType(hardware_mapping_node[0].as()); + } + else + { + status = beKA::beStatus::kBeStatusCodeObjMdParsingFailed; + break; + } + if (shader_node.second[kAmdgpuDisDotShaderSubtypeToken]) + { + shader.shader_subtype = BeAmdPalMetaData::GetShaderSubtype(shader_node.second[kAmdgpuDisDotShaderSubtypeToken].as()); + if (shader.shader_subtype != BeAmdPalMetaData::ShaderSubtype::kUnknown) + { + status = beKA::beStatus::kBeStatusRayTracingCodeObjMetaDataSuccess; + } + } + pipeline.shaders.push_back(shader); + } + + pipelines.push_back(pipeline); + } + } + catch (const YAML::ParserException&) + { + status = beKA::beStatus::kBeStatusCodeObjMdParsingFailed; + break; + } + catch (const std::runtime_error&) + { + status = beKA::beStatus::kBeStatusCodeObjMdParsingFailed; + break; + } + + start_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenStart, end_offset); + if (start_offset == std::string::npos) + { + break; + } + } + + if (status != beKA::beStatus::kBeStatusCodeObjMdParsingFailed && pipelines.size() > 0) + { + pipeline_md = std::move(pipelines[0]); + } + + return status; +} diff --git a/source/radeon_gpu_analyzer_backend/be_metadata_parser.h b/source/radeon_gpu_analyzer_backend/be_metadata_parser.h new file mode 100644 index 0000000..14d9525 --- /dev/null +++ b/source/radeon_gpu_analyzer_backend/be_metadata_parser.h @@ -0,0 +1,127 @@ +//====================================================================== +// Copyright 2024 Advanced Micro Devices, Inc. All rights reserved. +//====================================================================== + +#ifndef RGA_RADEONGPUANALYZERBACKEND_SRC_BE_METADATA_PARSER_H_ +#define RGA_RADEONGPUANALYZERBACKEND_SRC_BE_METADATA_PARSER_H_ + +// C++. +#include +#include + +// Local. +#include "radeon_gpu_analyzer_backend/be_program_builder.h" + +// A set of utilities for handling mangled shader names. +class BeMangledKernelUtils +{ +public: + // Returns unmangled shader name if given a mangled shader_name, + // otherwise just returns shader_name as is. + static std::string DemangleShaderName(const std::string& shader_name); + + // Remove Quotes from provided string if it contains a mangled name. + static std::string UnQuote(const std::string& str, char quote = '\"'); + + // Add Quotes to provided string if it contains a mangled name. + static std::string Quote(const std::string& str, char quote = '\"'); +}; + +// Metadata Parsed from Amdgpu-dis code object Metadata string. +class BeAmdPalMetaData +{ +public: + + // Enum to represent different stages in hardware pipeline. + enum class StageType + { + kLS, + kHS, + kES, + kGS, + kVS, + kPS, + kCS + }; + + // Enum to represent different shader types. + enum class ShaderType + { + kVertex, + kHull, + kDomain, + kGeometry, + kPixel, + kCompute + }; + + // Enum to represent different shader subtypes. + enum class ShaderSubtype + { + kUnknown, + kRayGeneration, + kMiss, + kAnyHit, + kClosestHit, + kIntersection, + kCallable, + kTraversal, + kLaunchKernel + }; + + // Struct to hold hardware stage details. + struct HardwareStageMetaData + { + StageType stage_type; + beKA::AnalysisData stats; + }; + + // Struct to hold shader function details. + struct ShaderFunctionMetaData + { + std::string name; + ShaderSubtype shader_subtype; + beKA::AnalysisData stats; + }; + + // Struct to hold shader details. + struct ShaderMetaData + { + ShaderType shader_type; + StageType hardware_mapping; + ShaderSubtype shader_subtype = ShaderSubtype::kUnknown; + }; + + // Struct to hold amdpal pipeline details. + struct PipelineMetaData + { + std::string api; + std::vector hardware_stages; + std::vector shader_functions; + std::vector shaders; + }; + + // Converts string stage name to StageType enum + static StageType GetStageType(const std::string& stage_name); + + // Converts string shader name to ShaderType enum + static ShaderType GetShaderType(const std::string& shader_name); + + // Converts string shader subtype to ShaderSubtype enum + static ShaderSubtype GetShaderSubtype(const std::string& subtype_name); + + // Converts StageType enum to string stage name. + static std::string GetStageName(StageType stage_type); + + // Converts ShaderType enum to string shader name. + static std::string GetShaderName(ShaderType shader_type); + + // Converts ShaderSubtype enum to string shader subtype. + static std::string GetShaderSubtypeName(ShaderSubtype subtype); + + // Parses amdgpu-dis output and extracts code object metadata. + static beKA::beStatus ParseAmdgpudisMetadata(const std::string& amdgpu_dis_output, BeAmdPalMetaData::PipelineMetaData& pipeline); + +}; + +#endif // RGA_RADEONGPUANALYZERBACKEND_SRC_BE_METADATA_PARSER_H_ diff --git a/source/radeon_gpu_analyzer_backend/be_program_builder_dx12.cpp b/source/radeon_gpu_analyzer_backend/be_program_builder_dx12.cpp index 8a58dbf..cfe926c 100644 --- a/source/radeon_gpu_analyzer_backend/be_program_builder_dx12.cpp +++ b/source/radeon_gpu_analyzer_backend/be_program_builder_dx12.cpp @@ -1476,7 +1476,9 @@ beKA::beStatus BeProgramBuilderDx12::Compile(const Config& config, beKA::beStatus BeProgramBuilderDx12::CompileDXRPipeline(const Config& config, const std::string& target_device, - std::string& out_text, std::vector& output_mapping, std::string& error_msg) + std::string& out_text, + std::vector& output_mapping, + std::string& error_msg) { beKA::beStatus ret = beStatus::kBeStatusInvalid; bool rc = EnableNullBackendForDevice(config, target_device); @@ -1503,8 +1505,8 @@ beKA::beStatus BeProgramBuilderDx12::CompileDXRPipeline(const Config& // If an HLSL input was given, we will only use the HLSL as an input, without // reading the state data. std::shared_ptr dxil_lib = std::make_shared(); - dxil_lib->input_type = DxrSourceType::kHlsl; - dxil_lib->full_path = config.dxr_hlsl; + dxil_lib->input_type = DxrSourceType::kHlsl; + dxil_lib->full_path = config.dxr_hlsl; state_desc.input_files.push_back(dxil_lib); } @@ -1564,110 +1566,33 @@ beKA::beStatus BeProgramBuilderDx12::CompileDXRPipeline(const Config& cmd << "--hlsl " << "\"" << config.dxr_hlsl << "\""; } - // Mode. - cmd << " --mode " << config.dxr_mode << " "; + // Launch Dx12 backend in Dxr mode. + cmd << " --dxr "; // Metadata output file, generate a temporary file for that. std::string metadata_filename = KcUtils::ConstructTempFileName("rga-dxr-output", kStrDefaultExtensionText); cmd << "--output-metadata " << "\"" << metadata_filename << "\"" << " "; - for (const std::string& currExport : config.dxr_exports) - { - cmd << "--export " << currExport << " "; - - // In "all" mode, we need to generate the results for all generated pipelines, therefore we need - // to generate the file names with a special token '*' which would be replaced by the backend - // with the relevant index of that pipeline. - bool is_all_mode = (config.dxr_exports.size() == 1 && config.dxr_exports[0].compare("all") == 0); - bool is_pipeline_mode = (RgaSharedUtils::ToLower(config.dxr_mode).compare("pipeline") == 0); - - // ISA. - if (!config.isa_file.empty()) - { - bool is_dir_output = KcUtils::IsDirectory(config.isa_file); - std::string patched_export_name = is_all_mode ? FILE_NAME_TOKEN_DXR : currExport; - if (!is_all_mode && is_pipeline_mode) - { - patched_export_name.append("_"); - patched_export_name.append(FILE_NAME_TOKEN_DXR); - } - - std::string generated_isa_filename; - bool is_filename_constructed = KcUtils::ConstructOutFileName(config.isa_file, - patched_export_name, target_device, "isa", generated_isa_filename, (is_pipeline_mode || !is_dir_output)); - assert(is_filename_constructed); - if (is_filename_constructed && !generated_isa_filename.empty()) - { - cmd << "--dxr-isa " << "\"" << generated_isa_filename << "\" "; - - // Delete that file if it already exists. - if (BeUtils::IsFilePresent(generated_isa_filename)) - { - BeUtils::DeleteFileFromDisk(generated_isa_filename); - } - } - } - - // Add the required output files to the command. - std::string target_device_lower = target_device; - std::transform(target_device_lower.begin(), target_device_lower.end(), target_device_lower.begin(), [](const char& c) { - return static_cast(std::tolower(c)); - }); - - // Statistics files. - if (!config.analysis_file.empty()) - { - bool is_dir_output = KcUtils::IsDirectory(config.analysis_file); - std::string patched_export_name = is_all_mode ? FILE_NAME_TOKEN_DXR : currExport; - if (!is_all_mode && is_pipeline_mode) - { - patched_export_name.append("_"); - patched_export_name.append(FILE_NAME_TOKEN_DXR); - } - - std::string generated_stats_filename; - bool is_filename_constructed = KcUtils::ConstructOutFileName(config.analysis_file, - patched_export_name, target_device_lower, - kStrDefaultExtensionStats, generated_stats_filename, (is_pipeline_mode || !is_dir_output)); - assert(is_filename_constructed); - if (is_filename_constructed && !generated_stats_filename.empty()) - { - cmd << "--dxr-stats " << "\"" << generated_stats_filename << "\" "; - - // Delete that file if it already exists. - if (BeUtils::IsFilePresent(generated_stats_filename)) - { - BeUtils::DeleteFileFromDisk(generated_stats_filename); - } - } - } - - // Binary files. - if (!config.binary_output_file.empty()) - { - std::string patched_export_name = is_all_mode ? FILE_NAME_TOKEN_DXR : currExport; - if (!is_all_mode && is_pipeline_mode) - { - patched_export_name.append("_"); - patched_export_name.append(FILE_NAME_TOKEN_DXR); - } + // Add the required output files to the command. + std::string target_device_lower = target_device; + std::transform(target_device_lower.begin(), target_device_lower.end(), target_device_lower.begin(), [](const char& c) { + return static_cast(std::tolower(c)); + }); - std::string generated_binary_file; - bool is_filename_constructed = KcUtils::ConstructOutFileName(config.binary_output_file, - patched_export_name, target_device_lower, - "bin", generated_binary_file); - assert(is_filename_constructed); - if (is_filename_constructed && !generated_binary_file.empty()) - { - cmd << "--dxr-bin " << "\"" << generated_binary_file << "\" "; - } + // Binary files. + std::string generated_binary_file; + bool is_filename_constructed = + KcUtils::ConstructOutFileName(config.binary_output_file, FILE_NAME_TOKEN_DXR, target_device_lower, "bin", generated_binary_file); + if (is_filename_constructed && !generated_binary_file.empty()) + { + cmd << "--dxr-bin " + << "\"" << generated_binary_file << "\" "; + } - // Delete that file if it already exists. - if (BeUtils::IsFilePresent(generated_binary_file)) - { - BeUtils::DeleteFileFromDisk(generated_binary_file); - } - } + // Delete that file if it already exists. + if (BeUtils::IsFilePresent(generated_binary_file)) + { + BeUtils::DeleteFileFromDisk(generated_binary_file); } // HLSL->DXIL mapping. diff --git a/source/radeon_gpu_analyzer_backend/be_program_builder_opengl.cpp b/source/radeon_gpu_analyzer_backend/be_program_builder_opengl.cpp index 6f37558..5257bae 100755 --- a/source/radeon_gpu_analyzer_backend/be_program_builder_opengl.cpp +++ b/source/radeon_gpu_analyzer_backend/be_program_builder_opengl.cpp @@ -503,6 +503,7 @@ bool BeProgramBuilderOpengl::GetDeviceGLName(const std::string& device_name, std gl_backend_values["gfx1101"] = "1101"; gl_backend_values["gfx1102"] = "1102"; gl_backend_values["gfx1103"] = "1103"; + gl_backend_values["gfx1150"] = "1150"; } // Fetch the relevant value. diff --git a/source/radeon_gpu_analyzer_backend/be_program_builder_vk_offline.cpp b/source/radeon_gpu_analyzer_backend/be_program_builder_vk_offline.cpp index 121d1e7..d0fea9e 100755 --- a/source/radeon_gpu_analyzer_backend/be_program_builder_vk_offline.cpp +++ b/source/radeon_gpu_analyzer_backend/be_program_builder_vk_offline.cpp @@ -38,8 +38,8 @@ static const std::map kVkAmdllpcTargetsToDeviceInfoTar {"gfx1100", "11.0.0"}, {"gfx1101", "11.0.1"}, {"gfx1102", "11.0.2"}, - {"gfx1103", "11.0.3"}}; -// gfx110x is not supported by amdllpc as of 07/11/2023. + {"gfx1103", "11.0.3"}, + {"gfx1150", "11.5.0"}}; static bool GetAmdllpcPath(std::string& amdllpc_path) diff --git a/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.cpp b/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.cpp index cab10ee..3c13b1f 100755 --- a/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.cpp +++ b/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.cpp @@ -6,17 +6,6 @@ #include #include -// Yaml. -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4996) -#pragma warning(disable : 4127) -#endif -#include "yaml-cpp/yaml.h" -#ifdef _WIN32 -#pragma warning(pop) -#endif - // Infra. #include "external/amdt_os_wrappers/Include/osFilePath.h" #include "external/amdt_os_wrappers/Include/osDirectory.h" @@ -153,48 +142,6 @@ static const std::string kVulkanBackendOptLayersFile = "--layers-file"; // VulkanBackend options: target GPU. static const std::string kVulkanBackendOptTarget = "--target"; -// Amdgpudis dot tokens. -static const std::string kStrLcCodeObjectMetadataTokenStart = "---\n"; -static const std::string kStrLcCodeObjectMetadataTokenEnd = "\n..."; -static const std::string kStrCodeObjectMetadataKeyKernels = "amdhsa.kernels"; -static const std::string kStrCodeObjectMetadataKeyPipelines = "amdpal.pipelines"; -static const std::string kAmdgpuDisDotApiToken = ".api"; -static const std::string kAmdgpuDisDotHardwareStagesToken = ".hardware_stages"; -static const std::string kAmdgpuDisDotScratchMemorySizeToken = ".scratch_memory_size"; -static const std::string kAmdgpuDisDotSgprCountToken = ".sgpr_count"; -static const std::string kAmdgpuDisDotSgprLimitToken = ".sgpr_limit"; -static const std::string kAmdgpuDisDotVgprCountToken = ".vgpr_count"; -static const std::string kAmdgpuDisDotVgprLimitToken = ".vgpr_limit"; -static const std::string kAmdgpuDisDotShaderFunctionsToken = ".shader_functions"; -static const std::string kAmdgpuDisDotLdsSizeToken = ".lds_size"; -static const std::string kAmdgpuDisDotShaderSubtypeToken = ".shader_subtype"; -static const std::string kAmdgpuDisDotShadersToken = ".shaders"; -static const std::string kAmdgpuDisDotHardwareMappingToken = ".hardware_mapping"; - -const std::string kStrLS = ".ls"; -const std::string kStrHS = ".hs"; -const std::string kStrES = ".es"; -const std::string kStrGS = ".gs"; -const std::string kStrVS = ".vs"; -const std::string kStrPS = ".ps"; -const std::string kStrCS = ".cs"; - -const std::string kStrVertex = ".vertex"; -const std::string kStrHull = ".hull"; -const std::string kStrDomain = ".domain"; -const std::string kStrGeometry = ".geometry"; -const std::string kStrPixel = ".pixel"; -const std::string kStrCompute = ".compute"; - -const std::string kStrUnknown = "Unknown"; -const std::string kStrRayGeneration = "RayGeneration"; -const std::string kStrMiss = "Miss"; -const std::string kStrAnyHit = "AnyHit"; -const std::string kStrClosestHit = "ClosestHit"; -const std::string kStrIntersection = "Intersection"; -const std::string kStrCallable = "Callable"; -const std::string kStrTraversal = "Traversal"; - // Copy the Vulkan Validation layers info from temp file ("tempInfoFile") to the Log file and user-provided validation info file ("outputFile"). // Delete the temp info file after copying its content. @@ -265,7 +212,7 @@ static std::string ConstructVulkanBackendOptions(const std::string& loader_debug // Output binary file name. // Needed if the target is gfx11 or above since ISA disassembly has to be extracted from CodeObject. // For older architectures this is only needed when explicitly requested by the user. - if (!bin_file.empty() || (KcUtils::IsNavi3Target(device) && !isa_files.empty())) + if (!bin_file.empty() || (KcUtils::IsNavi3AndBeyond(device) && !isa_files.empty())) { opts << " " << kVulkanBackendOptBinFile << " " << KcUtils::Quote(bin_file); } @@ -783,31 +730,6 @@ beStatus beProgramBuilderVulkan::InvokeVulkanBackend(const std::string& cmd_line return (status == KcUtils::ProcessStatus::kSuccess ? kBeStatusSuccess : kBeStatusVulkanBackendLaunchFailed); } -beKA::beStatus beProgramBuilderVulkan::InvokeAmdgpudis(const std::string& cmd_line_options, bool should_print_cmd, std::string& out_txt, std::string& error_msg) -{ - osFilePath amdgpu_dis_exe; - long exit_code = 0; - - // Construct the path to the amdgpu-dis executable. - osGetCurrentApplicationPath(amdgpu_dis_exe, false); - amdgpu_dis_exe.appendSubDirectory(kAmdgpudisRootDir); - amdgpu_dis_exe.setFileName(kAmdgpudisExecutable); -#ifdef _WIN32 - amdgpu_dis_exe.setFileExtension(kAmdgpudisExecutableExtension); -#endif - - KcUtils::ProcessStatus status = KcUtils::LaunchProcess(amdgpu_dis_exe.asString().asASCIICharArray(), - cmd_line_options, - "", - kProcessWaitInfinite, - should_print_cmd, - out_txt, - error_msg, - exit_code); - - return (status == KcUtils::ProcessStatus::kSuccess ? kBeStatusSuccess : kBeStatusVulkanAmdgpudisLaunchFailed); -} - bool beProgramBuilderVulkan::WriteIsaFileWithHwMapping(uint32_t stage, const BeAmdPalMetaData::PipelineMetaData& amdpal_pipeline, const std::map& shader_to_disassembly, @@ -912,7 +834,9 @@ beKA::beStatus beProgramBuilderVulkan::AmdgpudisBinaryToDisassembly(const std::s std::string amdgpu_dis_stderr; std::stringstream bin_file_with_quotes; bin_file_with_quotes << "\"" << bin_file << "\""; - status = InvokeAmdgpudis(bin_file_with_quotes.str(), should_print_cmd, amdgpu_dis_stdout, amdgpu_dis_stderr); + status = KcUtils::InvokeAmdgpudis(bin_file_with_quotes.str(), should_print_cmd, amdgpu_dis_stdout, amdgpu_dis_stderr) + ? beKA::kBeStatusSuccess + : beKA::kBeStatusVulkanAmdgpudisLaunchFailed; assert(status == beKA::kBeStatusSuccess); if (status == beKA::kBeStatusSuccess) { @@ -923,9 +847,9 @@ beKA::beStatus beProgramBuilderVulkan::AmdgpudisBinaryToDisassembly(const std::s if (is_amdgpu_dis_output_parsed && !shader_to_disassembly.empty()) { BeAmdPalMetaData::PipelineMetaData pipeline; - beKA::beStatus md_status = beProgramBuilderVulkan::ParseAmdgpudisMetadata(amdgpu_dis_stdout, pipeline); - assert(md_status == beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess); - if (md_status == beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess) + beKA::beStatus md_status = BeAmdPalMetaData::ParseAmdgpudisMetadata(amdgpu_dis_stdout, pipeline); + assert(md_status == beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess); + if (md_status == beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess) { // Write the ISA disassembly files. for (uint32_t stage = BePipelineStage::kVertex; stage < BePipelineStage::kCount; stage++) @@ -1046,7 +970,7 @@ beKA::beStatus beProgramBuilderVulkan::CompileSpirv(const std::string& loader_de // Disassemble the binaries to get the ISA disassembly from the CodeObject's .text section. // For gfx11 targets we need to disassemble the binary CodeObject and extract the disassembly from there. - if (KcUtils::IsNavi3Target(device) && !isa_files.empty()) + if (KcUtils::IsNavi3AndBeyond(device) && !isa_files.empty()) { std::string amdgpu_dis_stdout; std::map shader_to_disassembly; @@ -1119,248 +1043,3 @@ beKA::beStatus beProgramBuilderVulkan::PreprocessSource(const Config& config, co return status; } - - -BeAmdPalMetaData::StageType BeAmdPalMetaData::GetStageType(const std::string& stage_name) -{ - static const std::unordered_map stageMap = {{kStrLS, StageType::kLS}, - {kStrHS, StageType::kHS}, - {kStrES, StageType::kES}, - {kStrGS, StageType::kGS}, - {kStrVS, StageType::kVS}, - {kStrPS, StageType::kPS}, - {kStrCS, StageType::kCS}}; - - auto it = stageMap.find(stage_name); - if (it != stageMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown stage type: " + stage_name); -} - -BeAmdPalMetaData::ShaderType BeAmdPalMetaData::GetShaderType(const std::string& shader_name) -{ - static const std::unordered_map shaderMap = {{kStrVertex, ShaderType::kVertex}, - {kStrHull, ShaderType::kHull}, - {kStrDomain, ShaderType::kDomain}, - {kStrGeometry, ShaderType::kGeometry}, - {kStrPixel, ShaderType::kPixel}, - {kStrCompute, ShaderType::kCompute}}; - - auto it = shaderMap.find(shader_name); - if (it != shaderMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown shader type: " + shader_name); -} - -BeAmdPalMetaData::ShaderSubtype BeAmdPalMetaData::GetShaderSubtype(const std::string& subtype_name) -{ - static const std::unordered_map subtypeMap = {{kStrUnknown, ShaderSubtype::kUnknown}, - {kStrRayGeneration, ShaderSubtype::kRayGeneration}, - {kStrMiss, ShaderSubtype::kMiss}, - {kStrAnyHit, ShaderSubtype::kAnyHit}, - {kStrClosestHit, ShaderSubtype::kClosestHit}, - {kStrIntersection, ShaderSubtype::kIntersection}, - {kStrCallable, ShaderSubtype::kCallable}, - {kStrTraversal, ShaderSubtype::kTraversal}}; - - auto it = subtypeMap.find(subtype_name); - if (it != subtypeMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown shader subtype: " + subtype_name); -} - -std::string BeAmdPalMetaData::GetStageName(StageType stage_type) -{ - static const std::unordered_map inverseStageMap = {{StageType::kLS, kStrLS}, - {StageType::kHS, kStrHS}, - {StageType::kES, kStrES}, - {StageType::kGS, kStrGS}, - {StageType::kVS, kStrVS}, - {StageType::kPS, kStrPS}, - {StageType::kCS, kStrCS}}; - - auto it = inverseStageMap.find(stage_type); - if (it != inverseStageMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown stage type: " + std::to_string(static_cast(stage_type))); -} - -std::string BeAmdPalMetaData::GetShaderName(ShaderType shader_type) -{ - static const std::unordered_map inverseShaderMap = {{ShaderType::kVertex, kStrVertex}, - {ShaderType::kHull, kStrHull}, - {ShaderType::kDomain, kStrDomain}, - {ShaderType::kGeometry, kStrGeometry}, - {ShaderType::kPixel, kStrPixel}, - {ShaderType::kCompute, kStrCompute}}; - - auto it = inverseShaderMap.find(shader_type); - if (it != inverseShaderMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown shader type: " + std::to_string(static_cast(shader_type))); -} - -std::string BeAmdPalMetaData::GetShaderSubtypeName(ShaderSubtype subtype) -{ - static const std::unordered_map inverseSubtypeMap = {{ShaderSubtype::kUnknown, kStrUnknown}, - {ShaderSubtype::kRayGeneration, kStrRayGeneration}, - {ShaderSubtype::kMiss, kStrMiss}, - {ShaderSubtype::kAnyHit, kStrAnyHit}, - {ShaderSubtype::kClosestHit, kStrClosestHit}, - {ShaderSubtype::kIntersection, kStrIntersection}, - {ShaderSubtype::kCallable, kStrCallable}, - {ShaderSubtype::kTraversal, kStrTraversal}}; - - auto it = inverseSubtypeMap.find(subtype); - if (it != inverseSubtypeMap.end()) - { - return it->second; - } - throw std::runtime_error("Unknown shader subtype: " + std::to_string(static_cast(subtype))); -} - -uint64_t GetHardwareStageProperty(const YAML::Node& node, const std::string& key) -{ - uint64_t ret = static_cast(-1); - if (node[key]) - { - ret = node[key].as(); - } - return ret; -} - -beKA::beStatus beProgramBuilderVulkan::ParseAmdgpudisMetadata(const std::string& amdgpu_dis_output, BeAmdPalMetaData::PipelineMetaData& pipeline_md) -{ - beKA::beStatus status = beKA::beStatus::kBeStatusSuccess; - size_t start_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenStart); - size_t end_offset; - - std::vector pipelines; - while ((end_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenEnd, start_offset)) != std::string::npos) - { - try - { - const std::string& kernel_metadata_text = - amdgpu_dis_output.substr(start_offset, end_offset - start_offset + kStrLcCodeObjectMetadataTokenEnd.size()); - YAML::Node codeobj_metadata_node = YAML::Load(kernel_metadata_text); - - if (!codeobj_metadata_node.IsMap()) - { - status = beKA::beStatus::kBeStatusVulkanCodeObjMdParsingFailed; - break; - } - - if (codeobj_metadata_node[kStrCodeObjectMetadataKeyKernels]) - { - status = beKA::beStatus::kBeStatusVulkanComputeCodeObjMetaDataSuccess; - break; - } - - for (const auto& pipelineNode : codeobj_metadata_node[kStrCodeObjectMetadataKeyPipelines]) - { - BeAmdPalMetaData::PipelineMetaData pipeline; - pipeline.api = pipelineNode[kAmdgpuDisDotApiToken].as(); - - for (const auto& stageNode : pipelineNode[kAmdgpuDisDotHardwareStagesToken]) - { - BeAmdPalMetaData::HardwareStageMetaData stage; - - stage.stage_type = BeAmdPalMetaData::GetStageType(stageNode.first.as()); - stage.stats.lds_size_used = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotLdsSizeToken); - stage.stats.scratch_memory_used = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotScratchMemorySizeToken); - stage.stats.num_sgprs_used = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotSgprCountToken); - stage.stats.num_sgprs_available = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotSgprLimitToken); - stage.stats.num_vgprs_used = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotVgprCountToken); - stage.stats.num_vgprs_available = GetHardwareStageProperty(stageNode.second, kAmdgpuDisDotVgprLimitToken); - - pipeline.hardware_stages.push_back(stage); - } - - if (pipelineNode[kAmdgpuDisDotShaderFunctionsToken]) - { - for (const auto& functionNode : pipelineNode[kAmdgpuDisDotShaderFunctionsToken]) - { - BeAmdPalMetaData::ShaderFunctionMetaData function; - - function.name = functionNode.first.as(); - function.shader_subtype = BeAmdPalMetaData::GetShaderSubtype(functionNode.second[kAmdgpuDisDotShaderSubtypeToken].as()); - - function.stats.lds_size_used = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotLdsSizeToken); - function.stats.scratch_memory_used = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotScratchMemorySizeToken); - function.stats.num_sgprs_used = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotSgprCountToken); - function.stats.num_sgprs_available = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotSgprLimitToken); - function.stats.num_vgprs_used = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotVgprCountToken); - function.stats.num_vgprs_available = GetHardwareStageProperty(functionNode.second, kAmdgpuDisDotVgprLimitToken); - - pipeline.shader_functions.push_back(function); - } - status = beKA::beStatus::kBeStatusVulkanRayTracingCodeObjMetaDataSuccess; - } - else - { - status = beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess; - } - - for (const auto& shaderNode : pipelineNode[kAmdgpuDisDotShadersToken]) - { - BeAmdPalMetaData::ShaderMetaData shader; - shader.shader_type = BeAmdPalMetaData::GetShaderType(shaderNode.first.as()); - const YAML::Node& hardwareMappingNode = shaderNode.second[kAmdgpuDisDotHardwareMappingToken]; - if (hardwareMappingNode.IsSequence() && hardwareMappingNode.size() > 0) - { - shader.hardware_mapping = BeAmdPalMetaData::GetStageType(hardwareMappingNode[0].as()); - } - else - { - status = beKA::beStatus::kBeStatusVulkanCodeObjMdParsingFailed; - break; - } - if (shaderNode.second[kAmdgpuDisDotShaderSubtypeToken]) - { - shader.shader_subtype = BeAmdPalMetaData::GetShaderSubtype(shaderNode.second[kAmdgpuDisDotShaderSubtypeToken].as()); - if (shader.shader_subtype != BeAmdPalMetaData::ShaderSubtype::kUnknown) - { - status = beKA::beStatus::kBeStatusVulkanRayTracingCodeObjMetaDataSuccess; - } - } - pipeline.shaders.push_back(shader); - } - - pipelines.push_back(pipeline); - } - } - catch (const YAML::ParserException&) - { - status = beKA::beStatus::kBeStatusVulkanCodeObjMdParsingFailed; - break; - } - catch (const std::runtime_error&) - { - status = beKA::beStatus::kBeStatusVulkanCodeObjMdParsingFailed; - break; - } - - start_offset = amdgpu_dis_output.find(kStrLcCodeObjectMetadataTokenStart, end_offset); - if (start_offset == std::string::npos) - { - break; - } - } - - if (status != beKA::beStatus::kBeStatusVulkanCodeObjMdParsingFailed && pipelines.size() > 0) - { - pipeline_md = std::move(pipelines[0]); - } - - return status; -} diff --git a/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.h b/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.h index 9df9e8f..9bdf2d2 100644 --- a/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.h +++ b/source/radeon_gpu_analyzer_backend/be_program_builder_vulkan.h @@ -8,102 +8,11 @@ // Local. #include "radeon_gpu_analyzer_backend/be_data_types.h" #include "radeon_gpu_analyzer_backend/be_program_builder.h" +#include "radeon_gpu_analyzer_backend/be_metadata_parser.h" #include "source/radeon_gpu_analyzer_cli/kc_config.h" using namespace beKA; -// Metadata Parsed from Amdgpu-dis code object Metadata string. -class BeAmdPalMetaData -{ -public: - - // Enum to represent different stages in hardware pipeline. - enum class StageType - { - kLS, - kHS, - kES, - kGS, - kVS, - kPS, - kCS - }; - - // Enum to represent different shader types. - enum class ShaderType - { - kVertex, - kHull, - kDomain, - kGeometry, - kPixel, - kCompute - }; - - // Enum to represent different shader subtypes. - enum class ShaderSubtype - { - kUnknown, - kRayGeneration, - kMiss, - kAnyHit, - kClosestHit, - kIntersection, - kCallable, - kTraversal - }; - - // Struct to hold hardware stage details. - struct HardwareStageMetaData - { - StageType stage_type; - beKA::AnalysisData stats; - }; - - // Struct to hold shader function details. - struct ShaderFunctionMetaData - { - std::string name; - ShaderSubtype shader_subtype; - beKA::AnalysisData stats; - }; - - // Struct to hold shader details. - struct ShaderMetaData - { - ShaderType shader_type; - StageType hardware_mapping; - ShaderSubtype shader_subtype = ShaderSubtype::kUnknown; - }; - - // Struct to hold amdpal pipeline details. - struct PipelineMetaData - { - std::string api; - std::vector hardware_stages; - std::vector shader_functions; - std::vector shaders; - }; - - // Function to convert string stage name to StageType enum - static StageType GetStageType(const std::string& stage_name); - - // Function to convert string shader name to ShaderType enum - static ShaderType GetShaderType(const std::string& shader_name); - - // Function to convert string shader subtype to ShaderSubtype enum - static ShaderSubtype GetShaderSubtype(const std::string& subtype_name); - - // Function to convert StageType enum to string stage name. - static std::string GetStageName(StageType stage_type); - - // Function to convert ShaderType enum to string shader name. - static std::string GetShaderName(ShaderType shader_type); - - // Function to convert ShaderSubtype enum to string shader subtype. - static std::string GetShaderSubtypeName(ShaderSubtype subtype); -}; - // SPIR-V tool. enum class BeVulkanSpirvTool { @@ -151,10 +60,6 @@ class beProgramBuilderVulkan : public BeProgramBuilder static beStatus PreprocessSource(const Config& config, const std::string& glslang_bin_dir, const std::string& input_file, bool is_hlsl, bool should_print_cmd, std::string& output, std::string& error_msg); - // Invoke the amdgpu-dis executable. - static beStatus InvokeAmdgpudis(const std::string& cmd_line_options, bool should_print_cmd, - std::string& out_text, std::string& error_txt); - // Parses amdgpu-dis output and extracts a table with the amdgpu shader stage name being the key ("vs", "ps", etc.) // and that shader stage's disassembly the value. static beStatus ParseAmdgpudisOutput(const std::string& amdgpu_dis_output, @@ -179,10 +84,6 @@ class beProgramBuilderVulkan : public BeProgramBuilder const std::map& shader_to_disassembly, const std::string& isa_file); - // Parses amdgpu-dis output and extracts code object metadata. - static beKA::beStatus ParseAmdgpudisMetadata(const std::string& amdgpu_dis_output, - BeAmdPalMetaData::PipelineMetaData& pipeline); - private: // Invoke the glslang compiler executable. static beStatus InvokeGlslang(const std::string& glsl_bin_path, const std::string& cmd_line_options, diff --git a/source/radeon_gpu_analyzer_backend/be_static_isa_analyzer.cpp b/source/radeon_gpu_analyzer_backend/be_static_isa_analyzer.cpp index b3aa90e..ab7ab21 100755 --- a/source/radeon_gpu_analyzer_backend/be_static_isa_analyzer.cpp +++ b/source/radeon_gpu_analyzer_backend/be_static_isa_analyzer.cpp @@ -67,12 +67,17 @@ static std::string GetShaeIsaCmd(const gtString& target) const gtString kShaeGfx90a = L"gfx90a"; const gtString kShaeGfx942 = L"gfx942"; const gtString kShaeGfx10_1 = L"gfx10_1"; - const gtString kShaeGfx10_3 = L"gfx10_3"; - const gtString kShaeGfx11 = L"gfx11"; + const gtString kShaeGfx10_3 = L"gfx10_3"; + const gtString kShaeGfx11 = L"gfx11"; + const gtString kShaeGfx11_5 = L"gfx11_5"; std::stringstream shae_gfx_generation; shae_gfx_generation << "--isa "; - if (KcUtils::IsNavi3Target(target.asASCIICharArray())) + if (KcUtils::IsStrix(target.asASCIICharArray())) + { + shae_gfx_generation << kShaeGfx11_5.asASCIICharArray(); + } + else if (KcUtils::IsNavi3Target(target.asASCIICharArray())) { shae_gfx_generation << kShaeGfx11.asASCIICharArray(); } diff --git a/source/radeon_gpu_analyzer_backend/be_string_constants.h b/source/radeon_gpu_analyzer_backend/be_string_constants.h index 12e3f1c..5ce3067 100644 --- a/source/radeon_gpu_analyzer_backend/be_string_constants.h +++ b/source/radeon_gpu_analyzer_backend/be_string_constants.h @@ -5,24 +5,6 @@ #ifndef RGA_RADEONGPUANALYZERBACKEND_SRC_BE_STRING_CONSTANTS_H_ #define RGA_RADEONGPUANALYZERBACKEND_SRC_BE_STRING_CONSTANTS_H_ -// Device Names. -static const char* kDeviceNameGfx900 = "gfx900"; -static const char* kDeviceNameGfx902 = "gfx902"; -static const char* kDeviceNameGfx906 = "gfx906"; -static const char* kDeviceNameGfx1010 = "gfx1010"; -static const char* kDeviceNameGfx1011 = "gfx1011"; -static const char* kDeviceNameGfx1012 = "gfx1012"; -static const char* kDeviceNameGfx1030 = "gfx1030"; -static const char* kDeviceNameGfx1031 = "gfx1031"; -static const char* kDeviceNameGfx1032 = "gfx1032"; -static const char* kDeviceNameGfx1034 = "gfx1034"; -static const char* kDeviceNameGfx1035 = "gfx1035"; -static const char* kDeviceNameGfx1100 = "gfx1100"; -static const char* kDeviceNameGfx1101 = "gfx1101"; -static const char* kDeviceNameGfx1102 = "gfx1102"; -static const char* kDeviceNameGfx1103 = "gfx1103"; - - // LLVM Lightning Compiler. #if defined(_WIN64) || defined(__linux) static const wchar_t* kLcOpenclRootDir = L"utils/lc/opencl"; diff --git a/source/radeon_gpu_analyzer_backend/be_utils.cpp b/source/radeon_gpu_analyzer_backend/be_utils.cpp index 3ba84e9..5348303 100644 --- a/source/radeon_gpu_analyzer_backend/be_utils.cpp +++ b/source/radeon_gpu_analyzer_backend/be_utils.cpp @@ -103,6 +103,7 @@ bool BeUtils::GetAllGraphicsCards(std::vector& card_list, AddGenerationDevices(GDT_HW_GENERATION_GFX10, card_list, public_device_unique_names, convert_to_lower); AddGenerationDevices(GDT_HW_GENERATION_GFX103, card_list, public_device_unique_names, convert_to_lower); AddGenerationDevices(GDT_HW_GENERATION_GFX11, card_list, public_device_unique_names, convert_to_lower); + AddGenerationDevices(GDT_HW_GENERATION_GFX115, card_list, public_device_unique_names, convert_to_lower); AddGenerationDevices(GDT_HW_GENERATION_CDNA2, card_list, public_device_unique_names, convert_to_lower); AddGenerationDevices(GDT_HW_GENERATION_CDNA3, card_list, public_device_unique_names, convert_to_lower); @@ -319,95 +320,6 @@ bool BeUtils::DeviceNameLessThan(const std::string& a, const std::string& b) return ret; } -bool BeUtils::DisassembleCodeObject(const std::string& code_object_filename, bool should_print_cmd, - std::string& disassembly_whole, std::string& disassembly_text, std::string& error_msg) -{ - static const wchar_t* kLcDisassemblerExe = L"amdgpu-dis"; - static const wchar_t* kLcDisassemblerDir = L"utils/lc/disassembler"; - const char* kStrErrorCodeObjectParseFailure = "Error: failed to parse Code Object .text section."; - const char* kStrErrorLcDisassemblerLaunchFailure = "Error: failed to launch the LC disassembler."; - - // Build the command. - std::stringstream cmd; - cmd << code_object_filename; - - osFilePath lc_disassembler_exe; - long exit_code = 0; - - osGetCurrentApplicationPath(lc_disassembler_exe, false); - lc_disassembler_exe.appendSubDirectory(kLcDisassemblerDir); - lc_disassembler_exe.setFileName(kLcDisassemblerExe); - - // Clear the error message buffer. - error_msg.clear(); - std::string out_text; - - KcUtils::ProcessStatus status = KcUtils::LaunchProcess(lc_disassembler_exe.asString().asASCIICharArray(), - cmd.str(), - "", - kProcessWaitInfinite, - should_print_cmd, - out_text, - error_msg, - exit_code); - - // Extract the .text disassembly. - assert(!out_text.empty()); - disassembly_whole = out_text; - - if (!disassembly_whole.empty()) - { - // Find where the .text section starts. - size_t text_offset_start = disassembly_whole.find(".text"); - assert(text_offset_start != std::string::npos); - assert(text_offset_start != std::string::npos && - text_offset_start < disassembly_whole.size() + 5); - if (text_offset_start < disassembly_whole.size() + 5) - { - // Skip .text identifier. - text_offset_start += 5; - - // Find where the relevant portion of the disassembly ends. - size_t text_offset_end = disassembly_whole.find("s_code_end"); - if (text_offset_end == std::string::npos) - { - // If s_code_end could not be found, compromise on finding the beginning of the next section. - text_offset_end = disassembly_whole.find(".section", text_offset_start); - } - assert(text_offset_end != std::string::npos); - if (text_offset_end != std::string::npos) - { - // Extract the relevant section. - size_t num_characters = text_offset_end - text_offset_start; - assert(num_characters > 0); - assert(num_characters < disassembly_whole.size() - text_offset_start); - if (num_characters > 0 && num_characters < disassembly_whole.size() - text_offset_start) - { - disassembly_text = disassembly_whole.substr(text_offset_start, num_characters); - } - else if (error_msg.empty()) - { - error_msg = kStrErrorCodeObjectParseFailure; - } - } - else if (error_msg.empty()) - { - error_msg = kStrErrorCodeObjectParseFailure; - } - } - } - - if (disassembly_text.empty()) - { - if (status == KcUtils::ProcessStatus::kSuccess && error_msg.empty()) - { - error_msg = kStrErrorLcDisassemblerLaunchFailure; - } - } - - return (status == KcUtils::ProcessStatus::kSuccess ? beKA::beStatus::kBeStatusSuccess : beKA::beStatus::kBeStatusdx12BackendLaunchFailure); -} - static bool ExtractAttributeValue(const std::string &disassembly_whole, size_t kd_pos, const std::string& attribute_name, uint32_t& value) { bool ret = false; diff --git a/source/radeon_gpu_analyzer_backend/be_utils.h b/source/radeon_gpu_analyzer_backend/be_utils.h index 6e76f67..95eddc9 100644 --- a/source/radeon_gpu_analyzer_backend/be_utils.h +++ b/source/radeon_gpu_analyzer_backend/be_utils.h @@ -97,12 +97,6 @@ class BeUtils // number (e.g. gfx900 is less than gfx902 and gfx902 is less than gfx906). static bool DeviceNameLessThan(const std::string& a, const std::string& b); - // Disassembles the given Code Object, sets the output variables with the entire disassembly - // and with the .text section disassembly. If shouldPrintCmd is set to true, the invocation - // command of the external process would be printed to the console. - static bool DisassembleCodeObject(const std::string& code_object_filename, bool should_print_cmd, - std::string& disassembly_whole, std::string& disassembly_text, std::string& error_msg); - // Extracts statistics from a given Code Object's disassembly. // Returns true on success and false otherwise. static bool ExtractCodeObjectStatistics(const std::string& disassembly_whole, diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin.cpp index e1da6df..2e1b664 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin.cpp @@ -141,10 +141,10 @@ beKA::beStatus KcCliCommanderBin::IsBinaryInputValid(const Config& config) const beKA::beStatus KcCliCommanderBin::InvokeAmdgpudis(const std::string& bin_file, bool should_print_cmd, std::string& out_text, std::string& error_txt) const { - std::stringstream bin_file_with_quotes; - bin_file_with_quotes << "\"" << bin_file << "\""; - beKA::beStatus ret = beProgramBuilderVulkan::InvokeAmdgpudis(bin_file_with_quotes.str(), should_print_cmd, out_text, error_txt); - if (ret == beKA::beStatus::kBeStatusSuccess && out_text.empty()) + beKA::beStatus ret = KcUtils::InvokeAmdgpudis(KcUtils::Quote(bin_file), should_print_cmd, out_text, error_txt) + ? beKA::beStatus::kBeStatusSuccess + : beKA::beStatus::kBeStatusVulkanAmdgpudisLaunchFailed; + if (out_text.empty()) { ret = beKA::beStatus::kBeStatusVulkanAmdgpudisLaunchFailed; } @@ -160,23 +160,22 @@ beKA::beStatus KcCliCommanderBin::DetectAndSetWorkflowStrategy(const Config& con LogPreStep(kStrInfoDetectBinWorkflowType, config.binary_codeobj_file); } - // TODO: use std::make_unique function - currently incompatible with gcc7. - beKA::beStatus status = beProgramBuilderVulkan::ParseAmdgpudisMetadata(amdgpu_dis_output, amdpal_pipeline_md_); + beKA::beStatus status = BeAmdPalMetaData::ParseAmdgpudisMetadata(amdgpu_dis_output, amdpal_pipeline_md_); switch (status) { - case beKA::beStatus::kBeStatusVulkanRayTracingCodeObjMetaDataSuccess: + case beKA::beStatus::kBeStatusRayTracingCodeObjMetaDataSuccess: amdgpudis_parser_strategy_ = std::unique_ptr(new ParseAmdgpudisOutputGraphicStrategy()); - workflow_strategy_ = std::unique_ptr(new RayTracingBinaryWorkflowStrategy(log_callback_)); + workflow_strategy_ = std::unique_ptr(new RayTracingBinaryWorkflowStrategy(config.binary_codeobj_file, log_callback_)); status = beKA::beStatus::kBeStatusSuccess; break; - case beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess: + case beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess: amdgpudis_parser_strategy_ = std::unique_ptr(new ParseAmdgpudisOutputGraphicStrategy()); - workflow_strategy_ = std::unique_ptr(new GraphicsBinaryWorkflowStrategy(log_callback_)); + workflow_strategy_ = std::unique_ptr(new GraphicsBinaryWorkflowStrategy(config.binary_codeobj_file, log_callback_)); status = beKA::beStatus::kBeStatusSuccess; break; - case beKA::beStatus::kBeStatusVulkanComputeCodeObjMetaDataSuccess: + case beKA::beStatus::kBeStatusComputeCodeObjMetaDataSuccess: amdgpudis_parser_strategy_ = std::unique_ptr(new ParseAmdgpudisOutputComputeStrategy()); - workflow_strategy_ = std::unique_ptr(new ComputeBinaryWorkflowStrategy(log_callback_)); + workflow_strategy_ = std::unique_ptr(new ComputeBinaryWorkflowStrategy(config.binary_codeobj_file, log_callback_)); status = beKA::beStatus::kBeStatusSuccess; break; default: diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.cpp index cea2305..cebffe5 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.cpp @@ -5,9 +5,10 @@ #include "common/rg_log.h" // Backend. -#include "radeon_gpu_analyzer_backend/be_utils.h" +#include "radeon_gpu_analyzer_backend/be_metadata_parser.h" #include "radeon_gpu_analyzer_backend/be_opencl_definitions.h" #include "radeon_gpu_analyzer_backend/be_program_builder_vulkan.h" +#include "radeon_gpu_analyzer_backend/be_utils.h" // Local. #include "radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h" @@ -44,13 +45,15 @@ kRtxStageEntryTypes = RgEntryType::kDxrTraversal }; -static const char* kStrErrorCannotParseDisassembly = "Error: failed to parse LLVM disassembly."; -static const char* kStrErrorNoShaderFoundInDisassembly = "Error: LLVM disassembly does not contatin valid kernels."; -static const char* kAmdgpuDisDotTextToken = ".text"; -static const char* kAmdgpuDisShaderEndToken = "_symend:"; -static const char* kAmdgpuDisDotSizeToken = ".size"; -static const char* kAmdgpuDisKernelNameStartToken = "_symend-"; -static const char* kAmdgpuDisKernelName = "amdgpu_kernel_"; +static const char* kStrErrorCannotParseDisassembly = "Error: failed to parse LLVM disassembly."; +static const char* kStrErrorNoShaderFoundInDisassembly = "Error: LLVM disassembly does not contatin valid kernels."; +static const char* kAmdgpuDisDotTextToken = ".text"; +static const char* kAmdgpuDisShaderEndToken = "_symend:"; +static const char* kAmdgpuDisDotSizeToken = ".size"; +static const char* kAmdgpuDisKernelNameStartToken = "_symend-"; +static const char* kAmdgpuDisKernelNameStartTokenWithQuotes = "_symend\"-"; +static const char* kAmdgpuDisShaderEndTokenNoColon = "_symend"; +static const char* kAmdgpuDisKernelName = "amdgpu_kernel_"; beKA::beStatus ParseAmdgpudisOutputGraphicStrategy::ParseAmdgpudisKernels(const std::string& amdgpu_dis_output, std::map& kernel_to_disassembly, @@ -99,6 +102,8 @@ beKA::beStatus ParseAmdgpudisOutputComputeStrategy::ParseAmdgpudisKernels(const while (curr_pos != std::string::npos) { + bool is_kernel_name_in_quotes = false; + // Find the name of the kernel. std::string kernel_name; size_t end_of_line = amdgpu_dis_output.find("\n", curr_pos); @@ -110,12 +115,31 @@ beKA::beStatus ParseAmdgpudisOutputComputeStrategy::ParseAmdgpudisKernels(const kernel_name = line.substr(start, end_of_line - start); curr_pos = end_of_line; } + else + { + found = line.find(kAmdgpuDisKernelNameStartTokenWithQuotes); + if (found != std::string::npos) + { + is_kernel_name_in_quotes = true; + size_t start = found + strlen(kAmdgpuDisKernelNameStartTokenWithQuotes); + kernel_name = line.substr(start, end_of_line - start); + kernel_name = BeMangledKernelUtils::UnQuote(kernel_name); + curr_pos = end_of_line; + } + } if (!kernel_name.empty() && curr_pos != std::string::npos) { // Construct the shader end token "kernel_name_symend:". std::stringstream kernel_end_token_stream; - kernel_end_token_stream << kernel_name << kAmdgpuDisShaderEndToken; + if (is_kernel_name_in_quotes) + { + kernel_end_token_stream << BeMangledKernelUtils::Quote(kernel_name + kAmdgpuDisShaderEndTokenNoColon) << ":"; + } + else + { + kernel_end_token_stream << kernel_name << kAmdgpuDisShaderEndToken; + } std::string kernel_token_end = kernel_end_token_stream.str(); // Extract the kernel disassembly. @@ -123,6 +147,7 @@ beKA::beStatus ParseAmdgpudisOutputComputeStrategy::ParseAmdgpudisKernels(const kernel_offset_end = amdgpu_dis_output.find(kernel_token_end, kernel_offset_begin); std::string kernel_disassembly = amdgpu_dis_output.substr(curr_pos, kernel_offset_end - curr_pos); BeUtils::TrimLeadingAndTrailingWhitespace(kernel_disassembly, kernel_disassembly); + kernel_name = BeMangledKernelUtils::DemangleShaderName(kernel_name); kernel_to_disassembly[kernel_name] = KcCLICommanderLightningUtil::PrefixWithISAHeader(kernel_name, kernel_disassembly); } else @@ -271,7 +296,7 @@ void GraphicsBinaryWorkflowStrategy::StoreOutputFilesToOutputMD(const Config& RgOutputFiles& stage_md = device_md[stage]; if (stage_md.input_file.empty()) { - stage_md.input_file = config.binary_codeobj_file; + stage_md.input_file = binary_codeobj_file_; stage_md.entry_type = GetEntryType(graphics_api_, stage); stage_md.device = asic; } @@ -353,7 +378,7 @@ beKA::beStatus RayTracingBinaryWorkflowStrategy::WriteOutputFiles(const Config& assert(!kernel_to_disassembly.empty()); if (!kernel_to_disassembly.empty()) { - const std::string& isa_file = config.isa_file; + std::string base_isa_filename = config.isa_file; for (const auto& kernel : kernel_to_disassembly) { const auto& amdgpu_kernel_name = kernel.first; @@ -362,27 +387,26 @@ beKA::beStatus RayTracingBinaryWorkflowStrategy::WriteOutputFiles(const Config& if (ExtractShaderSubtype(amdpal_pipeline_md, amdgpu_kernel_name, shader_kernel_subtype)) { std::string concat_kernel_name = KcCLICommanderDxrUtil::CombineKernelAndKernelSubtype(amdgpu_kernel_name, shader_kernel_subtype); - std::string amdgpu_out_file_name; - if (KcUtils::ConstructOutFileName(isa_file, concat_kernel_name, asic, kStrDefaultFilenameIsa, amdgpu_out_file_name)) + std::string isa_filename; + KcCLICommanderDxrUtil::ConstructOutputFileName( + base_isa_filename, kStrDefaultFilenameIsa, kStrDefaultExtensionText, concat_kernel_name, asic, isa_filename); + if (!isa_filename.empty()) { - if (!amdgpu_out_file_name.empty()) - { - KcUtils::DeleteFile(amdgpu_out_file_name); - } + KcUtils::DeleteFile(isa_filename); - [[maybe_unused]] bool is_file_written = KcUtils::WriteTextFile(amdgpu_out_file_name, shader_kernel_content, nullptr); + [[maybe_unused]] bool is_file_written = KcUtils::WriteTextFile(isa_filename, shader_kernel_content, nullptr); assert(is_file_written); - if (!KcUtils::FileNotEmpty(amdgpu_out_file_name)) + if (!KcUtils::FileNotEmpty(isa_filename)) { status = beKA::beStatus::kBeStatusWriteToFileFailed; std::stringstream error_stream; - error_stream << concat_kernel_name << ", output file name " << amdgpu_out_file_name; + error_stream << concat_kernel_name << ", output file name " << isa_filename; error_msg = error_stream.str(); } else { // Store output metadata. - StoreOutputFilesToOutputMD(config, asic, amdgpu_kernel_name, shader_kernel_subtype, amdgpu_out_file_name); + StoreOutputFilesToOutputMD(config, asic, amdgpu_kernel_name, shader_kernel_subtype, isa_filename); status = beKA::beStatus::kBeStatusSuccess; } } @@ -394,7 +418,7 @@ beKA::beStatus RayTracingBinaryWorkflowStrategy::WriteOutputFiles(const Config& void RayTracingBinaryWorkflowStrategy::RunPostProcessingSteps(const Config& config, const BeAmdPalMetaData::PipelineMetaData& amdpal_pipeline_md) { - KcCLICommanderDxrUtil util(output_metadata_, config.print_process_cmd_line, log_callback_); + KcCLICommanderDxrUtil util(binary_codeobj_file_, output_metadata_, config.print_process_cmd_line, log_callback_); beKA::beStatus status = beKA::beStatus::kBeStatusSuccess; // Generate CSV files with parsed ISA if required. @@ -434,7 +458,7 @@ void RayTracingBinaryWorkflowStrategy::RunPostProcessingSteps(const Config& conf bool RayTracingBinaryWorkflowStrategy::RunPostCompileSteps(const Config& config) { // Compute workflows rely on output_metadata for cleaningup temp files. - KcCLICommanderDxrUtil util(output_metadata_, config.print_process_cmd_line, log_callback_); + KcCLICommanderDxrUtil util(binary_codeobj_file_, output_metadata_, config.print_process_cmd_line, log_callback_); return util.RunPostCompileSteps(config); } @@ -467,7 +491,7 @@ void RayTracingBinaryWorkflowStrategy::StoreOutputFilesToOutputMD(const Config& RgOutputFiles outFiles = RgOutputFiles(entry, isa_filename); outFiles.input_file = concat_kernel_name; outFiles.is_isa_file_temp = config.isa_file.empty(); - outFiles.bin_file = config.binary_codeobj_file; + outFiles.bin_file = binary_codeobj_file_; output_metadata_[{asic, concat_kernel_name}] = outFiles; } @@ -537,7 +561,7 @@ void ComputeBinaryWorkflowStrategy::StoreOutputFilesToOutputMD(const Config& RgOutputFiles outFiles = RgOutputFiles(RgEntryType::kOpenclKernel, isa_filename); outFiles.input_file = kernel_name; outFiles.is_isa_file_temp = config.isa_file.empty(); - outFiles.bin_file = config.binary_codeobj_file; + outFiles.bin_file = binary_codeobj_file_; outFiles.entry_abbreviation = kernel_abbreviation; output_metadata_[{asic, kernel_name}] = outFiles; } @@ -547,7 +571,7 @@ void ComputeBinaryWorkflowStrategy::RunPostProcessingSteps(const Config& config, CmpilerPaths compiler_paths = {config.compiler_bin_path, config.compiler_inc_path, config.compiler_lib_path}; bool should_print_cmd = config.print_process_cmd_line; - KcCLICommanderLightningUtil util(output_metadata_, should_print_cmd, log_callback_); + KcCLICommanderLightningUtil util(binary_codeobj_file_, output_metadata_, should_print_cmd, log_callback_); beKA::beStatus status = beKA::beStatus::kBeStatusSuccess; // Generate CSV files with parsed ISA if required. @@ -594,7 +618,7 @@ void ComputeBinaryWorkflowStrategy::RunPostProcessingSteps(const Config& config, bool ComputeBinaryWorkflowStrategy::RunPostCompileSteps(const Config& config) { // Compute workflows rely on output_metadata for cleaningup temp files. - KcCLICommanderLightningUtil util(output_metadata_, config.print_process_cmd_line, log_callback_); + KcCLICommanderLightningUtil util(binary_codeobj_file_, output_metadata_, config.print_process_cmd_line, log_callback_); CmpilerPaths compiler_paths = {config.compiler_bin_path, config.compiler_inc_path, config.compiler_lib_path}; return util.RunPostCompileSteps(config, compiler_paths); } diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h index a41098a..8c63b82 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h @@ -77,9 +77,11 @@ class BinaryWorkflowStrategy class GraphicsBinaryWorkflowStrategy : public BinaryWorkflowStrategy { public: - GraphicsBinaryWorkflowStrategy(LoggingCallbackFunction log_callback) - : log_callback_(log_callback) - {} + GraphicsBinaryWorkflowStrategy(const std::string& binary_codeobj_file, LoggingCallbackFunction log_callback) + : binary_codeobj_file_(binary_codeobj_file) + , log_callback_(log_callback) + { + } // Write Isa file(s) to disk for graphics workflows. beKA::beStatus WriteOutputFiles(const Config& config, @@ -95,9 +97,12 @@ class GraphicsBinaryWorkflowStrategy : public BinaryWorkflowStrategy bool RunPostCompileSteps(const Config& config) override; // The type of Graphics Api. - beProgramBuilderBinary::ApiEnum graphics_api_; + beProgramBuilderBinary::ApiEnum graphics_api_ = beProgramBuilderBinary::ApiEnum::kUnknown; private: + + // CodeObject Binary filename. + std::string binary_codeobj_file_; // Store output file names to the output metadata for graphics workflows. void StoreOutputFilesToOutputMD(const Config& config, @@ -120,8 +125,9 @@ class GraphicsBinaryWorkflowStrategy : public BinaryWorkflowStrategy class RayTracingBinaryWorkflowStrategy : public BinaryWorkflowStrategy { public: - RayTracingBinaryWorkflowStrategy(LoggingCallbackFunction log_callback) - : log_callback_(log_callback) + RayTracingBinaryWorkflowStrategy(const std::string& binary_codeobj_file, LoggingCallbackFunction log_callback) + : binary_codeobj_file_(binary_codeobj_file) + , log_callback_(log_callback) { } @@ -147,6 +153,9 @@ class RayTracingBinaryWorkflowStrategy : public BinaryWorkflowStrategy const std::string& kernel_subtype, const std::string& isa_filename); + // CodeObject Binary filename. + std::string binary_codeobj_file_; + // Output Metadata for raytracing workflows. RgClOutputMetadata output_metadata_; @@ -158,9 +167,11 @@ class RayTracingBinaryWorkflowStrategy : public BinaryWorkflowStrategy class ComputeBinaryWorkflowStrategy : public BinaryWorkflowStrategy { public: - ComputeBinaryWorkflowStrategy(LoggingCallbackFunction log_callback) - : log_callback_(log_callback) - {} + ComputeBinaryWorkflowStrategy(const std::string& binary_codeobj_file, LoggingCallbackFunction log_callback) + : binary_codeobj_file_(binary_codeobj_file) + , log_callback_(log_callback) + { + } // Write Isa file(s) to disk for compute workflows. beKA::beStatus WriteOutputFiles(const Config& config, @@ -184,6 +195,9 @@ class ComputeBinaryWorkflowStrategy : public BinaryWorkflowStrategy const std::string& kernel_abbreviation, const std::string& isa_filename); + // CodeObject Binary filename. + std::string binary_codeobj_file_; + // Output Metadata for compute workflows. RgClOutputMetadata output_metadata_; diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx11.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx11.cpp index ac02dfc..90cf910 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx11.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx11.cpp @@ -45,7 +45,7 @@ static const char* kStrInfoDx11DxAsmCodeGenerationSuccess = "DX ASM code generat static const char* kStrInfoDx11DxAsmCodeGenerationFailure = "DX ASM code generation failed."; // Unsupported devices. -static const std::set kUnsupportedDevicesDx11 = {"gfx902", "gfx904", "gfx908", "gfx90a", "gfx942"}; +static const std::set kUnsupportedDevicesDx11 = {"gfx902", "gfx904", "gfx908", "gfx90a", "gfx942", "gfx1033"}; KcCliCommanderDX::KcCliCommanderDX(void) { diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.cpp index ef96548..f8300c9 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.cpp @@ -5,6 +5,7 @@ // C++. #include +#include // Infra. #include "external/amdt_base_tools/Include/gtString.h" @@ -13,42 +14,43 @@ #include "external/amdt_os_wrappers/Include/osFilePath.h" // Backend. -#include "radeon_gpu_analyzer_backend/be_utils.h" -#include "radeon_gpu_analyzer_backend/be_data_types.h" #include "radeon_gpu_analyzer_backend/autogen/be_utils_dx12.h" +#include "radeon_gpu_analyzer_backend/be_data_types.h" +#include "radeon_gpu_analyzer_backend/be_metadata_parser.h" +#include "radeon_gpu_analyzer_backend/be_utils.h" // Shared. #include "common/rga_shared_utils.h" // Local. +#include "radeon_gpu_analyzer_cli/kc_cli_commander_bin_util.h" #include "radeon_gpu_analyzer_cli/kc_cli_commander_dx12.h" #include "radeon_gpu_analyzer_cli/kc_cli_string_constants.h" // Device info. #include "DeviceInfoUtils.h" -using namespace rga; - // ***************************************** // *** INTERNALLY LINKED SYMBOLS - START *** // ***************************************** // Constants - error messages. -static const char* kStrErrorDx12NoTargetProvided = "Error: no supported target device provided."; -static const char* kStrErrorDx12IsaNotGeneratedA = "Error: failed to generate ISA disassembly for "; -static const char* kStrErrorDx12AmdilNotGeneratedA = "Error: failed to generate AMDIL disassembly for "; +static const char* kStrErrorDx12NoTargetProvided = "Error: no supported target device provided."; +static const char* kStrErrorDx12IsaNotGeneratedA = "Error: failed to generate ISA disassembly for "; +static const char* kStrErrorDx12AmdilNotGeneratedA = "Error: failed to generate AMDIL disassembly for "; static const char* kStrErrorDx12OutputNotGeneratedB = " shader"; -static const char* kStrErrorDx12StatsNotGeneratedA = "Error: failed to generate resource usage statistics for "; -static const char* kStrErrorDx12StatsNotGeneratedB = " shader"; +static const char* kStrErrorDx12StatsNotGeneratedA = "Error: failed to generate resource usage statistics for "; +static const char* kStrErrorDx12StatsNotGeneratedB = " shader"; static const char* kStrErrorDx12BinaryNotGeneratedA = "Error: failed to extract pipeline binary for "; -static const char* kStrErrorInvalidDxcOptionArgument = "Error: argument to --dxc option should be path to the folder where DXC is located, not a full path to a file."; +static const char* kStrErrorInvalidDxcOptionArgument = + "Error: argument to --dxc option should be path to the folder where DXC is located, not a full path to a file."; static const char* kStrErrorGpsoFileWriteFailed = "Error: failed to write template .gpso file to: "; // DXR-specific error messages. -static const char* kStrErrorDxrIsaNotGeneratedB = " export."; +static const char* kStrErrorDxrIsaNotGeneratedB = " export."; static const char* kStrErrorDxrIsaNotGeneratedBPipeline = " pipeline."; -static const char* kStrErrorDxrNoSupportedTargetsFound = "Error: non of the targets which are supported by the driver is gfx1030 or beyond. Aborting."; +static const char* kStrErrorDxrNoSupportedTargetsFound = "Error: non of the targets which are supported by the driver is gfx1030 or beyond. Aborting."; // Constants - warnings messages. static const char* kStrWarningDx12AutoDeducingRootSignatureAsHlsl = "Warning: --rs-hlsl option not provided, assuming that root signature macro is defined in "; @@ -57,19 +59,27 @@ static const char* kStrWarningDx12AutoDeducingRootSignatureAsHlsl = "Warning: -- static const char* kStrWarningDxrSkippingUnsupportedTarget = "Warning: DXR mode only supports gfx1030 and beyond as a target. Skipping "; // Constants - info messages. -static const char* kStrInfoTemplateGpsoFileGenerated = "Template .gpso file created successfully."; -static const char* kStrInfoDx12PostProcessingSeparator = "-=-=-=-=-=-=-"; -static const char* kStrInfoDx12PostProcessing = "Post-processing..."; -static const char* kStrInfoDxrAssumingShaderMode = "Info: no --mode argument detected, assuming '--mode shader' by default."; -static const char* kStrInfoDxrOutputPipelineNumber = "pipeline #"; -static const char* kStrInfoDxrOutputPipelineName = "pipeline associated with raygeneration shader "; -static const char* kStrInfoDxrUsingDefaultShaderModel = "Info: using user-provided shader model instead of the default model ("; +static const char* kStrInfoTemplateGpsoFileGenerated = "Template .gpso file created successfully."; +static const char* kStrInfoDx12PostProcessingSeparator = "-=-=-=-=-=-=-"; +static const char* kStrInfoDx12PostProcessing = "Post-processing..."; +static const char* kStrInfoDxrUsingDefaultShaderModel = "Info: using user-provided shader model instead of the default model ("; +static const char* kStrInfoDxrUnifiedPipelineGenerated = "Pipeline compiled in Unified mode, expect a single uber shader in the output."; +static const char* kStrInfoDxrIndirectPipelineGenerated = "Pipeline compiled in Indirect mode."; +static const char* kStrInfoDxrExtractedDisassemblyA = "Extracting disassembly for pipeline associated with "; +static const char* kStrInfoDxrExtractedDisassemblyB = " shader "; +static const char* kStrInfoDxrExtractedDisassemblyC = "... "; +static const char* kStrInfoDisassemblingBinaryElfContainer = "Disassembling pipeline binary ELF container "; +static const char* kStrInfoDisassemblingBinaryElfContainerSuccess = "Pipeline binary ELF container disassembled successfully."; +static const char* kStrInfoDisassemblingBinaryElfFailure = "failure."; +static const char* kStrInfoDisassemblingBinaryElfContainerOnlyVegaRdna = + "Disassembling pipeline binary ELF container (--elf-dis) is only supported for binaries generated for Vega, RDNA and beyond. Skipping for "; // Constants - other. -static const char* kStrDxrUnifiedSuffix = "_unified"; -const char kStrFileNmaeTokenIndirect = '*'; +const char kStrFileNmaeTokenIndirect = '*'; const char* kStrDefaultDxrShaderModel = "lib_6_3"; +static const char* kAmdgpuDisShaderIdentifiersToken = "_amdgpu_shader_identifiers"; + // Update the user provided configuration if necessary. static void UpdateConfig(const Config& user_input, Config& updated_config) { @@ -142,14 +152,6 @@ static void UpdateConfig(const Config& user_input, Config& updated_config) } else { - // Use shader mode by default. - if (user_input.dxr_mode.compare(kStrDxrModeShader) != 0 && - user_input.dxr_mode.compare(kStrDxrModePipeline) != 0) - { - std::cout << kStrInfoDxrAssumingShaderMode << std::endl; - updated_config.dxr_mode = kStrDxrModeShader; - } - if (user_input.dxr_shader_model.empty()) { // Use the default shader model unless specified otherwise by the user. @@ -163,183 +165,61 @@ static void UpdateConfig(const Config& user_input, Config& updated_config) } } - -static bool PerformLiveVgprAnalysisDxr(const Config& config_updated, const std::string& isa_file, const std::string& target, - const std::string& output_filename, const std::string&, const RgDxrShaderResults& shader_results) +struct RaytracingPipelineMetaData : public BeAmdPalMetaData::PipelineMetaData { - bool is_ok = false; - if (!isa_file.empty()) - { - std::cout << kStrInfoPerformingLiveregAnalysisVgpr; - std::cout << kStrInfoDxrOutputShader << shader_results.export_name << kStrInfoDxrPerformingPostProcessing << std::endl; + // Return true if it is a compute pipeline metadata. + bool IsComputePipeline(); - // Delete the file if it already exists. - if (BeUtils::IsFilePresent(output_filename)) - { - KcUtils::DeleteFile(output_filename.c_str()); - } + // Returns true if the compute pipeline metadata is that of a Unified RayGen shader. + bool IsUnifiedRaygenShader(); - is_ok = KcUtils::PerformLiveRegisterAnalysis(isa_file, target, output_filename, NULL, - config_updated.print_process_cmd_line); + // Return true if it is a compute pipeline metadata. + bool IsComputeLibrary(); - if (is_ok) - { - if (KcUtils::FileNotEmpty(output_filename)) - { - std::cout << kStrInfoSuccess << std::endl; - } - else - { - std::cout << kStrInfoFailed << std::endl; - KcUtils::DeleteFile(output_filename); - } - } - } + // Returns true if type is a Ray Tracing Shader type. + static bool IsRayTracingShaderType(BeAmdPalMetaData::ShaderSubtype type); +}; - return is_ok; +bool RaytracingPipelineMetaData::IsComputePipeline() +{ + return shaders.size() == 1 && shader_functions.empty() && shaders.front().shader_type == BeAmdPalMetaData::ShaderType::kCompute; } -static bool PerformLiveSgprAnalysisDxr(const Config& config_updated, - const std::string& isa_file, - const std::string& target, - const std::string& output_filename, - const std::string& , - const RgDxrShaderResults& shader_results) +bool RaytracingPipelineMetaData::IsUnifiedRaygenShader() { - bool is_ok = false; - if (!isa_file.empty()) - { - std::cout << kStrInfoPerformingLiveregAnalysisSgpr; - std::cout << kStrInfoDxrOutputShader << shader_results.export_name << kStrInfoDxrPerformingPostProcessing << std::endl; - - // Delete the file if it already exists. - if (BeUtils::IsFilePresent(output_filename)) - { - KcUtils::DeleteFile(output_filename.c_str()); - } - - is_ok = KcUtils::PerformLiveRegisterAnalysis(isa_file, target, output_filename, NULL, config_updated.print_process_cmd_line, true); - - if (is_ok) - { - if (KcUtils::FileNotEmpty(output_filename)) - { - std::cout << kStrInfoSuccess << std::endl; - } - else - { - std::cout << kStrInfoFailed << std::endl; - KcUtils::DeleteFile(output_filename); - } - } - } - - return is_ok; + return IsComputePipeline() && shaders.front().shader_subtype == BeAmdPalMetaData::ShaderSubtype::kRayGeneration; } -static bool GeneratePerBlockCfgDxr(const Config& config_updated, const std::string& isa_file, const std::string& target, - const std::string& output_filename, const std::string&, const RgDxrShaderResults& shader_results) +bool RaytracingPipelineMetaData::IsComputeLibrary() { - bool is_ok = false; - if (!isa_file.empty()) - { - std::cout << kStrInfoContructingPerBlockCfg1; - std::cout << kStrInfoDxrOutputShader << shader_results.export_name << kStrInfoDxrPerformingPostProcessing << std::endl; - - // Delete the file if it already exists. - if (BeUtils::IsFilePresent(output_filename)) - { - KcUtils::DeleteFile(output_filename.c_str()); - } - - is_ok = KcUtils::GenerateControlFlowGraph(isa_file, target, output_filename, NULL, - false, config_updated.print_process_cmd_line); - - if (is_ok) - { - if (KcUtils::FileNotEmpty(output_filename)) - { - std::cout << kStrInfoSuccess << std::endl; - } - else - { - std::cout << kStrInfoFailed << std::endl; - KcUtils::DeleteFile(output_filename); - } - } - } - - return is_ok; + return shaders.empty() && shader_functions.size() == 1; } -static bool GeneratePerInstructionCfgDxr(const Config& config_updated, const std::string& isa_file, const std::string& target, - const std::string& output_filename, const std::string&, const RgDxrShaderResults& shader_results) +bool RaytracingPipelineMetaData::IsRayTracingShaderType(BeAmdPalMetaData::ShaderSubtype type) { - bool is_ok = false; - if (!isa_file.empty()) + bool ret = true; + switch (type) { - std::cout << kStrInfoContructingPerInstructionCfg1; - std::cout << kStrInfoDxrOutputShader << shader_results.export_name << kStrInfoDxrPerformingPostProcessing << std::endl; - - // Delete the file if it already exists. - if (BeUtils::IsFilePresent(output_filename)) - { - KcUtils::DeleteFile(output_filename.c_str()); - } - - is_ok = KcUtils::GenerateControlFlowGraph(isa_file, target, output_filename, NULL, - true, config_updated.print_process_cmd_line); - - if (is_ok) - { - if (KcUtils::FileNotEmpty(output_filename)) - { - std::cout << kStrInfoSuccess << std::endl; - } - else - { - std::cout << kStrInfoFailed << std::endl; - KcUtils::DeleteFile(output_filename); - } - } + case BeAmdPalMetaData::ShaderSubtype::kRayGeneration: + case BeAmdPalMetaData::ShaderSubtype::kMiss: + case BeAmdPalMetaData::ShaderSubtype::kAnyHit: + case BeAmdPalMetaData::ShaderSubtype::kClosestHit: + case BeAmdPalMetaData::ShaderSubtype::kIntersection: + case BeAmdPalMetaData::ShaderSubtype::kCallable: + break; + default: + ret = false; } - - return is_ok; + return ret; } -// Disassembles ELF container and saves it to the requested output file according to the given Config. -// pipelineBinary is the full path to the pipeline binary ELF container file. -static void DisassembleElfBinary(const std::string& target, const std::string& pipeline_binary, const Config& config, const std::string& output_filename, std::string error_msg) +bool IsDxrPostProcessingRequired(const Config& config) { - const char* kStrInfoDisassemblingBinaryElfContainer = "Disassembling pipeline binary ELF container "; - const char* kStrInfoDisassemblingBinaryElfContainerSuccess = "Pipeline binary ELF container disassembled successfully."; - const char* kStrInfoDisassemblingBinaryElfFailure = "failure."; - const char* kStrInfoDisassemblingBinaryElfContainerOnlyVegaRdna = "Disassembling pipeline binary ELF container (--elf-dis) is only supported for binaries generated for Vega, RDNA and beyond. Skipping for "; - std::cout << kStrInfoDisassemblingBinaryElfContainer << pipeline_binary << "... " << std::endl; - std::string elf_disassembly; - std::string elf_disassembly_dot_text; - - if (KcUtils::IsNaviTarget(target) || KcUtils::IsVegaTarget(target)) - { - const std::string quoted_binary_path = KcUtils::Quote(pipeline_binary); - bool is_elf_disassembled = BeUtils::DisassembleCodeObject(quoted_binary_path, - config.print_process_cmd_line, elf_disassembly, elf_disassembly_dot_text, error_msg); - assert(is_elf_disassembled); - if (is_elf_disassembled && !elf_disassembly.empty()) - { - std::cout << kStrInfoDisassemblingBinaryElfContainerSuccess << std::endl; - [[maybe_unused]] bool isElfDisassemblySaved = KcUtils::WriteTextFile(output_filename, elf_disassembly, nullptr); - assert(isElfDisassemblySaved); - } - else - { - std::cout << kStrInfoDisassemblingBinaryElfFailure << std::endl; - } - } - else - { - std::cout << kStrInfoDisassemblingBinaryElfContainerOnlyVegaRdna << target << "." << std::endl; - } + bool is_livereg_required = !config.livereg_analysis_file.empty(); + bool is_live_sgpr_required = !config.sgpr_livereg_analysis_file.empty(); + bool is_stats_required = !config.analysis_file.empty(); + bool is_cfg_required = (!config.block_cfg_file.empty() || !config.inst_cfg_file.empty()); + return is_livereg_required || is_live_sgpr_required || is_stats_required || is_cfg_required; } // **************************************** @@ -409,12 +289,6 @@ void KcCliCommanderDX12::RunCompileCommands(const Config& config, LoggingCallbac bool is_dxr = (config_updated.mode == RgaMode::kModeDxr); bool is_input_valid = dx12_backend_.ValidateAndGeneratePipeline(config_updated, is_dxr); - // In DXR pipeline mode, always assume "all" as the export. - if (is_dxr && !BeDx12Utils::IsDxrShaderMode(config_updated) && config_updated.dxr_exports.empty()) - { - config_updated.dxr_exports.push_back("all"); - } - bool was_asic_list_auto_generated = false; if (is_input_valid) { @@ -505,245 +379,37 @@ void KcCliCommanderDX12::RunCompileCommands(const Config& config, LoggingCallbac { for (const RgDxrPipelineResults& curr_pipeline_results : output_mapping) { - for (const RgDxrShaderResults& curr_shader_results : curr_pipeline_results.results) - { - // The key to the map is the export name. - const std::string& currExport = curr_shader_results.export_name; - - // Verify ISA files created. - if (!curr_shader_results.isa_disassembly.empty() && !KcUtils::FileNotEmpty(curr_shader_results.isa_disassembly)) - { - std::cout << kStrErrorDx12IsaNotGeneratedA << currExport - << kStrErrorDxrIsaNotGeneratedB << std::endl; - is_success = false; - } - - if (!curr_shader_results.stats.empty() && !KcUtils::FileNotEmpty(curr_shader_results.stats)) - { - std::cout << kStrErrorDx12StatsNotGeneratedA << currExport - << kStrErrorDxrIsaNotGeneratedB << std::endl; - is_success = false; - } - } - // Verify binary files created. - bool should_extract_pipeline_binaries = - config_updated.dxr_mode.compare(kStrDxrModeShader) != 0 && !curr_pipeline_results.pipeline_binary.empty(); + bool should_extract_pipeline_binaries = !curr_pipeline_results.pipeline_binary.empty(); if (should_extract_pipeline_binaries) { - if (!curr_pipeline_results.pipeline_binary.empty() && !KcUtils::FileNotEmpty(curr_pipeline_results.pipeline_binary)) + if (!KcUtils::FileNotEmpty(curr_pipeline_results.pipeline_binary)) { - std::cout << kStrErrorDx12BinaryNotGeneratedA << curr_pipeline_results.pipeline_name - << kStrErrorDxrIsaNotGeneratedBPipeline << std::endl; + std::cout << kStrErrorDx12BinaryNotGeneratedA << curr_pipeline_results.pipeline_binary + << kStrErrorDxrIsaNotGeneratedBPipeline << "\n"; is_success = false; } else { - // Generate ELF disassembly if needed. - if (!config_updated.elf_dis.empty()) + // Generate ELF disassembly. + std::string elf_disassembly; + is_success = DisassembleElfBinary( + config_updated, target, curr_pipeline_results.pipeline_binary, elf_disassembly, error_msg); + if (is_success) { - // Construct a name for the output file. - std::string output_filename; - is_ok = KcUtils::ConstructOutFileName(config_updated.elf_dis, "", - target, kStrDefaultExtensionText, output_filename); - - // Disassemble the pipeline binary. - DisassembleElfBinary(target, curr_pipeline_results.pipeline_binary, - config_updated, output_filename, error_msg); + is_success = PostProcessElfBinary( + config_updated, target, curr_pipeline_results.pipeline_binary, elf_disassembly, error_msg); } - } - } - } - } - - if (is_success) - { - const bool is_shader_mode = BeDx12Utils::IsDxrShaderMode(config_updated); - std::cout << kStrInfoSuccess << std::endl; - if (!config_updated.livereg_analysis_file.empty() || - !config_updated.sgpr_livereg_analysis_file.empty() || - !config_updated.inference_analysis_file.empty() || - !config_updated.inst_cfg_file.empty() || - !config_updated.block_cfg_file.empty()) - { - // Post-processing. - std::cout << kStrInfoDx12PostProcessingSeparator << std::endl; - std::cout << kStrInfoDx12PostProcessing << std::endl; - - // Live register analysis files. - if (!config_updated.livereg_analysis_file.empty()) - { - for (const RgDxrPipelineResults& curr_pipeline_results : output_mapping) - { - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name)) - { - // Announce the pipeline name in pipeline mode. - std::cout << kStrInfoPerformingLiveregAnalysisVgpr << - (curr_pipeline_results.isUnified ? kStrInfoDxrOutputPipelineName : kStrInfoDxrOutputPipelineNumber) << - curr_pipeline_results.pipeline_name << "..." << std::endl; - } - - for (const RgDxrShaderResults& curr_shader_results : curr_pipeline_results.results) - { - std::stringstream filename_suffix_stream; - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name) && - !curr_pipeline_results.isUnified) - { - filename_suffix_stream << curr_pipeline_results.pipeline_name << "_"; - } - filename_suffix_stream << curr_shader_results.export_name; - if (!is_shader_mode && curr_pipeline_results.isUnified) - { - filename_suffix_stream << kStrDxrUnifiedSuffix; - } - std::string filename_suffix = filename_suffix_stream.str(); - - // Do not append a suffix in case that the file name is empty, - // to prevent a situation where we have the shader name appearing twice. - bool should_append_suffix = !KcUtils::IsDirectory(config.livereg_analysis_file); - - std::string output_filename; - KcUtils::ConstructOutFileName(config.livereg_analysis_file, filename_suffix, - target, kStrDefaultExtensionLivereg, output_filename, should_append_suffix); - - PerformLiveVgprAnalysisDxr(config_updated, curr_shader_results.isa_disassembly, target, - output_filename, filename_suffix, curr_shader_results); - } - } - } - - // Live register analysis files (Sgpr). - if (!config_updated.sgpr_livereg_analysis_file.empty()) - { - for (const RgDxrPipelineResults& curr_pipeline_results : output_mapping) - { - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name)) - { - // Announce the pipeline name in pipeline mode. - std::cout << kStrInfoPerformingLiveregAnalysisSgpr - << (curr_pipeline_results.isUnified ? kStrInfoDxrOutputPipelineName - : kStrInfoDxrOutputPipelineNumber) - << curr_pipeline_results.pipeline_name << "..." << std::endl; - } - - for (const RgDxrShaderResults& curr_shader_results : curr_pipeline_results.results) + else { - std::stringstream filename_suffix_stream; - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name) && - !curr_pipeline_results.isUnified) - { - filename_suffix_stream << curr_pipeline_results.pipeline_name << "_"; - } - filename_suffix_stream << curr_shader_results.export_name; - if (!is_shader_mode && curr_pipeline_results.isUnified) - { - filename_suffix_stream << kStrDxrUnifiedSuffix; - } - std::string filename_suffix = filename_suffix_stream.str(); - - // Do not append a suffix in case that the file name is empty, - // to prevent a situation where we have the shader name appearing twice. - bool should_append_suffix = !KcUtils::IsDirectory(config.sgpr_livereg_analysis_file); - - std::string output_filename; - KcUtils::ConstructOutFileName(config.sgpr_livereg_analysis_file, - filename_suffix, - target, - kStrDefaultExtensionLiveregSgpr, - output_filename, - should_append_suffix); - - PerformLiveSgprAnalysisDxr(config_updated, - curr_shader_results.isa_disassembly, - target, - output_filename, - filename_suffix, - curr_shader_results); + std::cout << error_msg << "\n"; } } - } - // Per-block control-flow graphs. - if (!config_updated.block_cfg_file.empty()) - { - for (const RgDxrPipelineResults& curr_pipeline_results : output_mapping) + // Clean up temporary files. + if (!config.should_retain_temp_files && config.binary_output_file.empty()) { - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name)) - { - // Announce the pipeline name in pipeline mode. - std::cout << kStrInfoContructingPerBlockCfg1 << - (curr_pipeline_results.isUnified ? kStrInfoDxrOutputPipelineName : kStrInfoDxrOutputPipelineNumber) << - curr_pipeline_results.pipeline_name << "..." << std::endl; - } - - for (const RgDxrShaderResults& curr_shader_results : curr_pipeline_results.results) - { - std::stringstream filename_suffix_stream; - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name) && - !curr_pipeline_results.isUnified) - { - filename_suffix_stream << curr_pipeline_results.pipeline_name << "_"; - } - filename_suffix_stream << curr_shader_results.export_name; - if (!is_shader_mode && curr_pipeline_results.isUnified) - { - filename_suffix_stream << kStrDxrUnifiedSuffix; - } - std::string filename_suffix = filename_suffix_stream.str(); - - // Do not append a suffix in case that the file name is empty, - // to prevent a situation where we have the shader name appearing twice. - bool should_append_suffix = !KcUtils::IsDirectory(config.block_cfg_file); - - std::string output_filename; - KcUtils::ConstructOutFileName(config.block_cfg_file, filename_suffix, - target, kStrDefaultExtensionDot, output_filename, should_append_suffix); - - GeneratePerBlockCfgDxr(config_updated, curr_shader_results.isa_disassembly, target, - output_filename, filename_suffix, curr_shader_results); - } - } - } - - // Per-instruction control-flow graphs. - if (!config_updated.inst_cfg_file.empty()) - { - for (const RgDxrPipelineResults& curr_pipeline_results : output_mapping) - { - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name)) - { - // Announce the pipeline name in pipeline mode. - std::cout << kStrInfoContructingPerInstructionCfg1 << - (curr_pipeline_results.isUnified ? kStrInfoDxrOutputPipelineName : kStrInfoDxrOutputPipelineNumber) << - curr_pipeline_results.pipeline_name << "..." << std::endl; - } - - for (const RgDxrShaderResults& curr_shader_results : curr_pipeline_results.results) - { - std::stringstream filename_suffix_stream; - if (!BeProgramBuilderDx12::IsDxrNullPipeline(curr_pipeline_results.pipeline_name) && - !curr_pipeline_results.isUnified) - { - filename_suffix_stream << curr_pipeline_results.pipeline_name << "_"; - } - filename_suffix_stream << curr_shader_results.export_name; - if (!is_shader_mode && curr_pipeline_results.isUnified) - { - filename_suffix_stream << kStrDxrUnifiedSuffix; - } - std::string filename_suffix = filename_suffix_stream.str(); - - // Do not append a suffix in case that the file name is empty, - // to prevent a situation where we have the shader name appearing twice. - bool should_append_suffix = !KcUtils::IsDirectory(config.inst_cfg_file); - - std::string output_filename; - KcUtils::ConstructOutFileName(config.inst_cfg_file, filename_suffix, - target, kStrDefaultExtensionDot, output_filename, should_append_suffix); - - GeneratePerInstructionCfgDxr(config_updated, curr_shader_results.isa_disassembly, target, - output_filename, filename_suffix, curr_shader_results); - } + KcUtils::DeleteFileW(curr_pipeline_results.pipeline_binary); } } } @@ -803,13 +469,9 @@ void KcCliCommanderDX12::RunCompileCommands(const Config& config, LoggingCallbac } else if (!config_updated.elf_dis.empty()) { - // Construct a name for the output file. - std::string output_filename; - is_ok = KcUtils::ConstructOutFileName(config_updated.elf_dis, "", - target, kStrDefaultExtensionText, output_filename); - // Disassemble the pipeline binary. - DisassembleElfBinary(target, binary_file, config_updated, output_filename, error_msg); + std::string elf_disassembly; + is_ok = DisassembleElfBinary(config_updated, target, binary_file, elf_disassembly, error_msg, true); } } @@ -952,4 +614,151 @@ bool KcCliCommanderDX12::GetDX12DriverAsicList(const Config& config, std::set kernel_to_disassembly; + beKA::beStatus status = ParseAmdgpudisOutputGraphicStrategy{}.ParseAmdgpudisKernels(elf_disassembly, kernel_to_disassembly, error_msg); + if (status == beKA::beStatus::kBeStatusSuccess) + { + RayTracingBinaryWorkflowStrategy processor{pipeline_elf, log_callback_}; + RaytracingPipelineMetaData pipeline_md; + beKA::beStatus md_status = BeAmdPalMetaData::ParseAmdgpudisMetadata(elf_disassembly, pipeline_md); + assert(md_status == beKA::beStatus::kBeStatusRayTracingCodeObjMetaDataSuccess); + if (md_status == beKA::beStatus::kBeStatusRayTracingCodeObjMetaDataSuccess) + { + bool ignore_pipeline_binary = true; + if (pipeline_md.IsComputePipeline()) + { + if (pipeline_md.IsUnifiedRaygenShader()) + { + std::cout << kStrInfoDxrUnifiedPipelineGenerated << "\n"; + std::cout << kStrInfoDxrExtractedDisassemblyA << BeAmdPalMetaData::GetShaderSubtypeName(BeAmdPalMetaData::ShaderSubtype::kRayGeneration) + << kStrInfoDxrExtractedDisassemblyB << kStrInfoDxrExtractedDisassemblyC; + ignore_pipeline_binary = false; + } + else + { + std::cout << kStrInfoDxrIndirectPipelineGenerated << "\n"; + } + } + else if (pipeline_md.IsComputeLibrary()) + { + const auto& shader_function = pipeline_md.shader_functions.front(); + if (RaytracingPipelineMetaData::IsRayTracingShaderType(shader_function.shader_subtype)) + { + std::cout << kStrInfoDxrExtractedDisassemblyA << BeAmdPalMetaData::GetShaderSubtypeName(shader_function.shader_subtype) + << kStrInfoDxrExtractedDisassemblyB << shader_function.name << kStrInfoDxrExtractedDisassemblyC; + ignore_pipeline_binary = false; + } + else + { + auto found = kernel_to_disassembly.find(shader_function.name); + if (found != kernel_to_disassembly.end()) + { + kernel_to_disassembly.erase(found); + } + } + } + + if (!ignore_pipeline_binary) + { + status = processor.WriteOutputFiles(config, target, kernel_to_disassembly, pipeline_md, error_msg); + if (status == beKA::beStatus::kBeStatusSuccess) + { + std::cout << kStrInfoSuccess << "\n"; + // Post-processing. + if (IsDxrPostProcessingRequired(config)) + { + std::cout << kStrInfoDx12PostProcessingSeparator << "\n"; + std::cout << kStrInfoDx12PostProcessing << "\n"; + processor.RunPostProcessingSteps(config, pipeline_md); + } + is_success = true; + } + else + { + std::cout << kStrInfoFailed << "\n"; + } + } + } + } + else + { + if (elf_disassembly.find(kAmdgpuDisShaderIdentifiersToken) != std::string::npos) + { + // The current pipeline binary is based on NPRT enabled in 24.20 driver. + // This is just an implementation detail, and does not concern the user, + // but does NOT indicate a disassemlbly parsing failure. + is_success = true; + } + } + return is_success; +} #endif diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.h b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.h index e913629..3bba3ad 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.h +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dx12.h @@ -37,6 +37,22 @@ class KcCliCommanderDX12 : public KcCliCommander // Print the list of supported targets for DX12 driver. bool GetDX12DriverAsicList(const Config& config, std::set& target_gpus, bool print = false); + // Disassembles ELF container and saves it to the requested output file according to the given Config. + // pipelineBinary is the full path to the pipeline binary ELF container file. + bool DisassembleElfBinary(const Config& config, + const std::string& target, + const std::string& pipeline_elf, + std::string& elf_disassembly, + std::string& error_msg, + bool verbose = false) const; + + // Extract isa, stats, livereg, etc. from the dxr compiled elf binary. + bool PostProcessElfBinary(const Config& config, + const std::string& target, + const std::string& pipeline_elf, + const std::string& elf_disassembly, + std::string& error_msg); + std::vector dx_default_asic_list_; BeProgramBuilderDx12 dx12_backend_; }; diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.cpp index 983ecb0..3b4c105 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.cpp @@ -1,5 +1,6 @@ // C++ +#include #include // External. @@ -23,13 +24,22 @@ static const char* kStrKernelName = "Kernel name: "; static const char* kStrErrorFailedToCreateOutputFilenameForKernel = "Error: failed to construct output file name for kernel: "; -static const char* kStrInfoKernelForKernel = " for kernel "; +static const char* kStrInfoForShaderA = " shader"; +static const char* kStrInfoForShaderB = " ... "; +static const char* kStrInfoExtractRayTracingResourceUsage = "Extracting hardware resource usage for "; + +// Shader stage suffix. +static const std::string kStrCS = "cs"; +static const std::string kStrUnified = "unified"; static void LogResult(bool result) { std::cout << (result ? kStrInfoSuccess : kStrInfoFailed) << std::endl; } +// Initialize CLI session files. +std::set KcCLICommanderDxrUtil::session_output_files_ = {}; + bool KcCLICommanderDxrUtil::ParseIsaFilesToCSV(bool line_numbers) const { bool ret = true; @@ -89,16 +99,21 @@ bool KcCLICommanderDxrUtil::PerformLiveVgprAnalysis(const Config& config) const device_gtstr << device.c_str(); // Inform the user. - std::cout << kStrInfoPerformingLiveregAnalysisVgpr << device << kStrInfoKernelForKernel << entry_name << "... "; + const auto& p = SeparateKernelAndKernelSubtype(entry_name); + const std::string& kernel_name = p.first; + const std::string& kernel_subtype = p.second; + std::cout << kStrInfoPerformingLiveregAnalysisVgpr << kernel_subtype << kStrInfoForShaderA; + if (kernel_name != kStrCS) + { + std::cout << " " << kernel_name; + } + std::cout << kStrInfoForShaderB; // Construct a name for the output livereg file. - KcUtils::ConstructOutputFileName(config.livereg_analysis_file, - kStrDefaultExtensionLivereg, - kStrDefaultExtensionText, - entry_name, - device, - livereg_out_filename); - + std::string livereg_out_filename_std_string; + KcCLICommanderDxrUtil::ConstructOutputFileName( + config.livereg_analysis_file, kStrDefaultExtensionLivereg, kStrDefaultExtensionText, entry_name, device, livereg_out_filename_std_string); + livereg_out_filename << livereg_out_filename_std_string.c_str(); if (!livereg_out_filename.isEmpty()) { KcUtils::PerformLiveRegisterAnalysis(isa_filename, device_gtstr, livereg_out_filename, log_callback_, config.print_process_cmd_line, false); @@ -150,12 +165,25 @@ bool KcCLICommanderDxrUtil::PerformLiveSgprAnalysis(const Config& config) const device_gtstr << device.c_str(); // Inform the user. - std::cout << kStrInfoPerformingLiveregAnalysisSgpr << device << kStrInfoKernelForKernel << entry_name << "... "; + const auto& p = SeparateKernelAndKernelSubtype(entry_name); + const std::string& kernel_name = p.first; + const std::string& kernel_subtype = p.second; + std::cout << kStrInfoPerformingLiveregAnalysisSgpr << kernel_subtype << kStrInfoForShaderA; + if (kernel_name != kStrCS) + { + std::cout << " " << kernel_name; + } + std::cout << kStrInfoForShaderB; // Construct a name for the output livereg file. - KcUtils::ConstructOutputFileName( - config.sgpr_livereg_analysis_file, kStrDefaultExtensionLiveregSgpr, kStrDefaultExtensionText, entry_name, device, livereg_out_filename); - + std::string livereg_out_filename_std_string; + KcCLICommanderDxrUtil::ConstructOutputFileName(config.sgpr_livereg_analysis_file, + kStrDefaultExtensionLiveregSgpr, + kStrDefaultExtensionText, + entry_name, + device, + livereg_out_filename_std_string); + livereg_out_filename << livereg_out_filename_std_string.c_str(); if (!livereg_out_filename.isEmpty()) { KcUtils::PerformLiveRegisterAnalysis(isa_filename, device_gtstr, livereg_out_filename, log_callback_, config.print_process_cmd_line, true); @@ -207,13 +235,25 @@ bool KcCLICommanderDxrUtil::ExtractCFG(const Config& config) const gtString device_gtstr; device_gtstr << device.c_str(); - bool is_per_basic_block_cfg = !config.block_cfg_file.empty(); - std::cout << (is_per_basic_block_cfg ? kStrInfoContructingPerBlockCfg1 : kStrInfoContructingPerInstructionCfg1) << device << kStrInfoKernelForKernel - << entry_name << "... "; + // Inform the user. + bool is_per_basic_block_cfg = !config.block_cfg_file.empty(); + const auto& p = SeparateKernelAndKernelSubtype(entry_name); + const std::string& kernel_name = p.first; + const std::string& kernel_subtype = p.second; + std::cout << (is_per_basic_block_cfg ? kStrInfoContructingPerBlockCfg1 : kStrInfoContructingPerInstructionCfg1) << kernel_subtype + << kStrInfoForShaderA; + if (kernel_name != kStrCS) + { + std::cout << " " << kernel_name; + } + std::cout << kStrInfoForShaderB; // Construct a name for the output CFG file. std::string base_file = (is_per_basic_block_cfg ? config.block_cfg_file : config.inst_cfg_file); - KcUtils::ConstructOutputFileName(base_file, KC_STR_DEFAULT_CFG_SUFFIX, kStrDefaultExtensionDot, entry_name, device, cfg_out_filename); + std::string cfg_out_filename_std_string; + KcCLICommanderDxrUtil::ConstructOutputFileName( + base_file, KC_STR_DEFAULT_CFG_SUFFIX, kStrDefaultExtensionDot, entry_name, device, cfg_out_filename_std_string); + cfg_out_filename << cfg_out_filename_std_string.c_str(); if (!cfg_out_filename.isEmpty()) { KcUtils::GenerateControlFlowGraph( @@ -292,8 +332,15 @@ beKA::beStatus KcCLICommanderDxrUtil::ExtractStatistics(const Config& config, co if (success) { + std::cout << kStrInfoExtractRayTracingResourceUsage << kernel_subtype << kStrInfoForShaderA; + if (kernel_name != kStrCS) + { + std::cout << " " << kernel_name; + } + std::cout << kStrInfoForShaderB; + std::string stats_filename; - KcUtils::ConstructOutputFileName( + KcCLICommanderDxrUtil::ConstructOutputFileName( base_stats_filename, kStrDefaultExtensionStats, kStrDefaultExtensionCsv, concat_kernel_name, current_device, stats_filename); if (!outputMDItem.second.isa_file.empty() && !stats_filename.empty()) { @@ -322,7 +369,7 @@ beKA::beStatus KcCLICommanderDxrUtil::ExtractStatistics(const Config& config, co } } } - } + } device = outputMDItem.first.first; } @@ -341,7 +388,7 @@ bool KcCLICommanderDxrUtil::GenerateSessionMetadata(const Config& config) const if (ret && !output_metadata_.empty()) { - ret = KcXmlWriter::GenerateClSessionMetadataFile(config.session_metadata_file, config.binary_codeobj_file, file_kernel_data, output_metadata_); + ret = KcXmlWriter::GenerateClSessionMetadataFile(config.session_metadata_file, binary_codeobj_file_, file_kernel_data, output_metadata_); } return ret; @@ -389,16 +436,33 @@ bool KcCLICommanderDxrUtil::RunPostCompileSteps(const Config& config) std::string KcCLICommanderDxrUtil::CombineKernelAndKernelSubtype(const std::string& kernel, const std::string& kernel_subtype) { std::stringstream ss; - ss << kernel_subtype << "_" << kernel; + ss << kernel_subtype << "_"; + if (kernel == kStrCS) + { + ss << kStrUnified; + } + else + { + ss << kernel; + } return ss.str(); } std::pair KcCLICommanderDxrUtil::SeparateKernelAndKernelSubtype(const std::string& combined_name) { + std::pair ret; size_t offset = combined_name.find('_'); const std::string& ext = (offset != std::string::npos && offset < combined_name.size()) ? combined_name.substr(0, offset) : ""; const std::string& kernel = (offset != std::string::npos && ++offset < combined_name.size()) ? combined_name.substr(offset) : ""; - return {kernel, ext}; + if (kernel == kStrUnified) + { + ret = {kStrCS, ext}; + } + else + { + ret = {kernel, ext}; + } + return ret; } beKA::beStatus KcCLICommanderDxrUtil::ConvertStats(const BeRtxPipelineFiles& isaFiles, @@ -416,3 +480,34 @@ beKA::beStatus KcCLICommanderDxrUtil::ConvertStats(const BeRtxPipelineFiles& isa } return status; } + +void KcCLICommanderDxrUtil::ConstructOutputFileName(const std::string& base_output_filename, + const std::string& default_suffix, + const std::string& default_extension, + const std::string& entry_point_name, + const std::string& device_name, + std::string& generated_filename) +{ + KcUtils::ConstructOutputFileName(base_output_filename, default_suffix, default_extension, entry_point_name, device_name, generated_filename); + auto found = session_output_files_.find(generated_filename); + if (found == session_output_files_.end()) + { + session_output_files_.insert(generated_filename); + } + else + { + unsigned int counter = 1; + do + { + std::filesystem::path generated_filepath(generated_filename); + std::filesystem::path directory = generated_filepath.parent_path(); + std::string filename_no_ext = generated_filepath.stem().string(); + std::string extension = generated_filepath.extension().string(); + generated_filepath = directory / (filename_no_ext + '_' + std::to_string(counter) + extension); + generated_filename = generated_filepath.string(); + counter++; + found = session_output_files_.find(generated_filename); + } while (found != session_output_files_.end()); + session_output_files_.insert(generated_filename); + } +} diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.h b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.h index 39cae4d..92d5812 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.h +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_dxr_util.h @@ -22,10 +22,12 @@ class KcCLICommanderDxrUtil { public: - KcCLICommanderDxrUtil(RgClOutputMetadata& output_metadata, - bool should_print_cmd, + KcCLICommanderDxrUtil(const std::string& binary_codeobj_file, + RgClOutputMetadata& output_metadata, + bool should_print_cmd, LoggingCallbackFunction log_callback) - : output_metadata_(output_metadata) + : binary_codeobj_file_(binary_codeobj_file) + , output_metadata_(output_metadata) , should_print_cmd_(should_print_cmd) , log_callback_(log_callback) {} @@ -60,6 +62,14 @@ class KcCLICommanderDxrUtil const Config& config, const std::string& device); + // Wrapper around KcUtils::ConstructOutputFileName() to keep track of session output files. + static void ConstructOutputFileName(const std::string& base_output_filename, + const std::string& default_suffix, + const std::string& default_extension, + const std::string& entry_point_name, + const std::string& device_name, + std::string& generated_filename); + private: // Generate RGA CLI session metadata file. @@ -70,6 +80,9 @@ class KcCLICommanderDxrUtil // ---- DATA ---- + // CodeObject Binary filename. + std::string binary_codeobj_file_; + // Output Metadata. RgClOutputMetadata& output_metadata_; @@ -79,6 +92,9 @@ class KcCLICommanderDxrUtil // Log callback function. LoggingCallbackFunction log_callback_; + // Ouput files generated for the CLI session. + static std::set session_output_files_; + }; #endif // RGA_RADEONGPUANALYZERCLI_SRC_KC_CLI_COMMANDER_DXR_UTIL_H_ \ No newline at end of file diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning.cpp index 48c8563..6bc27c1 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning.cpp @@ -61,7 +61,8 @@ kLcLlvmTargetsToDeviceInfoTargets = { {"gfx801", "carrizo"}, {"gfx1100", "gfx1100"}, {"gfx1101", "gfx1101"}, {"gfx1102", "gfx1102"}, - {"gfx1103", "gfx1103"} }; + {"gfx1103", "gfx1103"}, + {"gfx1150", "gfx1150"} }; // For some devices, clang does not accept device names that RGA gets from DeviceInfo. // This table maps the DeviceInfo names to names accepted by clang for such devices. @@ -262,7 +263,7 @@ bool KcCLICommanderLightning::Compile(const Config& config) // Generate CSV files with parsed ISA if required. if (config.is_parsed_isa_required && (result == beKA::kBeStatusSuccess || targets_.size() > 1)) { - KcCLICommanderLightningUtil util(output_metadata_, should_print_cmd_, log_callback_); + KcCLICommanderLightningUtil util(config.binary_codeobj_file, output_metadata_, should_print_cmd_, log_callback_); result = util.ParseIsaFilesToCSV(config.is_line_numbers_required) ? beKA::beStatus::kBeStatusSuccess : beKA::beStatus::kBeStatusParseIsaToCsvFailed; } @@ -510,7 +511,7 @@ void KcCLICommanderLightning::RunCompileCommands(const Config& config, LoggingCa { bool is_multiple_devices = (config.asics.size() > 1); bool status = Compile(config); - KcCLICommanderLightningUtil util(output_metadata_, should_print_cmd_, log_callback_); + KcCLICommanderLightningUtil util(config.binary_codeobj_file, output_metadata_, should_print_cmd_, log_callback_); // Block post-processing until quality of analysis engine improves when processing llvm disassembly. bool is_livereg_required = !config.livereg_analysis_file.empty(); @@ -972,7 +973,7 @@ bool KcCLICommanderLightning::GetSupportedTargets(std::set& targets bool KcCLICommanderLightning::RunPostCompileSteps(const Config& config) { - KcCLICommanderLightningUtil util(output_metadata_, should_print_cmd_, log_callback_); + KcCLICommanderLightningUtil util(config.binary_codeobj_file, output_metadata_, should_print_cmd_, log_callback_); return util.RunPostCompileSteps(config, compiler_paths_); } diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.cpp index a0ab053..5d692e0 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.cpp @@ -878,7 +878,7 @@ bool KcCLICommanderLightningUtil::GenerateSessionMetadata(const Config& config, if (ret && !output_metadata_.empty()) { - ret = KcXmlWriter::GenerateClSessionMetadataFile(config.session_metadata_file, config.binary_codeobj_file, file_kernel_data, output_metadata_); + ret = KcXmlWriter::GenerateClSessionMetadataFile(config.session_metadata_file, binary_codeobj_file_, file_kernel_data, output_metadata_); } return ret; diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.h b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.h index 605345b..300b22e 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.h +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_lightning_util.h @@ -25,10 +25,12 @@ class KcCLICommanderLightningUtil { public: - KcCLICommanderLightningUtil(RgClOutputMetadata& output_metadata, - bool should_print_cmd, + KcCLICommanderLightningUtil(const std::string& binary_codeobj_file, + RgClOutputMetadata& output_metadata, + bool should_print_cmd, LoggingCallbackFunction log_callback) - : output_metadata_(output_metadata) + : binary_codeobj_file_(binary_codeobj_file) + , output_metadata_(output_metadata) , should_print_cmd_(should_print_cmd) , log_callback_(log_callback) {} @@ -79,6 +81,9 @@ class KcCLICommanderLightningUtil // ---- DATA ---- + // CodeObject Binary filename. + std::string binary_codeobj_file_; + // Output Metadata. RgClOutputMetadata& output_metadata_; diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_opengl.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_opengl.cpp index e5ab561..b8717df 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_opengl.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_opengl.cpp @@ -28,7 +28,7 @@ static const char* kStrErrTextFileWriteFailed = "Error: unable to write static const char* kStrErrNoInputFile = "Error: no input file received."; // Unsupported devices. -static const std::set kUnsupportedDevicesOpengl = {"gfx900", "gfx902", "gfx904", "gfx906", "gfx908", "gfx90a", "gfx90c", "gfx942"}; +static const std::set kUnsupportedDevicesOpengl = {"gfx900", "gfx902", "gfx904", "gfx906", "gfx908", "gfx90a", "gfx90c", "gfx942", "gfx1033"}; void KcCliCommanderOpenGL::GlcStatsToString(const beKA::AnalysisData& stats, std::stringstream& serialized_stats) { diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_vk_offline.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_vk_offline.cpp index 7102655..bdc9ef7 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_vk_offline.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_vk_offline.cpp @@ -7,32 +7,31 @@ // Local. #include "radeon_gpu_analyzer_cli/kc_cli_commander_vk_offline.h" +#include "radeon_gpu_analyzer_cli/kc_cli_commander_vulkan_util.h" +#include "radeon_gpu_analyzer_cli/kc_statistics_parser_vulkan.h" #include "radeon_gpu_analyzer_cli/kc_cli_string_constants.h" #include "radeon_gpu_analyzer_cli/kc_utils.h" -#include "radeon_gpu_analyzer_cli/kc_statistics_parser_vulkan.h" -#include "radeon_gpu_analyzer_cli/kc_cli_commander_vulkan_util.h" // Backend. -#include "radeon_gpu_analyzer_backend/be_program_builder_vulkan.h" #include "radeon_gpu_analyzer_backend/be_backend.h" +#include "radeon_gpu_analyzer_backend/be_program_builder_vulkan.h" +#include "radeon_gpu_analyzer_backend/be_metadata_parser.h" #include "radeon_gpu_analyzer_backend/be_utils.h" // Shared between CLI and GUI. -#include "common/rga_version_info.h" #include "common/rga_shared_utils.h" +#include "common/rga_version_info.h" // Infra. -#include "external/amdt_os_wrappers/Include/osFilePath.h" #include "external/amdt_os_wrappers/Include/osDirectory.h" - - +#include "external/amdt_os_wrappers/Include/osFilePath.h" // Constants: error messages. static const char* kStrErrorVkOfflineCannotExtractVulkanVersion = "Error: unable to extract the Vulkan version."; static const char* kStrErrorVkOfflineMixedInputFiles = "Error: cannot mix stage-specific input files (--vert, --tesc, --tese, --geom, --frag, --comp) with a stage-less SPIR-V input file."; // Unsupported devices. -static const std::set kUnsupportedDevicesVkOffline = {"gfx908", "gfx90a", "gfx942"}; +static const std::set kUnsupportedDevicesVkOffline = {"gfx900", "gfx902", "gfx904", "gfx906", "gfx908", "gfx90a", "gfx90c", "gfx942", "gfx1033"}; KcCLICommanderVkOffline::KcCLICommanderVkOffline() : vulkan_builder_(new BeProgramBuilderVkOffline) { @@ -676,9 +675,9 @@ void KcCLICommanderVkOffline::RunCompileCommands(const Config& config, LoggingCa StoreOutputFilesToOutputMD(device, spv_files, isa_files, stats_files); BeAmdPalMetaData::PipelineMetaData pipeline; - auto md_status = beProgramBuilderVulkan::ParseAmdgpudisMetadata(amdgpu_dis_stdout, pipeline); - assert(md_status == beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess); - if (md_status == beKA::beStatus::kBeStatusVulkanGraphicsCodeObjMetaDataSuccess) + auto md_status = BeAmdPalMetaData::ParseAmdgpudisMetadata(amdgpu_dis_stdout, pipeline); + assert(md_status == beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess); + if (md_status == beKA::beStatus::kBeStatusGraphicsCodeObjMetaDataSuccess) { vk_util.ExtractStatistics(config, device, pipeline, shader_to_disassembly); } diff --git a/source/radeon_gpu_analyzer_cli/kc_cli_commander_vulkan.cpp b/source/radeon_gpu_analyzer_cli/kc_cli_commander_vulkan.cpp index 3776706..2e1ffd1 100644 --- a/source/radeon_gpu_analyzer_cli/kc_cli_commander_vulkan.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_cli_commander_vulkan.cpp @@ -347,7 +347,7 @@ static bool ConstructVkOutputFileNames(const Config& config, status = KcUtils::ConstructOutFileName(base_bin_filename, "", (!config.should_avoid_binary_device_prefix ? device : ""), (config.should_avoid_binary_suffix ? "" : kStrVulkanBinaryFileExtension), bin_filename); } - else if (KcUtils::IsNavi3Target(device) && !base_isa_filename.empty()) + else if (KcUtils::IsNavi3AndBeyond(device) && !base_isa_filename.empty()) { status = KcUtils::ConstructOutFileName(kStrDefaultFilenameOutputBinaryFileName, "", @@ -368,7 +368,7 @@ static bool ConstructVkOutputFileNames(const Config& config, } } - if (KcUtils::IsNavi3Target(device) && !isa_filenames.empty()) + if (KcUtils::IsNavi3AndBeyond(device) && !isa_filenames.empty()) { status = KcUtils::ConstructOutFileName(base_bin_filename, "", @@ -1280,7 +1280,7 @@ void KcCliCommanderVulkan::CompileSpvToIsaForDevice(const Config& config, const std::copy_if(isa_files.cbegin(), isa_files.cend(), std::back_inserter(temp_files_), [&](const std::string& s) { return !s.empty(); }); - if (KcUtils::IsNavi3Target(device)) + if (KcUtils::IsNavi3AndBeyond(device)) { temp_files_.push_back(bin_file_name); } diff --git a/source/radeon_gpu_analyzer_cli/kc_config.h b/source/radeon_gpu_analyzer_cli/kc_config.h index a94f3ab..3ee2bbc 100644 --- a/source/radeon_gpu_analyzer_cli/kc_config.h +++ b/source/radeon_gpu_analyzer_cli/kc_config.h @@ -145,9 +145,7 @@ struct Config // DX12: DXR. std::string dxr_state_desc; ///< Full path to the DXR state description file. std::string dxr_hlsl; ///< Full path to the DXR HLSL input file. - std::string dxr_mode; ///< DXR mode: shader or pipeline. std::string dxr_shader_model; ///< DXR shader model: shader model to be used for DXR front-end compilation. - std::vector dxr_exports; ///< DXR exports to retrieve disassembly for. In pipeline mode this should be one or more a raygeneration shaders. // DX12: debug layer. bool dx12_debug_layer_enabled = false; ///< True to enable D3D12 debug layer. diff --git a/source/radeon_gpu_analyzer_cli/kc_parse_cmd_line.cpp b/source/radeon_gpu_analyzer_cli/kc_parse_cmd_line.cpp index b79343c..f0efaef 100644 --- a/source/radeon_gpu_analyzer_cli/kc_parse_cmd_line.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_parse_cmd_line.cpp @@ -358,10 +358,6 @@ bool ParseCmdLine(int argc, char* argv[], Config& config) // DXR-specific. opts.add_options(dxr_opt) ("hlsl", "Full path to DXR HLSL input file that contains the state definition.", po::value(config.dxr_hlsl)) - ("mode", "DXR mode: 'shader' to compile a specific shader, or 'pipeline' to compile all pipelines in the State Object. By default, shader mode is assumed.", po::value(config.dxr_mode)) - ("export", "The export name of the shader for which to retrieve results - only relevant to shader mode (--mode shader)." - " this can be an export name of any shader in the state object.", - po::value>(config.dxr_exports)) ("dxr-model", "Shader model used for DXR HLSL compilation. Use this option to override " "the shader model that is used for HLSL compilation by default (lib_6_3).", po::value(config.dxr_shader_model)) @@ -805,15 +801,10 @@ bool ParseCmdLine(int argc, char* argv[], Config& config) std::cout << "Examples:" << std::endl; std::cout << " View supported targets for DXR:" << std::endl; std::cout << " " << program_name << " -s dxr -l" << std::endl; - std::cout << " Compile and generate RDNA ISA disassembly for a shader named MyRaygenShader which is defined in C:\\shaders\\Raytracing.hlsl:" << std::endl; - std::cout << " " << program_name << " -s dxr --hlsl C:\\shaders\\Raytracing.hlsl --export MyRaygenShader --isa C:\\output\\isa.txt" << std::endl; - std::cout << " Compile and generate RDNA ISA disassembly and HW resource usage statistics for a shader named MyClosestHitShader which is defined in C:\\shaders\\Raytracing.hlsl:" << std::endl; - std::cout << " " << program_name << " -s dxr --hlsl C:\\shaders\\Raytracing.hlsl --export MyClosestHitShader --isa C:\\output\\isa.txt -a C:\\output\\stats.txt" << std::endl; std::cout << " Compile and generate RDNA ISA disassembly for all DXR pipelines defined in C:\\shaders\\Raytracing.hlsl:" << std::endl; - std::cout << " " << program_name << " -s dxr --mode pipeline --hlsl C:\\shaders\\Raytracing.hlsl --isa C:\\output\\isa.txt" << std::endl; + std::cout << " " << program_name << " -s dxr --hlsl C:\\shaders\\Raytracing.hlsl --isa C:\\output\\isa.txt" << std::endl; std::cout << " Compile and generate RDNA ISA disassembly for all DXR pipelines which are defined in C:\\shaders\\rt.hlsl with additional headers that are located in C:\\shaders\\include:" << std::endl; - std::cout << " " << program_name << " -s dxr --mode pipeline --hlsl C:\\shaders\\rt.hlsl -I C:\\shaders\\include --isa C:\\output\\isa.txt" << std::endl; - + std::cout << " " << program_name << " -s dxr --hlsl C:\\shaders\\rt.hlsl -I C:\\shaders\\include --isa C:\\output\\isa.txt" << std::endl; } else if ((config.requested_command == Config::kHelp) && (config.mode == beKA::RgaMode::kModeOpenclOffline)) { diff --git a/source/radeon_gpu_analyzer_cli/kc_statistics_device_props.h b/source/radeon_gpu_analyzer_cli/kc_statistics_device_props.h index d30a6ea..beee96b 100644 --- a/source/radeon_gpu_analyzer_cli/kc_statistics_device_props.h +++ b/source/radeon_gpu_analyzer_cli/kc_statistics_device_props.h @@ -47,5 +47,6 @@ static const std::map kRgaDeviceProps = {"gfx1100", {106, 256, 65536, 16, 4}}, {"gfx1101", {106, 256, 65536, 16, 4}}, {"gfx1102", {106, 256, 65536, 16, 4}}, - {"gfx1103", {106, 256, 65536, 16, 4}} + {"gfx1103", {106, 256, 65536, 16, 4}}, + {"gfx1150", {106, 256, 65536, 16, 4}} }; diff --git a/source/radeon_gpu_analyzer_cli/kc_utils.cpp b/source/radeon_gpu_analyzer_cli/kc_utils.cpp index 5c7df84..3b53400 100644 --- a/source/radeon_gpu_analyzer_cli/kc_utils.cpp +++ b/source/radeon_gpu_analyzer_cli/kc_utils.cpp @@ -21,6 +21,7 @@ // Backend. #include "radeon_gpu_analyzer_backend/be_static_isa_analyzer.h" #include "radeon_gpu_analyzer_backend/be_utils.h" +#include "radeon_gpu_analyzer_backend/be_string_constants.h" // Shared. #include "common/rga_shared_utils.h" @@ -1766,6 +1767,16 @@ void KcUtils::CheckForUpdates() } } +bool KcUtils::IsStrix(const std::string& target_name) +{ + return target_name == "gfx1150"; +} + +bool KcUtils::IsNavi3AndBeyond(const std::string& target_name) +{ + return IsStrix(target_name) || IsNavi3Target(target_name); +} + bool KcUtils::IsNavi3Target(const std::string& target_name) { // Token to identify Navi3 targets. @@ -1885,3 +1896,22 @@ bool KcUtils::IsComputeBitSet(RgEntryType rga_entry_type) } return ret; } + +bool KcUtils::InvokeAmdgpudis(const std::string& cmd_line_options, bool should_print_cmd, std::string& out_txt, std::string& error_msg) +{ + osFilePath amdgpu_dis_exe; + long exit_code = 0; + + // Construct the path to the amdgpu-dis executable. + osGetCurrentApplicationPath(amdgpu_dis_exe, false); + amdgpu_dis_exe.appendSubDirectory(kAmdgpudisRootDir); + amdgpu_dis_exe.setFileName(kAmdgpudisExecutable); +#ifdef _WIN32 + amdgpu_dis_exe.setFileExtension(kAmdgpudisExecutableExtension); +#endif + + KcUtils::ProcessStatus status = KcUtils::LaunchProcess( + amdgpu_dis_exe.asString().asASCIICharArray(), cmd_line_options, "", kProcessWaitInfinite, should_print_cmd, out_txt, error_msg, exit_code); + + return status == KcUtils::ProcessStatus::kSuccess; +} \ No newline at end of file diff --git a/source/radeon_gpu_analyzer_cli/kc_utils.h b/source/radeon_gpu_analyzer_cli/kc_utils.h index 26f5cd7..1a934e0 100644 --- a/source/radeon_gpu_analyzer_cli/kc_utils.h +++ b/source/radeon_gpu_analyzer_cli/kc_utils.h @@ -328,6 +328,12 @@ class KcUtils // Checks for available updates. static void CheckForUpdates(); + + // Returns true if the target is Navi3 or beyond and false otherwise. + static bool IsStrix(const std::string& target_name); + + // Returns true if the target is Navi3 or beyond and false otherwise. + static bool IsNavi3AndBeyond(const std::string& target_name); // Returns true if the target is of the Navi3 generation and false otherwise. static bool IsNavi3Target(const std::string& target_name); @@ -383,6 +389,9 @@ class KcUtils // Returns true if the compute bit is set for given entry_type. static bool IsComputeBitSet(RgEntryType rga_entry_type); + // Invoke the amdgpu-dis executable. + static bool InvokeAmdgpudis(const std::string& cmd_line_options, bool should_print_cmd, std::string& out_text, std::string& error_txt); + private: // This is a static class (no instances). KcUtils(const KcUtils& other); diff --git a/source/radeon_gpu_analyzer_gui/cmake/devtools_qt_helper.cmake b/source/radeon_gpu_analyzer_gui/cmake/devtools_qt_helper.cmake index e7cd5fd..5c53d68 100644 --- a/source/radeon_gpu_analyzer_gui/cmake/devtools_qt_helper.cmake +++ b/source/radeon_gpu_analyzer_gui/cmake/devtools_qt_helper.cmake @@ -31,33 +31,6 @@ if (NOT Qt6_DIR) endif () endif () -# START_REMOVE_DURING_SANITIZATION -# linuxdeployqt -if (UNIX AND NOT APPLE) - - if (Qt6_DIR) - set(LINUXDEPLOYQT_URL "http://bdcartifactory.amd.com/artifactory/DevToolsBDC/Assets/radeon_developer_panel/linuxdeployqt6.tar.xz") - else () - set(LINUXDEPLOYQT_URL "http://bdcartifactory.amd.com/artifactory/DevToolsBDC/Assets/radeon_developer_panel/linuxdeployqt.zip") - endif () - - include(FetchContent) - FetchContent_Declare( - linuxdeployqt - URL ${LINUXDEPLOYQT_URL} - SOURCE_DIR ${PROJECT_SOURCE_DIR}/external/linuxdeployqt - ) - FetchContent_MakeAvailable(linuxdeployqt) - - find_program(LINUXDEPLOYQT "linuxdeployqt" HINTS "${PROJECT_SOURCE_DIR}/external/linuxdeployqt") - if (LINUXDEPLOYQT) - message(STATUS "Found linuxdeployqt: ${LINUXDEPLOYQT}") - else () - message(ERROR "linuxdeployqt not found but is required for build") - endif () -endif () -# END_REMOVE_DURING_SANITIZATION - if (Qt5_DIR OR Qt6_DIR) ####################################################################################################################### # Setup the INSTALL target to include Qt DLLs diff --git a/source/radeon_gpu_analyzer_gui/main.cpp b/source/radeon_gpu_analyzer_gui/main.cpp index 313df83..2ff11c6 100644 --- a/source/radeon_gpu_analyzer_gui/main.cpp +++ b/source/radeon_gpu_analyzer_gui/main.cpp @@ -12,6 +12,9 @@ #include #endif +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_app_state.h" #include "radeon_gpu_analyzer_gui/qt/rg_main_window.h" @@ -64,6 +67,28 @@ int main(int argc, char *argv[]) std::shared_ptr global_settings = RgConfigManager::Instance().GetGlobalConfig(); assert(global_settings != nullptr); + ColorThemeType color_mode = static_cast(global_settings->color_theme); + + if (color_mode == kColorThemeTypeCount) + { + color_mode = QtCommon::QtUtils::DetectOsSetting(); + } + + QtCommon::QtUtils::ColorTheme::Get().SetColorTheme(static_cast(color_mode)); + + QPalette common_palette = QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette(); + if (color_mode == kColorThemeTypeDark) + { + common_palette.setColor(QPalette::Midlight, QColor(60, 60, 60)); + common_palette.setColor(QPalette::Highlight, QColor(100, 100, 50, 130)); + } + else + { + common_palette.setColor(QPalette::Midlight, QColor(200, 200, 200)); + common_palette.setColor(QPalette::Highlight, QColor(255, 255, 178)); + } + qApp->setPalette(common_palette); + bool enable_feature_interop = QCoreApplication::arguments().count() == 2; if (enable_feature_interop) { diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_opencl.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_opencl.h index 4d7aef9..48f8134 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_opencl.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_opencl.h @@ -116,6 +116,6 @@ private slots: RgPreprocessorDirectivesDialog* preprocessor_directives_dialog_ = nullptr; // The generated interface view object. - Ui::RgBuildSettingsViewOpenCL ui_; + Ui::rgBuildSettingsViewOpenCL ui_; }; #endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_BUILD_SETTINGS_VIEW_OPENCL_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_vulkan.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_vulkan.h index 757deaf..9a7a2a1 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_vulkan.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_settings_view_vulkan.h @@ -161,6 +161,6 @@ private slots: RgBuildSettingsVulkan initial_settings_; // The generated interface view object. - Ui::RgBuildSettingsViewVulkan ui_; + Ui::rgBuildSettingsViewVulkan ui_; }; #endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_BUILD_SETTINGS_VIEW_VULKAN_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_view.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_view.h index edce8f2..09031da 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_view.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_view.h @@ -442,6 +442,9 @@ private slots: // Create an API-specific file menu. virtual bool CreateMenu(QWidget* parent) = 0; + // Reapply the stylesheet for the API-specific file menu when the color theme has changed. + virtual void ReapplyMenuStyleSheet() = 0; + // Connect API-specific RgBuildView signals to the disassembly view. virtual void ConnectDisassemblyViewApiSpecificSignals() {} diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_binary.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_binary.h index b878d66..15f025c 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_binary.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_binary.h @@ -102,6 +102,9 @@ private slots: // Create an API-specific file menu. virtual bool CreateMenu(QWidget* parent) override; + // Reapply the stylesheet for the API-specific file menu when the color theme has changed. + virtual void ReapplyMenuStyleSheet() override; + // Connect API-specific RgBuildView signals to the disassembly view. virtual void ConnectDisassemblyViewApiSpecificSignals() override; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_opencl.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_opencl.h index 3c9d6e0..7d22577 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_opencl.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_opencl.h @@ -91,6 +91,9 @@ private slots: // Create an API-specific file menu. virtual bool CreateMenu(QWidget* parent) override; + // Reapply the stylesheet for the API-specific file menu when the color theme has changed. + virtual void ReapplyMenuStyleSheet() override; + // Connect API-specific RgBuildView signals to the disassembly view. virtual void ConnectDisassemblyViewApiSpecificSignals() override; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_vulkan.h b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_vulkan.h index abaed06..8a794a7 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_build_view_vulkan.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_build_view_vulkan.h @@ -161,6 +161,9 @@ private slots: // Create an API-specific file menu. virtual bool CreateMenu(QWidget* parent) override; + // Reapply the stylesheet for the Vulkan-specific file menu when the color theme has changed. + virtual void ReapplyMenuStyleSheet() override; + // Connect API-specific RgBuildView signals to the disassembly view. virtual void ConnectDisassemblyViewApiSpecificSignals() override; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_editor_element.h b/source/radeon_gpu_analyzer_gui/qt/rg_editor_element.h index 25f3d21..4a08a5d 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_editor_element.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_editor_element.h @@ -28,7 +28,10 @@ enum class RgStyleFlags : char // The row is displayed as the "Current Search Result," because it's flagged as containing a // search result, and it's the current result being focused on. - SearchResultCurrent = 1 << 2 + SearchResultCurrent = 1 << 2, + + // Max value of style flag. + MaxRgStyleFlags = CurrentRow | SearchResultOccurrence | SearchResultCurrent }; // This enum identifies each row's data. diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_global_settings_view.h b/source/radeon_gpu_analyzer_gui/qt/rg_global_settings_view.h index de43612..89203cd 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_global_settings_view.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_global_settings_view.h @@ -96,6 +96,23 @@ public slots: // Handler for when include files viewer text box editing is finished. void HandleIncludeFilesViewerEditingFinished(); + /// @brief Handle Color theme changed in the settings. + /// + /// color_theme_option Color theme option that was selected. + void HandleColorThemeComboBoxChanged(QListWidgetItem* color_theme_option); + + /// @brief Set the color theme for the application. + /// + /// @return Whether the the user wanted to restart the application. + bool SetColorTheme(); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + /// @brief Handle Color scheme changed in the OS. + /// + /// color_scheme The color scheme selected by the OS. + void HandleOsColorSchemeChanged(Qt::ColorScheme color_scheme); +#endif + private slots: // Handler for when the line edits lose focus. void HandleFocusOutEvent(); diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h index e3b25be..eb32158 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h @@ -83,7 +83,7 @@ class RgIsaDisassemblyTableModel : public ModelViewMapper // Populate the model by loading a disassembly CSV file. bool PopulateFromCsvFile(const std::string& csv_file_full_path); - // Load the data in the given live VGPR file into the model. + // Load the data in the given live VGPR file into the model. bool LoadLiveVgprsData(const std::string& live_vgpr_file_full_path); // Set the correlated input source line index to highlight. @@ -203,4 +203,4 @@ class RgIsaDisassemblyTableModel : public ModelViewMapper // Boolean to indicate if the user already pressed F4. bool is_show_current_max_vgpr_enabled_ = false; }; -#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_TABLE_MODEL_H_ +#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_TABLE_MODEL_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_view.h b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_view.h index dd08a51..bc903da 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_view.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_view.h @@ -147,6 +147,9 @@ private slots: // Handler invoked when the table's context menu should be opened. void HandleOpenContextMenu(const QPoint& widget_click_position); + // Handler invoked when the color theme is changed. + void HandleColorThemeChanged(); + protected: // Connect signals used for the right-click context menu. void ConnectContextMenuSignals(); @@ -211,4 +214,4 @@ private slots: // The disassembly view's interface. Ui::RgIsaDisassemblyTableView ui_; }; -#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_TABLE_VIEW_H_ +#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_TABLE_VIEW_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_view.h b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_view.h index 02e873d..2c72ecc 100755 --- a/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_view.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_view.h @@ -184,7 +184,6 @@ protected slots: // Handler to open the GPU list widget. void HandleOpenGpuListWidget(); - protected: // A map that associates an GPU name to a list of program build outputs. typedef std::map> GpuToEntryVector; @@ -232,7 +231,7 @@ protected slots: bool PopulateResourceUsageEntries(const GpuToEntryVector& gpu_to_resource_usage_csv_entries); // Connect resource usage view signals. - void ConnectResourceUsageViewSignals(RgResourceUsageView * resource_usage_view); + void ConnectResourceUsageViewSignals(RgResourceUsageView* resource_usage_view); // Populate the names in the column visibility list. void PopulateColumnVisibilityList(); @@ -300,4 +299,4 @@ protected slots: // The interface responsible for presenting disassembly results for multiple GPUs. Ui::RgIsaDisassemblyView ui_; }; -#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_VIEW_H_ +#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_ISA_DISASSEMBLY_VIEW_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_menu.h b/source/radeon_gpu_analyzer_gui/qt/rg_menu.h index 1878ac0..d165c25 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_menu.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_menu.h @@ -39,8 +39,8 @@ struct RgCliBuildOutput; typedef std::map StringToFileItemMap; // Stylesheet for add/create buttons when in focus. -static const char* kStrButtonFocusOutStylesheet = "QPushButton { margin: 1px; background: rgb(214, 214, 214);}"; -static const char* kStrButtonFocusInStylesheet = "QPushButton { border: 1px solid #6666FF; margin: 1px; background: rgb(253,255,174);}"; +static const char* kStrButtonFocusOutStylesheet = "QPushButton { margin: 1px; background: palette(button);}"; +static const char* kStrButtonFocusInStylesheet = "QPushButton { border: 1px solid #6666FF; margin: 1px; background: palette(highlight); }"; // Indices for special case file items. enum class FileMenuFocusItems diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_menu_build_settings_item.h b/source/radeon_gpu_analyzer_gui/qt/rg_menu_build_settings_item.h index 313cf88..0777ab3 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_menu_build_settings_item.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_menu_build_settings_item.h @@ -63,7 +63,7 @@ private slots: void ConnectSignals(); // The Build Settings file item interface. - Ui::RgMenuBuildSettingsItem ui_; + Ui::rgMenuBuildSettingsItem ui_; // Flag to keep track of whether this item is currently selected. bool current_ = false; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_menu_file_item_opencl.h b/source/radeon_gpu_analyzer_gui/qt/rg_menu_file_item_opencl.h index 3ee3d8e..eeedeac 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_menu_file_item_opencl.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_menu_file_item_opencl.h @@ -192,6 +192,6 @@ public slots: std::string last_selected_entry__name_; // The generated view object. - Ui::RgMenuFileItemOpenCL ui_; + Ui::rgMenuFileItemOpenCL ui_; }; #endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_MENU_FILE_ITEM_OPENCL_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h b/source/radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h index 6431e65..ebb8b21 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h @@ -73,7 +73,7 @@ private slots: void LostFocus(); // The Build Settings file item interface. - Ui::RgMenuPipelineStateItem ui_; + Ui::rgMenuPipelineStateItem ui_; // Flag to keep track of whether this item is currently selected. bool current_ = false; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h b/source/radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h index f9db1aa..d222957 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h @@ -37,6 +37,9 @@ class RgRecentProjectWidget : public QWidget // Return the icon button name. QString GetIconProjectType() const; + // Update the link button stylesheets after the color theme has been updated. + void UpdateLinkButtonStyleSheet(); + private: // The project name button. QPushButton* project_button_ = nullptr; diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_start_tab.h b/source/radeon_gpu_analyzer_gui/qt/rg_start_tab.h index 0053773..d237616 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_start_tab.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_start_tab.h @@ -60,6 +60,9 @@ protected slots: // Handler for a click on a recent program item. void HandleRecentProjectClickedEvent(QAbstractButton* recent_file_button); + // Handle when the color theme is changed. Sets the link button stylesheets and icons for the recent files list. + void OnColorThemeChanged(); + protected: // Apply API-specific string constants to the view object's widgets. virtual void ApplyApiStringConstants() = 0; @@ -104,6 +107,9 @@ protected slots: // Set the view's cursor for each relevant widget. void SetCursor(); + // Set the sytlesheet for the link buttons; + void SetLinkButtonStylesheet(); + // Set the project API icon to recent projects push button. void SetProjectAPIIcon(RgProjectAPI api, RgRecentProjectWidget* widget); @@ -116,4 +122,4 @@ protected slots: // The parent widget. QWidget* parent_ = nullptr; }; -#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_START_TAB_H_ +#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_START_TAB_H_ diff --git a/source/radeon_gpu_analyzer_gui/qt/rg_startup_dialog.h b/source/radeon_gpu_analyzer_gui/qt/rg_startup_dialog.h index 0719ae9..dcafbc8 100644 --- a/source/radeon_gpu_analyzer_gui/qt/rg_startup_dialog.h +++ b/source/radeon_gpu_analyzer_gui/qt/rg_startup_dialog.h @@ -42,6 +42,13 @@ private slots: // Handler for when the user selects the API by using up/down arrow keys. void HandleListWidgetItemSelected(int current_row); +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + /// @brief Handle Color scheme changed in the OS. + /// + /// color_scheme The color scheme selected by the OS. + void HandleOsColorSchemeChanged(Qt::ColorScheme color_scheme); +#endif + private: // Set the cursor to pointing hand cursor. void SetCursor() const; diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/add_file_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/add_file_icon_dark_mode.svg new file mode 100644 index 0000000..8cb498d --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/add_file_icon_dark_mode.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/binary_icon_wide_dark.png b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/binary_icon_wide_dark.png new file mode 100644 index 0000000..1ac7240 Binary files /dev/null and b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/binary_icon_wide_dark.png differ diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_dark.png b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_dark.png new file mode 100644 index 0000000..f0270c5 Binary files /dev/null and b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_dark.png differ diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_wide_dark.png b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_wide_dark.png new file mode 100644 index 0000000..a968eb7 Binary files /dev/null and b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/opencl_icon_wide_dark.png differ diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/vulkan_icon_dark.png b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/vulkan_icon_dark.png new file mode 100644 index 0000000..b293820 Binary files /dev/null and b/source/radeon_gpu_analyzer_gui/resources/icons/api_logos/vulkan_icon_dark.png differ diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/checkmark_black.svg b/source/radeon_gpu_analyzer_gui/resources/icons/checkmark_black.svg new file mode 100644 index 0000000..77391d2 --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/checkmark_black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/filter_rows_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/filter_rows_icon_dark_mode.svg new file mode 100644 index 0000000..ab45a4a --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/filter_rows_icon_dark_mode.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/find_next_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/find_next_icon_dark_mode.svg new file mode 100644 index 0000000..7c08fbc --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/find_next_icon_dark_mode.svg @@ -0,0 +1,49 @@ + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/find_previous_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/find_previous_icon_dark_mode.svg new file mode 100644 index 0000000..7092f3f --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/find_previous_icon_dark_mode.svg @@ -0,0 +1,48 @@ + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/magnifying_glass_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/magnifying_glass_icon_dark_mode.svg new file mode 100644 index 0000000..81092c4 --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/magnifying_glass_icon_dark_mode.svg @@ -0,0 +1,47 @@ + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/new_file_icon_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/new_file_icon_dark_mode.svg new file mode 100644 index 0000000..d0b5954 --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/new_file_icon_dark_mode.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/icons/state_settings_cube_dark_mode.svg b/source/radeon_gpu_analyzer_gui/resources/icons/state_settings_cube_dark_mode.svg new file mode 100644 index 0000000..09b8bb9 --- /dev/null +++ b/source/radeon_gpu_analyzer_gui/resources/icons/state_settings_cube_dark_mode.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + diff --git a/source/radeon_gpu_analyzer_gui/resources/radeon_gpu_analyzer_gui.qrc b/source/radeon_gpu_analyzer_gui/resources/radeon_gpu_analyzer_gui.qrc index b04b44b..a37e49c 100644 --- a/source/radeon_gpu_analyzer_gui/resources/radeon_gpu_analyzer_gui.qrc +++ b/source/radeon_gpu_analyzer_gui/resources/radeon_gpu_analyzer_gui.qrc @@ -47,5 +47,16 @@ stylesheets/binary/rg_file_menu_style_binary.qss stylesheets/binary/rg_main_window_style_binary.qss icons/api_logos/binary_icon_wide.png + icons/api_logos/binary_icon_wide_dark.png + icons/api_logos/opencl_icon_wide_dark.png + icons/api_logos/vulkan_icon_dark.png + icons/checkmark_black.svg + icons/new_file_icon_dark_mode.svg + icons/state_settings_cube_dark_mode.svg + icons/add_file_icon_dark_mode.svg + icons/filter_rows_icon_dark_mode.svg + icons/find_next_icon_dark_mode.svg + icons/find_previous_icon_dark_mode.svg + icons/magnifying_glass_icon_dark_mode.svg diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_application_style_binary.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_application_style_binary.qss index 8eef02f..cf9869f 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_application_style_binary.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_application_style_binary.qss @@ -1,9 +1,37 @@ /********************************************************************/ /* Frame focus border /********************************************************************/ -QFrame:focus, -QLineEdit:focus, + +QCheckBox:!focus +{ + border-color: palette(text); +} + QCheckBox:focus +{ + border-color: rgb(128, 0, 128); +} + +QCheckBox::indicator +{ + border: 1px solid palette(text); + background-color: rgb(240, 240, 240); + width: 10px; + height: 10px; +} + +QCheckBox::indicator:checked +{ + image: url(:/icons/checkmark_black.svg); +} + +QLineEdit +{ + border: 1px solid palette(text); +} + +QFrame:focus, +QLineEdit:focus { border: 1px solid rgb(128, 0, 128); } @@ -23,8 +51,8 @@ RgBuildSettingsViewOpencl #compilerIncludesBrowseButton:hover, RgBuildSettingsViewOpencl #compilerLibrariesBrowseButton:hover, RgBuildSettingsViewOpencl #optimizationLevelComboBox:hover { + background-color: palette(alternate-base); border: 1px solid rgb(128, 0, 128); - background: rgb(240, 240, 240); } RgViewContainer[viewHovered="true"][viewFocused="false"] RgMenuTitlebar #itemBackground, @@ -50,7 +78,7 @@ RgViewContainer[viewFocused="true"] #viewTitlebar /********************************************************************/ RgBuildSettingsViewOpencl #targetGPUsLineEdit { - background-color: rgb(240, 240, 240); + background-color: palette(alternate-base); } /********************************************************************/ @@ -58,5 +86,5 @@ RgBuildSettingsViewOpencl #targetGPUsLineEdit /********************************************************************/ QLineEdit { - border: 1px solid black; + border: 1px solid palette(text); } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_file_menu_style_binary.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_file_menu_style_binary.qss index 83985a3..c17615e 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_file_menu_style_binary.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_file_menu_style_binary.qss @@ -2,19 +2,17 @@ /* File menu item (RgMenuFileItemOpencl) /********************************************************************/ -/* The default color is grayish light yellow. */ +/* The default color. */ RgMenuFileItemOpencl #itemBackground { - background-color: rgb(253, 255, 242); border-style: solid; border-width: 1px; border-color: rgb(128, 0, 128); } -/* Current item color is light yellow (the RGA "highlight" color). */ +/* Current item color. */ RgMenuFileItemOpencl #itemBackground[current=true] { - background-color: rgb(255, 255, 178); border-style: solid; border-width: 1px; border-color: rgb(128, 0, 128); @@ -62,7 +60,6 @@ RgIsaDisassemblyView #frame[selected=false] RgLinkSourceMenuItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } @@ -80,7 +77,6 @@ RgLinkSourceMenuItem QPushButton:hover RgMenuBuildSettingsItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_main_window_style_binary.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_main_window_style_binary.qss index 2400038..e49fc08 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_main_window_style_binary.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/binary/rg_main_window_style_binary.qss @@ -5,7 +5,6 @@ /* Tab basic styling */ #mainTabWidget QTabBar::tab { - background: rgb(51,51,51); bottom: 1px; padding: 4px 8px; } @@ -43,4 +42,4 @@ rgRenameProjectDialog #lineEditProjectName:focus rgRenameProjectDialog #lineEditProjectName:hover { border: 1px solid rgb(128, 0, 128); -} \ No newline at end of file +} diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_application_style_opencl.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_application_style_opencl.qss index 5d5b0d4..7bf41f0 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_application_style_opencl.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_application_style_opencl.qss @@ -1,9 +1,38 @@ /********************************************************************/ /* Frame focus border /********************************************************************/ -QFrame:focus, -QLineEdit:focus, + +QCheckBox:!focus +{ + border-color: palette(text); +} + QCheckBox:focus +{ + border-color: lightGreen; +} + +QCheckBox::indicator +{ + border: 1px solid palette(text); + background-color: rgb(240, 240, 240); + width: 10px; + height: 10px; +} + +QCheckBox::indicator:checked +{ + image: url(:/icons/checkmark_black.svg); +} + +QLineEdit, +QPlainTextEdit +{ + border: 1px solid palette(text); +} + +QFrame:focus, +QLineEdit:focus { border: 1px solid lightGreen; } @@ -23,8 +52,8 @@ RgBuildSettingsViewOpencl #compilerIncludesBrowseButton:hover, RgBuildSettingsViewOpencl #compilerLibrariesBrowseButton:hover, RgBuildSettingsViewOpencl #optimizationLevelComboBox:hover { + background-color: palette(alternate-base); border: 1px solid lightGreen; - background: rgb(240, 240, 240); } RgViewContainer[viewHovered="true"][viewFocused="false"] RgMenuTitlebar #itemBackground, @@ -50,13 +79,5 @@ RgViewContainer[viewFocused="true"] #viewTitlebar /********************************************************************/ RgBuildSettingsViewOpencl #targetGPUsLineEdit { - background-color: rgb(240, 240, 240); -} - -/********************************************************************/ -/* Line edit border color -/********************************************************************/ -QLineEdit -{ - border: 1px solid black; + background-color: palette(alternate-base); } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_file_menu_style_opencl.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_file_menu_style_opencl.qss index 511d03b..e60b8df 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_file_menu_style_opencl.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/opencl/rg_file_menu_style_opencl.qss @@ -2,19 +2,17 @@ /* File menu item (RgMenuFileItemOpencl) /********************************************************************/ -/* The default color is grayish light yellow. */ +/* The default color. */ RgMenuFileItemOpencl #itemBackground { - background-color: rgb(253, 255, 242); border-style: solid; border-width: 1px; border-color: rgb(18, 152, 0); } -/* Current item color is light yellow (the RGA "highlight" color). */ +/* Current item color. */ RgMenuFileItemOpencl #itemBackground[current=true] { - background-color: rgb(255, 255, 178); border-style: solid; border-width: 1px; border-color: rgb(18, 152, 0); @@ -53,7 +51,7 @@ RgIsaDisassemblyView #frame[selected=true] RgIsaDisassemblyView #frame[selected=false] { - border: 1px solid black; + border: 1px solid palette(text); } /********************************************************************/ @@ -62,7 +60,6 @@ RgIsaDisassemblyView #frame[selected=false] RgAddCreateMenuItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } @@ -80,7 +77,6 @@ RgAddCreateMenuItem QPushButton:hover RgMenuBuildSettingsItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_application_style.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_application_style.qss index ec964c2..3591c3e 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_application_style.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_application_style.qss @@ -1,9 +1,12 @@ /********************************************************************/ /* Splitters /********************************************************************/ -QSplitter::handle + +RgIsaDisassemblyView #frame, +RgCliOutputView #outputTextEdit, +RgSourceCodeEditor { - background: white; + border: 1px solid palette(text); } /********************************************************************/ @@ -54,7 +57,6 @@ RgIsaDisassemblyView #viewTitlebar #line /********************************************************************/ RgIsaDisassemblyCustomTableView QHeaderView::section:hover { - background-color: white; border: none; padding-left: 6px white; font: 9pt; @@ -63,7 +65,6 @@ RgIsaDisassemblyCustomTableView QHeaderView::section:hover RgIsaDisassemblyCustomTableView QHeaderView::section:!hover { font: 9pt; - background-color: white; border: none; padding-left: 6px white; } @@ -73,20 +74,18 @@ RgIsaDisassemblyCustomTableView QHeaderView::section:!hover /********************************************************************/ RgFindTextWidget QPushButton { - border: 1px solid black; - background-color: rgb(240, 240, 240); + border: 1px solid palette(text); } RgFindTextWidget QPushButton:hover:!pressed { - background-color: rgb(229, 243, 255); - border: 1px solid black; + border: 1px solid palette(text); } RgFindTextWidget QPushButton:checked { - background-color: rgb(229, 243, 255); - border: 1px solid black; + background: palette(highlight); + border: 1px solid palette(text); } /********************************************************************/ @@ -102,7 +101,6 @@ RgCliOutputView #viewTitlebar QLabel /********************************************************************/ RgCliOutputView QTextEdit { - background: rgb(240, 240, 240); } RgCliOutputView #clearOutputPushButton @@ -112,19 +110,16 @@ RgCliOutputView #clearOutputPushButton RgCliOutputView #clearOutputPushButton:focus { - background: rgba(255, 255, 255, 50); border: 0px; } RgCliOutputView #clearOutputPushButton:hover { - background: rgba(255, 255, 255, 50); border: 0px; } RgCliOutputView #clearOutputPushButton:pressed { - background: rgba(255, 255, 255, 100); border: 0px; } @@ -164,7 +159,7 @@ RgViewContainer[isMaximized="true"] #viewMaximizeButton:hover gIncludeDirectoriesView #includeDirsList { background: transparent; - border: 1px solid black; + border: 1px solid palette(text); } /********************************************************************/ @@ -172,37 +167,37 @@ gIncludeDirectoriesView #includeDirsList /********************************************************************/ RgGlobalSettingsView #generalLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgGlobalSettingsView #disassemblyViewLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgGlobalSettingsView #sourceCodeEditorLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgGlobalSettingsView #inputFilesLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgGlobalSettingsView #outputFilesLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgGlobalSettingsView RgComboBox, ScaledFontComboBox { - combobox-popup: 0; color: black; padding: 0px 0px 0px 0px; + combobox-popup: 0; + padding: 0px 0px 0px 0px; } QComboBox { - selection-color: black; } RgGlobalSettingsView#columnVisibilityArrowPushButton @@ -215,47 +210,48 @@ RgGlobalSettingsView#columnVisibilityArrowPushButton /********************************************************************/ RgBuildSettingsViewOpencl #allOptionsTextEdit { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #additionalOptionsTextEdit { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #additionalOptionsHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #settingsCommandLineHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #generalHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #openCLOptionsHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #alternativeCompilerLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl #outputFilesLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewOpencl RgComboBox { - combobox-popup: 0; color: black; padding: 0px 0px 0px 0px; + combobox-popup: 0; + padding: 0px 0px 0px 0px; } /********************************************************************/ @@ -263,51 +259,50 @@ RgBuildSettingsViewOpencl RgComboBox /********************************************************************/ RgBuildSettingsViewVulkan #allOptionsTextEdit { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #settingsCommandLineHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #generalHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #vulkanOptionsHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #vulkanSettingsHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #alternativeCompilerHeaderLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgBuildSettingsViewVulkan #outputFilesLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } rgBuildSettingsViewVulkan #outputFilesLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); } /********************************************************************/ -/* Set the pipeline tree view's background color to yellow. +/* Set the pipeline tree view's selection color to black. /********************************************************************/ RgPipelineStateView #settingsTree::item:selected { - background-color: rgb(253,255,174); - selection-color: black; + selection-color: palette(text); } /********************************************************************/ @@ -315,7 +310,6 @@ RgPipelineStateView #settingsTree::item:selected /********************************************************************/ QScrollBar::handle:vertical { - background: lightGrey; min-height: 20px; height: 20px; max-height: 20px; @@ -323,12 +317,10 @@ QScrollBar::handle:vertical QScrollBar::handle:horizontal { - background: lightGrey; } QScrollBar:vertical { - background: rgb(240,240,240); width: 20px; margin-top: 22px; margin-right: 0; @@ -338,7 +330,6 @@ QScrollBar:vertical QScrollBar:horizontal { - background: rgb(240,240,240); height: 20px; margin-top: 0; margin-right: 25px; @@ -351,7 +342,6 @@ QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical height: 20px; width: 20px; margin: 0; - background: rgb(240,240,240); subcontrol-origin: margin; } @@ -359,7 +349,6 @@ QScrollBar::add-line:horizontal { width: 25px; subcontrol-origin: margin; - background: rgb(240,240,240); } QScrollBar::sub-line:horizontal @@ -367,7 +356,6 @@ QScrollBar::sub-line:horizontal width: 25px; subcontrol-position: left; subcontrol-origin: margin; - background: rgb(240,240,240); } QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical @@ -383,7 +371,6 @@ QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal QScrollBar::up-arrow:vertical { width: 20px; - background: rgb(240,240,240); image: url(:/icons/arrow_up.svg); } @@ -391,7 +378,6 @@ QScrollBar::down-arrow:vertical { width: 20px; border: none; - background: rgb(240,240,240); image: url(:/icons/arrow_down.svg); } @@ -399,7 +385,6 @@ QScrollBar::left-arrow:horizontal { height: 20px; border: none; - background: rgb(240,240,240); image: url(:/icons/arrow_left.svg); } @@ -407,6 +392,33 @@ QScrollBar::right-arrow:horizontal { height: 20px; border: none; - background: rgb(240,240,240); image: url(:/icons/arrow_right.svg); } + +QCheckBox::indicator +{ + border: 1px solid palette(text); + background-color: rgb(240, 240, 240); + width: 10px; + height: 10px; +} + +QCheckBox::indicator:checked +{ + image: url(:/icons/checkmark_black.svg); +} + +RgEditorElement *[selected=true] +{ + background-color: palette(highlight); +} + +RgEditorElement *[resultOccurrence=true][currentResult=false][selected=false] +{ + background-color: palette(alternate-base); +} + +RgEditorElement *[currentResult=true] +{ + background-color: palette(highlight); +} diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_file_menu_style.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_file_menu_style.qss index 12c2a19..73bdfdf 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_file_menu_style.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_file_menu_style.qss @@ -5,7 +5,7 @@ /* The default color is gray. */ RgMenuFileItemGraphics #itemBackground { - background-color: rgb(234, 235, 230); + background-color: palette(midlight); border-style: solid; border-width: 1px; border-color: rgb(135,20,16); @@ -14,7 +14,7 @@ RgMenuFileItemGraphics #itemBackground /* Current item color is light yellow (the RGA "highlight" color). */ RgMenuFileItemGraphics #itemBackground[current=true] { - background-color: rgb(253,255,174); + background-color: palette(highlight); border-style: solid; border-width: 1px; border-color: rgb(135,20,16); @@ -23,7 +23,7 @@ RgMenuFileItemGraphics #itemBackground[current=true] /* Occupied but not current item color is grayish light yellow. */ RgMenuFileItemGraphics #itemBackground[current=false][occupied=true] { - background-color: rgb(253, 255, 238); + background-color: palette(base); border-style: solid; border-width: 1px; border-color: rgb(135,20,16); @@ -65,7 +65,6 @@ RgMenuFileItemGraphics #removeButton:hover RgMenuPipelineStateItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_main_window_style.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_main_window_style.qss index e51d4ea..6a093a4 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_main_window_style.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/rg_main_window_style.qss @@ -2,195 +2,191 @@ /* Global /*************************************/ +QMenu::item:disabled +{ + background-color: palette(window); + color: palette(disabled-text); +} + ArrowIconComboBox { -background: white; -border: none; -font-size: 8pt; -text-align:left; + border: none; + font-size: 8pt; + text-align:left; } RgIsaDisassemblyView ArrowIconComboBox { -background: rgb(51, 51, 51); -border: none; + border: none; } RgIsaDisassemblyCustomTableView { -font-size: 10pt; + font-size: 10pt; } ListWidget { -font-size: 8pt; -text-align: left; -border: 1px solid gray; + font-size: 8pt; + text-align: left; + border: 1px solid gray; } ListWidget QCheckBox { -font-size: 8pt; -padding-left: 3px; + font-size: 8pt; + padding-left: 3px; } ListWidget QLabel { -font-size: 8pt; -padding-left: 3px; + font-size: 8pt; + padding-left: 3px; } ListWidget::item:hover { -background: rgb(214, 214, 214); + background-color: palette(alternate-base); } ListWidget::item:selected { -background: rgb(143, 193, 231); + background-color: palette(highlight); } ListWidget::item { -border-bottom: none; + border-bottom: none; } CheckBoxWidget { -font-size: 8pt; + font-size: 8pt; } CheckBoxWidget::indicator::checked::disabled { -image: url(:/Resources/assets/checkbox_on_gray.svg); + image: url(:/Resources/assets/checkbox_on_gray.svg); } CheckBoxWidget::indicator::unchecked::disabled { -image: url(:/Resources/assets/checkbox_off_gray.svg); + image: url(:/Resources/assets/checkbox_off_gray.svg); } CheckBoxWidget::indicator:checked { -image: url(:/Resources/assets/checkbox_on.svg); + image: url(:/Resources/assets/checkbox_on.svg); } CheckBoxWidget::indicator:unchecked { -image: url(:/Resources/assets/checkbox_off.svg); + image: url(:/Resources/assets/checkbox_off.svg); } ColoredLegendGraphicsView { -font-size: 8pt; + font-size: 8pt; } DonutPieWidget { -background-color: white; } NavigationListWidget { -background: rgb(240, 240, 240); -border-right: 2px groove gray; -outline: none; -border: none; -font: 8pt; + border-right: 2px groove gray; + outline: none; + border: none; + font: 8pt; } NavigationListWidget::item:hover { -background: rgb(214, 214, 214); } NavigationListWidget::item:selected { -background: rgb(143, 193, 231); } NavigationListWidget::item { -border-bottom: none; -padding: 7px; -color: rgb(51, 51, 51); + border-bottom: none; + padding: 7px; + color: rgb(51, 51, 51); } RecentTraceMiniWidget { -font-size: 8pt; + font-size: 8pt; } ScaledCycleButton { -background: white; -border: none; -text-align:center; + border: none; + text-align:center; } ScaledTableView, ScaledTreeView { -font-size: 9pt; + font-size: 9pt; } ScaledHeaderView { -font: bold 9pt; + font: bold 9pt; } ScaledTabWidget { -font: bold 8pt; + font: bold 8pt; } ScaledTabWidget > QTabBar::tab { -padding: 0.5em 1em 0.5em 1em; + padding: 0.5em 1em 0.5em 1em; } ScaledTabWidget > QTabBar::tab:!first { -margin-left: -1px; + margin-left: -1px; } ScaledTabWidget > QTabBar::tab:selected { -background-color: white; -border: 1px solid #C4C4C3; + border: 1px solid #C4C4C3; } ScaledTabWidget > QTabBar::tab:!selected { -background-color: rgb(236, 236, 236); -border-right: 1px solid #C4C4C3; -border-left: 1px solid #C4C4C3; + border-right: 1px solid #C4C4C3; + border-left: 1px solid #C4C4C3; } -ScaledTabWidget > QTabBar::tab:!selected:hover { -background-color: rgb(237, 246, 255) +ScaledTabWidget > QTabBar::tab:!selected:hover +{ } ScaledLabel, ScaledPushButton, QLabel, QPushButton { -font-size: 8pt; + font-size: 8pt; } ScaledLineEdit { -font-size: 8pt; -border: 1px solid black; + font-size: 8pt; + border: 1px solid palette(text); } TextSearchWidget { -font-size: 8pt; -border: 1px solid gray; -background: white; + font-size: 8pt; + border: 1px solid gray; } ScaledCheckBox { -font-size: 8pt; + font-size: 8pt; } /********************************************************************/ @@ -199,7 +195,6 @@ font-size: 8pt; RgMainWindow QTabWidget::pane { border : 0px solid #444; - background: solid white; } RgMainWindow #mainTabWidget > QTabWidget::pane @@ -226,14 +221,9 @@ RgMainWindow #mainTabWidget > QTabBar::tab background: rgb(51,51,51); } -RgMainWindow QMenuBar +#startTab, #settingsTab { - background: white; -} - -RgMainWindow QMenuBar::item:selected -{ - background: rgb(229, 243, 255); + background: palette(window); } RgStatusBar @@ -248,7 +238,7 @@ RgStatusBar /* Link button basic styling */ #RgStartTab > QPushButton { - color: rgb(0, 0, 255); + color: palette(link); border: none; text-align: left; font: 10pt; @@ -263,7 +253,7 @@ RgStatusBar /* Link button basic styling */ #recentProgramsWrapper > QPushButton { - color: rgb(0, 0, 255); + color: palette(link); border: none; text-align: left; font: 10pt; @@ -273,7 +263,7 @@ RgStatusBar /* Link button basic styling */ QPushButton#recentTracesOtherPushButton { - color: rgb(0, 0, 255); + color: palette(link); border: none; text-align: left; text-decoration: underline; @@ -306,27 +296,24 @@ RgStartTab #startLabel, #recentLabel, #helpLabel, #helloLabel RgSettingsTab #rightFrame { - background: white; } RgSettingsTab #leftFrame { - background: rgb(240, 240, 240); + background: palette(alternate-base); } RgSettingsTab #scrollArea { - background: white; } RgSettingsTab #scrollAreaWidgetContents { - background: white; } RgSettingsTab #settingsListWidget { - background: rgb(240, 240, 240); + background: palette(alternate-base); border-right: 2px groove gray; outline: none; border: none; @@ -335,12 +322,12 @@ RgSettingsTab #settingsListWidget RgSettingsTab #settingsListWidget::item:hover { - background: rgb(214, 214, 214); + background: gray; } RgSettingsTab #settingsListWidget::item:selected { - background: rgb(253,255,174); + background: palette(highlight); } RgSettingsTab #settingsListWidget::item @@ -348,7 +335,6 @@ RgSettingsTab #settingsListWidget::item border-bottom: none; padding: 7px; padding-left: 30px; - color: rgb(51, 51, 51); font: bold 8pt; } @@ -359,7 +345,7 @@ RgSettingsTab #rightFrame > QFrame:focus RgSettingsTab #globalSettingsLabel { - background: rgb(240, 240, 240); + background: palette(alternate-base); font: 8pt; padding: 5px; } @@ -381,7 +367,7 @@ QComboBox::drop-down /* Link button basic styling */ RgAboutDialog #checkForUpdatesButton { - color: rgb(0, 0, 255); + color: palette(link); border: none; text-align: left; } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_application_style_vulkan.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_application_style_vulkan.qss index abd9c76..33cb2a0 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_application_style_vulkan.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_application_style_vulkan.qss @@ -1,8 +1,31 @@ /********************************************************************/ /* Line Edit and Checkbox focus border /********************************************************************/ -QLineEdit:focus, + +RgCheckBox:!focus +{ + border-color: palette(text); +} + RgCheckBox:focus +{ + border-color: rgb(224, 30, 55); +} + +QCheckBox::indicator +{ + border: 1px solid palette(text); + background-color: rgb(240, 240, 240); + width: 10px; + height: 10px; +} + +QCheckBox::indicator:checked +{ + image: url(:/icons/checkmark_black.svg); +} + +QLineEdit:focus { border: 1px solid rgb(224, 30, 55); } @@ -12,7 +35,7 @@ RgCheckBox:focus /********************************************************************/ RgMenuGraphics { - border: 1px solid black; + border: 1px solid palette(text); } /********************************************************************/ @@ -20,7 +43,7 @@ RgMenuGraphics /********************************************************************/ QFrame:focus { - border: 1px solid black; + border: 1px solid palette(text); } RgBuildSettingsViewVulkan #addTargetGPUsButton:focus, @@ -34,8 +57,8 @@ RgBuildSettingsViewVulkan #predefinedMacrosBrowseButton:hover, RgBuildSettingsViewVulkan #ICDLocationBrowseButton:hover, RgBuildSettingsViewVulkan #compilerBrowseButton:hover { + background-color: palette(alternate-base); border: 1px solid rgb(224, 30, 55); - background: rgb(240, 240, 240); } RgViewContainer[viewHovered="true"][viewFocused="false"] RgMenuTitlebar #itemBackground, @@ -61,7 +84,7 @@ RgViewContainer[viewFocused="true"] #viewTitlebar /********************************************************************/ RgBuildSettingsViewVulkan #targetGPUsLineEdit { - background-color: rgb(240, 240, 240); + background-color: palette(alternate-base); } /********************************************************************/ @@ -69,7 +92,7 @@ RgBuildSettingsViewVulkan #targetGPUsLineEdit /********************************************************************/ QLineEdit { - border: 1px solid black; + border: 1px solid palette(text); } rgPipelineStateEditorWidgetNumeric #lineEdit:focus @@ -82,5 +105,5 @@ rgPipelineStateEditorWidgetNumeric #lineEdit:focus /********************************************************************/ RgBuildSettingsViewVulkan #allOptionsTextEdit { - border: 1px solid black; + border: 1px solid palette(text); } diff --git a/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_file_menu_style_vulkan.qss b/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_file_menu_style_vulkan.qss index 927af55..714d92d 100644 --- a/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_file_menu_style_vulkan.qss +++ b/source/radeon_gpu_analyzer_gui/resources/stylesheets/vulkan/rg_file_menu_style_vulkan.qss @@ -4,7 +4,6 @@ RgMenuBuildSettingsItem QPushButton { - background-color: rgb(214, 214, 214); text-align: left; padding-left: 11px; } @@ -26,5 +25,6 @@ RgIsaDisassemblyView #frame[selected=true] RgIsaDisassemblyView #frame[selected=false] { - border: 1px solid black; + border: 1px solid palette(text); + } \ No newline at end of file diff --git a/source/radeon_gpu_analyzer_gui/rg_about_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_about_dialog.cpp index de1e8ab..7082abf 100644 --- a/source/radeon_gpu_analyzer_gui/rg_about_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_about_dialog.cpp @@ -19,6 +19,12 @@ #include "source/common/rga_version_info.h" #include "source/common/rga_shared_utils.h" +// Check for Updates Dialog dimensions. +static const int kUpdatesPendingDialogWidth = 400; +static const int kUpdatesPendingDialogHeight = 150; +static const int kUpdatesResultsDialogWidth = 400; +static const int kUpdatesResultsDialogHeight = 300; + RgAboutDialog::RgAboutDialog(QWidget* parent) : QDialog(parent), check_for_updates_dialog_(nullptr), @@ -28,9 +34,6 @@ RgAboutDialog::RgAboutDialog(QWidget* parent) : { ui_.setupUi(this); - // Set the background to white. - RgUtils::SetBackgroundColor(this, Qt::white); - // Disable the help button in the title bar, and disable resizing of this dialog. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); @@ -102,11 +105,8 @@ void RgAboutDialog::HandleCheckForUpdatesClicked() check_for_updates_dialog_ = new QDialog(this); check_for_updates_dialog_->setWindowTitle(kStrAppName); check_for_updates_dialog_->setWindowFlags(check_for_updates_dialog_->windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); - check_for_updates_dialog_->setFixedWidth(250); - check_for_updates_dialog_->setFixedHeight(100); - - // Set background to white. - RgUtils::SetBackgroundColor(check_for_updates_dialog_, Qt::white); + check_for_updates_dialog_->setFixedWidth(kUpdatesPendingDialogWidth); + check_for_updates_dialog_->setFixedHeight(kUpdatesPendingDialogHeight); QVBoxLayout* layout = new QVBoxLayout(); check_for_updates_dialog_->setLayout(layout); @@ -199,13 +199,10 @@ void RgAboutDialog::HandleCheckForUpdatesCompleted(UpdateCheck::ThreadController // Change from default title. results_dialog->setWindowTitle(kStrUpdatesResultsWindowTitle); - // Set background to white. - RgUtils::SetBackgroundColor(results_dialog, Qt::white); - // Set this dialog to get deleted when it is closed. results_dialog->setAttribute(Qt::WA_DeleteOnClose, true); results_dialog->setWindowFlags(results_dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint); - results_dialog->setFixedSize(400, 300); + results_dialog->setFixedSize(kUpdatesResultsDialogWidth, kUpdatesResultsDialogHeight); QDialogButtonBox* button_box = results_dialog->findChild("button_box_"); if (button_box != nullptr) { diff --git a/source/radeon_gpu_analyzer_gui/rg_add_create_menu_item.cpp b/source/radeon_gpu_analyzer_gui/rg_add_create_menu_item.cpp index 665b33f..b3407ab 100644 --- a/source/radeon_gpu_analyzer_gui/rg_add_create_menu_item.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_add_create_menu_item.cpp @@ -1,15 +1,26 @@ #include "radeon_gpu_analyzer_gui/qt/rg_add_create_menu_item.h" +// QtCommon. +#include "qt_common/utils/qt_util.h" + #include "radeon_gpu_analyzer_gui/rg_data_types_opencl.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -RgAddCreateMenuItem::RgAddCreateMenuItem(RgMenu* parent) : - RgMenuItem(parent) +RgAddCreateMenuItem::RgAddCreateMenuItem(RgMenu* parent) + : RgMenuItem(parent) { ui_.setupUi(this); ui_.addButton->setContentsMargins(0, 0, 0, 0); ui_.createButton->setContentsMargins(0, 0, 0, 0); + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + + if (color_theme == kColorThemeTypeDark) + { + ui_.addButton->setIcon(QIcon(":/icons/add_file_icon_dark_mode.svg")); + ui_.createButton->setIcon(QIcon(":/icons/new_file_icon_dark_mode.svg")); + } + // Set button tooltips and status tips. RgUtils::SetToolAndStatusTip(kStrMenuBarOpenExistingFileTooltipOpencl, ui_.addButton); RgUtils::SetToolAndStatusTip(kStrMenuBarCreateNewFileTooltipOpencl, ui_.createButton); diff --git a/source/radeon_gpu_analyzer_gui/rg_app_state_binary.cpp b/source/radeon_gpu_analyzer_gui/rg_app_state_binary.cpp index 21efdda..724cbcd 100644 --- a/source/radeon_gpu_analyzer_gui/rg_app_state_binary.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_app_state_binary.cpp @@ -240,7 +240,7 @@ std::string RgAppStateBinary::GetGlobalSettingsViewStylesheet() const "RgGlobalSettingsView #defaultLangComboBox:hover" "{" "border: 1px solid rgb(128, 0, 128);" - "background: rgb(240, 240, 240);" + "background-color: palette(alternate-base);" "}"; return kStrBinaryAppSettingsStylesheet; } diff --git a/source/radeon_gpu_analyzer_gui/rg_app_state_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_app_state_opencl.cpp index fbe6406..56f0e37 100644 --- a/source/radeon_gpu_analyzer_gui/rg_app_state_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_app_state_opencl.cpp @@ -320,7 +320,7 @@ std::string RgAppStateOpencl::GetGlobalSettingsViewStylesheet() const "RgGlobalSettingsView #defaultLangComboBox:hover" "{" "border: 1px solid lightGreen;" - "background: rgb(240, 240, 240);" + "background-color: palette(alternate-base);" "}"; return kStrOpenclAppSettingsStylesheet; } @@ -362,7 +362,7 @@ std::string RgAppStateOpencl::GetBuildSettingsViewStylesheet() const "RgBuildSettingsView #compilerLibrariesLineEdit:hover" "{" "border: 1px solid lightGreen;" - "background: rgb(240, 240, 240);" + "background-color: palette(alternate-base);" "}"; return kStrOpenclBuildSettingsStylesheet; } \ No newline at end of file diff --git a/source/radeon_gpu_analyzer_gui/rg_app_state_vulkan.cpp b/source/radeon_gpu_analyzer_gui/rg_app_state_vulkan.cpp index d437ed1..2f19b3a 100644 --- a/source/radeon_gpu_analyzer_gui/rg_app_state_vulkan.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_app_state_vulkan.cpp @@ -313,7 +313,7 @@ std::string RgAppStateVulkan::GetGlobalSettingsViewStylesheet() const "RgGlobalSettingsView #defaultLangComboBox:hover" "{" "border: 1px solid rgb(224, 30, 55);" - "background: rgb(240, 240, 240);" + "background-color: palette(alternate-base);" "}"; return kStrVulkanAppSettingsStylesheet; } @@ -343,7 +343,7 @@ std::string RgAppStateVulkan::GetBuildSettingsViewStylesheet() const "RgBuildSettingsView #outputFileBinaryNameLineEdit:hover" "{" "border: 1px solid rgb(224, 30, 55);" - "background: rgb(240, 240, 240);" + "background-color: palette(alternate-base);" "}"; return kStrVulkanBuildSettingsStylesheet; } diff --git a/source/radeon_gpu_analyzer_gui/rg_build_settings_view_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_build_settings_view_opencl.cpp index efec046..a636607 100644 --- a/source/radeon_gpu_analyzer_gui/rg_build_settings_view_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_build_settings_view_opencl.cpp @@ -37,12 +37,6 @@ RgBuildSettingsViewOpencl::RgBuildSettingsViewOpencl(QWidget* parent, const RgBu // Setup the UI. ui_.setupUi(this); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Create the include directories editor view. include_directories_view_ = new RgIncludeDirectoriesView(kOptionsListDelimiter, this); diff --git a/source/radeon_gpu_analyzer_gui/rg_build_settings_view_vulkan.cpp b/source/radeon_gpu_analyzer_gui/rg_build_settings_view_vulkan.cpp index 5ae6000..dde2d1b 100644 --- a/source/radeon_gpu_analyzer_gui/rg_build_settings_view_vulkan.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_build_settings_view_vulkan.cpp @@ -39,12 +39,6 @@ RgBuildSettingsViewVulkan::RgBuildSettingsViewVulkan(QWidget* parent, const RgBu // Setup the UI. ui_.setupUi(this); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Create the include directories editor view. include_directories_view_ = new RgIncludeDirectoriesView(kOptionsListDelimiter, this); diff --git a/source/radeon_gpu_analyzer_gui/rg_build_view_binary.cpp b/source/radeon_gpu_analyzer_gui/rg_build_view_binary.cpp index 33d6ddc..3eca4f4 100644 --- a/source/radeon_gpu_analyzer_gui/rg_build_view_binary.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_build_view_binary.cpp @@ -10,6 +10,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Infra. #include "source/common/rga_shared_utils.h" @@ -204,9 +207,16 @@ bool RgBuildViewBinary::CreateMenu(QWidget* parent) is_connected = connect(this, &RgBuildViewBinary::UpdateFileColoring, file_menu_, &RgMenuBinary::ProjectBuildSuccess); assert(is_connected); + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgBuildViewBinary::ReapplyMenuStyleSheet); + return file_menu_ != nullptr; } +void RgBuildViewBinary::ReapplyMenuStyleSheet() +{ + factory_->ApplyFileMenuStylesheet(file_menu_); +} + void RgBuildViewBinary::ConnectDisassemblyViewApiSpecificSignals() { assert(disassembly_view_ != nullptr); diff --git a/source/radeon_gpu_analyzer_gui/rg_build_view_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_build_view_opencl.cpp index 52eba28..06117df 100644 --- a/source/radeon_gpu_analyzer_gui/rg_build_view_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_build_view_opencl.cpp @@ -8,6 +8,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Infra. #include "source/common/rga_shared_utils.h" @@ -209,9 +212,16 @@ bool RgBuildViewOpencl::CreateMenu(QWidget* parent) is_connected = connect(this, &RgBuildViewOpencl::UpdateFileColoring, file_menu_, &RgMenuOpencl::ProjectBuildSuccess); assert(is_connected); + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgBuildViewOpencl::ReapplyMenuStyleSheet); + return file_menu_ != nullptr; } +void RgBuildViewOpencl::ReapplyMenuStyleSheet() +{ + factory_->ApplyFileMenuStylesheet(file_menu_); +} + void RgBuildViewOpencl::ConnectDisassemblyViewApiSpecificSignals() { assert(disassembly_view_ != nullptr); diff --git a/source/radeon_gpu_analyzer_gui/rg_build_view_vulkan.cpp b/source/radeon_gpu_analyzer_gui/rg_build_view_vulkan.cpp index b4b56c7..c9641a6 100644 --- a/source/radeon_gpu_analyzer_gui/rg_build_view_vulkan.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_build_view_vulkan.cpp @@ -10,6 +10,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Infra. #include "source/common/vulkan/rg_pso_factory_vulkan.h" #include "source/common/vulkan/rg_pso_serializer_vulkan.h" @@ -39,9 +42,10 @@ #include "radeon_gpu_analyzer_gui/rg_xml_session_config.h" // PSO editor container frame name. -static const char* kStrPsoEditorFrameName = "PSOEditorContainerFrame"; +static const char* kStrPsoEditorFrameName = "PSOEditorContainerFrame"; static const char* kStrApplicationInformationMessage = "Used vk-spv-offline mode."; -static const char* kStrApplicationInformationTooltip = "Compilation failed with AMD's Vulkan ICD (amdvlk), used vk-spv-offline mode instead. Check the build output window for more details."; +static const char* kStrApplicationInformationTooltip = + "Compilation failed with AMD's Vulkan ICD (amdvlk), used vk-spv-offline mode instead. Check the build output window for more details."; RgBuildViewVulkan::RgBuildViewVulkan(QWidget* parent) : RgBuildViewGraphics(RgProjectAPI::kVulkan, parent) @@ -62,19 +66,31 @@ void RgBuildViewVulkan::ConnectBuildSettingsSignals() RgBuildView::ConnectBuildSettingsSignals(); // Connect the notification of pending state changes from the Vulkan build settings to the build view. - bool is_connected = connect(static_cast(build_settings_view_), &RgBuildSettingsViewVulkan::PendingChangesStateChanged, this, &RgBuildView::HandleBuildSettingsPendingChangesStateChanged); + bool is_connected = connect(static_cast(build_settings_view_), + &RgBuildSettingsViewVulkan::PendingChangesStateChanged, + this, + &RgBuildView::HandleBuildSettingsPendingChangesStateChanged); assert(is_connected); // Connect the notification that the build settings have been saved from the Vulkan build settings to the build view. - is_connected = connect(static_cast(build_settings_view_), &RgBuildSettingsViewVulkan::ProjectBuildSettingsSaved, this, &RgBuildView::HandleBuildSettingsSaved); + is_connected = connect(static_cast(build_settings_view_), + &RgBuildSettingsViewVulkan::ProjectBuildSettingsSaved, + this, + &RgBuildView::HandleBuildSettingsSaved); assert(is_connected); // Connect to build settings view's edit line's "focus in" event to color the frame red. - is_connected = connect(static_cast(build_settings_view_), &RgBuildSettingsViewVulkan::SetFrameBorderRedSignal, this, &RgBuildView::HandleSetFrameBorderRed); + is_connected = connect(static_cast(build_settings_view_), + &RgBuildSettingsViewVulkan::SetFrameBorderRedSignal, + this, + &RgBuildView::HandleSetFrameBorderRed); assert(is_connected); // Connect to build settings view's edit line's "focus out" event to color the frame black. - is_connected = connect(static_cast(build_settings_view_), &RgBuildSettingsViewVulkan::SetFrameBorderBlackSignal, this, &RgBuildView::HandleSetFrameBorderBlack); + is_connected = connect(static_cast(build_settings_view_), + &RgBuildSettingsViewVulkan::SetFrameBorderBlackSignal, + this, + &RgBuildView::HandleSetFrameBorderBlack); assert(is_connected); } @@ -160,7 +176,8 @@ bool RgBuildViewVulkan::ConnectMenuSignals() assert(pipeline_state_item != nullptr); if (pipeline_state_item != nullptr) { - is_connected = connect(pipeline_state_item, &RgMenuPipelineStateItem::PipelineStateButtonClicked, this, &RgBuildViewVulkan::HandlePipelineStateMenuItemClicked); + is_connected = connect( + pipeline_state_item, &RgMenuPipelineStateItem::PipelineStateButtonClicked, this, &RgBuildViewVulkan::HandlePipelineStateMenuItemClicked); assert(is_connected); } @@ -186,11 +203,10 @@ void RgBuildViewVulkan::HandleBuildSettingsMenuItemClicked() bool RgBuildViewVulkan::HandlePipelineStateFileSaved() { - bool is_ok = false; + bool is_ok = false; std::string error_string; - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) @@ -229,21 +245,18 @@ void RgBuildViewVulkan::HandlePipelineStateFileLoaded() // Open the file browser in the last selected directory. std::string pipeline_state_file_path = RgConfigManager::Instance().GetLastSelectedFolder(); - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) { // Select the relevant file filter based on the pipeline type (compute, graphics). - bool is_graphics_pipeline = (vulkan_clone->pipeline.type == RgPipelineType::kGraphics); - const char* pso_file_filter = is_graphics_pipeline ? kStrDefaultPipelineFileExtensionFilterGraphics : - kStrDefaultPipelineFileExtensionFilterCompute; + bool is_graphics_pipeline = (vulkan_clone->pipeline.type == RgPipelineType::kGraphics); + const char* pso_file_filter = is_graphics_pipeline ? kStrDefaultPipelineFileExtensionFilterGraphics : kStrDefaultPipelineFileExtensionFilterCompute; // Display an "Open file" dialog to let the user choose // which pipeline state configuration file to use. - bool is_ok = RgUtils::OpenFileDialog(this, pipeline_state_file_path, - kStrPipelineStateFileDialogCaption, pso_file_filter); + bool is_ok = RgUtils::OpenFileDialog(this, pipeline_state_file_path, kStrPipelineStateFileDialogCaption, pso_file_filter); if (is_ok) { @@ -256,8 +269,7 @@ bool RgBuildViewVulkan::LoadPipelineStateFile(const std::string& pipeline_state_ { bool is_ok = false; - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); std::string error_string; assert(vulkan_clone != nullptr); @@ -353,8 +365,7 @@ bool RgBuildViewVulkan::PopulateMenu() { bool is_file_loaded = false; - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) @@ -367,7 +378,7 @@ bool RgBuildViewVulkan::PopulateMenu() // Step through each stage type in a graphics pipeline by default. size_t first_stage = static_cast(RgPipelineStage::kVertex); - size_t last_stage = static_cast(RgPipelineStage::kFragment); + size_t last_stage = static_cast(RgPipelineStage::kFragment); // If a compute pipeline is being loaded, only attempt to load the single Compute stage. if (!is_graphics_pipeline) @@ -427,8 +438,7 @@ bool RgBuildViewVulkan::IsGcnDisassemblyGenerated(const std::string& input_file_ auto targetGpuOutputsIter = build_outputs_.find(current_target_gpu_); if (targetGpuOutputsIter != build_outputs_.end()) { - std::shared_ptr build_output = - std::dynamic_pointer_cast(targetGpuOutputsIter->second); + std::shared_ptr build_output = std::dynamic_pointer_cast(targetGpuOutputsIter->second); assert(build_output != nullptr); if (build_output != nullptr) @@ -436,7 +446,7 @@ bool RgBuildViewVulkan::IsGcnDisassemblyGenerated(const std::string& input_file_ auto input_file_iter = build_output->per_file_output.find(input_file_path); if (input_file_iter != build_output->per_file_output.end()) { - RgFileOutputs& file_outputs = input_file_iter->second; + RgFileOutputs& file_outputs = input_file_iter->second; is_current_file_disassembled = !file_outputs.outputs.empty(); } } @@ -448,7 +458,9 @@ bool RgBuildViewVulkan::IsGcnDisassemblyGenerated(const std::string& input_file_ bool RgBuildViewVulkan::LoadSessionMetadata(const std::string& metadata_file_path, std::shared_ptr& build_output) { bool ret = false; + std::shared_ptr gpu_output_vulkan = nullptr; + ret = RgXMLSessionConfig::ReadSessionMetadataVulkan(metadata_file_path, gpu_output_vulkan); assert(ret); if (ret) @@ -471,14 +483,13 @@ void RgBuildViewVulkan::ReloadFile(const std::string& file_path) // If it's a SPIR-V binary file, disassemble it and update the disassembly text in the code editor. if (file_item->GetFileType() == RgVulkanInputType::kSpirv) { - std::string cli_output, compiler_path; + std::string cli_output, compiler_path; const std::string& disasm_file_path = spv_disasm_files_[file_item->GetStage()]; assert(!disasm_file_path.empty()); if (!disasm_file_path.empty()) { // Get the "alternative compiler path" setting value. - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr && vulkan_clone->build_settings != nullptr); if (vulkan_clone != nullptr && vulkan_clone->build_settings != nullptr) @@ -511,8 +522,8 @@ void RgBuildViewVulkan::ShowCurrentFileDisassembly() bool is_current_file_disassembled = false; // Show the currently selected file's first entry point disassembly (if there is no currently selected entry). - const std::string& input_filepath = file_menu_->GetSelectedFilePath(); - RgMenuFileItem* selected_file_item = file_menu_->GetSelectedFileItem(); + const std::string& input_filepath = file_menu_->GetSelectedFilePath(); + RgMenuFileItem* selected_file_item = file_menu_->GetSelectedFileItem(); assert(selected_file_item != nullptr); if (selected_file_item != nullptr) @@ -543,8 +554,8 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) { // Get the file editor for the file menu item. RgSourceCodeEditor* file_editor = nullptr; - const std::string file_path = file_item->GetFilename(); - auto iter = source_code_editors_.find(file_path); + const std::string file_path = file_item->GetFilename(); + auto iter = source_code_editors_.find(file_path); assert(iter != source_code_editors_.end()); if (iter != source_code_editors_.end()) { @@ -553,8 +564,7 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) assert(file_editor != nullptr); assert(clone_index_ < project_->clones.size()); - if (file_editor != nullptr && file_menu_ != nullptr && - (clone_index_ < project_->clones.size())) + if (file_editor != nullptr && file_menu_ != nullptr && (clone_index_ < project_->clones.size())) { // Check if the file needs reassembling (modified SPIR-V disassembly). bool need_reassemble = false; @@ -568,9 +578,9 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) // If so, we have to replace the original spv binary with the modified disassembly file in the Project. if (need_reassemble && file_editor->document()->isModified()) { - RgPipelineStage stage = file_item->GetStage(); + RgPipelineStage stage = file_item->GetStage(); const std::string& spv_disasm_file_path = spv_disasm_files_[stage]; - QFileInfo file_info(spv_disasm_file_path.c_str()); + QFileInfo file_info(spv_disasm_file_path.c_str()); // Write the editor text to file if the file path is valid. if (!spv_disasm_file_path.empty()) @@ -581,7 +591,7 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) // Show the Code Editor title message warning the user about replacing original spv binary file // with its disassembly in the project. const std::string msg = file_info.fileName().toStdString() + ". " + kStrSourceEditorTitlebarSpirvDisasmSavedA + " " + - kStrFileContextMenuRestoreSpv + " " + kStrSourceEditorTitlebarSpirvDisasmSavedB; + kStrFileContextMenuRestoreSpv + " " + kStrSourceEditorTitlebarSpirvDisasmSavedB; file_editor->SetTitleBarText(msg); // If it's the current item, display the message on the title bar. @@ -595,7 +605,7 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) // Replace the spv binary file with its disassembly in the project, File Menu and in the Code Editor map. const std::string& spv_file_path = file_item->GetFilename(); - auto editor = source_code_editors_.find(spv_file_path); + auto editor = source_code_editors_.find(spv_file_path); assert(editor != source_code_editors_.end()); if (editor != source_code_editors_.end()) { @@ -605,12 +615,11 @@ void RgBuildViewVulkan::SaveFile(RgMenuFileItemGraphics* file_item) } // Store the original spv binary path to the project so that a user can restore it later. - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) { - vulkan_clone->spv_backup_.type = vulkan_clone->pipeline.type; + vulkan_clone->spv_backup_.type = vulkan_clone->pipeline.type; vulkan_clone->spv_backup_.shader_stages[stage] = spv_file_path; // Replace file path in the project. @@ -829,7 +838,8 @@ void RgBuildViewVulkan::ConnectPipelineStateViewSignals() assert(is_connected); // Connect the pipeline state tree focus out signal. - is_connected = connect(pipeline_state_view_, &RgPipelineStateView::PipelineStateTreeFocusOut, this, &RgBuildViewVulkan::HandlePipelineStateTreeFocusOut); + is_connected = + connect(pipeline_state_view_, &RgPipelineStateView::PipelineStateTreeFocusOut, this, &RgBuildViewVulkan::HandlePipelineStateTreeFocusOut); assert(is_connected); is_connected = connect(view_manager_, &RgViewManager::PsoEditorWidgetFocusOutSignal, this, &RgBuildViewVulkan::HandlePipelineStateTreeFocusOut); @@ -926,7 +936,7 @@ void RgBuildViewVulkan::HandleSelectedFileChanged(const std::string& old_file_pa // Make the disassembly view visible because the file has build outputs to display. std::string selected_entrypoint_name = kStrDefaultVulkanGlslEntrypointName; - emit SelectedEntrypointChanged(current_target_gpu_, new_file_path, selected_entrypoint_name); + emit SelectedEntrypointChanged(current_target_gpu_, new_file_path, selected_entrypoint_name); // Update the titlebar for the current source editor. UpdateSourceEditorTitlebar(editor); @@ -957,7 +967,7 @@ void RgBuildViewVulkan::HandleSourceFileSelectedLineChanged(RgSourceCodeEditor* if (disassembly_view_ != nullptr && !disassembly_view_->IsEmpty()) { const std::string& input_filename = GetFilepathForEditor(editor); - bool isDisassembled = IsGcnDisassemblyGenerated(input_filename); + bool isDisassembled = IsGcnDisassemblyGenerated(input_filename); if (isDisassembled) { int correlated_line_number = kInvalidCorrelationLineIndex; @@ -991,9 +1001,8 @@ void RgBuildViewVulkan::HandleAddExistingFile() if (file_menu_ != nullptr) { std::string file_path_to_add; - bool is_ok = RgUtils::OpenFileDialog(this, RgProjectAPI::kVulkan, file_path_to_add); - if (is_ok && !file_path_to_add.empty() && RgUtils::IsFileExists(file_path_to_add) && - !file_menu_->IsFileInMenu(file_path_to_add)) + bool is_ok = RgUtils::OpenFileDialog(this, RgProjectAPI::kVulkan, file_path_to_add); + if (is_ok && !file_path_to_add.empty() && RgUtils::IsFileExists(file_path_to_add) && !file_menu_->IsFileInMenu(file_path_to_add)) { // Convert the path separators to match the style used in the session metadata. std::string native_file_path = QDir::toNativeSeparators(file_path_to_add.c_str()).toStdString(); @@ -1050,8 +1059,7 @@ void RgBuildViewVulkan::HandleExistingFileDragAndDrop(RgPipelineStage stage, con assert(file_menu_ != nullptr); if (file_menu_ != nullptr && !file_path_to_add.empty()) { - if (!file_menu_->IsFileInMenu(file_path_to_add) && - RgUtils::IsFileExists(file_path_to_add)) + if (!file_menu_->IsFileInMenu(file_path_to_add) && RgUtils::IsFileExists(file_path_to_add)) { // Convert the path separators to match the style used in the session metadata. std::string native_file_path = QDir::toNativeSeparators(file_path_to_add.c_str()).toStdString(); @@ -1091,11 +1099,10 @@ void RgBuildViewVulkan::HandleRemoveFileButtonClicked(RgPipelineStage stage) if (is_valid_range) { - std::shared_ptr graphics_clone - = std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr graphics_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); std::string stage_file_path; - bool is_stage_occupied = RgConfigManager::Instance().GetShaderStageFilePath(stage, graphics_clone, stage_file_path); + bool is_stage_occupied = RgConfigManager::Instance().GetShaderStageFilePath(stage, graphics_clone, stage_file_path); assert(is_stage_occupied); if (is_stage_occupied) @@ -1151,7 +1158,7 @@ void RgBuildViewVulkan::HandleRemoveFileButtonClicked(RgPipelineStage stage) // Emit a signal to update various menu items. const bool is_menu_empty = vulkan_file_menu->IsEmpty(); - emit vulkan_file_menu->FileMenuItemCountChanged(is_menu_empty); + emit vulkan_file_menu->FileMenuItemCountChanged(is_menu_empty); } DestroyBuildOutputsForFile(stage_file_path); @@ -1187,7 +1194,7 @@ void RgBuildViewVulkan::HandleRestoreOriginalSpvClicked(RgPipelineStage stage) if (file_item != nullptr && file_menu_ != nullptr) { const std::string spv_disasm = file_item->GetFilename(); - const std::string orig_spv = vulkan_clone->spv_backup_.shader_stages[stage]; + const std::string orig_spv = vulkan_clone->spv_backup_.shader_stages[stage]; if (ShowRevertToSpvBinaryConfirmation(orig_spv)) { @@ -1254,13 +1261,20 @@ bool RgBuildViewVulkan::CreateMenu(QWidget* parent) bool is_connected = connect(file_menu_, &RgMenuVulkan::EnablePipelineMenuItem, this, &RgBuildViewVulkan::EnablePipelineMenuItem); assert(is_connected); - // Connect disable build settings menu item signals. + // Connect disable build settings menu item signals. is_connected = connect(file_menu_, &RgMenuVulkan::EnableBuildSettingsMenuItem, this, &RgBuildViewVulkan::EnableBuildSettingsMenuItem); assert(is_connected); + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgBuildViewVulkan::ReapplyMenuStyleSheet); + return file_menu_ != nullptr; } +void RgBuildViewVulkan::ReapplyMenuStyleSheet() +{ + factory_->ApplyFileMenuStylesheet(file_menu_); +} + void RgBuildViewVulkan::HandleEnumListWidgetStatus(bool is_open) { assert(pipeline_state_view_ != nullptr); @@ -1284,7 +1298,8 @@ bool RgBuildViewVulkan::CreatePipelineStateModel() if (pipeline_state_model_ != nullptr) { // Connect the list widget status signal. - bool is_connected = connect(pipeline_state_model_, &RgPipelineStateModelVulkan::EnumListWidgetStatusSignal, this, &RgBuildViewVulkan::HandleEnumListWidgetStatus); + bool is_connected = + connect(pipeline_state_model_, &RgPipelineStateModelVulkan::EnumListWidgetStatusSignal, this, &RgBuildViewVulkan::HandleEnumListWidgetStatus); assert(is_connected); // Connect the shortcut hot key signal. @@ -1300,20 +1315,19 @@ bool RgBuildViewVulkan::CreatePipelineStateModel() if (res) { - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) { - bool is_pipeline_state_initialized = false; + bool is_pipeline_state_initialized = false; std::string error_string; assert(pipeline_state_index_ < vulkan_clone->pso_states.size()); if (pipeline_state_index_ < vulkan_clone->pso_states.size()) { RgPipelineState& currentPipelineState = vulkan_clone->pso_states[pipeline_state_index_]; - bool is_state_file_exists = RgUtils::IsFileExists(currentPipelineState.pipeline_state_file_path); + bool is_state_file_exists = RgUtils::IsFileExists(currentPipelineState.pipeline_state_file_path); if (is_state_file_exists) { // Load the state file from disk. @@ -1404,8 +1418,7 @@ void RgBuildViewVulkan::CreatePipelineStateView(QWidget* parent) if (res) { - std::shared_ptr clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(clone != nullptr); if (clone != nullptr) @@ -1430,13 +1443,12 @@ void RgBuildViewVulkan::ConnectDisassemblyViewApiSpecificSignals() if (disassembly_view_ != nullptr) { // Connect the handler invoked when the user changes the selected entry point. - bool is_connected = connect(this, &RgBuildViewVulkan::SelectedEntrypointChanged, - disassembly_view_, &RgIsaDisassemblyView::HandleSelectedEntrypointChanged); + bool is_connected = + connect(this, &RgBuildViewVulkan::SelectedEntrypointChanged, disassembly_view_, &RgIsaDisassemblyView::HandleSelectedEntrypointChanged); assert(is_connected); // Connect the remove button focus events. - is_connected = connect(disassembly_view_, &RgIsaDisassemblyView::RemoveFileMenuButtonFocus, - file_menu_, &RgMenuVulkan::HandleRemoveFileMenuButtonFocus); + is_connected = connect(disassembly_view_, &RgIsaDisassemblyView::RemoveFileMenuButtonFocus, file_menu_, &RgMenuVulkan::HandleRemoveFileMenuButtonFocus); assert(is_connected); } } @@ -1455,7 +1467,7 @@ bool RgBuildViewVulkan::IsSourceFileInProject(const std::string& source_file_pat // Step through all possible pipeline stages to check if the given source file exists. uint32_t first_stage = static_cast(RgPipelineStage::kVertex); - uint32_t last_stage = static_cast(RgPipelineStage::kCompute); + uint32_t last_stage = static_cast(RgPipelineStage::kCompute); assert(project_ != nullptr); if (project_ != nullptr) @@ -1504,10 +1516,10 @@ bool RgBuildViewVulkan::ReplaceInputFileInBuildOutput(const std::string& old_fil if (ret) { auto first_target_gpu = build_outputs_.begin(); - auto last_target_gpu = build_outputs_.end(); + auto last_target_gpu = build_outputs_.end(); for (auto targetGpuIter = first_target_gpu; targetGpuIter != last_target_gpu; ++targetGpuIter) { - ret = false; + ret = false; std::shared_ptr build_output = targetGpuIter->second; // Search for outputs for the given source file and replace its key (input file path) with the new one. @@ -1520,7 +1532,7 @@ bool RgBuildViewVulkan::ReplaceInputFileInBuildOutput(const std::string& old_fil auto outputs = it->second; build_output->per_file_output.erase(it); build_output->per_file_output[new_file_path] = outputs; - ret = true; + ret = true; } } } @@ -1549,7 +1561,8 @@ bool RgBuildViewVulkan::CreateNewSourceFile(RgPipelineStage stage, const std::st // Generate a path to where the new empty file will live in the projects directory. std::string new_file_name; - RgConfigManager::GenerateNewSourceFilepath(project_->project_name, clone_index_, source_file_name, file_extension.str(), new_file_name, full_source_file_path); + RgConfigManager::GenerateNewSourceFilepath( + project_->project_name, clone_index_, source_file_name, file_extension.str(), new_file_name, full_source_file_path); // Ensure that the folder where the file will be saved already exists. std::string sourcefile_folder; @@ -1622,8 +1635,7 @@ bool RgBuildViewVulkan::CreateProject(RgPipelineType pipeline_type) if (res) { - std::shared_ptr clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); // Initialize the clone's pipeline type. clone->pipeline.type = pipeline_type; @@ -1659,8 +1671,7 @@ void RgBuildViewVulkan::CreatePipelineStateFile() if (res) { - std::shared_ptr clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(clone != nullptr); if (clone != nullptr) @@ -1673,19 +1684,19 @@ void RgBuildViewVulkan::CreatePipelineStateFile() pipeline_name_stream << pipeline_count; std::string pipeline_state_name = pipeline_name_stream.str(); - bool is_graphics_pipeline = (clone->pipeline.type == RgPipelineType::kGraphics); - const char* pso_file_extension = is_graphics_pipeline ? kStrDefaultPipelineFileExtensionGraphics : - kStrDefaultPipelineFileExtensionCompute; + bool is_graphics_pipeline = (clone->pipeline.type == RgPipelineType::kGraphics); + const char* pso_file_extension = is_graphics_pipeline ? kStrDefaultPipelineFileExtensionGraphics : kStrDefaultPipelineFileExtensionCompute; // Build a file path to a new pipeline state file. std::string pipeline_state_file_path; - RgConfigManager::GenerateNewPipelineFilepath(project_->project_name, clone_index_, pipeline_state_name, pso_file_extension, pipeline_state_file_path); + RgConfigManager::GenerateNewPipelineFilepath( + project_->project_name, clone_index_, pipeline_state_name, pso_file_extension, pipeline_state_file_path); // Does the Pipeline State File's target directory already exist? Pipeline State // files are stored alongside the clone's source files. If the directory does not // yet exist, it needs to be created before attempting to write the file. std::string directory_path; - bool is_ok = RgUtils::ExtractFileDirectory(pipeline_state_file_path, directory_path); + bool is_ok = RgUtils::ExtractFileDirectory(pipeline_state_file_path, directory_path); if (is_ok) { bool directory_exists = RgUtils::IsDirExists(directory_path); @@ -1697,10 +1708,10 @@ void RgBuildViewVulkan::CreatePipelineStateFile() if (is_ok) { - RgPipelineState pipeline_state_file = {}; - pipeline_state_file.name = pipeline_state_name; + RgPipelineState pipeline_state_file = {}; + pipeline_state_file.name = pipeline_state_name; pipeline_state_file.pipeline_state_file_path = pipeline_state_file_path; - pipeline_state_file.is_active = true; + pipeline_state_file.is_active = true; // Add the new PSO file to the current clone's PSO states vector. clone->pso_states.push_back(pipeline_state_file); @@ -1732,8 +1743,7 @@ void RgBuildViewVulkan::SetStageSourceFile(RgPipelineStage stage, const std::str // Enable reverting to original SPIR-V binary if it's present in the Project Clone. if (fileAdded && file_type.first == RgVulkanInputType::kSpirvTxt) { - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr); if (vulkan_clone != nullptr) @@ -1779,7 +1789,7 @@ void RgBuildViewVulkan::SetStageSourceFile(RgPipelineStage stage, const std::str bool RgBuildViewVulkan::DisasmSpvFile(const std::string& spv_file, std::string& spv_disasm_file) { std::string proj_dir; - bool is_ok = RgUtils::ExtractFileDirectory(project_->project_file_full_path, proj_dir); + bool is_ok = RgUtils::ExtractFileDirectory(project_->project_file_full_path, proj_dir); assert(is_ok); if (is_ok && RgUtils::ConstructSpvDisasmFileName(proj_dir, spv_file, spv_disasm_file)) { @@ -1790,8 +1800,7 @@ bool RgBuildViewVulkan::DisasmSpvFile(const std::string& spv_file, std::string& if (is_ok) { // Get the "alternative compiler path" setting value. - std::shared_ptr vulkan_clone = - std::dynamic_pointer_cast(project_->clones[clone_index_]); + std::shared_ptr vulkan_clone = std::dynamic_pointer_cast(project_->clones[clone_index_]); assert(vulkan_clone != nullptr && vulkan_clone->build_settings != nullptr); if (vulkan_clone != nullptr && vulkan_clone->build_settings != nullptr) @@ -1839,7 +1848,7 @@ void RgBuildViewVulkan::HandlePipelineStateTreeFocusOut() assert(pso_editor_frame_ != nullptr); if (pso_editor_frame_ != nullptr) { - QString style_sheet_string = QString("#") + kStrPsoEditorFrameName + QString(" { border: 1px solid black }"); + QString style_sheet_string = QString("#") + kStrPsoEditorFrameName + QString(" { border: 1px solid palette(text) }"); pso_editor_frame_->setStyleSheet(style_sheet_string); } } @@ -1848,7 +1857,7 @@ void RgBuildViewVulkan::UpdateApplicationNotificationMessage() { std::string message = ""; std::string tooltip = ""; - size_t pos = cli_output_window_->GetText().find("vk-spv-offline"); + size_t pos = cli_output_window_->GetText().find("vk-spv-offline"); if (pos != std::string::npos) { message = kStrApplicationInformationMessage; diff --git a/source/radeon_gpu_analyzer_gui/rg_config_file.cpp b/source/radeon_gpu_analyzer_gui/rg_config_file.cpp index cabd1a5..b5a468d 100644 --- a/source/radeon_gpu_analyzer_gui/rg_config_file.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_config_file.cpp @@ -1011,6 +1011,9 @@ bool RgXmlConfigFile::WriteGlobalSettings(std::shared_ptr glob global_settings_elem->InsertEndChild(font_family_element); } + // Write the font size into the font element. + RgXMLUtils::AppendXMLElement(doc, global_settings_elem, kXmlNodeGlobalColorTheme, global_settings->color_theme); + // Write the include files viewer. RgXMLUtils::AppendXMLElement(doc, global_settings_elem, kXmlNodeGlobalIncludeFilesViewer, global_settings->include_files_viewer.c_str()); @@ -1765,6 +1768,19 @@ static bool ExtractGlobalSettings_2_3(tinyxml2::XMLNode* global_settings_node, s ret = ret && ExtractFontInformation(elem, global_settings); } if (ret) + { + tinyxml2::XMLElement* test_elem = elem->NextSiblingElement(kXmlNodeGlobalColorTheme); + unsigned color_theme_number = 2; + + if (test_elem != nullptr) + { + ret = ret && RgXMLUtils::ReadNodeTextUnsigned(test_elem, color_theme_number); + elem = test_elem; + } + + global_settings->color_theme = color_theme_number; + } + if (ret) { // Extract default include files viewer. // Before we move on keep the current node in case that we fail reading this node. diff --git a/source/radeon_gpu_analyzer_gui/rg_config_file_definitions.h b/source/radeon_gpu_analyzer_gui/rg_config_file_definitions.h index a02f303..adb2f22 100644 --- a/source/radeon_gpu_analyzer_gui/rg_config_file_definitions.h +++ b/source/radeon_gpu_analyzer_gui/rg_config_file_definitions.h @@ -250,6 +250,9 @@ static const char* kXmlNodeGlobalFontFamilyType = "Type"; // The font size element. static const char* kXmlNodeGlobalFontSize = "Size"; +// The font size element. +static const char* kXmlNodeGlobalColorTheme = "ColorTheme"; + // The default include file viewer. static const char* kXmlNodeGlobalIncludeFilesViewer = "IncludeFilesViewer"; diff --git a/source/radeon_gpu_analyzer_gui/rg_config_manager.cpp b/source/radeon_gpu_analyzer_gui/rg_config_manager.cpp index a8fda6a..01acaac 100644 --- a/source/radeon_gpu_analyzer_gui/rg_config_manager.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_config_manager.cpp @@ -387,6 +387,9 @@ void RgConfigManager::ResetToFactoryDefaults(RgGlobalSettings& global_settings) // Default font size. global_settings.font_size = 10; + // Default color theme. + global_settings.color_theme = 2; + // Default app to open include files. global_settings.include_files_viewer = kStrGlobalSettingsSrcViewIncludeViewerDefault; diff --git a/source/radeon_gpu_analyzer_gui/rg_data_types.h b/source/radeon_gpu_analyzer_gui/rg_data_types.h index 51536df..eac9f00 100644 --- a/source/radeon_gpu_analyzer_gui/rg_data_types.h +++ b/source/radeon_gpu_analyzer_gui/rg_data_types.h @@ -344,13 +344,13 @@ struct RgResourceUsageData // A structure used to hold data parsed from a livereg output file. struct RgLiveregData { - int total_vgprs; - int vgprs_granularity; - int used; - int allocated; - int max_vgprs; - int unmatched_count; - std::vector max_vgpr_line_numbers; + int total_vgprs; + int vgprs_granularity; + int used; + int allocated; + int max_vgprs; + int unmatched_count; + std::vector max_vgpr_line_numbers; std::vector is_current_max_vgpr_line_number; }; @@ -383,6 +383,7 @@ struct RgGlobalSettings , default_api(other.default_api) , font_family(other.font_family) , font_size(other.font_size) + , color_theme(other.color_theme) , include_files_viewer(other.include_files_viewer) , input_file_ext_glsl(other.input_file_ext_glsl) , input_file_ext_hlsl(other.input_file_ext_hlsl) @@ -398,9 +399,10 @@ struct RgGlobalSettings (visible_disassembly_view_columns == other.visible_disassembly_view_columns) && (use_default_project_name == other.use_default_project_name) && (should_prompt_for_api == other.should_prompt_for_api) && (default_api == other.default_api) && (font_family == other.font_family) && (font_size == other.font_size) && - (include_files_viewer == other.include_files_viewer) && (input_file_ext_glsl == other.input_file_ext_glsl) && - (input_file_ext_hlsl == other.input_file_ext_hlsl) && (input_file_ext_spv_txt == other.input_file_ext_spv_txt) && - (input_file_ext_spv_bin == other.input_file_ext_spv_bin) && (default_lang == other.default_lang); + (color_theme == other.color_theme) && (include_files_viewer == other.include_files_viewer) && + (input_file_ext_glsl == other.input_file_ext_glsl) && (input_file_ext_hlsl == other.input_file_ext_hlsl) && + (input_file_ext_spv_txt == other.input_file_ext_spv_txt) && (input_file_ext_spv_bin == other.input_file_ext_spv_bin) && + (default_lang == other.default_lang); return isSame; } @@ -448,6 +450,9 @@ struct RgGlobalSettings // The font size. int font_size = 0; + // The application's default color theme. + int color_theme = 2; + // The app to use to open include files. std::string include_files_viewer = kStrGlobalSettingsSrcViewIncludeViewerDefault; @@ -657,4 +662,3 @@ struct RgIsaLineLabel : RgIsaLine }; #endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_RG_DATA_TYPES_H_ - diff --git a/source/radeon_gpu_analyzer_gui/rg_definitions.h b/source/radeon_gpu_analyzer_gui/rg_definitions.h index 8d8a57f..5946307 100644 --- a/source/radeon_gpu_analyzer_gui/rg_definitions.h +++ b/source/radeon_gpu_analyzer_gui/rg_definitions.h @@ -2,7 +2,7 @@ #define RGA_RADEONGPUANALYZERGUI_INCLUDE_RG_DEFINITIONS_H_ // The mode string used for Binary mode. -static const char* kStrModeStringBinary = "bin"; +static const char* kStrModeStringBinary = "bin"; // The mode string used for OpenCL mode. static const char* kStrModeStringOpencl = "opencl"; @@ -14,10 +14,10 @@ static const char* kStrModeStringVulkan = "vulkan"; static const char* kStrDefaultVulkanGlslEntrypointName = "main"; // Standard truncation lengths. -static const int kTextTruncateLengthFront = 10; -static const int kTextTruncateLengthBack = 10; -static const int kTextTruncateLengthBackOpencl = 10; -static const int kTextTruncateLengthBackVulkan = 2; +static const int kTextTruncateLengthFront = 10; +static const int kTextTruncateLengthBack = 10; +static const int kTextTruncateLengthBackOpencl = 10; +static const int kTextTruncateLengthBackVulkan = 2; // The constant used when the selected line in the source file doesn't have any correlated disassembly lines. static const int kInvalidCorrelationLineIndex = -1; @@ -35,49 +35,49 @@ static const int kBuildViewFontSize = 10; static const char* kIsRepolishingBlocked = "isRepolishingBlocked"; // Home page definitions. -static const char* kActionHotkeyOpenProject = "Ctrl+Alt+O"; -static const char* kActionHotkeyBackToHome = "Ctrl+Alt+H"; -static const char* kActionHotkeyExit = "Alt+F4"; -static const char* kActionHotkeyAbout = "Ctrl+F1"; -static const char* kActionHotkeyHelpManual = "F1"; +static const char* kActionHotkeyOpenProject = "Ctrl+Alt+O"; +static const char* kActionHotkeyBackToHome = "Ctrl+Alt+H"; +static const char* kActionHotkeyExit = "Alt+F4"; +static const char* kActionHotkeyAbout = "Ctrl+F1"; +static const char* kActionHotkeyHelpManual = "F1"; // Focus navigation hotkey definitions. -static const char* kActionHotkeyNextView = "Ctrl+Tab"; -static const char* kActionHotkeyPreviousView = "Shift+Ctrl+Tab"; +static const char* kActionHotkeyNextView = "Ctrl+Tab"; +static const char* kActionHotkeyPreviousView = "Shift+Ctrl+Tab"; // File menu hotkey definitions. -static const char* kActionHotkeyFileMenuNextItem = "Down"; -static const char* kActionHotkeyFileMenuPrevItem = "Up"; -static const char* kActionHotkeyFileMenuActivateSpace = "Space"; -static const char* kActionHotkeyFileMenuContextMenu = "Shift+F10"; -static const char* kActionHotkeyFileMenuActivateReturn = "Return"; -static const char* kActionHotkeyFileMenuActivateEnter = "Enter"; -static const char* kActionHotkeyFileMenuRename = "F2"; -static const char* kActionHotkeyFileMenuActivateTab = "Tab"; +static const char* kActionHotkeyFileMenuNextItem = "Down"; +static const char* kActionHotkeyFileMenuPrevItem = "Up"; +static const char* kActionHotkeyFileMenuActivateSpace = "Space"; +static const char* kActionHotkeyFileMenuContextMenu = "Shift+F10"; +static const char* kActionHotkeyFileMenuActivateReturn = "Return"; +static const char* kActionHotkeyFileMenuActivateEnter = "Enter"; +static const char* kActionHotkeyFileMenuRename = "F2"; +static const char* kActionHotkeyFileMenuActivateTab = "Tab"; static const char* kActionHotkeyFileMenuActivateShiftTab = "Shift+Tab"; // Edit menu hotkey definitions. -static const char* kActionHotkeyGoToLine = "Ctrl+G"; -static const char* kActionHotkeyFind = "Ctrl+F"; -static const char* kActionHotkeyFindNext = "F3"; -static const char* kActionHotkeyFindPrevious = "Shift+F3"; -static const char* kActionHotkeyShowMaxVgprs = "Ctrl+F4"; +static const char* kActionHotkeyGoToLine = "Ctrl+G"; +static const char* kActionHotkeyFind = "Ctrl+F"; +static const char* kActionHotkeyFindNext = "F3"; +static const char* kActionHotkeyFindPrevious = "Shift+F3"; +static const char* kActionHotkeyShowMaxVgprs = "Ctrl+F4"; // Build menu hotkey definitions. -static const char* kActionHotkeyBuildProject = "Ctrl+Shift+B"; -static const char* kActionHotkeyBuildSettings = "F8"; -static const char* kActionHotkeyPipelineState = "F9"; -static const char* kActionHotkeyBuildCancel = "Ctrl+Shift+T"; +static const char* kActionHotkeyBuildProject = "Ctrl+Shift+B"; +static const char* kActionHotkeyBuildSettings = "F8"; +static const char* kActionHotkeyPipelineState = "F9"; +static const char* kActionHotkeyBuildCancel = "Ctrl+Shift+T"; // Source view hotkey definitions. -static const char* kSourceEditorHotkeyContextMenuCut = "Ctrl+X"; -static const char* kSourceEditorHotkeyContextMenuCopy = "Ctrl+C"; -static const char* kSourceEditorHotkeyContextMenuPaste = "Ctrl+V"; +static const char* kSourceEditorHotkeyContextMenuCut = "Ctrl+X"; +static const char* kSourceEditorHotkeyContextMenuCopy = "Ctrl+C"; +static const char* kSourceEditorHotkeyContextMenuPaste = "Ctrl+V"; static const char* kSourceEditorHotkeyContextMenuSelectAll = "Ctrl+A"; // Disassembly view hot key definitions. -static const char* kDisassemblyViewHotkeyGpuSelection = "Ctrl+T"; -static const char* kDisassemblyViewHotKeyNextMaxVgprLine = "F4"; +static const char* kDisassemblyViewHotkeyGpuSelection = "Ctrl+T"; +static const char* kDisassemblyViewHotKeyNextMaxVgprLine = "F4"; static const char* kDisassemblyViewHotKeyPreviousMaxVgprLine = "Shift+F4"; // View container hot key definitions. @@ -87,18 +87,21 @@ static const char* kSwitchContainerSize = "Ctrl+R"; static const char* kRestoreDefaultSettings = "Ctrl+R"; // Icon resource paths. -static const char* kIconResourceRgaLogo = ":/icons/rga_icon.png"; -static const char* kIconResourceFindMagnifyingGlass = ":/icons/magnifying_glass_icon.svg"; -static const char* kIconResourceExpandedRow = ":/icons/expand_file_item.svg"; -static const char* kIconResourceCollapsedRow = ":/icons/collapsed_arrow.svg"; -static const char* kIconResourceRemoveNotification = ":/icons/correlation_warning_icon.svg"; -static const char* kIconMaxVgprNotification = ":/icons/max_vgpr_warning_icon.svg"; -static const char* kIconMaxVgprNoIsaMatch = ":/icons/max_vgpr_no_isa_match_icon.svg"; +static const char* kIconResourceRgaLogo = ":/icons/rga_icon.png"; +static const char* kIconResourceFindMagnifyingGlass = ":/icons/magnifying_glass_icon.svg"; +static const char* kIconResourceFindMagnifyingGlassDark = ":/icons/magnifying_glass_icon_dark_mode.svg"; +static const char* kIconResourceExpandedRowLight = ":/icons/expand_file_item.svg"; +static const char* kIconResourceCollapsedRowLight = ":/icons/collapsed_arrow.svg"; +static const char* kIconResourceExpandedRowDark = ":/icons/arrow_down.svg"; +static const char* kIconResourceCollapsedRowDark = ":/icons/arrow_right.svg"; +static const char* kIconResourceRemoveNotification = ":/icons/correlation_warning_icon.svg"; +static const char* kIconMaxVgprNotification = ":/icons/max_vgpr_warning_icon.svg"; +static const char* kIconMaxVgprNoIsaMatch = ":/icons/max_vgpr_no_isa_match_icon.svg"; // Live VGPR tootip. -static const char* kLiveVgprTooltip1 = "%1 used, %2 allocated out of %3 VGPRs."; -static const char* kLiveVgprTooltip2 = "\nReduce VGPR consumption by %1 to save %2 VGPRs (HW allocates VGPRs in blocks of %3)"; -static const char* kLiveVgprNATooltip = "Could not parse %1 instructions (look for \"N/A\" under VGPR pressure)"; +static const char* kLiveVgprTooltip1 = "%1 used, %2 allocated out of %3 VGPRs."; +static const char* kLiveVgprTooltip2 = "\nReduce VGPR consumption by %1 to save %2 VGPRs (HW allocates VGPRs in blocks of %3)"; +static const char* kLiveVgprNATooltip = "Could not parse %1 instructions (look for \"N/A\" under VGPR pressure)"; static const char* kLiveVgprMaxVgprTooltip = "Number of used VGPRs exceeded max VGPRs"; // Live VGPR label string. @@ -108,11 +111,15 @@ static const char* kLiveVgprLabelString = "label"; static const char* kOptionsListDelimiter = ";"; // Macros. -#define RG_SAFE_DELETE(ptr) { delete ptr; ptr = nullptr;} +#define RG_SAFE_DELETE(ptr) \ + { \ + delete ptr; \ + ptr = nullptr; \ + } #ifdef WIN32 - #define STRCPY(dst, size, src) strcpy_s(dst, size, src) +#define STRCPY(dst, size, src) strcpy_s(dst, size, src) #else - #define STRCPY(dst, size, src) strncpy(dst, src, size) +#define STRCPY(dst, size, src) strncpy(dst, src, size) #endif -#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_RG_DEFINITIONS_H_ +#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_RG_DEFINITIONS_H_ diff --git a/source/radeon_gpu_analyzer_gui/rg_editor_element.cpp b/source/radeon_gpu_analyzer_gui/rg_editor_element.cpp index 114b45c..4df7af6 100644 --- a/source/radeon_gpu_analyzer_gui/rg_editor_element.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_editor_element.cpp @@ -7,6 +7,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_editor_element.h" #include "radeon_gpu_analyzer_gui/qt/rg_label.h" @@ -25,30 +28,6 @@ static const int kIndentationWidth = 20; // The horizontal position where the Value column starts. static const int kValueColumnPosition = 180; -// The stylesheet for each row in the PSO editor tree. Dynamic properties and repolishing -// are used to update the row background color without resetting the stylesheet string. -static const QString kStrRowStylesheet = -"* \ -{ \ - background-color: rgba(255, 128 255, 255); \ -} \ - \ -*[selected=true] \ -{ \ - background-color: rgba(255, 255, 178, 255); \ -} \ - \ -*[resultOccurrence=true][currentResult=false][selected=false] \ -{ \ - background-color: rgba(192, 192, 192, 255); \ -} \ - \ -*[currentResult=true] \ -{ \ - background-color: rgba(255, 255, 178, 255); \ -} \ -"; - RgEditorElement::RgEditorElement(QWidget* parent, const std::string& member_name, RgEditorDataType data_type, std::function value_changed_callback) : QWidget(parent) , member_name_(member_name) @@ -71,9 +50,6 @@ RgEditorElement::RgEditorElement(QWidget* parent, const std::string& member_name // Connect internal signals to slots. ConnectSignals(); - - // Apply a stylesheet to the row that's used to alter the background color. - setStyleSheet(kStrRowStylesheet); } void RgEditorElement::AppendChildItem(RgEditorElement* item) @@ -321,12 +297,14 @@ void RgEditorElement::RemoveStyleFlag(RgStyleFlags style_flag) { // Get the row's current style. uint32_t row_style_flags = GetStyleFlags(); + if (row_style_flags <= static_cast(RgStyleFlags::MaxRgStyleFlags)) + { + // Remove the given style flag. + row_style_flags &= ~static_cast(style_flag); - // Remove the given style flag. - row_style_flags &= ~static_cast(style_flag); - - // Apply the updated style flags to the row. - SetStyleFlags(row_style_flags); + // Apply the updated style flags to the row. + SetStyleFlags(row_style_flags); + } } RgEditorElement* RgEditorElement::GetParentItem() const @@ -345,8 +323,9 @@ int RgEditorElement::GetRowIndex() const if (parent_item_ != nullptr) { // Find this item within the parent's children. - auto child_iter = std::find_if( - parent_item_->child_items_.begin(), parent_item_->child_items_.end(), [this](std::shared_ptr child) { return child.get() == this; }); + auto child_iter = std::find_if(parent_item_->child_items_.begin(), parent_item_->child_items_.end(), [this](std::shared_ptr child) { + return child.get() == this; + }); if (child_iter != parent_item_->child_items_.end()) { // Compute the child index for this item. @@ -362,15 +341,31 @@ void RgEditorElement::SetExpansionState(RgRowExpansionState state, bool update_c // Update the row's expansion state. row_state_ = state; + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + // Toggle the visibility of all children based on the row state. bool is_row_expanded = (row_state_ == RgRowExpansionState::kExpanded); if (is_row_expanded) { - ui_.expandPushButton->setIcon(QIcon(kIconResourceExpandedRow)); + if (color_theme == ColorThemeType::kColorThemeTypeDark) + { + ui_.expandPushButton->setIcon(QIcon(kIconResourceExpandedRowDark)); + } + else + { + ui_.expandPushButton->setIcon(QIcon(kIconResourceExpandedRowLight)); + } } else { - ui_.expandPushButton->setIcon(QIcon(kIconResourceCollapsedRow)); + if (color_theme == ColorThemeType::kColorThemeTypeDark) + { + ui_.expandPushButton->setIcon(QIcon(kIconResourceCollapsedRowDark)); + } + else + { + ui_.expandPushButton->setIcon(QIcon(kIconResourceCollapsedRowLight)); + } } int num_children = ChildCount(); @@ -527,8 +522,7 @@ void RgEditorElement::ExpandTreeEntry() void RgEditorElement::HandleExpandClicked() { // Toggle the expanded/collapsed state of the row. - RgRowExpansionState new_row_state = (row_state_ == RgRowExpansionState::kExpanded) ? - RgRowExpansionState::kCollapsed : RgRowExpansionState::kExpanded; + RgRowExpansionState new_row_state = (row_state_ == RgRowExpansionState::kExpanded) ? RgRowExpansionState::kCollapsed : RgRowExpansionState::kExpanded; // Update the expansion state. SetExpansionState(new_row_state); @@ -627,7 +621,7 @@ void RgEditorElement::UpdateIndentation() // Calculate the width of the member name label. const QRect bounding_rect = font_metrics.boundingRect(member_name_.c_str()); - const int width = bounding_rect.width(); + const int width = bounding_rect.width(); // Set the width of the value indent spacer. This aligns all editor widgets under the value // column to the same horizontal position. @@ -658,7 +652,7 @@ void RgEditorElement::HighlightButtonSubString(int start_location, const std::st void RgEditorElement::UpdateButtonSubString() { - QPushButton *pPushButton = ui_.editorHost->findChild(); + QPushButton* pPushButton = ui_.editorHost->findChild(); ArrowIconComboBox* combo_box = dynamic_cast(pPushButton); if (combo_box != nullptr) { @@ -674,7 +668,7 @@ void RgEditorElement::UpdateStringMatchingLocation(int start_location, int lengt bool is_found = false; // Remove any entries that do not match the search string anymore. - int count = 0; + int count = 0; std::vector remove_entries; for (auto& string_data : string_highlight_data_) { @@ -694,9 +688,9 @@ void RgEditorElement::UpdateStringMatchingLocation(int start_location, int lengt { if (string_data.start_location == start_location) { - string_data.end_location = start_location + length; + string_data.end_location = start_location + length; string_data.highlight_string = search_string; - is_found = true; + is_found = true; SetHighlightColor(string_data); break; } @@ -706,21 +700,23 @@ void RgEditorElement::UpdateStringMatchingLocation(int start_location, int lengt if (!is_found) { StringHighlightData string_highlight_data = {}; - string_highlight_data.start_location = start_location; - string_highlight_data.end_location = start_location + length; - string_highlight_data.highlight_string = search_string; + string_highlight_data.start_location = start_location; + string_highlight_data.end_location = start_location + length; + string_highlight_data.highlight_string = search_string; SetHighlightColor(string_highlight_data); string_highlight_data_.push_back(string_highlight_data); } } -void RgEditorElement::SetHighlightColor(StringHighlightData& string_highlight_data) +void RgEditorElement::SetHighlightColor(StringHighlightData& string_highlight_data) { // The color in which the current match would be highlighted. - static const QColor kHighlightColorMatchOther = QColor::fromRgba(qRgba(254, 206, 0, 200)); + static const QColor kHighlightColorMatchOther = QtCommon::QtUtils::ColorTheme::Get().GetCurrentThemeColors().row_selected_color; + //QColor::fromRgba(qRgba(254, 206, 0, 200)); // The color in which any match would be highlighted. - static QColor kHighlightColorMatchCurrent = QColor::fromRgba(qRgba(165, 175, 146, 200)); + static QColor kHighlightColorMatchCurrent = qApp->palette().color(QPalette::Highlight); + //QColor::fromRgba(qRgba(165, 175, 146, 200)); if (is_current_match_) { @@ -734,7 +730,7 @@ void RgEditorElement::SetHighlightColor(StringHighlightData& string_highlight_d void RgEditorElement::ResetButtonSubString() { - QPushButton *push_buttons = ui_.editorHost->findChild(); + QPushButton* push_buttons = ui_.editorHost->findChild(); ArrowIconComboBox* combo_box = dynamic_cast(push_buttons); assert(combo_box != nullptr); if (combo_box != nullptr) diff --git a/source/radeon_gpu_analyzer_gui/rg_factory.h b/source/radeon_gpu_analyzer_gui/rg_factory.h index bfcb20c..05e698d 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory.h +++ b/source/radeon_gpu_analyzer_gui/rg_factory.h @@ -57,6 +57,9 @@ class RgFactory // Create an API-specific file menu. virtual RgMenu* CreateFileMenu(QWidget* parent) = 0; + // Apply the stylesheet for the api-specific file menu. + virtual void ApplyFileMenuStylesheet(QWidget* widget) = 0; + // Create an API-specific start tab. virtual RgStartTab* CreateStartTab(QWidget* parent) = 0; diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_binary.cpp b/source/radeon_gpu_analyzer_gui/rg_factory_binary.cpp index 83a2f35..a85f92e 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_binary.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_factory_binary.cpp @@ -82,13 +82,18 @@ RgMenu* RgFactoryBinary::CreateFileMenu(QWidget* parent) RgMenu* menu = new RgMenuBinary(parent); // Apply the file menu stylesheet. + ApplyFileMenuStylesheet(menu); + + return menu; +} + +void RgFactoryBinary::ApplyFileMenuStylesheet(QWidget* widget) +{ std::vector stylesheet_file_names; stylesheet_file_names.push_back(kStylesheetPackage.file_menu_stylesheet); stylesheet_file_names.push_back(kStylesheetPackage.file_menu_api_stylesheet); - [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, menu); + [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, widget); assert(status); - - return menu; } RgStartTab* RgFactoryBinary::CreateStartTab(QWidget* parent) diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_binary.h b/source/radeon_gpu_analyzer_gui/rg_factory_binary.h index fff8867..8e14f9e 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_binary.h +++ b/source/radeon_gpu_analyzer_gui/rg_factory_binary.h @@ -40,6 +40,9 @@ class RgFactoryBinary : public RgFactory // Create an OpenCL file menu. virtual RgMenu* CreateFileMenu(QWidget* parent) override; + // Apply the stylesheet for the Binary file menu. + virtual void ApplyFileMenuStylesheet(QWidget* widget) override; + // Create an OpenCL-specific start tab. virtual RgStartTab* CreateStartTab(QWidget* parent) override; diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_factory_opencl.cpp index 046a8a2..94d1f9f 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_factory_opencl.cpp @@ -82,13 +82,18 @@ RgMenu* RgFactoryOpencl::CreateFileMenu(QWidget* parent) RgMenu* menu = new RgMenuOpencl(parent); // Apply the file menu stylesheet. + ApplyFileMenuStylesheet(menu); + + return menu; +} + +void RgFactoryOpencl::ApplyFileMenuStylesheet(QWidget* widget) +{ std::vector stylesheet_file_names; stylesheet_file_names.push_back(kStylesheetPackage.file_menu_stylesheet); stylesheet_file_names.push_back(kStylesheetPackage.file_menu_api_stylesheet); - [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, menu); + [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, widget); assert(status); - - return menu; } RgStartTab* RgFactoryOpencl::CreateStartTab(QWidget* parent) diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_opencl.h b/source/radeon_gpu_analyzer_gui/rg_factory_opencl.h index 93343a9..7bc4fa6 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_opencl.h +++ b/source/radeon_gpu_analyzer_gui/rg_factory_opencl.h @@ -42,6 +42,9 @@ class RgFactoryOpencl : public RgFactory // Create an OpenCL file menu. virtual RgMenu* CreateFileMenu(QWidget* parent) override; + // Apply the stylesheet for the OpenCL file menu. + virtual void ApplyFileMenuStylesheet(QWidget* widget) override; + // Create an OpenCL-specific start tab. virtual RgStartTab* CreateStartTab(QWidget* parent) override; diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.cpp b/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.cpp index 6e51805..bb13476 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.cpp @@ -84,15 +84,20 @@ RgIsaDisassemblyView* RgFactoryVulkan::CreateDisassemblyView(QWidget* parent) RgMenu* RgFactoryVulkan::CreateFileMenu(QWidget* parent) { RgMenu* menu = new RgMenuVulkan(parent); - + // Apply the file menu stylesheet. + ApplyFileMenuStylesheet(menu); + + return menu; +} + +void RgFactoryVulkan::ApplyFileMenuStylesheet(QWidget* widget) +{ std::vector stylesheet_file_names; stylesheet_file_names.push_back(kStylesheetPackage.file_menu_stylesheet); stylesheet_file_names.push_back(kStylesheetPackage.file_menu_api_stylesheet); - [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, menu); + [[maybe_unused]] bool status = RgUtils::LoadAndApplyStyle(stylesheet_file_names, widget); assert(status); - - return menu; } RgStartTab* RgFactoryVulkan::CreateStartTab(QWidget* parent) diff --git a/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.h b/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.h index 2204acc..19b25ae 100644 --- a/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.h +++ b/source/radeon_gpu_analyzer_gui/rg_factory_vulkan.h @@ -33,6 +33,9 @@ class RgFactoryVulkan : public RgFactoryGraphics // Create a Vulkan-specific file menu. virtual RgMenu* CreateFileMenu(QWidget* parent) override; + // Apply the stylesheet for the Vulkan-specific file menu. + virtual void ApplyFileMenuStylesheet(QWidget* widget) override; + // Create a Vulkan-specific start tab. virtual RgStartTab* CreateStartTab(QWidget* parent) override; diff --git a/source/radeon_gpu_analyzer_gui/rg_find_text_widget.cpp b/source/radeon_gpu_analyzer_gui/rg_find_text_widget.cpp index 1538a5a..80c28fb 100644 --- a/source/radeon_gpu_analyzer_gui/rg_find_text_widget.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_find_text_widget.cpp @@ -1,6 +1,9 @@ // C++. #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_find_text_widget.h" #include "radeon_gpu_analyzer_gui/qt/rg_source_code_editor.h" @@ -8,12 +11,21 @@ #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -RgFindTextWidget::RgFindTextWidget(QWidget* parent) : - QWidget(parent) +RgFindTextWidget::RgFindTextWidget(QWidget* parent) + : QWidget(parent) { // Initialize the interface object. ui_.setupUi(this); + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + + if (color_theme == kColorThemeTypeDark) + { + ui_.filterRowsPushButton->setIcon(QIcon(":/icons/filter_rows_icon_dark_mode.svg")); + ui_.findPreviousPushButton->setIcon(QIcon(":/icons/new_file_icon_dark_mode.svg")); + ui_.findNextPushButton->setIcon(QIcon(":/icons/find_previous_icon_dark_mode.svg")); + } + // Set the tooltip and status tip for the Find next button. RgUtils::SetToolAndStatusTip(kStrEditFindNextTooltip, ui_.findNextPushButton); @@ -25,7 +37,18 @@ RgFindTextWidget::RgFindTextWidget(QWidget* parent) : // Add a Search magnifying glass to the search textbox. ui_.searchLineEdit->setClearButtonEnabled(true); - ui_.searchLineEdit->addAction(QIcon(kIconResourceFindMagnifyingGlass), QLineEdit::LeadingPosition); + + if (color_theme == kColorThemeTypeDark) + { + ui_.filterRowsPushButton->setIcon(QIcon(":/icons/filter_rows_icon_dark_mode.svg")); + ui_.findPreviousPushButton->setIcon(QIcon(":/icons/find_previous_icon_dark_mode.svg")); + ui_.findNextPushButton->setIcon(QIcon(":/icons/find_next_icon_dark_mode.svg")); + ui_.searchLineEdit->addAction(QIcon(kIconResourceFindMagnifyingGlassDark), QLineEdit::LeadingPosition); + } + else + { + ui_.searchLineEdit->addAction(QIcon(kIconResourceFindMagnifyingGlass), QLineEdit::LeadingPosition); + } // Create the keyboard actions associated with the Find widget. CreateActions(); @@ -235,10 +258,7 @@ void RgFindTextWidget::UpdateSearchOptions() if (search_context_ != nullptr) { // Update the search options by sending the option button states to the search context. - search_context_->SetSearchOptions({ - ui_.filterRowsPushButton->isChecked(), - ui_.matchCasePushButton->isChecked() - }); + search_context_->SetSearchOptions({ui_.filterRowsPushButton->isChecked(), ui_.matchCasePushButton->isChecked()}); // Trigger the search. search_context_->ResetSearch(); diff --git a/source/radeon_gpu_analyzer_gui/rg_global_settings_view.cpp b/source/radeon_gpu_analyzer_gui/rg_global_settings_view.cpp index d53e2e6..90585b0 100644 --- a/source/radeon_gpu_analyzer_gui/rg_global_settings_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_global_settings_view.cpp @@ -5,9 +5,12 @@ // Qt. #include #include +#include #include #include #include +#include +#include #include // Infra. @@ -36,6 +39,10 @@ static const QColor kApiColorBinary = QColor(128, 0, 128); static const QColor kApiColorOpencl = QColor(18, 152, 0); static const QColor kApiColorVulkan = QColor(224, 30, 55); +const static QString kLightThemeOption = "Light"; +const static QString kDarkThemeOption = "Dark"; +const static QString kDetectOsOption = "Detect OS"; + // Columns push button font size. const int kPushButtonFontSize = 11; @@ -47,12 +54,6 @@ RgGlobalSettingsView::RgGlobalSettingsView(QWidget* parent, const RgGlobalSettin // Setup the UI. ui_.setupUi(this); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Create the widget used to control column visibility. CreateColumnVisibilityControls(); @@ -62,6 +63,18 @@ RgGlobalSettingsView::RgGlobalSettingsView(QWidget* parent, const RgGlobalSettin // Initialize the combo box for font size. PopulateFontSizeDropdown(); + ui_.color_theme_combo_box_->InitSingleSelect(this, kLightThemeOption, false, "Color Theme: "); + ui_.color_theme_combo_box_->AddItem(kLightThemeOption, kColorThemeTypeLight); + ui_.color_theme_combo_box_->AddItem(kDarkThemeOption, kColorThemeTypeDark); + ui_.color_theme_combo_box_->AddItem(kDetectOsOption, kColorThemeTypeCount); + + ui_.color_theme_combo_box_->SetSelectedRow(initial_settings_.color_theme); + + connect(ui_.color_theme_combo_box_, &ArrowIconComboBox::SelectedItem, this, &RgGlobalSettingsView::HandleColorThemeComboBoxChanged); +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &RgGlobalSettingsView::HandleOsColorSchemeChanged); +#endif + // Push values to various widgets. PushToWidgets(global_settings); @@ -232,6 +245,8 @@ void RgGlobalSettingsView::PushToWidgets(const RgGlobalSettings& global_settings ui_.fontSizeComboBox->setCurrentIndex(index); } + ui_.color_theme_combo_box_->SetSelectedRow(global_settings.color_theme); + // Include files viewer. ui_.includeFilesViewerLineEdit->setText(global_settings.include_files_viewer.c_str()); @@ -281,6 +296,8 @@ RgGlobalSettings RgGlobalSettingsView::PullFromWidgets() const // Font size. settings.font_size = ui_.fontSizeComboBox->itemData(ui_.fontSizeComboBox->currentIndex()).toInt(); + settings.color_theme = ui_.color_theme_combo_box_->CurrentRow(); + // Include files viewer. settings.include_files_viewer = ui_.includeFilesViewerLineEdit->text().toStdString(); @@ -826,6 +843,131 @@ void RgGlobalSettingsView::HandleComboBoxChanged(int index) HandlePendingChangesStateChanged(GetHasPendingChanges()); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +void RgGlobalSettingsView::HandleOsColorSchemeChanged(Qt::ColorScheme color_scheme) +{ + if (RgConfigManager::Instance().GetGlobalConfig()->color_theme != kColorThemeTypeCount) + { + return; + } + + if (color_scheme == Qt::ColorScheme::Unknown) + { + return; + } + + ColorThemeType color_mode = kColorThemeTypeLight; + if (color_scheme == Qt::ColorScheme::Light) + { + color_mode = kColorThemeTypeLight; + } + else if (color_scheme == Qt::ColorScheme::Dark) + { + color_mode = kColorThemeTypeDark; + } + + if (color_mode == QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()) + { + return; + } + + QtCommon::QtUtils::ColorTheme::Get().SetColorTheme(color_mode); + + qApp->setPalette(QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette()); + + emit QtCommon::QtUtils::ColorTheme::Get().ColorThemeUpdated(); +} +#endif + +void RgGlobalSettingsView::HandleColorThemeComboBoxChanged(QListWidgetItem* color_theme_option) +{ + ColorThemeType selected_color_mode = static_cast(color_theme_option->data(Qt::UserRole).toInt()); + + // If the setting was not changed, return early. + if (selected_color_mode == RgConfigManager::Instance().GetGlobalConfig()->color_theme) + { + return; + } + + HandlePendingChangesStateChanged(GetHasPendingChanges()); +} + +bool RgGlobalSettingsView::SetColorTheme() +{ + ColorThemeType selected_color_mode = static_cast(initial_settings_.color_theme); + + // If the setting was not changed return early. + if (selected_color_mode == QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()) + { + return false; + } + + ColorThemeType color_mode = selected_color_mode; + + if (selected_color_mode == kColorThemeTypeCount) + { + color_mode = QtCommon::QtUtils::DetectOsSetting(); + } + + // If the setting was changed, but won't result in a color theme change return early. + if (color_mode == QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()) + { + return false; + } + + + QString color_theme_changed_title = "Color Theme Changed. Restart Application?"; + QString color_theme_changed_text = + "Not all UI elements will update to reflect the change in color theme until the application has restarted. Restart Application?"; + + int ret = QtCommon::QtUtils::ShowMessageBox( + this, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Question, color_theme_changed_title, color_theme_changed_text); + + bool restart = false; + + if (ret == QMessageBox::Cancel) + { + int old_color_theme = RgConfigManager::Instance().GetGlobalConfig()->color_theme; + + for (int i = 0; i <= kColorThemeTypeCount; i++) + { + if (i == old_color_theme) + { + ui_.color_theme_combo_box_->SetSelectedRow(i); + } + } + initial_settings_.color_theme = old_color_theme; + } + else + { + QtCommon::QtUtils::ColorTheme::Get().SetColorTheme(color_mode); + + if (ret == QMessageBox::Yes) + { + restart = true; + } + else if (ret == QMessageBox::No) + { + + QPalette common_palette = QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette(); + if (color_mode == kColorThemeTypeDark) + { + common_palette.setColor(QPalette::Midlight, QColor(60, 60, 60)); + common_palette.setColor(QPalette::Highlight, QColor(100, 100, 50, 130)); + } + else + { + common_palette.setColor(QPalette::Midlight, QColor(200, 200, 200)); + common_palette.setColor(QPalette::Highlight, QColor(255, 255, 178)); + } + qApp->setPalette(common_palette); + + emit QtCommon::QtUtils::ColorTheme::Get().ColorThemeUpdated(); + } + } + return restart; +} + bool RgGlobalSettingsView::GetHasPendingChanges() const { RgGlobalSettings current_settings = PullFromWidgets(); @@ -873,6 +1015,8 @@ bool RgGlobalSettingsView::SaveSettings() // Reset the initial settings to match what the UI shows. initial_settings_ = PullFromWidgets(); + bool restart = SetColorTheme(); + // Update the config manager to use these new settings. RgConfigManager& config_manager = RgConfigManager::Instance(); config_manager.SetGlobalConfig(initial_settings_); @@ -886,6 +1030,34 @@ bool RgGlobalSettingsView::SaveSettings() HandlePendingChangesStateChanged(false); } + if (restart) + { + QString default_exe_name; + default_exe_name.append(QDir::separator()); + default_exe_name.append(kStrAppFolderName); + +#ifdef WIN32 + // Append an extension only in Windows. + default_exe_name.append(".exe"); +#endif + + const QString rga_executable = QDir::toNativeSeparators(qApp->applicationDirPath() + default_exe_name); + + QFileInfo file(rga_executable); + if (file.exists()) + { + QProcess* process = new QProcess(this); + if (process != nullptr) + { + bool process_result = process->startDetached(rga_executable); + if (process_result) + { + qApp->quit(); + } + } + } + } + return is_saved; } diff --git a/source/radeon_gpu_analyzer_gui/rg_goto_line_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_goto_line_dialog.cpp index afc78fc..6d93d54 100644 --- a/source/radeon_gpu_analyzer_gui/rg_goto_line_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_goto_line_dialog.cpp @@ -20,12 +20,6 @@ RgGoToLineDialog::RgGoToLineDialog(int maxLineNumber, QWidget* parent) : // Disable the help button in the title bar. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Set the validator for the line number edit box. QValidator *validator = new QIntValidator(0, max_line_number_, this); diff --git a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_custom_table_view.cpp b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_custom_table_view.cpp index 0495ec6..0c8a54a 100644 --- a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_custom_table_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_custom_table_view.cpp @@ -9,6 +9,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_custom_table_view.h" #include "radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h" @@ -16,8 +19,8 @@ #include "radeon_gpu_analyzer_gui/rg_definitions.h" #include "radeon_gpu_analyzer_gui/rg_string_constants.h" -// The highlight color to use for correlated source lines. -static QColor kCorrelationHighlightColor = QColor(Qt::yellow).lighter(170); +// The highlight colors to use for selected source lines. +static QColor kCorrelationHighlightColor[ColorThemeType::kColorThemeTypeCount] = {QColor(Qt::yellow).lighter(170), QColor(80, 80, 40, 100)}; static QColor kLightBlueSelectionColor = QColor(229, 243, 255); // Colors for VGPR pressure ranges. @@ -65,7 +68,7 @@ static void DrawVgprWidget(QPainter* painter, const QStyleOptionViewItem& option // Set the background highlight color for the cell when the row is selected. if (option.state & QStyle::State_Selected) { - painter->fillRect(option.rect, kCorrelationHighlightColor); + painter->fillRect(option.rect, kCorrelationHighlightColor[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); } // Get the number of VGPR registers. @@ -208,7 +211,7 @@ class RgTreeviewSelectionDelegateVulkan : public QItemDelegate QColor item_foreground_color = model_index.data(Qt::ForegroundRole).value(); view_option.palette.setColor(QPalette::HighlightedText, item_foreground_color); - QColor background_color(kCorrelationHighlightColor); + QColor background_color(kCorrelationHighlightColor[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); view_option.palette.setColor(QPalette::Highlight, background_color); QItemDelegate::paint(painter, view_option, model_index); @@ -236,7 +239,7 @@ class RgTreeviewSelectionDelegateOpencl : public QItemDelegate QColor item_foreground_color = model_index.data(Qt::ForegroundRole).value(); view_option.palette.setColor(QPalette::HighlightedText, item_foreground_color); - QColor background_color(kCorrelationHighlightColor); + QColor background_color(kCorrelationHighlightColor[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); view_option.palette.setColor(QPalette::Highlight, background_color); QItemDelegate::paint(painter, view_option, model_index); @@ -267,7 +270,7 @@ class RgTreeviewSelectionDelegateBinary : public QItemDelegate QColor item_foreground_color = model_index.data(Qt::ForegroundRole).value(); view_option.palette.setColor(QPalette::HighlightedText, item_foreground_color); - QColor background_color(kCorrelationHighlightColor); + QColor background_color(kCorrelationHighlightColor[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); view_option.palette.setColor(QPalette::Highlight, background_color); QItemDelegate::paint(painter, view_option, model_index); @@ -396,7 +399,7 @@ void RgIsaDisassemblyCustomTableView::drawRow(QPainter* painter, const QStyleOpt if (is_line_correlated_with_input_file) { // Paint the row background with the highlight color. - painter->fillRect(options.rect, kCorrelationHighlightColor); + painter->fillRect(options.rect, kCorrelationHighlightColor[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); // If the row background gets painted manually, reset the row's background brush to be transparent. new_options.palette.setBrush(QPalette::Base, Qt::transparent); diff --git a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_model.cpp b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_model.cpp index c82a624..821bf75 100644 --- a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_model.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_model.cpp @@ -10,6 +10,10 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" +#include "qt_common/utils/shared_isa_dictionary.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_isa_disassembly_table_model.h" #include "radeon_gpu_analyzer_gui/qt/rg_output_file_utils.h" @@ -25,22 +29,25 @@ // The color to use for label backgrounds within the table. static const QColor kBranchLabelInstructionColor = QColor(37, 36, 225); -static const QColor kBranchLabelBackgroundColor = QColor("lightGray").lighter(113); -RgIsaDisassemblyTableModel::RgIsaDisassemblyTableModel(uint32_t model_count, QWidget* parent) : - ModelViewMapper(model_count) +RgIsaDisassemblyTableModel::RgIsaDisassemblyTableModel(uint32_t model_count, QWidget* parent) + : ModelViewMapper(model_count) { // Create the table model. isa_table_model_ = new QStandardItemModel(0, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCount), parent); // Add column headers to the table. - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kAddress), new QStandardItem(kStrDisassemblyTableColumnAddress)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOpcode), new QStandardItem(kStrDisassemblyTableColumnOpcode)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOperands), new QStandardItem(kStrDisassemblyTableColumnOperands)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kFunctionalUnit), new QStandardItem(kStrDisassemblyTableColumnFunctionalUnit)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCycles), new QStandardItem(kStrDisassemblyTableColumnCycles)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kBinaryEncoding), new QStandardItem(kStrDisassemblyTableColumnBinaryEncoding)); - isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kLiveVgprs), new QStandardItem(kStrDisassemblyTableLiveVgprs)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kAddress), + new QStandardItem(kStrDisassemblyTableColumnAddress)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOpcode), new QStandardItem(kStrDisassemblyTableColumnOpcode)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOperands), + new QStandardItem(kStrDisassemblyTableColumnOperands)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kFunctionalUnit), + new QStandardItem(kStrDisassemblyTableColumnFunctionalUnit)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCycles), new QStandardItem(kStrDisassemblyTableColumnCycles)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kBinaryEncoding), + new QStandardItem(kStrDisassemblyTableColumnBinaryEncoding)); + isa_table_model_->setHorizontalHeaderItem(GetTableColumnIndex(RgIsaDisassemblyTableColumns::kLiveVgprs), new QStandardItem(kStrDisassemblyTableLiveVgprs)); } const std::vector& RgIsaDisassemblyTableModel::GetCorrelatedLineIndices() const @@ -62,7 +69,7 @@ bool RgIsaDisassemblyTableModel::GetInputSourceLineNumberFromInstructionRow(int { // Return the input source file's line number that corresponds with the given disassembly line number. input_source_line_number = input_source_line_iter->second; - ret = true; + ret = true; } return ret; @@ -80,7 +87,7 @@ void RgIsaDisassemblyTableModel::GetLabelNameToLineIndexMap(std::map label_line = std::static_pointer_cast(current_line); // Extract the label name and insert into the output map. - std::string label_name = label_line->label_name; + std::string label_name = label_line->label_name; link_labels[label_name] = line_index; } } @@ -100,7 +107,7 @@ void RgIsaDisassemblyTableModel::GetLineIndexToLabelNameMap(std::mapfunctional_unit.compare("Branch") == 0) { std::string jump_destination = instruction_line->operands; - link_labels[line_index] = jump_destination; + link_labels[line_index] = jump_destination; } } } @@ -110,7 +117,7 @@ void RgIsaDisassemblyTableModel::InsertLabelRows() { // Try to insert labels into the start column if possible. int start_column = GetTableColumnIndex(RgIsaDisassemblyTableColumns::kAddress); - int end_column = GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCount); + int end_column = GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCount); // The column index to insert the labels into. label_column_index_ = start_column; @@ -146,8 +153,8 @@ void RgIsaDisassemblyTableModel::InsertLabelRows() // Add the label text to the model. SetTableModelText(label_line->label_name, row_index, label_column_index_); - // Set the background color to yellow to make the label stand out more. - SetTableModelBackgroundColor(kBranchLabelBackgroundColor, row_index, label_column_index_); + // Set the background color to make the label stand out more. + SetTableModelBackgroundColor(qApp->palette().color(QPalette::AlternateBase), row_index, label_column_index_); } } } @@ -162,8 +169,8 @@ bool RgIsaDisassemblyTableModel::IsBranchOperandItem(const QModelIndex& model_in bool is_label_link_item = false; // Find the disassembly row for the item. - int row_index = model_index.row(); - std::shared_ptr isa_line = disassembled_isa_lines_[row_index]; + int row_index = model_index.row(); + std::shared_ptr isa_line = disassembled_isa_lines_[row_index]; // Determine what kind of instruction is represented in this row. if (isa_line->type == RgIsaLineType::kInstruction) @@ -175,7 +182,7 @@ bool RgIsaDisassemblyTableModel::IsBranchOperandItem(const QModelIndex& model_in if (instruction_line->functional_unit.compare("Branch") == 0) { // Is the given index in the Operands column? That's the column a label needs to be painted in. - int column_index = model_index.column(); + int column_index = model_index.column(); bool is_operands_column = column_index == GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOperands); if (is_operands_column) { @@ -192,7 +199,7 @@ bool RgIsaDisassemblyTableModel::IsColumnVisible(int column_index) const bool is_visible = false; // Check the global config settings to see if the column should be visible. - RgConfigManager& config_manager = RgConfigManager::Instance(); + RgConfigManager& config_manager = RgConfigManager::Instance(); std::shared_ptr global_settings = config_manager.GetGlobalConfig(); assert(global_settings != nullptr); if (global_settings != nullptr) @@ -283,11 +290,7 @@ bool RgIsaDisassemblyTableModel::LoadLiveVgprsData(const std::string& live_vgpr_ if (!live_vgpr_file_full_path.empty()) { // Parse the live VGPR data. - status = RgOutputFileUtils::ParseLiveVgprsData(live_vgpr_file_full_path, - disassembled_isa_lines_, - vgpr_isa_lines_, - vgpr_file_lines_, - livereg_data_); + status = RgOutputFileUtils::ParseLiveVgprsData(live_vgpr_file_full_path, disassembled_isa_lines_, vgpr_isa_lines_, vgpr_file_lines_, livereg_data_); assert(status); // Populate the view with live VGPR data. @@ -369,7 +372,7 @@ bool RgIsaDisassemblyTableModel::GetDisassemblyLineIndicesFromInputSourceLine(in { // Return the list of disassembly line indices. disassembly_lines = disassembly_instruction_lines_iter->second; - ret = true; + ret = true; } return ret; @@ -382,18 +385,29 @@ int RgIsaDisassemblyTableModel::GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns QColor RgIsaDisassemblyTableModel::GetFunctionalUnitColor(const std::string& functional_unit) const { - QColor color; + QColor color = QtCommon::QtUtils::ColorTheme::Get().GetCurrentThemeColors().graphics_scene_text_color; - static const std::map kFunctionalUnitColors = - { - { FUNC_UNIT_SALU, QColor(28, 124, 84) }, - { FUNC_UNIT_VALU, QColor(75, 124, 140) }, - { FUNC_UNIT_SMEM, QColor(227, 29, 63).darker(110) }, - { FUNC_UNIT_VMEM, QColor(227, 29, 63).darker(90) }, - { FUNC_UNIT_INTERNAL_FLOW, QColor("black").lighter(150) }, - { FUNC_UNIT_BRANCH, kBranchLabelInstructionColor }, + static std::map kFunctionalUnitColors = { + {FUNC_UNIT_SALU, QColor(28, 124, 84)}, + {FUNC_UNIT_VALU, QColor(75, 124, 140)}, + {FUNC_UNIT_SMEM, QColor(227, 29, 63).darker(110)}, + {FUNC_UNIT_VMEM, QColor(227, 29, 63).darker(90)}, + {FUNC_UNIT_INTERNAL_FLOW, QColor("black").lighter(150)}, + {FUNC_UNIT_BRANCH, kBranchLabelInstructionColor}, }; + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + kFunctionalUnitColors = { + {FUNC_UNIT_SALU, QtCommon::QtUtils::kIsaDarkThemeColorLightGreen}, + {FUNC_UNIT_VALU, QtCommon::QtUtils::kIsaDarkThemeColorLightBlue}, + {FUNC_UNIT_SMEM, QtCommon::QtUtils::kIsaDarkThemeColorRed}, + {FUNC_UNIT_VMEM, QtCommon::QtUtils::kIsaDarkThemeColorRed}, + {FUNC_UNIT_INTERNAL_FLOW, QtCommon::QtUtils::ColorTheme::Get().GetCurrentThemeColors().graphics_scene_text_color}, + {FUNC_UNIT_BRANCH, QtCommon::QtUtils::kIsaDarkThemeColorBlue}, + }; + } + auto unit = kFunctionalUnitColors.find(functional_unit); if (unit != kFunctionalUnitColors.end()) { @@ -410,7 +424,7 @@ bool RgIsaDisassemblyTableModel::LoadCsvData(const std::string& csv_file_full_pa // Clear out existing data. disassembled_isa_lines_.clear(); - QFile csv_file(csv_file_full_path.c_str()); + QFile csv_file(csv_file_full_path.c_str()); QTextStream file_stream(&csv_file); // Attempt to open the file to read each instruction line. @@ -429,9 +443,9 @@ bool RgIsaDisassemblyTableModel::LoadCsvData(const std::string& csv_file_full_pa if (!isa_line.isEmpty()) { // Parse the line that was just read into a new RgIsaLine. - std::shared_ptr new_line = nullptr; - int input_source_line_index = kInvalidCorrelationLineIndex; - bool is_split_successful = ParseCsvIsaLine(isa_line.toStdString(), new_line, input_source_line_index); + std::shared_ptr new_line = nullptr; + int input_source_line_index = kInvalidCorrelationLineIndex; + bool is_split_successful = ParseCsvIsaLine(isa_line.toStdString(), new_line, input_source_line_index); // Was the line processed correctly? assert(is_split_successful); @@ -444,7 +458,7 @@ bool RgIsaDisassemblyTableModel::LoadCsvData(const std::string& csv_file_full_pa if (input_source_line_index != kInvalidCorrelationLineIndex) { // Use a map to associate the current line of disassembly with the input source line index. - int disassembly_line_index = static_cast(disassembled_isa_lines_.size()); + int disassembly_line_index = static_cast(disassembled_isa_lines_.size()); instruction_line_number_to_input_source_line_number_[disassembly_line_index] = input_source_line_index; // Find the minimum line number of the entry point in the input file. @@ -520,7 +534,7 @@ bool RgIsaDisassemblyTableModel::ParseCsvIsaLine(const std::string& disassembled input_source_line_index = kInvalidCorrelationLineIndex; std::vector line_tokens; - std::stringstream line_stream; + std::stringstream line_stream; line_stream.str(disassembled_line); std::string substr; @@ -532,83 +546,83 @@ bool RgIsaDisassemblyTableModel::ParseCsvIsaLine(const std::string& disassembled switch (num_quotes_in_token) { case 0: - { - // If there are no quotes, just add the token to the line tokens list. - line_tokens.push_back(substr); - } - break; + { + // If there are no quotes, just add the token to the line tokens list. + line_tokens.push_back(substr); + } + break; case 1: + { + // Found a start quote. Keep reading new tokens to find the matching end quote. + std::stringstream token_stream; + do { - // Found a start quote. Keep reading new tokens to find the matching end quote. - std::stringstream token_stream; - do - { - // Add the token to the quoted column string. - token_stream << substr << ','; - std::getline(line_stream, substr, ','); - } while (!(substr.find('"') != substr.npos)); + // Add the token to the quoted column string. + token_stream << substr << ','; + std::getline(line_stream, substr, ','); + } while (!(substr.find('"') != substr.npos)); - // Add the final portion of the token to the stream. - token_stream << substr; + // Add the final portion of the token to the stream. + token_stream << substr; - // Remove the quotation marks from the final token string. - std::string quoted_token = token_stream.str(); - quoted_token.erase(std::remove(quoted_token.begin(), quoted_token.end(), '\"'), quoted_token.end()); + // Remove the quotation marks from the final token string. + std::string quoted_token = token_stream.str(); + quoted_token.erase(std::remove(quoted_token.begin(), quoted_token.end(), '\"'), quoted_token.end()); - // Add the token to the line tokens list. - line_tokens.push_back(quoted_token); - } - break; + // Add the token to the line tokens list. + line_tokens.push_back(quoted_token); + } + break; case 2: - { - // There's a single token surrounded with 2 quotes. Just remove the quotes and add the token to the lines. - substr.erase(std::remove(substr.begin(), substr.end(), '\"'), substr.end()); - line_tokens.push_back(substr); - } - break; + { + // There's a single token surrounded with 2 quotes. Just remove the quotes and add the token to the lines. + substr.erase(std::remove(substr.begin(), substr.end(), '\"'), substr.end()); + line_tokens.push_back(substr); + } + break; default: // If this happens, the format of the ISA line likely wasn't handled correctly. assert(false); } } - int num_columns = static_cast(line_tokens.size()); + int num_columns = static_cast(line_tokens.size()); const int num_csv_columns = static_cast(RgIsaDisassemblyCsvFileColumns::kCount); switch (num_columns) { case 1: - { - // This line is a label line that indicates a new section of instructions. - std::shared_ptr label_line = std::make_shared(); - label_line->label_name = line_tokens[0]; - label_line->type = RgIsaLineType::kLabel; - - // The line was parsed successfully. - parsed_line = std::static_pointer_cast(label_line); - ret = true; - } - break; + { + // This line is a label line that indicates a new section of instructions. + std::shared_ptr label_line = std::make_shared(); + label_line->label_name = line_tokens[0]; + label_line->type = RgIsaLineType::kLabel; + + // The line was parsed successfully. + parsed_line = std::static_pointer_cast(label_line); + ret = true; + } + break; case num_csv_columns: - { - // Add each token to the output structure. - std::shared_ptr instruction_line = std::make_shared(); - - // Assign the values into the instruction line object. - instruction_line->address = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kAddress)]; - instruction_line->opcode = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kOpcode)]; - instruction_line->operands = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kOperands)]; - instruction_line->functional_unit = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kFunctionalUnit)]; - instruction_line->cycles = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kCycles)]; - instruction_line->binary_encoding = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kBinaryEncoding)]; - - // Extract the source line number as an integer. - input_source_line_index = std::stoi(line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kSourceLineNumber)].c_str()); - - // The line was parsed successfully, so assign it to the output instance. - parsed_line = std::static_pointer_cast(instruction_line); - ret = true; - } - break; + { + // Add each token to the output structure. + std::shared_ptr instruction_line = std::make_shared(); + + // Assign the values into the instruction line object. + instruction_line->address = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kAddress)]; + instruction_line->opcode = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kOpcode)]; + instruction_line->operands = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kOperands)]; + instruction_line->functional_unit = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kFunctionalUnit)]; + instruction_line->cycles = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kCycles)]; + instruction_line->binary_encoding = line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kBinaryEncoding)]; + + // Extract the source line number as an integer. + input_source_line_index = std::stoi(line_tokens[GetCsvColumnIndex(RgIsaDisassemblyCsvFileColumns::kSourceLineNumber)].c_str()); + + // The line was parsed successfully, so assign it to the output instance. + parsed_line = std::static_pointer_cast(instruction_line); + ret = true; + } + break; default: // Catch cases where the type of line format is unhandled. assert(false); @@ -630,8 +644,8 @@ void RgIsaDisassemblyTableModel::ClearLabelLines() // Add the label text to the model. SetTableModelText("", row_index, label_column_index_); - // Set the background color to white, because the data was erased. - SetTableModelBackgroundColor(QColor(Qt::white), row_index, label_column_index_); + // Set the background color, because the data was erased. + SetTableModelBackgroundColor(qApp->palette().color(QPalette::Base), row_index, label_column_index_); } } } @@ -650,8 +664,8 @@ void RgIsaDisassemblyTableModel::GetColumnMaxWidths(const QVector& selected { if (disassembled_isa_lines_[row]->type == RgIsaLineType::kInstruction) { - QVariant call_text = isa_table_model_->data(isa_table_model_->index(row, col)); - max_width = std::max(max_width, static_cast(call_text.toString().size())); + QVariant call_text = isa_table_model_->data(isa_table_model_->index(row, col)); + max_width = std::max(max_width, static_cast(call_text.toString().size())); } } } @@ -662,11 +676,11 @@ void RgIsaDisassemblyTableModel::GetColumnMaxWidths(const QVector& selected void RgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selected_row_numbers) { - const int MIN_COLUMN_OFFSET = 4; - std::shared_ptr global_settings = RgConfigManager::Instance().GetGlobalConfig(); + const int MIN_COLUMN_OFFSET = 4; + std::shared_ptr global_settings = RgConfigManager::Instance().GetGlobalConfig(); // Calculate maximum width for each column in the selected ISA region. - std::vector max_column_width; + std::vector max_column_width; GetColumnMaxWidths(selected_row_numbers, max_column_width); // Add a tab as a delimiter between each column. @@ -674,14 +688,14 @@ void RgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selecte // Build a string including each line in the selected range. std::stringstream clipboard_text; - foreach(auto row_index, selected_row_numbers) + foreach (auto row_index, selected_row_numbers) { // Is the current row an instruction or a label? std::shared_ptr isa_line = disassembled_isa_lines_[row_index]; if (isa_line->type == RgIsaLineType::kInstruction) { - bool is_first_token_in_line = true; - std::string prev_column_text = ""; + bool is_first_token_in_line = true; + std::string prev_column_text = ""; // Add the contents of visible columns to the clipboard text. for (int column_index = 0, prev_visible_column_index = 0; column_index < global_settings->visible_disassembly_view_columns.size(); ++column_index) @@ -700,9 +714,10 @@ void RgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selecte // Append sufficient number of spaces so that the columns are aligned. // The number of needed spaces is based on the width of the text in the previous column and its maximum width. assert(prev_visible_column_index < max_column_width.size()); - std::string delimiter = ""; + std::string delimiter = ""; for (size_t i = 0, num_spaces = MIN_COLUMN_OFFSET + max_column_width[prev_visible_column_index++] - prev_column_text.size(); - i < num_spaces; ++i) + i < num_spaces; + ++i) { delimiter += COLUMN_DELIMITER_SYMBOL; } @@ -711,14 +726,16 @@ void RgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selecte // Get the cell data. QModelIndex cell_index = isa_table_model_->index(row_index, column_index); - QVariant cell_text = isa_table_model_->data(cell_index); + QVariant cell_text = isa_table_model_->data(cell_index); // If the data is invalid, get it from somewhere else. if (!cell_text.isValid()) { // Check if the functional unit is set to "Branch". // If it is, get the data from Operands column from disassembled ISA Lines instead. - QString cell_text_string = isa_table_model_->data(isa_table_model_->index(row_index, static_cast(RgIsaDisassemblyTableColumns::kFunctionalUnit))).toString(); + QString cell_text_string = + isa_table_model_->data(isa_table_model_->index(row_index, static_cast(RgIsaDisassemblyTableColumns::kFunctionalUnit))) + .toString(); if (cell_text_string.compare("Branch") == 0) { isa_line = disassembled_isa_lines_[row_index]; @@ -744,7 +761,7 @@ void RgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selecte { // Extract the label text from whatever column the label is in. QModelIndex cell_index = isa_table_model_->index(row_index, label_column_index_); - QVariant cell_text = isa_table_model_->data(cell_index); + QVariant cell_text = isa_table_model_->data(cell_index); // Append the label name to the clipboard text. clipboard_text << cell_text.toString().toStdString(); @@ -775,11 +792,11 @@ void RgIsaDisassemblyTableModel::InitializeModelData() std::shared_ptr instruction_line = std::static_pointer_cast(isa_line); // Update the model cells with data from each disassembled ISA instruction line. - SetTableModelText(instruction_line->address, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kAddress)); - SetTableModelText(instruction_line->opcode, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOpcode)); - SetTableModelText(instruction_line->functional_unit, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kFunctionalUnit)); - SetTableModelText(instruction_line->cycles, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCycles)); - SetTableModelText(instruction_line->binary_encoding, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kBinaryEncoding)); + SetTableModelText(instruction_line->address, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kAddress)); + SetTableModelText(instruction_line->opcode, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kOpcode)); + SetTableModelText(instruction_line->functional_unit, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kFunctionalUnit)); + SetTableModelText(instruction_line->cycles, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kCycles)); + SetTableModelText(instruction_line->binary_encoding, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kBinaryEncoding)); SetTableModelText(instruction_line->num_live_registers, line_index, GetTableColumnIndex(RgIsaDisassemblyTableColumns::kLiveVgprs)); // Set the tooltip for the live VGPR cell. @@ -799,8 +816,8 @@ void RgIsaDisassemblyTableModel::InitializeModelData() } else if (isa_line->type == RgIsaLineType::kLabel) { - // Get the instruction line. - isa_line = disassembled_isa_lines_[line_index]; + // Get the instruction line. + isa_line = disassembled_isa_lines_[line_index]; std::shared_ptr instruction_line = std::static_pointer_cast(isa_line); // Update the model cells with data from each disassembled ISA instruction line. @@ -814,7 +831,7 @@ void RgIsaDisassemblyTableModel::InitializeModelData() void RgIsaDisassemblyTableModel::CreateTooltip(std::string& tooltip, const std::string& num_live_registers) const { // Extract live VGPRs and granularity values. - QStringList values = QString::fromStdString(num_live_registers).split(","); + QStringList values = QString::fromStdString(num_live_registers).split(","); // Verify the split. if (values.size() == 2) @@ -873,7 +890,7 @@ void RgIsaDisassemblyTableModel::UpdateCurrentMaxVgprLine() void RgIsaDisassemblyTableModel::ResetCurrentMaxVgprValues() { // Reset the maximum VGPR values. - current_max_vgpr_index_ = 0; + current_max_vgpr_index_ = 0; is_show_current_max_vgpr_enabled_ = false; // Set all lines to be not current max VGPR lines. @@ -909,7 +926,7 @@ bool RgIsaDisassemblyTableModel::GetNextMaxVgprLineNumber(int& line_number) is_show_current_max_vgpr_enabled_ = true; } - line_number = livereg_data_.max_vgpr_line_numbers.at(current_max_vgpr_index_); + line_number = livereg_data_.max_vgpr_line_numbers.at(current_max_vgpr_index_); is_valid_line = true; } diff --git a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_view.cpp b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_view.cpp index bcef979..1b27f24 100644 --- a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_table_view.cpp @@ -11,7 +11,7 @@ #include #include -// Infra. +// QtCommon. #include "qt_common/utils/qt_util.h" // Local. @@ -25,17 +25,25 @@ // The bottom margin of the disassembly table. static const int kTableBottomMargin = 5; +// The style for the tooltip background color. +static const QString kStyleSheetText[ColorThemeType::kColorThemeTypeCount] = { + "QToolTip {background-color: rgb(240, 230, 200); border: 1px solid palette(text);}", + "QToolTip {background-color: rgb(60, 60, 60); border: 1px solid palette(text);}"}; + // A class used to filter the ISA disassembly table columns. class RgIsaDisassemblyTableModelFilteringModel : public QSortFilterProxyModel { public: - RgIsaDisassemblyTableModelFilteringModel(RgIsaDisassemblyTableModel* source_model, QObject* parent = nullptr) : - QSortFilterProxyModel(parent), source_model_(source_model) {} + RgIsaDisassemblyTableModelFilteringModel(RgIsaDisassemblyTableModel* source_model, QObject* parent = nullptr) + : QSortFilterProxyModel(parent) + , source_model_(source_model) + { + } ~RgIsaDisassemblyTableModelFilteringModel() = default; protected: // A column-filtering predicate. - virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override + virtual bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const override { Q_UNUSED(source_parent); @@ -57,8 +65,8 @@ class RgIsaDisassemblyTableModelFilteringModel : public QSortFilterProxyModel RgIsaDisassemblyTableModel* source_model_ = nullptr; }; -RgIsaDisassemblyTableView::RgIsaDisassemblyTableView(QWidget* parent) : - QWidget(parent) +RgIsaDisassemblyTableView::RgIsaDisassemblyTableView(QWidget* parent) + : QWidget(parent) { ui_.setupUi(this); @@ -82,6 +90,12 @@ RgIsaDisassemblyTableView::RgIsaDisassemblyTableView(QWidget* parent) : // Allow the last column to stretch. ui_.instructionsTreeView->header()->setStretchLastSection(true); + // Set style for the tooltip background color. + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + setStyleSheet(kStyleSheetText[color_theme]); + connect( + &QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgIsaDisassemblyTableView::HandleColorThemeChanged); + // Initialize the context menu. InitializeContextMenu(); @@ -126,7 +140,7 @@ void RgIsaDisassemblyTableView::InitializeModelData() } bool RgIsaDisassemblyTableView::LoadDisassembly(const std::string& disassembly_csv_file_path) - { +{ is_disassembly_cached_ = isa_table_model_->PopulateFromCsvFile(disassembly_csv_file_path); if (is_disassembly_cached_) @@ -150,7 +164,7 @@ bool RgIsaDisassemblyTableView::LoadLiveVgpr(const std::string& live_vgpr_file_p if (is_live_vgpr_cached_) { - // Cache the path to the live Vgprs file being loaded. + // Cache the path to the live Vgprs file being loaded. live_vgprs_file_path_ = live_vgpr_file_path; // Adjust the table column widths after populating with data. @@ -207,7 +221,7 @@ void RgIsaDisassemblyTableView::SetVgprColumnWidth() if (global_settings->visible_disassembly_view_columns[column_index]) { // Compare the header name for each column until the VGPR column is found. - QStandardItem* item = isa_table_model->horizontalHeaderItem(column_index); + QStandardItem* item = isa_table_model->horizontalHeaderItem(column_index); assert(item != nullptr); if (item != nullptr) { @@ -249,7 +263,7 @@ void RgIsaDisassemblyTableView::RequestTableResize() static const int kColumnPadding = 20; // Compute the ideal width of the table and emit a signal to readjust the view dimensions. - int min_width = QtCommon::QtUtils::ComputeMinimumTableWidth(ui_.instructionsTreeView, kMaxNumRows, kColumnPadding); + int min_width = QtCommon::QtUtils::ComputeMinimumTableWidth(ui_.instructionsTreeView, kMaxNumRows, kColumnPadding); emit DisassemblyTableWidthResizeRequested(min_width); } @@ -364,12 +378,12 @@ void RgIsaDisassemblyTableView::HandleCopyDisassemblyClicked() QVector selected_row_numbers; QItemSelectionModel* selection_model = ui_.instructionsTreeView->selectionModel(); - const QItemSelection selection = selection_model->selection(); + const QItemSelection selection = selection_model->selection(); if (!selection.isEmpty()) { // Get the selected line numbers. QItemSelectionModel* table_selection_model = ui_.instructionsTreeView->selectionModel(); - QModelIndexList selected_rows = table_selection_model->selectedRows(); + QModelIndexList selected_rows = table_selection_model->selectedRows(); for (auto& current_index : selected_rows) { int row_index = current_index.row(); @@ -388,7 +402,7 @@ void RgIsaDisassemblyTableView::HandleOpenDisassemblyInFileBrowserClicked() { // Use the path to the loaded CSV file to figure out which folder to open. std::string build_output_directory; - bool is_ok = RgUtils::ExtractFileDirectory(disassembly_file_path_, build_output_directory); + bool is_ok = RgUtils::ExtractFileDirectory(disassembly_file_path_, build_output_directory); assert(is_ok); if (is_ok) { @@ -422,8 +436,8 @@ void RgIsaDisassemblyTableView::HandleCurrentSelectionChanged(const QItemSelecti isa_table_model_->GetInputSourceLineNumberFromInstructionRow(first_selected_row_index, input_source_line_number); // Did the user select a line that isn't currently highlighted? - const std::vector& indices = isa_table_model_->GetCorrelatedLineIndices(); - auto correlated_lines_iter = std::find(indices.begin(), indices.end(), first_selected_row_index); + const std::vector& indices = isa_table_model_->GetCorrelatedLineIndices(); + auto correlated_lines_iter = std::find(indices.begin(), indices.end(), first_selected_row_index); if (correlated_lines_iter == indices.end()) { // Invalidate the currently highlighted lines. @@ -431,7 +445,7 @@ void RgIsaDisassemblyTableView::HandleCurrentSelectionChanged(const QItemSelecti } // Do the instruction lines in the selected block all contiguously map to the same input source file line? - int correlated_line_index = kInvalidCorrelationLineIndex; + int correlated_line_index = kInvalidCorrelationLineIndex; bool is_contiguous_block_selected = IsContiguousCorrelatedRangeSelected(correlated_line_index); if (is_contiguous_block_selected) @@ -461,6 +475,12 @@ void RgIsaDisassemblyTableView::HandleOpenContextMenu(const QPoint& widget_click context_menu_->exec(click_point); } +void RgIsaDisassemblyTableView::HandleColorThemeChanged() +{ + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + setStyleSheet(kStyleSheetText[color_theme]); +} + void RgIsaDisassemblyTableView::ConnectContextMenuSignals() { // Connect the handler responsible for triggering a copy to clipboard from the table. @@ -499,31 +519,40 @@ void RgIsaDisassemblyTableView::ConnectSelectionSignals() void RgIsaDisassemblyTableView::ConnectSignals() { // Connect the disassembly table's focus in signal. - bool is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FrameFocusInSignal, this, &RgIsaDisassemblyTableView::FrameFocusInSignal); + bool is_connected = + connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FrameFocusInSignal, this, &RgIsaDisassemblyTableView::FrameFocusInSignal); assert(is_connected); // Connect the disassembly table's focus out signal. - is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FrameFocusOutSignal, this, &RgIsaDisassemblyTableView::FrameFocusOutSignal); + is_connected = + connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FrameFocusOutSignal, this, &RgIsaDisassemblyTableView::FrameFocusOutSignal); assert(is_connected); // Connect the disassembly table view's enable scroll bar signal. - is_connected = connect(this, &RgIsaDisassemblyTableView::EnableScrollbarSignals, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::EnableScrollbarSignals); + is_connected = + connect(this, &RgIsaDisassemblyTableView::EnableScrollbarSignals, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::EnableScrollbarSignals); assert(is_connected); // Connect the disassembly table view's disable scroll bar signal. - is_connected = connect(this, &RgIsaDisassemblyTableView::DisableScrollbarSignals, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::DisableScrollbarSignals); + is_connected = + connect(this, &RgIsaDisassemblyTableView::DisableScrollbarSignals, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::DisableScrollbarSignals); assert(is_connected); // Connect the disassembly table's target GPU push button focus in signal. - is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusTargetGpuPushButton, this, &RgIsaDisassemblyTableView::FocusTargetGpuPushButton); + is_connected = connect( + ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusTargetGpuPushButton, this, &RgIsaDisassemblyTableView::FocusTargetGpuPushButton); assert(is_connected); // Connect the disassembly table's target GPU push button focus in signal. - is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::SwitchDisassemblyContainerSize, this, &RgIsaDisassemblyTableView::SwitchDisassemblyContainerSize); + is_connected = connect(ui_.instructionsTreeView, + &RgIsaDisassemblyCustomTableView::SwitchDisassemblyContainerSize, + this, + &RgIsaDisassemblyTableView::SwitchDisassemblyContainerSize); assert(is_connected); // Connect the disassembly table's columns push button focus in signal. - is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusColumnPushButton, this, &RgIsaDisassemblyTableView::FocusColumnPushButton); + is_connected = + connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusColumnPushButton, this, &RgIsaDisassemblyTableView::FocusColumnPushButton); assert(is_connected); // Connect the disassembly table's source window focus in signal. @@ -531,11 +560,13 @@ void RgIsaDisassemblyTableView::ConnectSignals() assert(is_connected); // Connect the disassembly table view's update current sub widget signal. - is_connected = connect(this, &RgIsaDisassemblyTableView::UpdateCurrentSubWidget, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::HandleUpdateCurrentSubWidget); + is_connected = connect( + this, &RgIsaDisassemblyTableView::UpdateCurrentSubWidget, ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::HandleUpdateCurrentSubWidget); assert(is_connected); // Connect the disassembly table's focus cli output window signal. - is_connected = connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusCliOutputWindow, this, &RgIsaDisassemblyTableView::FocusCliOutputWindow); + is_connected = + connect(ui_.instructionsTreeView, &RgIsaDisassemblyCustomTableView::FocusCliOutputWindow, this, &RgIsaDisassemblyTableView::FocusCliOutputWindow); assert(is_connected); } @@ -544,7 +575,7 @@ bool RgIsaDisassemblyTableView::GetSelectedRowRange(int& min_row, int& max_row) bool got_range = false; QItemSelectionModel* table_selection_model = ui_.instructionsTreeView->selectionModel(); - auto rows_selection = table_selection_model->selectedRows(); + auto rows_selection = table_selection_model->selectedRows(); if (!rows_selection.isEmpty()) { @@ -554,8 +585,8 @@ bool RgIsaDisassemblyTableView::GetSelectedRowRange(int& min_row, int& max_row) for (QModelIndex& current_index : rows_selection) { int row_index = current_index.row(); - min_row = (row_index < min_row) ? row_index : min_row; - max_row = (row_index > max_row) ? row_index : max_row; + min_row = (row_index < min_row) ? row_index : min_row; + max_row = (row_index > max_row) ? row_index : max_row; } got_range = true; @@ -614,17 +645,17 @@ void RgIsaDisassemblyTableView::InitializeLinkLabels() std::vector labelLinks; auto start_label = link_labels.begin(); - auto end_label = link_labels.end(); + auto end_label = link_labels.end(); for (auto labels_iter = start_label; labels_iter != end_label; ++labels_iter) { // Extract the line number and label text from the map. - int label_line_index = labels_iter->first; - std::string& label_text = labels_iter->second; + int label_line_index = labels_iter->first; + std::string& label_text = labels_iter->second; QStandardItemModel* table_model = isa_table_model_->GetTableModel(); // Compute the index in the table where the link needs to get inserted. - QModelIndex label_index = table_model->index(label_line_index, column_index); + QModelIndex label_index = table_model->index(label_line_index, column_index); QModelIndex filtered_index = isa_table_filtering_model_->mapFromSource(label_index); if (filtered_index.isValid()) @@ -666,8 +697,8 @@ bool RgIsaDisassemblyTableView::IsContiguousCorrelatedRangeSelected(int& correla bool is_non_contiguous = false; // Find the bounds of the selected row indices. - int min_row = 0; - int max_row = 0; + int min_row = 0; + int max_row = 0; bool got_range = GetSelectedRowRange(min_row, max_row); if (got_range) { @@ -675,8 +706,8 @@ bool RgIsaDisassemblyTableView::IsContiguousCorrelatedRangeSelected(int& correla int correlated_line = kInvalidCorrelationLineIndex; for (int selected_row_index = min_row; selected_row_index <= max_row; ++selected_row_index) { - int input_line_index = 0; - bool got_line = isa_table_model_->GetInputSourceLineNumberFromInstructionRow(selected_row_index, input_line_index); + int input_line_index = 0; + bool got_line = isa_table_model_->GetInputSourceLineNumberFromInstructionRow(selected_row_index, input_line_index); if (got_line) { if (correlated_line != kInvalidCorrelationLineIndex) @@ -684,14 +715,14 @@ bool RgIsaDisassemblyTableView::IsContiguousCorrelatedRangeSelected(int& correla if (input_line_index != correlated_line) { // The instruction was emitted due to a different input source line. This isn't a contiguous block. - is_non_contiguous = true; + is_non_contiguous = true; correlated_line_index = kInvalidCorrelationLineIndex; break; } } else { - correlated_line = input_line_index; + correlated_line = input_line_index; correlated_line_index = input_line_index; } } @@ -704,7 +735,7 @@ bool RgIsaDisassemblyTableView::IsContiguousCorrelatedRangeSelected(int& correla void RgIsaDisassemblyTableView::ScrollToLine(int line_number) { // Find the row of the index at the top left of the table. - int first_visible_row = 0; + int first_visible_row = 0; const QModelIndex first_visible_index = ui_.instructionsTreeView->indexAt(ui_.instructionsTreeView->rect().topLeft()); if (first_visible_index.isValid()) { @@ -724,7 +755,7 @@ void RgIsaDisassemblyTableView::ScrollToLine(int line_number) // If the line we're scrolling to is already visible within view, don't scroll the view. const int adjust_visible_row = kTableBottomMargin; - bool is_line_visible = (line_number >= first_visible_row) && (line_number <= last_visible_row - adjust_visible_row); + bool is_line_visible = (line_number >= first_visible_row) && (line_number <= last_visible_row - adjust_visible_row); if (!is_line_visible) { // Scroll the instruction table's vertical scrollbar to the given line. diff --git a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_view.cpp b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_view.cpp index 2088228..4fa028a 100644 --- a/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_isa_disassembly_view.cpp @@ -36,8 +36,8 @@ #include "radeon_gpu_analyzer_gui/rg_utils.h" // Names of special widgets within the disassembly view. -static const char* kStrDisassemblyColumnVisibilityList = "DisassemblyColumnVisibilityList"; -static const char* kStrDisassemblyColumnListItemCheckbox = "ListWidgetCheckBox"; +static const char* kStrDisassemblyColumnVisibilityList = "DisassemblyColumnVisibilityList"; +static const char* kStrDisassemblyColumnListItemCheckbox = "ListWidgetCheckBox"; static const char* kStrDisassemblyColumnListItemAllCheckbox = "ListWidgetAllCheckBox"; // Object name associated with the target GPU dropdown list. @@ -49,8 +49,8 @@ const int kPushButtonFontSize = 11; // Error message for missing live VGPR output file. const QString kStrLiveVgprFileMissingError = "Live VGPR output file missing."; -RgIsaDisassemblyView::RgIsaDisassemblyView(QWidget* parent) : - QWidget(parent) +RgIsaDisassemblyView::RgIsaDisassemblyView(QWidget* parent) + : QWidget(parent) { ui_.setupUi(this); @@ -95,14 +95,13 @@ RgIsaDisassemblyView::~RgIsaDisassemblyView() } } - void RgIsaDisassemblyView::ClearBuildOutput() { if (!gpu_tab_views_.empty()) { // Destroy all existing GPU tabs. auto first_gpu_tab = gpu_tab_views_.begin(); - auto last_gpu_tab = gpu_tab_views_.end(); + auto last_gpu_tab = gpu_tab_views_.end(); for (auto gpu_tab_iter = first_gpu_tab; gpu_tab_iter != last_gpu_tab; ++gpu_tab_iter) { ui_.disassemblyTableHostWidget->removeWidget(gpu_tab_iter->second); @@ -135,7 +134,10 @@ void RgIsaDisassemblyView::RemoveInputFileEntries(const std::string& input_file_ DestroyResourceUsageViewsForFile(input_file_path); } -void RgIsaDisassemblyView::HandleInputFileSelectedLineChanged(const std::string& target_gpu, const std::string& input_file_path, std::string& entry_name, int line_index) +void RgIsaDisassemblyView::HandleInputFileSelectedLineChanged(const std::string& target_gpu, + const std::string& input_file_path, + std::string& entry_name, + int line_index) { // Get the currently active stacked view. RgIsaDisassemblyTabView* current_tab_view = GetTargetGpuTabWidgetByTabName(target_gpu); @@ -147,7 +149,9 @@ void RgIsaDisassemblyView::HandleInputFileSelectedLineChanged(const std::string& } } -void RgIsaDisassemblyView::HandleSelectedEntrypointChanged(const std::string& target_gpu, const std::string& input_file_path, const std::string& selected_entrypoint_name) +void RgIsaDisassemblyView::HandleSelectedEntrypointChanged(const std::string& target_gpu, + const std::string& input_file_path, + const std::string& selected_entrypoint_name) { // Get the currently active stacked view. RgIsaDisassemblyTabView* target_tab_view = GetTargetGpuTabWidgetByTabName(target_gpu); @@ -210,14 +214,14 @@ void RgIsaDisassemblyView::HandleColumnVisibilityComboBoxItemClicked(QCheckBox* if (all_checked) { // All the items were checked, so disable the "All" option. - QListWidgetItem* all_item = ui_.columnVisibilityArrowPushButton->FindItem(0); - QCheckBox* all_check_box = (QCheckBox*)all_item->listWidget()->itemWidget(all_item); + QListWidgetItem* all_item = ui_.columnVisibilityArrowPushButton->FindItem(0); + QCheckBox* all_check_box = (QCheckBox*)all_item->listWidget()->itemWidget(all_item); all_check_box->setDisabled(true); } else { - QListWidgetItem* all_item = ui_.columnVisibilityArrowPushButton->FindItem(0); - QCheckBox* all_check_box = (QCheckBox*)all_item->listWidget()->itemWidget(all_item); + QListWidgetItem* all_item = ui_.columnVisibilityArrowPushButton->FindItem(0); + QCheckBox* all_check_box = (QCheckBox*)all_item->listWidget()->itemWidget(all_item); all_check_box->setDisabled(false); } @@ -304,15 +308,18 @@ void RgIsaDisassemblyView::HandleTargetGpuChanged() void RgIsaDisassemblyView::ConnectDisassemblyTabViewSignals(RgIsaDisassemblyTabView* entry_view) { // Connect the new disassembly GPU tab's source input file highlight line changed signal. - bool is_connected = connect(entry_view, &RgIsaDisassemblyTabView::InputSourceHighlightedLineChanged, this, &RgIsaDisassemblyView::InputSourceHighlightedLineChanged); + bool is_connected = + connect(entry_view, &RgIsaDisassemblyTabView::InputSourceHighlightedLineChanged, this, &RgIsaDisassemblyView::InputSourceHighlightedLineChanged); assert(is_connected); // Connect the disassembly table's resized event handler. - is_connected = connect(entry_view, &RgIsaDisassemblyTabView::DisassemblyTableWidthResizeRequested, this, &RgIsaDisassemblyView::DisassemblyTableWidthResizeRequested); + is_connected = + connect(entry_view, &RgIsaDisassemblyTabView::DisassemblyTableWidthResizeRequested, this, &RgIsaDisassemblyView::DisassemblyTableWidthResizeRequested); assert(is_connected); // Connect the disassembly view's column visibility updated signal. - is_connected = connect(this, &RgIsaDisassemblyView::DisassemblyColumnVisibilityUpdated, entry_view, &RgIsaDisassemblyTabView::HandleColumnVisibilityFilterStateChanged); + is_connected = connect( + this, &RgIsaDisassemblyView::DisassemblyColumnVisibilityUpdated, entry_view, &RgIsaDisassemblyTabView::HandleColumnVisibilityFilterStateChanged); assert(is_connected); // Connect the disassembly view's set frame border red signal. @@ -456,7 +463,8 @@ void RgIsaDisassemblyView::CreateTargetGpuListControls() ui_.targetGpuPushButton->InitSingleSelect(this, "Target GPU", false); // Connect the signal used to handle a change in the selected target GPU. - [[maybe_unused]] bool is_connected = connect(ui_.targetGpuPushButton, &ArrowIconComboBox::SelectionChanged, this, &RgIsaDisassemblyView::HandleTargetGpuChanged); + [[maybe_unused]] bool is_connected = + connect(ui_.targetGpuPushButton, &ArrowIconComboBox::SelectionChanged, this, &RgIsaDisassemblyView::HandleTargetGpuChanged); assert(is_connected); } @@ -476,7 +484,7 @@ QString RgIsaDisassemblyView::GetDisassemblyColumnName(RgIsaDisassemblyTableColu {RgIsaDisassemblyTableColumns::kFunctionalUnit, kStrDisassemblyTableColumnFunctionalUnit}, {RgIsaDisassemblyTableColumns::kCycles, kStrDisassemblyTableColumnCycles}, {RgIsaDisassemblyTableColumns::kBinaryEncoding, kStrDisassemblyTableColumnBinaryEncoding}, - { RgIsaDisassemblyTableColumns::kLiveVgprs, kStrDisassemblyTableLiveVgprHeaderPart}, + {RgIsaDisassemblyTableColumns::kLiveVgprs, kStrDisassemblyTableLiveVgprHeaderPart}, }; auto column_name_iter = kColumnNameMap.find(column); @@ -511,7 +519,7 @@ void RgIsaDisassemblyView::PopulateTargetGpuList(const RgBuildOutputsMap& build_ { // Get a mapping of the compute capability to architecture. std::map compute_capability_to_arch; - bool has_arch_mapping = RgUtils::GetComputeCapabilityToArchMapping(compute_capability_to_arch); + bool has_arch_mapping = RgUtils::GetComputeCapabilityToArchMapping(compute_capability_to_arch); // Block signals to stop updates when each new GPU is added to the list. ui_.targetGpuPushButton->blockSignals(true); @@ -532,7 +540,7 @@ void RgIsaDisassemblyView::PopulateTargetGpuList(const RgBuildOutputsMap& build_ // If applicable, prepend the gfx notation (for example, "gfx802/Tonga" for "Tonga"). std::string gfx_notation; - bool has_gfx_notation = RgUtils::GetGfxNotation(target_gpu, gfx_notation); + bool has_gfx_notation = RgUtils::GetGfxNotation(target_gpu, gfx_notation); if (has_gfx_notation && !gfx_notation.empty()) { presented_name << gfx_notation << "/"; @@ -557,13 +565,11 @@ void RgIsaDisassemblyView::PopulateTargetGpuList(const RgBuildOutputsMap& build_ assert(!targets.empty()); // Sort and choose the latest target. - std::sort(targets.begin(), - targets.end(), [&](const std::string& a, const std::string& b) - { + std::sort(targets.begin(), targets.end(), [&](const std::string& a, const std::string& b) { const char* kGfxNotationToken = "gfx"; - bool ret = true; - size_t sz_a = a.find(kGfxNotationToken); - size_t sz_b = b.find(kGfxNotationToken); + bool ret = true; + size_t sz_a = a.find(kGfxNotationToken); + size_t sz_b = b.find(kGfxNotationToken); if (sz_a == std::string::npos && sz_b == std::string::npos) { // Neither name is in gfx-notation, compare using standard string logic. @@ -585,16 +591,16 @@ void RgIsaDisassemblyView::PopulateTargetGpuList(const RgBuildOutputsMap& build_ assert(split_b.size() > 1); if (split_a.size() > 1 && split_b.size() > 1) { - try - { - int numA = std::stoi(split_a[1], nullptr, 16); - int numB = std::stoi(split_b[1], nullptr, 16); - ret = ((numB - numA) > 0); - } - catch (...) - { - ret = false; - } + try + { + int numA = std::stoi(split_a[1], nullptr, 16); + int numB = std::stoi(split_b[1], nullptr, 16); + ret = ((numB - numA) > 0); + } + catch (...) + { + ret = false; + } } } return !ret; @@ -624,7 +630,7 @@ bool RgIsaDisassemblyView::PopulateDisassemblyEntries(const GpuToEntryVector& gp // Step through each GPU and insert a new RgIsaDisassemblyTabView into a new tab. for (auto gpu_entry_iter = gpu_to_disassembly_csv_entries.begin(); gpu_entry_iter != gpu_to_disassembly_csv_entries.end(); ++gpu_entry_iter) { - const std::string& gpu_name = gpu_entry_iter->first; + const std::string& gpu_name = gpu_entry_iter->first; const std::vector& gpu_entries = gpu_entry_iter->second; // Does a tab already exist for the target GPU we're loading results for? @@ -670,7 +676,7 @@ bool RgIsaDisassemblyView::PopulateResourceUsageEntries(const GpuToEntryVector& // Step through each GPU and insert a new RgResourceView underneath the disassembly table. for (auto gpu_entry_iter = gpu_to_resource_usage_csv_entries.begin(); gpu_entry_iter != gpu_to_resource_usage_csv_entries.end(); ++gpu_entry_iter) { - const std::string& gpu_name = gpu_entry_iter->first; + const std::string& gpu_name = gpu_entry_iter->first; const std::vector& gpu_entries = gpu_entry_iter->second; // Create a resource usage disassembly table for each entry, and add it to the layout. @@ -678,7 +684,7 @@ bool RgIsaDisassemblyView::PopulateResourceUsageEntries(const GpuToEntryVector& for (const RgEntryOutput& entry : gpu_entries) { OutputFileTypeFinder outputFileTypeSearcher(RgCliOutputFileType::kHwResourceUsageFile); - auto csv_file_iter = std::find_if(entry.outputs.begin(), entry.outputs.end(), outputFileTypeSearcher); + auto csv_file_iter = std::find_if(entry.outputs.begin(), entry.outputs.end(), outputFileTypeSearcher); if (csv_file_iter != entry.outputs.end()) { // Create a CSV parser to read the resource usage file. @@ -686,12 +692,12 @@ bool RgIsaDisassemblyView::PopulateResourceUsageEntries(const GpuToEntryVector& // Attempt to parse the file. std::string parse_error_string; - bool parsed_successfully = resource_usage_file_parser.Parse(parse_error_string); + bool parsed_successfully = resource_usage_file_parser.Parse(parse_error_string); if (parsed_successfully) { // Extract the parsed data, and populate the resource usage view. const RgResourceUsageData& resource_usage_data = resource_usage_file_parser.GetData(); - RgResourceUsageView* resource_usage_view = new RgResourceUsageView(); + RgResourceUsageView* resource_usage_view = new RgResourceUsageView(); resource_usage_view->PopulateView(resource_usage_data); resource_usage_text_ = resource_usage_view->GetResourceUsageText(); resource_usage_font_ = resource_usage_view->GetResourceUsageFont(); @@ -761,14 +767,15 @@ void RgIsaDisassemblyView::PopulateColumnVisibilityList() { // Add an item for each possible column in the table. QString column_name = GetDisassemblyColumnName(static_cast(column_index)); - bool is_checked = global_settings->visible_disassembly_view_columns[column_index]; + bool is_checked = global_settings->visible_disassembly_view_columns[column_index]; QCheckBox* check_box = ui_.columnVisibilityArrowPushButton->AddCheckboxItem(column_name, column_index, is_checked, false); // Set list widget's check box's focus proxy to be the frame. SetCheckBoxFocusProxies(check_box); } - bool is_connected = connect(ui_.columnVisibilityArrowPushButton, &ArrowIconComboBox::CheckboxChanged, this, &RgIsaDisassemblyView::HandleColumnVisibilityComboBoxItemClicked); + bool is_connected = connect( + ui_.columnVisibilityArrowPushButton, &ArrowIconComboBox::CheckboxChanged, this, &RgIsaDisassemblyView::HandleColumnVisibilityComboBoxItemClicked); Q_ASSERT(is_connected); UpdateAllCheckBox(); @@ -842,7 +849,7 @@ void RgIsaDisassemblyView::DestroyDisassemblyViewsForFile(const std::string& inp // Step through each GPU tab and try to remove the entries associated with the given input file. auto start_tab = gpu_tab_views_.begin(); - auto end_tab = gpu_tab_views_.end(); + auto end_tab = gpu_tab_views_.end(); for (auto tab_iter = start_tab; tab_iter != end_tab; ++tab_iter) { // Search the tab for entries to remove. @@ -887,8 +894,8 @@ void RgIsaDisassemblyView::DestroyResourceUsageViewsForFile(const std::string& i for (auto gpu_iter = gpu_resource_usage_views_.begin(); gpu_iter != gpu_resource_usage_views_.end(); ++gpu_iter) { // Find all resource views related to the given input file. - InputToEntrypointViews& input_file_to_views_iter = gpu_iter->second; - auto entrypoint_resource_usageviews_iter = input_file_to_views_iter.find(input_file_path); + InputToEntrypointViews& input_file_to_views_iter = gpu_iter->second; + auto entrypoint_resource_usageviews_iter = input_file_to_views_iter.find(input_file_path); if (entrypoint_resource_usageviews_iter != input_file_to_views_iter.end()) { // Step through each entrypoint's resource usage view, and destroy it. @@ -1039,7 +1046,10 @@ void RgIsaDisassemblyView::ConnectTitleBarDoubleClick(const RgViewContainer* dis assert(disassembly_view_container != nullptr); if (disassembly_view_container != nullptr) { - [[maybe_unused]] bool is_connected = connect(ui_.viewTitlebar, &RgIsaDisassemblyViewTitlebar::ViewTitleBarDoubleClickedSignal, disassembly_view_container, &RgViewContainer::MaximizeButtonClicked); + [[maybe_unused]] bool is_connected = connect(ui_.viewTitlebar, + &RgIsaDisassemblyViewTitlebar::ViewTitleBarDoubleClickedSignal, + disassembly_view_container, + &RgViewContainer::MaximizeButtonClicked); assert(is_connected); } } @@ -1065,7 +1075,7 @@ bool RgIsaDisassemblyView::ReplaceInputFilePath(const std::string& old_file_path for (auto& gpu_and_resource_usage : gpu_resource_usage_views_) { auto& file_and_resource_usage = gpu_and_resource_usage.second; - auto it = file_and_resource_usage.find(old_file_path); + auto it = file_and_resource_usage.find(old_file_path); if ((result = (it != file_and_resource_usage.end())) == true) { std::map resUsageView = it->second; diff --git a/source/radeon_gpu_analyzer_gui/rg_label.cpp b/source/radeon_gpu_analyzer_gui/rg_label.cpp index 9a785fb..e964bae 100644 --- a/source/radeon_gpu_analyzer_gui/rg_label.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_label.cpp @@ -59,7 +59,7 @@ void RgLabel::paintEvent(QPaintEvent* event) // Set properties for the text. QPen pen; - pen.setColor(Qt::black); + pen.setColor(QtCommon::QtUtils::ColorTheme::Get().GetCurrentThemeColors().graphics_scene_text_color); pen.setWidth(1); painter.setPen(pen); diff --git a/source/radeon_gpu_analyzer_gui/rg_main_window.cpp b/source/radeon_gpu_analyzer_gui/rg_main_window.cpp index 0f02283..cb14f5d 100644 --- a/source/radeon_gpu_analyzer_gui/rg_main_window.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_main_window.cpp @@ -53,7 +53,7 @@ RgMainWindow::RgMainWindow(QWidget* parent) { // Get the startup mode. RgConfigManager& config_manager = RgConfigManager::Instance(); - RgProjectAPI current_api = config_manager.GetCurrentAPI(); + RgProjectAPI current_api = config_manager.GetCurrentAPI(); // We must have a known mode at startup. assert(current_api != RgProjectAPI::kUnknown); @@ -67,19 +67,9 @@ RgMainWindow::RgMainWindow(QWidget* parent) // Set the window icon to the product logo. setWindowIcon(QIcon(kIconResourceRgaLogo)); - // Set the background color to white. - this->setAutoFillBackground(true); - qApp->setPalette(QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette()); - - // Install the event filter. installEventFilter(this); - // Set the status bar message's font color to white. - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::GlobalColor::white); - statusBar()->setPalette(palette); - // Declare DisassemblyViewSubWidgets as a meta type so it can be used with slots/signals. int id = qRegisterMetaType(); Q_UNUSED(id); @@ -106,6 +96,9 @@ void RgMainWindow::InitMainWindow() // Increase the double click interval as the default one is too quick. const int doubleClickInterval = qApp->doubleClickInterval(); qApp->setDoubleClickInterval(doubleClickInterval * 2); + + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgMainWindow::SetApplicationStylesheet); + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgMainWindow::ApplyMainWindowStylesheet); } void RgMainWindow::ConnectSignals() @@ -161,7 +154,8 @@ void RgMainWindow::CreateSettingsTab() ui_.settingsTab->layout()->addWidget(settings_tab_); // Handle when the Settings tab signals that it has pending changes. - bool is_connected = connect(settings_tab_, &RgSettingsTab::PendingChangesStateChanged, this, &RgMainWindow::HandleHasSettingsPendingStateChanged); + bool is_connected = + connect(settings_tab_, &RgSettingsTab::PendingChangesStateChanged, this, &RgMainWindow::HandleHasSettingsPendingStateChanged); assert(is_connected); Q_UNUSED(is_connected); } @@ -300,7 +294,8 @@ void RgMainWindow::ConnectBuildViewSignals() if (build_view != nullptr) { // Editor text change handler. - bool is_connected = connect(build_view, &RgBuildView::CurrentEditorModificationStateChanged, this, &RgMainWindow::OnCurrentEditorModificationStateChanged); + bool is_connected = + connect(build_view, &RgBuildView::CurrentEditorModificationStateChanged, this, &RgMainWindow::OnCurrentEditorModificationStateChanged); assert(is_connected); // Connect the project count changed signal. @@ -328,7 +323,8 @@ void RgMainWindow::ConnectBuildViewSignals() assert(is_connected); // Connect the update application notification message signal. - is_connected = connect(build_view, &RgBuildView::UpdateApplicationNotificationMessageSignal, this, &RgMainWindow::HandleUpdateAppNotificationMessage); + is_connected = + connect(build_view, &RgBuildView::UpdateApplicationNotificationMessageSignal, this, &RgMainWindow::HandleUpdateAppNotificationMessage); assert(is_connected); // Connect the project build failure signal. @@ -390,7 +386,7 @@ void RgMainWindow::HandleEnablePipelineMenuItem(bool is_enabled) void RgMainWindow::HandleEnableBuildSettingsMenuItem(bool is_enabled) { - // Update the Build menu item for "Build settings". + // Update the Build menu item for "Build settings". build_settings_action_->setEnabled(is_enabled); } @@ -793,7 +789,7 @@ bool RgMainWindow::OpenProjectFileAtPath(const std::string& project_file_path) // Read the project file to determine the project's API. The GUI's current mode may have to // be changed to match the API used by the project. std::shared_ptr project = nullptr; - is_project_loaded = RgXmlConfigFile::ReadProjectConfigFile(project_file_path, project); + is_project_loaded = RgXmlConfigFile::ReadProjectConfigFile(project_file_path, project); assert(is_project_loaded); assert(project != nullptr); @@ -863,7 +859,7 @@ bool RgMainWindow::OpenProjectFileAtPath(const std::string& project_file_path) // Destroy the RgBuildView instance since the project is not being opened. DestroyBuildView(); - // Reset the window title. + // Reset the window title. ResetWindowTitle(); // Reset the status bar. @@ -884,9 +880,9 @@ void RgMainWindow::SetWindowTitle(const std::string& title_text) window_title << kStrAppName << " - "; // Determine which API is being used. - std::string api_name; + std::string api_name; RgProjectAPI project_api = RgConfigManager::Instance().GetCurrentAPI(); - bool is_ok = RgUtils::ProjectAPIToString(project_api, api_name, false); + bool is_ok = RgUtils::ProjectAPIToString(project_api, api_name, false); assert(is_ok); if (is_ok) { @@ -907,9 +903,9 @@ void RgMainWindow::ResetWindowTitle() window_title << kStrAppName; // Determine which API is being used. - std::string api_name; + std::string api_name; RgProjectAPI project_api = RgConfigManager::Instance().GetCurrentAPI(); - bool is_ok = RgUtils::ProjectAPIToString(project_api, api_name, false); + bool is_ok = RgUtils::ProjectAPIToString(project_api, api_name, false); assert(is_ok); if (is_ok) { @@ -949,8 +945,7 @@ void RgMainWindow::HandleProjectFileCountChanged(bool is_project_empty) // the pipeline state items are enabled, since we are in a project (and not in the home page). build_settings_action_->setEnabled(true); assert(app_state_ != nullptr); - if (app_state_ != nullptr && app_state_->IsGraphics() && - pipeline_state_action_ != nullptr) + if (app_state_ != nullptr && app_state_->IsGraphics() && pipeline_state_action_ != nullptr) { pipeline_state_action_->setEnabled(true); } @@ -1025,7 +1020,6 @@ void RgMainWindow::HandleOpenProjectFileEvent() if (!IsInputFileNameBlank()) { - assert(settings_tab_ != nullptr); if (settings_tab_ != nullptr) { @@ -1042,11 +1036,11 @@ void RgMainWindow::HandleOpenProjectFileEvent() if (did_uesr_confirm) { std::string selected_file; - bool is_ok = RgUtils::OpenProjectDialog(this, selected_file); + bool is_ok = RgUtils::OpenProjectDialog(this, selected_file); // Verify that the project name is valid. std::string error_string; - bool is_valid_project_name = RgUtils::IsValidProjectName(selected_file, error_string); + bool is_valid_project_name = RgUtils::IsValidProjectName(selected_file, error_string); if (is_valid_project_name && is_ok && !selected_file.empty()) { // Destroy current BuildView if it has some project open. @@ -1077,7 +1071,7 @@ void RgMainWindow::HandleOpenProjectFileEvent() { // Display error message box. std::stringstream msg; - std::string filename; + std::string filename; msg << error_string << " \""; RgUtils::ExtractFileName(selected_file, filename, false); msg << filename << "\"."; @@ -1201,8 +1195,8 @@ void RgMainWindow::HandleBackToHomeEvent() void RgMainWindow::HandleExitEvent() { - static const int kTopMargin = 8; - bool is_save_settings_accepted = true; + static const int kTopMargin = 8; + bool is_save_settings_accepted = true; // Prompt the user to save any pending changes on SETTINGS tab. @@ -1227,7 +1221,8 @@ void RgMainWindow::HandleExitEvent() if (is_accepted && is_save_settings_accepted) { // Save the window geometry. - RgConfigManager::Instance().SetWindowGeometry(pos().x(), pos().y() + statusBar()->height() + kTopMargin, size().width(), size().height(), windowState()); + RgConfigManager::Instance().SetWindowGeometry( + pos().x(), pos().y() + statusBar()->height() + kTopMargin, size().width(), size().height(), windowState()); QApplication::exit(0); } @@ -1237,9 +1232,9 @@ void RgMainWindow::HandleExitEvent() // Exit out of the application only if the user did NOT press cancel. if (is_save_settings_accepted) { - // Save the window geometry. - RgConfigManager::Instance().SetWindowGeometry(pos().x(), pos().y() + statusBar()->height() + kTopMargin, size().width(), size().height(), windowState()); + RgConfigManager::Instance().SetWindowGeometry( + pos().x(), pos().y() + statusBar()->height() + kTopMargin, size().width(), size().height(), windowState()); QApplication::exit(0); } @@ -1288,7 +1283,7 @@ void RgMainWindow::dragEnterEvent(QDragEnterEvent* event) } } -void RgMainWindow::dropEvent(QDropEvent *event) +void RgMainWindow::dropEvent(QDropEvent* event) { // Get list of all file urls. QList file_urls = event->mimeData()->urls(); @@ -1298,7 +1293,7 @@ void RgMainWindow::dropEvent(QDropEvent *event) { // Verify that the project file name is valid. std::string error_message; - bool is_project_file_valid = RgUtils::IsValidProjectName(file_urls.at(0).toLocalFile().toStdString(), error_message); + bool is_project_file_valid = RgUtils::IsValidProjectName(file_urls.at(0).toLocalFile().toStdString(), error_message); if (is_project_file_valid) { bool is_load_successful = OpenProjectFileAtPath(file_urls.at(0).toLocalFile().toStdString()); @@ -1326,12 +1321,12 @@ void RgMainWindow::dropEvent(QDropEvent *event) { // Convert url list to a string list of local file paths. QStringList filename_strings; - bool is_file_valid = false; + bool is_file_valid = false; for (QUrl& file_url : file_urls) { if (file_url.isLocalFile()) { - QString filename = file_url.toLocalFile(); + QString filename = file_url.toLocalFile(); std::string error_message; is_file_valid = RgUtils::IsSourceFileTypeValid(filename.toStdString()); // Filter out all files that aren't valid source files. @@ -1390,8 +1385,8 @@ void RgMainWindow::HandleGettingStartedGuideEvent() { // Build the path to the quickstart guide document. static const char* QUICKSTART_GUIDE_RELATIVE_PATH = "/help/rga/quickstart.html"; - QString quickstart_file_path = "file:///"; - QString app_dir_path = qApp->applicationDirPath(); + QString quickstart_file_path = "file:///"; + QString app_dir_path = qApp->applicationDirPath(); quickstart_file_path.append(app_dir_path); quickstart_file_path.append(QUICKSTART_GUIDE_RELATIVE_PATH); QDesktopServices::openUrl(QUrl(quickstart_file_path, QUrl::TolerantMode)); @@ -1401,8 +1396,8 @@ void RgMainWindow::HandleHelpManual() { // Build the path to the help manual document. static const char* HELP_MANUAL_RELATIVE_PATH = "/help/rga/help_manual.html"; - QString help_manual_file_path = "file:///"; - QString app_dir_path = qApp->applicationDirPath(); + QString help_manual_file_path = "file:///"; + QString app_dir_path = qApp->applicationDirPath(); help_manual_file_path.append(app_dir_path); help_manual_file_path.append(HELP_MANUAL_RELATIVE_PATH); QDesktopServices::openUrl(QUrl(help_manual_file_path, QUrl::TolerantMode)); @@ -1447,7 +1442,6 @@ void RgMainWindow::HandleBuildSettingsEvent() // Enable the Build menu item for "Build settings". build_settings_action_->setEnabled(false); - } } @@ -1490,8 +1484,7 @@ void RgMainWindow::HandlePipelineStateEvent() assert(app_state_ != nullptr); if (app_state_ != nullptr) { - std::shared_ptr graphics_app_state = - std::static_pointer_cast(app_state_); + std::shared_ptr graphics_app_state = std::static_pointer_cast(app_state_); assert(graphics_app_state != nullptr); if (graphics_app_state != nullptr) @@ -1564,8 +1557,7 @@ void RgMainWindow::HandleProjectLoaded(std::shared_ptr project) build_project_action_->setEnabled(false); build_settings_action_->setEnabled(true); assert(app_state_ != nullptr); - if (app_state_ != nullptr && app_state_->IsGraphics() && - pipeline_state_action_ != nullptr) + if (app_state_ != nullptr && app_state_->IsGraphics() && pipeline_state_action_ != nullptr) { pipeline_state_action_->setEnabled(true); } @@ -1597,8 +1589,7 @@ void RgMainWindow::HandleFocusNextWidget() while (test_widget != nullptr) { // Check that the widget accepts focus and is visible to the current focus widget. - if (test_widget->focusPolicy() != Qt::NoFocus && - test_widget->isVisibleTo(focus_widget)) + if (test_widget->focusPolicy() != Qt::NoFocus && test_widget->isVisibleTo(focus_widget)) { focus_widget = test_widget; break; @@ -1626,8 +1617,7 @@ void RgMainWindow::HandleFocusPrevWidget() while (test_widget != nullptr) { // Check that the widget accepts focus and is visible to the current focus widget. - if (test_widget->focusPolicy() != Qt::NoFocus && - test_widget->isVisibleTo(focus_widget)) + if (test_widget->focusPolicy() != Qt::NoFocus && test_widget->isVisibleTo(focus_widget)) { focus_widget = test_widget; break; @@ -1684,7 +1674,7 @@ void RgMainWindow::ResetViewStateAfterBuild() build_project_action_->setEnabled(false); build_settings_action_->setEnabled(false); cancel_build_action_->setEnabled(false); - + go_to_line_action_->setEnabled(false); find_action_->setEnabled(false); @@ -1704,7 +1694,7 @@ void RgMainWindow::ResetViewStateAfterBuild() { pipeline_state_action_->setEnabled(true); } - } + } assert(app_state_ != nullptr); if (app_state_ != nullptr) @@ -1775,8 +1765,7 @@ void RgMainWindow::HandleProjectBuildStarted() // Do not allow going to the build settings or pipeline state view. build_settings_action_->setEnabled(false); assert(app_state_ != nullptr); - if (app_state_ != nullptr && app_state_->IsGraphics() && - pipeline_state_action_ != nullptr) + if (app_state_ != nullptr && app_state_->IsGraphics() && pipeline_state_action_ != nullptr) { pipeline_state_action_->setEnabled(false); } @@ -1868,8 +1857,8 @@ void RgMainWindow::CreateAppNotificationMessageLabel(const std::string& message, app_notification_widget_->setToolTip(QString::fromStdString(tooltip)); // Create icon and text labels. - QIcon* icon = new QIcon(kIconResourceRemoveNotification); - QPixmap pixmap = icon->pixmap(QSize(24, 24)); + QIcon* icon = new QIcon(kIconResourceRemoveNotification); + QPixmap pixmap = icon->pixmap(QSize(24, 24)); QLabel* icon_label = new QLabel(app_notification_widget_); icon_label->setPixmap(pixmap); QLabel* text_label = new QLabel(QString::fromStdString(message), app_notification_widget_); @@ -2265,7 +2254,7 @@ bool RgMainWindow::eventFilter(QObject* object, QEvent* event) } else if (event->type() == QEvent::KeyPress) { - QKeyEvent* key_event = static_cast(event); + QKeyEvent* key_event = static_cast(event); Qt::KeyboardModifiers keyboard_modifiers = QApplication::keyboardModifiers(); if ((key_event->key() != Qt::Key_Up) && (key_event->key() != Qt::Key_Down)) { @@ -2298,8 +2287,7 @@ bool RgMainWindow::eventFilter(QObject* object, QEvent* event) bool RgMainWindow::LoadBinaryCodeObject(const QString filename) { QStringList filename_strings; - bool is_file_valid = RgUtils::IsFileExists(filename.toStdString()) && - RgUtils::IsSourceFileTypeValid(filename.toStdString()); + bool is_file_valid = RgUtils::IsFileExists(filename.toStdString()) && RgUtils::IsSourceFileTypeValid(filename.toStdString()); if (is_file_valid) { filename_strings.push_back(filename); diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_binary.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_binary.cpp index 6b65bda..d337c94 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_binary.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_binary.cpp @@ -20,7 +20,7 @@ #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -static const char* kStrButtonFocusInStylesheetBinary = "QPushButton { background: rgb(253,255,174); border: 2px inset rgb(128, 0, 128); }"; +static const char* kStrButtonFocusInStylesheetBinary = "QPushButton { background: palette(highlight); border: 2px inset rgb(128, 0, 128); }"; RgMenuBinary::RgMenuBinary(QWidget* parent) : RgMenu(parent) diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_build_settings_item.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_build_settings_item.cpp index fb1c849..d3ec5ba 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_build_settings_item.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_build_settings_item.cpp @@ -5,16 +5,20 @@ // Qt. #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/qt/rg_menu_build_settings_item.h" -static const char* kStrButtonFocusInStylesheetGraphics = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* kStrButtonFocusOutStylesheet = "QPushButton { margin: 1px; background: rgb(214, 214, 214);}"; -static const char* kStrBuildSettingsButtonName = "buildSettingsButton"; +static const char* kStrButtonFocusInStylesheetGraphics = + "QPushButton { background: palette(highlight); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; +static const char* kStrButtonFocusOutStylesheet = "QPushButton {background: palette(button); margin: 1px; }"; +static const char* kStrBuildSettingsButtonName = "buildSettingsButton"; -RgMenuBuildSettingsItem::RgMenuBuildSettingsItem(RgMenu* parent, QString tooltip) : - RgMenuItem(parent) +RgMenuBuildSettingsItem::RgMenuBuildSettingsItem(RgMenu* parent, QString tooltip) + : RgMenuItem(parent) { ui_.setupUi(this); @@ -24,6 +28,13 @@ RgMenuBuildSettingsItem::RgMenuBuildSettingsItem(RgMenu* parent, QString tooltip // Set the tool tip. this->setToolTip(tooltip); + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + + if (color_theme == kColorThemeTypeDark) + { + ui_.buildSettingsButton->setIcon(QIcon(":/icons/gear_icon_white.svg")); + } + // Set the mouse cursor to pointing hand cursor. SetCursor(Qt::PointingHandCursor); diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_file_item_graphics.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_file_item_graphics.cpp index acdfe18..672c185 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_file_item_graphics.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_file_item_graphics.cpp @@ -8,6 +8,9 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_menu_file_item_graphics.h" #include "radeon_gpu_analyzer_gui/qt/rg_menu_graphics.h" @@ -16,7 +19,8 @@ #include "radeon_gpu_analyzer_gui/rg_utils_graphics.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -static const char* kStrSubButtonNoFocusStylesheet = "rgMenuFileItemGraphics #addFilePushButton:hover\ +static const char* kStrSubButtonNoFocusStylesheet = + "rgMenuFileItemGraphics #addFilePushButton:hover\ { \ border-style: solid;\ border-width: 2px;\ @@ -28,7 +32,7 @@ border-style: solid;\ border-width: 2px;\ border-color: rgb(135,20,16)}"; static const char* kStrSubButtonInFocusStylesheet = "border: 2px inset rgb(135, 20, 16);"; -static const char* kStrFileMenuItemNameGraphics = "fileMenuItemGraphics"; +static const char* kStrFileMenuItemNameGraphics = "fileMenuItemGraphics"; RgMenuFileItemGraphics::RgMenuFileItemGraphics(RgMenu* parent, RgPipelineStage stage) : RgMenuFileItem("", parent) @@ -36,6 +40,13 @@ RgMenuFileItemGraphics::RgMenuFileItemGraphics(RgMenu* parent, RgPipelineStage s { ui_.setupUi(this); + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + + if (color_theme == kColorThemeTypeDark) + { + ui_.addFilePushButton->setIcon(QIcon(":/icons/add_file_icon_dark_mode.svg")); + } + // Disable the renaming controls upon creation. ShowRenameControls(false); @@ -177,7 +188,7 @@ void RgMenuFileItemGraphics::RemoveContextMenuActionRestoreSpv() void RgMenuFileItemGraphics::SetStringConstants() { // Create a utility class instance based on the current API. It will be used to display API-specific shader stage names. - RgProjectAPI current_api = RgConfigManager::Instance().GetCurrentAPI(); + RgProjectAPI current_api = RgConfigManager::Instance().GetCurrentAPI(); std::shared_ptr graphics_util = RgUtilsGraphics::CreateUtility(current_api); assert(graphics_util != nullptr); @@ -220,7 +231,7 @@ void RgMenuFileItemGraphics::SetStringConstants() void RgMenuFileItemGraphics::UpdateFilenameLabelText() { // Create a utility class instance based on the current API. It will be used to display API-specific shader stage names. - RgProjectAPI current_api = RgConfigManager::Instance().GetCurrentAPI(); + RgProjectAPI current_api = RgConfigManager::Instance().GetCurrentAPI(); std::shared_ptr graphics_util = RgUtilsGraphics::CreateUtility(current_api); assert(graphics_util != nullptr); @@ -329,14 +340,14 @@ void RgMenuFileItemGraphics::mousePressEvent(QMouseEvent* event) } } -void RgMenuFileItemGraphics::resizeEvent(QResizeEvent *event) +void RgMenuFileItemGraphics::resizeEvent(QResizeEvent* event) { Q_UNUSED(event); UpdateFilenameLabelText(); } -void RgMenuFileItemGraphics::showEvent(QShowEvent *event) +void RgMenuFileItemGraphics::showEvent(QShowEvent* event) { Q_UNUSED(event); @@ -411,10 +422,10 @@ void RgMenuFileItemGraphics::dragEnterEvent(QDragEnterEvent* event) QUrl url = mime_data->urls().at(0); // Do not allow the user to use PSO files. - bool valid_file = true; - QString extension; - const QString file_path = url.toLocalFile(); - QStringList name_extension = file_path.split(kStrFileExtensionDelimiter); + bool valid_file = true; + QString extension; + const QString file_path = url.toLocalFile(); + QStringList name_extension = file_path.split(kStrFileExtensionDelimiter); assert(name_extension.size() == 2); if (name_extension.size() == 2) { @@ -465,7 +476,7 @@ void RgMenuFileItemGraphics::dragLeaveEvent(QDragLeaveEvent* event) SetCurrent(false); } -void RgMenuFileItemGraphics::dragMoveEvent(QDragMoveEvent *event) +void RgMenuFileItemGraphics::dragMoveEvent(QDragMoveEvent* event) { // If there is already a file present in this stage, // do not allow the user to drop here. diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_file_item_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_file_item_opencl.cpp index 0f43f6a..8cf6df8 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_file_item_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_file_item_opencl.cpp @@ -29,7 +29,9 @@ kStrXmlNodeRtxVec = kStrXmlNodeDxrTraversal }; -static const char* kStrFileMenuItemColor = "#itemBackground[current = true] {background-color: rgb(253, 255, 215); border-style: solid; border-width: 1px; border-color: rgb(18, 152, 0);}"; +// Stylesheet for file menu items for when they are selcted and not selected. +static const char* kStrFileMenuItemColor = "#itemBackground[current = false] {background-color: palette(midlight)} #itemBackground[current = true] {background-color: palette(base); border-style: solid; border-width: 1px;}"; + static const int s_FILE_MENU_KERNEL_ITEM_HEIGHT = 20; static const int s_FILE_MENU_DXR_KERNEL_ITEM_HEIGHT = s_FILE_MENU_KERNEL_ITEM_HEIGHT * 2; @@ -231,6 +233,8 @@ RgMenuFileItemOpencl::RgMenuFileItemOpencl(const std::string& file_full_path, Rg { ui_.setupUi(this); + setStyleSheet(kStrFileMenuItemColor); + UpdateFilepath(full_file_path_); // Start as a saved item. diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_graphics.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_graphics.cpp index 4901561..13bfad6 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_graphics.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_graphics.cpp @@ -10,8 +10,10 @@ #include "radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h" #include "radeon_gpu_analyzer_gui/qt/rg_menu_file_item_graphics.h" -static const char* kStrButtonFocusInStylesheetGraphics = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* kButtonTabbedStylesheet = "QPushButton { border: 2px solid rgb(135,20,16); margin: 1px; background: rgb(214,214,214);}"; +// Stylesheets for the menu buttons. +static const char* kStrButtonFocusInStylesheetGraphics = "QPushButton { background: palette(highlight); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; +static const char* kButtonTabbedStylesheet = "QPushButton { border: 2px solid rgb(135,20,16); margin: 1px; background: palette(button);}"; + static const char* kFileMenuNameGraphics = "fileMenuGraphics"; static const int kPipelineStateButtonIndex = 1; diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_opencl.cpp index a383f25..25651b7 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_opencl.cpp @@ -20,7 +20,8 @@ #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -static const char* kStrButtonFocusInStylesheetOpencl = "QPushButton { background: rgb(253,255,174); border: 2px inset rgb(18, 152, 0); }"; +// Stylessheet for the menu buttons. +static const char* kStrButtonFocusInStylesheetOpencl = "QPushButton { background: palette(highlight); border: 2px inset rgb(18, 152, 0); }"; RgMenuOpencl::RgMenuOpencl(QWidget* parent) : RgMenu(parent) diff --git a/source/radeon_gpu_analyzer_gui/rg_menu_pipeline_state_item.cpp b/source/radeon_gpu_analyzer_gui/rg_menu_pipeline_state_item.cpp index fa516cd..d09ee5a 100644 --- a/source/radeon_gpu_analyzer_gui/rg_menu_pipeline_state_item.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_menu_pipeline_state_item.cpp @@ -7,18 +7,26 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/qt/rg_menu_pipeline_state_item.h" -static const char* kStrButtonFocusInStylesheetGraphics = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* kStrButtonFocusOutStylesheet = "QPushButton { margin: 1px; background: rgb(214, 214, 214);}"; +// Stylesheet for the when the menu buttons have focus. +static const char* kStrButtonFocusInStylesheetGraphics = + "QPushButton { background: palette(highlight); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; + +// Stylesheet for the when the menu buttons do not have focus. +static const char* kStrButtonFocusOutStylesheet = "QPushButton { margin: 1px; }"; + static const char* kStrDefaultPipelineFileExtensionGraphicsLocal = "gpso"; -static const char* kStrDefaultPipelineFileExtensionComputeLocal = "cpso"; +static const char* kStrDefaultPipelineFileExtensionComputeLocal = "cpso"; RgMenuPipelineStateItem::RgMenuPipelineStateItem(RgPipelineType pipeline_type, RgMenu* parent) - : pipeline_type_(pipeline_type), - RgMenuItem(parent) + : pipeline_type_(pipeline_type) + , RgMenuItem(parent) { ui_.setupUi(this); @@ -28,6 +36,13 @@ RgMenuPipelineStateItem::RgMenuPipelineStateItem(RgPipelineType pipeline_type, R // Set the tool tip. this->setToolTip(kStrGraphicsMenuPipelineStateTooltip); + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); + + if (color_theme == kColorThemeTypeDark) + { + ui_.pipelineStateButton->setIcon(QIcon(":/icons/state_settings_cube_dark_mode.svg")); + } + // Set the mouse cursor to arrow cursor. SetCursor(Qt::PointingHandCursor); @@ -140,10 +155,10 @@ void RgMenuPipelineStateItem::dragEnterEvent(QDragEnterEvent* event) QUrl url = mime_data->urls().at(0); // Verify we have the correct file for the current pipeline type. - bool valid_file = false; - QString extension; - const QString file_path = url.toLocalFile(); - QStringList num_extension = file_path.split(kStrFileExtensionDelimiter); + bool valid_file = false; + QString extension; + const QString file_path = url.toLocalFile(); + QStringList num_extension = file_path.split(kStrFileExtensionDelimiter); assert(num_extension.size() == 2); if (num_extension.size() == 2) { diff --git a/source/radeon_gpu_analyzer_gui/rg_ordered_list_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_ordered_list_dialog.cpp index b15a52f..77ed8b8 100644 --- a/source/radeon_gpu_analyzer_gui/rg_ordered_list_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_ordered_list_dialog.cpp @@ -23,12 +23,6 @@ RgOrderedListDialog::RgOrderedListDialog(const char* delimiter, QWidget* parent) // Setup the UI. ui_.setupUi(this); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Set the window icon. setWindowIcon(QIcon(":/icons/rgaIcon.png")); diff --git a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_editor_widget_numeric.cpp b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_editor_widget_numeric.cpp index f88ff2e..be27d58 100644 --- a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_editor_widget_numeric.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_editor_widget_numeric.cpp @@ -175,7 +175,7 @@ void RgPipelineStateEditorWidgetNumeric::UpdateStringMatchingLocation(int start_ string_highlight_data.start_location = start_location; string_highlight_data.end_location = start_location + length; string_highlight_data.highlight_string = search_string; - string_highlight_data.highlight_color = Qt::yellow; + string_highlight_data.highlight_color = Qt::magenta; string_highlight_data_.push_back(string_highlight_data); } } diff --git a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_tree.cpp b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_tree.cpp index f8dfb8e..7c51068 100644 --- a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_tree.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_tree.cpp @@ -12,17 +12,11 @@ #include "radeon_gpu_analyzer_gui/qt/rg_pipeline_state_tree.h" #include "radeon_gpu_analyzer_gui/qt/rg_pipeline_state_model.h" -// A stylesheet applied to the entire pipeline state tree. -static const QString kStrPsoTreeStylesheet = "background-color: rgba(255, 255, 255, 255);"; - RgPipelineStateTree::RgPipelineStateTree(QWidget* parent) : QScrollArea(parent) { ui_.setupUi(this); - // Apply the stylesheet to the custom tree widget. - this->setStyleSheet(kStrPsoTreeStylesheet); - // Enable mouse hover events for each row. ui_.scrollingPanel->setMouseTracking(true); } diff --git a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_view.cpp b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_view.cpp index 593990c..d1d76d7 100644 --- a/source/radeon_gpu_analyzer_gui/rg_pipeline_state_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_pipeline_state_view.cpp @@ -5,7 +5,7 @@ #include #include -// Infra. +// QtCommon. #include "qt_common/utils/qt_util.h" // Local. diff --git a/source/radeon_gpu_analyzer_gui/rg_recent_project_widget.cpp b/source/radeon_gpu_analyzer_gui/rg_recent_project_widget.cpp index d1040f0..c3d3882 100644 --- a/source/radeon_gpu_analyzer_gui/rg_recent_project_widget.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_recent_project_widget.cpp @@ -3,26 +3,15 @@ // Qt. #include +#include + +// QtCommon. +#include "qt_common/utils/common_definitions.h" +#include "qt_common/utils/qt_util.h" // Local. #include "radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h" -const static QString kStrProjectButtonStylesheet( - "QPushButton" - "{" - "color: rgb(0, 0, 255);" - "padding: 0 0 0 0;" - "border: none;" - "text-align: left;" - "font: 10pt;" - "spacing : 10;" - "}" - "QPushButton:hover" - "{" - "color: rgb(255, 128, 0);" - "}" -); - static const int kApiIconWidth = 50; static const int kApiIconHeight = 25; @@ -45,8 +34,19 @@ RgRecentProjectWidget::RgRecentProjectWidget(QWidget* parent) : horizontal_layout_->addWidget(project_button_); horizontal_layout_->addWidget(icon_button_); - project_button_->setStyleSheet(kStrProjectButtonStylesheet); - icon_button_->setStyleSheet(kStrProjectButtonStylesheet); + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + project_button_->setStyleSheet(kDarkLinkButtonStylesheet); + icon_button_->setStyleSheet(kDarkLinkButtonStylesheet); + } + else + { + project_button_->setStyleSheet(kLinkButtonStylesheet); + icon_button_->setStyleSheet(kLinkButtonStylesheet); + } + + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgRecentProjectWidget::UpdateLinkButtonStyleSheet); + icon_button_->setFocusPolicy(Qt::NoFocus); // Set the icon size. @@ -54,6 +54,20 @@ RgRecentProjectWidget::RgRecentProjectWidget(QWidget* parent) : icon_button_->setIconSize(size); } +void RgRecentProjectWidget::UpdateLinkButtonStyleSheet() +{ + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + project_button_->setStyleSheet(kDarkLinkButtonStylesheet); + icon_button_->setStyleSheet(kDarkLinkButtonStylesheet); + } + else + { + project_button_->setStyleSheet(kLinkButtonStylesheet); + icon_button_->setStyleSheet(kLinkButtonStylesheet); + } +} + void RgRecentProjectWidget::SetProjectName(const QString& filename) { // Set project button text. diff --git a/source/radeon_gpu_analyzer_gui/rg_rename_project_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_rename_project_dialog.cpp index 2402d2d..1755cfe 100644 --- a/source/radeon_gpu_analyzer_gui/rg_rename_project_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_rename_project_dialog.cpp @@ -17,9 +17,6 @@ RgRenameProjectDialog::RgRenameProjectDialog(std::string& project_name, QWidget* // Setup the UI. ui_.setupUi(this); - // Set the background to white. - RgUtils::SetBackgroundColor(this, Qt::white); - // Generate a unique project name based on the incoming base name string. project_name_ = RgUtils::GenerateDefaultProjectName(); ui_.lineEditProjectName->setText(project_name_.c_str()); diff --git a/source/radeon_gpu_analyzer_gui/rg_resource_usage_view.cpp b/source/radeon_gpu_analyzer_gui/rg_resource_usage_view.cpp index 93751b0..732510a 100644 --- a/source/radeon_gpu_analyzer_gui/rg_resource_usage_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_resource_usage_view.cpp @@ -1,7 +1,7 @@ // C++. #include -// Infra. +// QtCommon. #include "qt_common/utils/qt_util.h" // Local. diff --git a/source/radeon_gpu_analyzer_gui/rg_settings_buttons_view.cpp b/source/radeon_gpu_analyzer_gui/rg_settings_buttons_view.cpp index c5bf468..b618379 100644 --- a/source/radeon_gpu_analyzer_gui/rg_settings_buttons_view.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_settings_buttons_view.cpp @@ -32,12 +32,6 @@ RgSettingsButtonsView::RgSettingsButtonsView(QWidget* parent) : // Setup the UI. ui_.setupUi(this); - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - // Connect the signals. ConnectSignals(); diff --git a/source/radeon_gpu_analyzer_gui/rg_source_code_editor.cpp b/source/radeon_gpu_analyzer_gui/rg_source_code_editor.cpp index f386b6d..422e78e 100644 --- a/source/radeon_gpu_analyzer_gui/rg_source_code_editor.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_source_code_editor.cpp @@ -5,16 +5,20 @@ #include #include +// QtCommon. +#include "qt_common/utils/qt_util.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_source_code_editor.h" #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/rg_definitions.h" #include "radeon_gpu_analyzer_gui/rg_utils.h" -// Use a light yellow to highlight the line that the cursor is on. -static const QColor kColorHighlightedRow = QColor(Qt::yellow).lighter(170); +// Highglight color for the selcted line the cursor is on. +static QColor kColorHighlightedRow[ColorThemeType::kColorThemeTypeCount] = {QColor(Qt::yellow).lighter(170), QColor(80, 80, 40, 100)}; -RgSourceCodeEditor::RgSourceCodeEditor(QWidget* parent, RgSrcLanguage lang) : QPlainTextEdit(parent) +RgSourceCodeEditor::RgSourceCodeEditor(QWidget* parent, RgSrcLanguage lang) + : QPlainTextEdit(parent) { line_number_area_ = new LineNumberArea(this); @@ -31,7 +35,6 @@ RgSourceCodeEditor::RgSourceCodeEditor(QWidget* parent, RgSrcLanguage lang) : QP // Set the border color. setObjectName("sourceCodeEditor"); - setStyleSheet("#sourceCodeEditor {border: 1px solid black;}"); // Create the syntax highlighter. if (lang != RgSrcLanguage::Unknown) @@ -131,7 +134,7 @@ RgSourceCodeEditor::RgSourceCodeEditor(QWidget* parent, RgSrcLanguage lang) : QP int RgSourceCodeEditor::LineNumberAreaWidth() const { int digits = 1; - int max = qMax(1, blockCount()); + int max = qMax(1, blockCount()); while (max >= 10) { max /= 10; @@ -146,13 +149,13 @@ int RgSourceCodeEditor::LineNumberAreaWidth() const void RgSourceCodeEditor::ScrollToLine(int line_number) { // Compute the last visible text block. - QTextBlock first_visible = firstVisibleBlock(); - auto last_visible_line_position = QPoint(0, viewport()->height() - 1); - QTextBlock last_visible_block = cursorForPosition(last_visible_line_position).block(); + QTextBlock first_visible = firstVisibleBlock(); + auto last_visible_line_position = QPoint(0, viewport()->height() - 1); + QTextBlock last_visible_block = cursorForPosition(last_visible_line_position).block(); // Get the first and last visible line numbers in the editor. int first_visible_line_number = firstVisibleBlock().blockNumber(); - int last_visible_line_number = last_visible_block.blockNumber(); + int last_visible_line_number = last_visible_block.blockNumber(); // Only scroll the textbox if the target line is not currently visible. // Scroll 5 lines above the cursor position if the cursor is too close to the editor upper bound. @@ -218,7 +221,7 @@ void RgSourceCodeEditor::UpdateLineNumberAreaWidth(int /* new_block_count */) setViewportMargins(LineNumberAreaWidth(), 0, 0, 0); } -void RgSourceCodeEditor::UpdateLineNumberArea(const QRect &rect, int dy) +void RgSourceCodeEditor::UpdateLineNumberArea(const QRect& rect, int dy) { if (dy) { @@ -238,7 +241,7 @@ void RgSourceCodeEditor::UpdateLineNumberArea(const QRect &rect, int dy) void RgSourceCodeEditor::HandleOpenHeaderFile() { QString line_text; - bool is_valid = GetCurrentLineText(line_text); + bool is_valid = GetCurrentLineText(line_text); if (is_valid) { // Parse the line. @@ -271,7 +274,7 @@ void RgSourceCodeEditor::HandleOpenHeaderFile() { // Fire the signal: user requested to open header file. QString filename = line_broken_b[0]; - emit OpenHeaderFileRequested(filename); + emit OpenHeaderFileRequested(filename); } } } @@ -306,8 +309,8 @@ bool RgSourceCodeEditor::GetCurrentLineText(QString& line_text) bool RgSourceCodeEditor::IsIncludeDirectiveLine(const QString& line_text) { // We use this token to identify if a line is an include directive. - static const char* INCLUDE_DIR_TOKEN = "#include "; - bool is_include_directive = line_text.startsWith(INCLUDE_DIR_TOKEN); + static const char* INCLUDE_DIR_TOKEN = "#include "; + bool is_include_directive = line_text.startsWith(INCLUDE_DIR_TOKEN); return is_include_directive; } @@ -323,8 +326,8 @@ void RgSourceCodeEditor::ShowContextMenu(const QPoint& pt) open_header_file_action_->setEnabled(IsIncludeDirectiveLine(line_text)); // Only enable cut, copy if there is text selected. - QTextCursor cursor = this->textCursor(); - bool has_selection = cursor.hasSelection(); + QTextCursor cursor = this->textCursor(); + bool has_selection = cursor.hasSelection(); cut_text_action_->setEnabled(has_selection); copy_text_action_->setEnabled(has_selection); @@ -360,7 +363,7 @@ void RgSourceCodeEditor::HighlightCursorLine(QList& s if (!isReadOnly()) { QTextEdit::ExtraSelection current_line_selection; - current_line_selection.format.setBackground(kColorHighlightedRow); + current_line_selection.format.setBackground(kColorHighlightedRow[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); current_line_selection.format.setProperty(QTextFormat::FullWidthSelection, true); current_line_selection.cursor = textCursor(); current_line_selection.cursor.clearSelection(); @@ -378,10 +381,10 @@ void RgSourceCodeEditor::HighlightCorrelatedSourceLines(QListfindBlockByLineNumber(row_index - 1); + QTextBlock line_text_block = file_document->findBlockByLineNumber(row_index - 1); QTextCursor cursor(line_text_block); selection.cursor = cursor; selection.cursor.clearSelection(); @@ -429,7 +432,7 @@ void RgSourceCodeEditor::UpdateCursorPositionHelper(bool is_correlated) setExtraSelections(extra_selections); // Track the current and previously-selected line numbers. - int current_line = GetSelectedLineNumber(); + int current_line = GetSelectedLineNumber(); static int last_cursor_position = current_line; if (current_line != last_cursor_position) { @@ -506,8 +509,8 @@ bool RgSourceCodeEditor::GetTextAtLine(int line_number, QString& text) const if (is_line_valid) { QTextBlock lineBlock = document()->findBlockByLineNumber(line_number - 1); - text = lineBlock.text(); - ret = true; + text = lineBlock.text(); + ret = true; } return ret; @@ -516,27 +519,29 @@ bool RgSourceCodeEditor::GetTextAtLine(int line_number, QString& text) const void RgSourceCodeEditor::LineNumberAreaPaintEvent(QPaintEvent* event) { QPainter painter(line_number_area_); - painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(120)); - QTextBlock block = firstVisibleBlock(); - int block_number = block.blockNumber(); - int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top(); - int bottom = top + (int)blockBoundingRect(block).height(); + painter.fillRect(event->rect(), qApp->palette().color(QPalette::AlternateBase)); + + QTextBlock block = firstVisibleBlock(); + int block_number = block.blockNumber(); + int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int)blockBoundingRect(block).height(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QString number = QString::number(block_number + 1); - painter.setPen(QColor(Qt::darkGray).darker(100)); + + painter.setPen(qApp->palette().color(QPalette::Text)); + QFont default_font = this->document()->defaultFont(); painter.setFont(default_font); - painter.drawText(0, top, line_number_area_->width(), fontMetrics().height(), - Qt::AlignCenter, number); + painter.drawText(0, top, line_number_area_->width(), fontMetrics().height(), Qt::AlignCenter, number); } - block = block.next(); - top = bottom; + block = block.next(); + top = bottom; bottom = top + (int)blockBoundingRect(block).height(); ++block_number; } @@ -557,8 +562,7 @@ void RgSourceCodeEditor::mousePressEvent(QMouseEvent* event) // Simulate a left click event to bring us to the current line. Qt::MouseButtons buttons; QMouseEvent* dummy_event = - new QMouseEvent(event->type(), event->position(), event->globalPosition(), - Qt::MouseButton::LeftButton, buttons, event->modifiers()); + new QMouseEvent(event->type(), event->position(), event->globalPosition(), Qt::MouseButton::LeftButton, buttons, event->modifiers()); emit mousePressEvent(dummy_event); } else @@ -585,8 +589,14 @@ void RgSourceCodeEditor::mouseDoubleClickEvent(QMouseEvent* event) { Q_UNUSED(event); - static const QColor kHighlightGreenColor = QColor::fromRgb(124, 252, 0); - static const QColor kHighlightDarkGreenColor = QColor::fromRgb(0, 102, 51); + static QColor kHighlightGreenColor = QColor::fromRgb(124, 252, 0); + static QColor kHighlightDarkGreenColor = QColor::fromRgb(0, 172, 102); + + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + kHighlightGreenColor = QColor::fromRgb(72, 128, 0); + kHighlightDarkGreenColor = QColor::fromRgb(0, 51, 26); + } // Override the double-click event to avoid QPlainTextEdit // from interpreting the sequence that happens when we simulate @@ -600,7 +610,7 @@ void RgSourceCodeEditor::mouseDoubleClickEvent(QMouseEvent* event) // Highlight the current line with yellow background. QTextEdit::ExtraSelection current_line_selection; - current_line_selection.format.setBackground(kColorHighlightedRow); + current_line_selection.format.setBackground(kColorHighlightedRow[QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()]); current_line_selection.format.setProperty(QTextFormat::FullWidthSelection, true); current_line_selection.cursor = textCursor(); current_line_selection.cursor.clearSelection(); @@ -611,10 +621,10 @@ void RgSourceCodeEditor::mouseDoubleClickEvent(QMouseEvent* event) // Setup foreground and background colors to // highlight the double clicked word. - QBrush background_brush(kHighlightGreenColor); - QBrush text_brush(Qt::black); - QPen outline_color(Qt::gray, 1); - QString selected_text = cursor.selectedText(); + QBrush background_brush(kHighlightGreenColor); + QBrush text_brush(QtCommon::QtUtils::ColorTheme::Get().GetCurrentThemeColors().graphics_scene_text_color); + QPen outline_color(Qt::gray, 1); + QString selected_text = cursor.selectedText(); // Get indices of all matching text. std::vector search_result_indices; @@ -642,4 +652,3 @@ void RgSourceCodeEditor::mouseDoubleClickEvent(QMouseEvent* event) // Set the selections that were just created. setExtraSelections(extra_selections); } - diff --git a/source/radeon_gpu_analyzer_gui/rg_start_tab.cpp b/source/radeon_gpu_analyzer_gui/rg_start_tab.cpp index 6fbe778..db4b265 100644 --- a/source/radeon_gpu_analyzer_gui/rg_start_tab.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_start_tab.cpp @@ -5,6 +5,11 @@ // Qt. #include #include +#include + +// QtCommon. +#include "qt_common/utils/common_definitions.h" +#include "qt_common/utils/qt_util.h" // Local. #include "radeon_gpu_analyzer_gui/qt/rg_recent_project_widget.h" @@ -17,9 +22,14 @@ #include "radeon_gpu_analyzer_gui/rg_string_constants.h" #include "radeon_gpu_analyzer_gui/rg_definitions.h" +// Icons for each api type and each color mode. +static QString kOpenClIcons[ColorThemeType::kColorThemeTypeCount] = {":/icons/api_logos/opencl_icon_wide.png", ":/icons/api_logos/opencl_icon_wide_dark.png"}; +static QString kVulkanIcons[ColorThemeType::kColorThemeTypeCount] = {":/icons/api_logos/vulkan_icon.png", ":/icons/api_logos/vulkan_icon_dark.png"}; +static QString kBinaryIcons[ColorThemeType::kColorThemeTypeCount] = {":/icons/api_logos/binary_icon_wide.png", ":/icons/api_logos/binary_icon_wide_dark.png"}; + RgStartTab::RgStartTab(QWidget* parent) - : QWidget(parent), - parent_(parent) + : QWidget(parent) + , parent_(parent) { // Setup the UI. ui_.setupUi(this); @@ -48,6 +58,9 @@ void RgStartTab::Initialize() // Set the cursor type for specific widgets in the view. SetCursor(); + SetLinkButtonStylesheet(); + connect(&QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgStartTab::OnColorThemeChanged); + // Install an event filter to handle up/down arrow keys on the recent files list widget. qApp->installEventFilter(this); } @@ -203,26 +216,55 @@ void RgStartTab::SetCursor() ui_.helpManualPushButton->setCursor(Qt::PointingHandCursor); } +void RgStartTab::SetLinkButtonStylesheet() +{ + QString stylesheet; + + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + stylesheet = kDarkLinkButtonStylesheet; + } + else + { + stylesheet = kLinkButtonStylesheet; + } + + std::vector start_buttons; + GetStartButtons(start_buttons); + + for (auto start_button : start_buttons) + { + start_button->setStyleSheet(stylesheet); + } + + ui_.recentProjectsOtherPushButton->setStyleSheet(stylesheet); + ui_.aboutRGAPushButton->setStyleSheet(stylesheet); + ui_.gettingStartedPushButton->setStyleSheet(stylesheet); + ui_.helpManualPushButton->setStyleSheet(stylesheet); + ui_.noRecentSessionsDummyPushButton->setStyleSheet(stylesheet); +} + void RgStartTab::SetProjectAPIIcon(RgProjectAPI api, RgRecentProjectWidget* recent_project_widget) { + ColorThemeType color_theme = QtCommon::QtUtils::ColorTheme::Get().GetColorTheme(); // Get and set the appropriate API icon. switch (api) { case RgProjectAPI::kOpenCL: { - recent_project_widget->SetIcon(QIcon(":/icons/api_logos/opencl_icon_wide.png")); + recent_project_widget->SetIcon(QIcon(kOpenClIcons[color_theme])); recent_project_widget->SetIconProjectType(kStrApiNameOpencl); } break; case RgProjectAPI::kVulkan: { - recent_project_widget->SetIcon(QIcon(":/icons/api_logos/vulkan_icon.png")); + recent_project_widget->SetIcon(QIcon(kVulkanIcons[color_theme])); recent_project_widget->SetIconProjectType(kStrApiNameVulkan); } break; case RgProjectAPI::kBinary: { - recent_project_widget->SetIcon(QIcon(":/icons/api_logos/binary_icon_wide.png")); + recent_project_widget->SetIcon(QIcon(kBinaryIcons[color_theme])); recent_project_widget->SetIconProjectType(kStrApiAbbreviationBinary); } break; @@ -267,17 +309,18 @@ void RgStartTab::PopulateRecentProjectsList() // button is being identified within the group when signals are being fired. int button_index = num_recent_projects; for (std::vector>::const_reverse_iterator project_iter = recent_projects.rbegin(); - project_iter != recent_projects.rend(); ++project_iter) + project_iter != recent_projects.rend(); + ++project_iter) { if (*project_iter != nullptr) { // Display the most recent projects at the end of the list. - const std::string& project_path = (*project_iter)->project_path; - RgProjectAPI project_api_type = (*project_iter)->api_type; + const std::string& project_path = (*project_iter)->project_path; + RgProjectAPI project_api_type = (*project_iter)->api_type; // Extract just the filename to display in the list of recent projects. std::string project_name; - bool is_ok = RgUtils::ExtractFileName(project_path, project_name, true); + bool is_ok = RgUtils::ExtractFileName(project_path, project_name, true); assert(is_ok); if (is_ok) @@ -302,7 +345,8 @@ void RgStartTab::PopulateRecentProjectsList() recent_project_widget->setContextMenuPolicy(Qt::CustomContextMenu); // Connect signal/slot for the context menu. - is_connected = connect(recent_project_widget, &RgRecentProjectWidget::customContextMenuRequested, this, &RgStartTab::HandleContextMenuRequest); + is_connected = + connect(recent_project_widget, &RgRecentProjectWidget::customContextMenuRequested, this, &RgStartTab::HandleContextMenuRequest); assert(is_connected); // Add the recent project button to the group. @@ -322,6 +366,49 @@ QWidget* RgStartTab::GetRecentProgramsListWidget() const return ui_.recentProgramsWrapper; } +void RgStartTab::OnColorThemeChanged() +{ + SetLinkButtonStylesheet(); + + const std::vector>& recent_projects = RgConfigManager::Instance().GetRecentProjects(); + + bool has_recent_projects = recent_projects.size() > 0; + + // Change the visibility of the "No recent sessions" label depending on what's in the settings file. + ui_.noRecentSessionsDummyPushButton->setVisible(!has_recent_projects); + + if (has_recent_projects) + { + int i = 0; + + QLayout* recent_projects_list = ui_.recentProgramsWrapper->layout(); + assert(recent_projects_list != nullptr); + + int num_recent_projects = static_cast(recent_projects.size()); + + // The index of the button in the QButtonGroup. This is how the + // button is being identified within the group when signals are being fired. + int button_index = num_recent_projects; + for (std::vector>::const_reverse_iterator project_iter = recent_projects.rbegin(); + project_iter != recent_projects.rend(); + ++project_iter) + { + if (*project_iter != nullptr) + { + RgProjectAPI project_api_type = (*project_iter)->api_type; + + RgRecentProjectWidget* recent_project_widget = qobject_cast(recent_projects_list->itemAt(i)->widget()); + if (recent_project_widget != nullptr) + { + SetProjectAPIIcon(project_api_type, recent_project_widget); + } + } + + i++; + } + } +} + // Get the button used to create a new project. QPushButton* RgStartTab::GetCreateNewFileButton() { @@ -350,14 +437,14 @@ void RgStartTab::HandleContextMenuRequest(const QPoint& pos) QList menu_actions = menu_.actions(); // Extract the file name clicked on - QObject* sender = QObject::sender(); + QObject* sender = QObject::sender(); RgRecentProjectWidget* recent_project_widget = qobject_cast(sender); assert(recent_project_widget != nullptr); if (recent_project_widget != nullptr) { QString filename = recent_project_widget->GetProjectName(); - foreach(auto action, menu_actions) + foreach (auto action, menu_actions) { if (action == open_recent_action_) { @@ -379,11 +466,11 @@ void RgStartTab::HandleContextMenuRequest(const QPoint& pos) QString menu_selection = action->text(); // Find out the index into the button group for this file - QList button_list = recent_project_button_group_->buttons(); - int recent_file_index = 0; + QList button_list = recent_project_button_group_->buttons(); + int recent_file_index = 0; // Find the index for the button clicked on - foreach(auto button, button_list) + foreach (auto button, button_list) { recent_file_index++; if (filename.compare(button->text()) == 0) @@ -393,14 +480,14 @@ void RgStartTab::HandleContextMenuRequest(const QPoint& pos) } // Determine the index of the recent item that was clicked. - int selected_file_index = button_list.count() - recent_file_index; - bool is_index_valid = (selected_file_index >= 0 && selected_file_index < button_list.count()); + int selected_file_index = button_list.count() - recent_file_index; + bool is_index_valid = (selected_file_index >= 0 && selected_file_index < button_list.count()); assert(is_index_valid); if (is_index_valid) { // Pull the recent project info out of the global settings structure. std::shared_ptr global_settings = RgConfigManager::Instance().GetGlobalConfig(); - const std::string& project_path = global_settings->recent_projects[selected_file_index]->project_path; + const std::string& project_path = global_settings->recent_projects[selected_file_index]->project_path; if (action == open_recent_action_) { @@ -412,7 +499,7 @@ void RgStartTab::HandleContextMenuRequest(const QPoint& pos) { // Get the directory where the project's settings file lives. std::string file_directory; - bool got_directory = RgUtils::ExtractFileDirectory(project_path, file_directory); + bool got_directory = RgUtils::ExtractFileDirectory(project_path, file_directory); assert(got_directory); if (got_directory) @@ -433,7 +520,7 @@ void RgStartTab::HandleRecentProjectClickedEvent(QAbstractButton* recent_file_bu if (global_settings != nullptr && recent_project_button_group_ != nullptr && recent_file_button != nullptr) { int recent_file_index = recent_project_button_group_->id(recent_file_button); - bool is_valid_range = (recent_file_index >= 0 && recent_file_index < global_settings->recent_projects.size()); + bool is_valid_range = (recent_file_index >= 0 && recent_file_index < global_settings->recent_projects.size()); assert(is_valid_range); // If the file index is valid, attempt to open the file. @@ -481,18 +568,18 @@ bool RgStartTab::eventFilter(QObject* object, QEvent* event) switch (key_event->key()) { case Qt::Key_Up: + { + // Give focus to the last item under the "Start" section. + std::vector start_buttons; + GetStartButtons(start_buttons); + if (!start_buttons.empty()) { - // Give focus to the last item under the "Start" section. - std::vector start_buttons; - GetStartButtons(start_buttons); - if (!start_buttons.empty()) - { - QPushButton* last_start_button = *(start_buttons.rbegin()); - last_start_button->setFocus(); - } - filtered = true; + QPushButton* last_start_button = *(start_buttons.rbegin()); + last_start_button->setFocus(); } - break; + filtered = true; + } + break; case Qt::Key_Down: // Give focus to the next widget. ui_.recentProjectsOtherPushButton->setFocus(); @@ -523,7 +610,7 @@ bool RgStartTab::ProcessKeyPress(QKeyEvent* key_event, const QString& object_nam { assert(key_event != nullptr); - static const char* kStrNewFilePushButton = "newFilePushButton"; + static const char* kStrNewFilePushButton = "newFilePushButton"; static const char* kStrGettingStartedPushButton = "gettingStartedPushButton"; bool result = true; diff --git a/source/radeon_gpu_analyzer_gui/rg_startup_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_startup_dialog.cpp index 8239b97..d772cd3 100644 --- a/source/radeon_gpu_analyzer_gui/rg_startup_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_startup_dialog.cpp @@ -1,8 +1,9 @@ // C++. #include #include +#include -// Infra. +// QtCommon. #include "qt_common/utils/qt_util.h" // Local. @@ -17,25 +18,20 @@ static const int kHorizontalLayoutSpacing = 15; static const int kLeftAndRightMargin = 23; static const int kSpacingAfterLabel = 10; -static const std::vector kDescription = -{ - kStrStartupDialogBinaryDescription, - kStrStartupDialogOpenclDescription, - kStrStartupDialogVulkanDescription -}; + +static const std::vector kDescription = {kStrStartupDialogBinaryDescription, + kStrStartupDialogOpenclDescription, + kStrStartupDialogVulkanDescription}; + int maxDescriptionWidth = 0; -RgStartupDialog::RgStartupDialog(QWidget* parent) : - QDialog(parent), - selected_api_(static_cast(static_cast(RgProjectAPI::kApiCount) - 1)), - should_not_ask_again_(false) +RgStartupDialog::RgStartupDialog(QWidget* parent) + : QDialog(parent) + , selected_api_(static_cast(static_cast(RgProjectAPI::kApiCount) - 1)) + , should_not_ask_again_(false) { ui_.setupUi(this); - // Set the background color to white. - setAutoFillBackground(true); - setPalette(QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette()); - // Disable the help button in the title bar, and disable resizing of this dialog. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); @@ -51,7 +47,7 @@ RgStartupDialog::RgStartupDialog(QWidget* parent) : RgProjectAPI current_api = static_cast(api_index); std::string api_string; RgUtils::ProjectAPIToString(current_api, api_string, false); - ui_.apiListWidget->addItem(QString::fromStdString(api_string)); + ui_.apiListWidget->addItem(QString::fromStdString(api_string)); } // Select Vulkan selection in the list widget by default. @@ -75,6 +71,10 @@ RgStartupDialog::RgStartupDialog(QWidget* parent) : //Scale the dialog and the widget inside it. ScaleDialog(); + + setStyleSheet( + "QCheckBox::indicator { border: 1px solid palette(text); background-color: rgb(240, 240, 240); width: 12px; height: 12px; } " + "QCheckBox::indicator:checked { image: url(:/icons/checkmark_black.svg);}"); } void RgStartupDialog::ConnectSignals() const @@ -98,8 +98,49 @@ void RgStartupDialog::ConnectSignals() const // Connect the handler invoked when the user selects the API by using up/down arrow keys. is_connected = connect(ui_.apiListWidget, &QListWidget::currentRowChanged, this, &RgStartupDialog::HandleListWidgetItemSelected); assert(is_connected); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + is_connected = connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &RgStartupDialog::HandleOsColorSchemeChanged); + assert(is_connected); +#endif } +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +void RgStartupDialog::HandleOsColorSchemeChanged(Qt::ColorScheme color_scheme) +{ + if (RgConfigManager::Instance().GetGlobalConfig()->color_theme != kColorThemeTypeCount) + { + return; + } + + if (color_scheme == Qt::ColorScheme::Unknown) + { + return; + } + + ColorThemeType color_mode = kColorThemeTypeLight; + if (color_scheme == Qt::ColorScheme::Light) + { + color_mode = kColorThemeTypeLight; + } + else if (color_scheme == Qt::ColorScheme::Dark) + { + color_mode = kColorThemeTypeDark; + } + + if (color_mode == QtCommon::QtUtils::ColorTheme::Get().GetColorTheme()) + { + return; + } + + QtCommon::QtUtils::ColorTheme::Get().SetColorTheme(color_mode); + + qApp->setPalette(QtCommon::QtUtils::ColorTheme::Get().GetCurrentPalette()); + + emit QtCommon::QtUtils::ColorTheme::Get().ColorThemeUpdated(); +} +#endif + void RgStartupDialog::SetCursor() const { // Set the cursor to pointing hand cursor for various widgets. @@ -162,7 +203,7 @@ void RgStartupDialog::HandleListWidgetItemClicked(QListWidgetItem* item) // Also update the description. ui_.descriptionLabel->setText(kStrStartupDialogBinaryDescription); - } + } else { // Should not get here. @@ -221,7 +262,7 @@ void RgStartupDialog::SetDescriptionLength() { for (const char* text : kDescription) { - const QFont font = ui_.descriptionLabel->font(); + const QFont font = ui_.descriptionLabel->font(); QFontMetrics fm(font); const int text_width = fm.horizontalAdvance(text); @@ -246,9 +287,9 @@ void RgStartupDialog::ScaleDialog() int right_margin; int bottom_margin; this->layout()->getContentsMargins(&left_margin, &top_margin, &right_margin, &bottom_margin); - left_margin = left_margin; - top_margin = top_margin; - right_margin = right_margin; + left_margin = left_margin; + top_margin = top_margin; + right_margin = right_margin; bottom_margin = bottom_margin; this->layout()->setContentsMargins(left_margin, top_margin, right_margin, bottom_margin); diff --git a/source/radeon_gpu_analyzer_gui/rg_status_bar.cpp b/source/radeon_gpu_analyzer_gui/rg_status_bar.cpp index 37b1b29..e84ab51 100644 --- a/source/radeon_gpu_analyzer_gui/rg_status_bar.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_status_bar.cpp @@ -45,7 +45,6 @@ static const char* kStrApiModeTreeWidgetStylesheet = "border: 1px solid black"; static const char* kStrApiModeTreeWidgetObjectName = "modeAPIList"; static const char* kStrCheckBoxDisabledIconFile = ":/icons/checked_disabled_icon.svg"; static const char* kStrCheckBoxIconLabelStylesheet = "border: none"; -static const QColor kApiModeTreeWidgetFirstColumnBackgroundColor = QColor(240, 240, 240); class RgApiTreeWidgetItemStyleDelegate : public QStyledItemDelegate { @@ -242,7 +241,6 @@ void RgStatusBar::CreateApiTreeWidget() QString toolTip = kStrApiButtonTooltipA + QString::fromStdString(display_string) + kStrApiButtonTooltipB; item->setToolTip(kTreeWidgetIconColumnId, toolTip); item->setToolTip(kTreeWidgetApiColumnId, toolTip); - item->setBackground(kTreeWidgetIconColumnId, kApiModeTreeWidgetFirstColumnBackgroundColor); } } api_mode_tree_widget_->resizeColumnToContents(kTreeWidgetApiColumnId); @@ -593,14 +591,13 @@ void RgStatusBar::HandleTreeWidgetItemEntered(QTreeWidgetItem* item, const int c } // Set the background color for the current item to light blue. - QColor light_blue(229, 243, 255); assert(item != nullptr); if (item != nullptr) { const int column_count = item->columnCount(); for (int column_number = 0; column_number < column_count; column_number++) { - item->setBackground(column_number, light_blue); + item->setBackground(column_number, qApp->palette().color(QPalette::Highlight)); } } } diff --git a/source/radeon_gpu_analyzer_gui/rg_status_bar_binary.cpp b/source/radeon_gpu_analyzer_gui/rg_status_bar_binary.cpp index 6e3d22a..e0fbf72 100644 --- a/source/radeon_gpu_analyzer_gui/rg_status_bar_binary.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_status_bar_binary.cpp @@ -22,7 +22,7 @@ static const QString kStrModePushButtonStylesheet( "background-color: rgba(160, 0, 160, 255);" "}" ); -static const QString kStrStatusBarBackgroundColorBinary = "background-color: rgb(128, 0, 128)"; +static const QString kStrStatusBarBackgroundColorBinary = "background-color: rgb(128, 0, 128); color: white;"; static const QColor kModePushButtonHoverColor = QColor(160, 0, 160, 255); static const QColor kModePushButtonNonHoverColor = QColor(128, 0, 128); diff --git a/source/radeon_gpu_analyzer_gui/rg_status_bar_opencl.cpp b/source/radeon_gpu_analyzer_gui/rg_status_bar_opencl.cpp index b61c2d4..f5f8c15 100644 --- a/source/radeon_gpu_analyzer_gui/rg_status_bar_opencl.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_status_bar_opencl.cpp @@ -21,7 +21,7 @@ static const QString kStrModePushButtonStylesheet( "background-color: rgba(20, 175, 0, 255);" "}" ); -static const QString kStrStatusBarBackgroundColorOpencl = "background-color: rgb(18, 152, 0)"; +static const QString kStrStatusBarBackgroundColorOpencl = "background-color: rgb(18, 152, 0); color: white;"; static const QColor kModePushButtonHoverColor = QColor(20, 175, 0, 255); static const QColor kModePushButtonNonHoverColor = QColor(18, 152, 0); diff --git a/source/radeon_gpu_analyzer_gui/rg_status_bar_vulkan.cpp b/source/radeon_gpu_analyzer_gui/rg_status_bar_vulkan.cpp index 59c71aa..d8ccbbc 100644 --- a/source/radeon_gpu_analyzer_gui/rg_status_bar_vulkan.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_status_bar_vulkan.cpp @@ -21,7 +21,7 @@ static const QString kStrModePushButtonStylesheet( "background-color: rgba(255, 36, 65, 255);" "}" ); -static const QString kStrStatusBarBackgroundColorVulkan = "background-color: rgb(224,30,55)"; +static const QString kStrStatusBarBackgroundColorVulkan = "background-color: rgb(224,30,55); color: white;"; static const QColor kModePushButtonHoverColor = QColor(255, 36, 65, 255); static const QColor kModePushButtonNonHoverColor = QColor(224, 30, 55, 255); diff --git a/source/radeon_gpu_analyzer_gui/rg_string_constants.h b/source/radeon_gpu_analyzer_gui/rg_string_constants.h index 5fa020a..4043b34 100644 --- a/source/radeon_gpu_analyzer_gui/rg_string_constants.h +++ b/source/radeon_gpu_analyzer_gui/rg_string_constants.h @@ -18,14 +18,14 @@ static const char* kStrAppFolderName = "RadeonGPUAnalyzer"; #ifdef __linux static const char* kStrExecutableName = "rga"; #else -static const char* kStrExecutableName = "rga.exe"; +static const char* kStrExecutableName = "rga.exe"; #endif // Projects folder name. #ifdef __linux static const char* kStrProjectsFolderName = "projects"; #else -static const char* kStrProjectsFolderName = "Projects"; +static const char* kStrProjectsFolderName = "Projects"; #endif // __linux // String used to build the window title text. @@ -79,7 +79,6 @@ static const char* kStrLogLaunchingCli = "Launching RGA CLI with c static const char* kStrLogExtractSettingsError = "Error reading settings file."; static const char* kStrLogCannotLoadBinaryCodeObject = "Failed to load binary code object file."; - // *** LOG FILE MESSAGES - END *** // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -233,13 +232,13 @@ static const char* kStrRestoreDefaultSettings = "Restore default settings."; // *** STATUS BAR STRINGS - START *** static const char* kStrStatusBarFileModifiedOutsideEnv = "The current file has been changed outside the environment."; -static const char* kStrStatusBarStarted = "started..."; -static const char* kStrStatusBarFailed = "failed"; -static const char* kStrStatusBarCanceled = "canceled"; -static const char* kStrStatusBarSucceeded = "succeeded"; -static const char* kStrStatusBarBuild = "Build "; -static const char* kStrStatusBarAnalysis = "Binary Analysis "; -static const char* kStrBuildCanceled = "Build canceled"; +static const char* kStrStatusBarStarted = "started..."; +static const char* kStrStatusBarFailed = "failed"; +static const char* kStrStatusBarCanceled = "canceled"; +static const char* kStrStatusBarSucceeded = "succeeded"; +static const char* kStrStatusBarBuild = "Build "; +static const char* kStrStatusBarAnalysis = "Binary Analysis "; +static const char* kStrBuildCanceled = "Build canceled"; // *** STATUS BAR STRINGS - END *** @@ -251,7 +250,7 @@ static const char* kStrBuildCanceled = "Build canceled"; #ifdef __linux static const char* kStrFileContextMenuOpenContainingFolder = "Show in file browser"; #else -static const char* kStrFileContextMenuOpenContainingFolder = "Show in explorer"; +static const char* kStrFileContextMenuOpenContainingFolder = "Show in explorer"; #endif static const char* kStrFileContextMenuRenameFile = "Rename"; static const char* kStrFileContextMenuRemoveFile = "Remove"; @@ -307,17 +306,17 @@ static const char* kStrMenuBarConfirmRemoveFileDialogTitle = "Remove file"; static const char* kStrMenuBarConfirmRemoveFileDialogWarning = " will be removed from the project. Are you sure?"; // Check if the user wants to reload an externally modified file. -static const char* kStrReloadFileDialogTitle = "Reload file"; -static const char* kStrReloadFileDialogText = "This file has been modified by another program.\nDo you want to reload it?"; -static const char* kStrReloadFileDialogTextBinary = "This file has been modified by another program.\nRGA will reload it."; +static const char* kStrReloadFileDialogTitle = "Reload file"; +static const char* kStrReloadFileDialogText = "This file has been modified by another program.\nDo you want to reload it?"; +static const char* kStrReloadFileDialogTextBinary = "This file has been modified by another program.\nRGA will reload it."; static const char* kStrCreateFileDialogTitle = "Create file"; static const char* kStrCreateFileDialogText = "Failed to find file, it may have been modified by an external program.\nDo you want to create it?"; static const char* kStrRemoveFileDialogTitle = "Remove file"; static const char* kStrRemoveFileDialogText = "Otherwise, the file will be removed from the project."; -static const char* kStrRemoveFileDialogTextBinary = "Failed to find file, it may have been modified by an external program.\nThe file will now be removed from this project."; - +static const char* kStrRemoveFileDialogTextBinary = + "Failed to find file, it may have been modified by an external program.\nThe file will now be removed from this project."; // Confirm that the user wants to revert to original SPIR-V binary shader file. static const char* kStrMenuBarVulkanConfirmRevertToOrigSpvA = "This will revert all SPIR-V assembly edits and restore the original SPIR-V binary from: "; @@ -583,10 +582,10 @@ static const char* kStrMainWindowStylesheetFileVulkan = "vulkan/rg_main_window_ static const char* kStrMainWindowStylesheetFileBinary = "binary/rg_main_window_style_binary.qss"; // Disassembly view frame border color. -static const char* kStrDisassemblyFrameBorderRedStylesheet = "QFrame#frame {border: 1px solid rgb(224,30,55)}"; -static const char* kStrDisassemblyFrameBorderGreenStylesheet = "QFrame#frame {border: 1px solid rgb(18, 152, 0)}"; +static const char* kStrDisassemblyFrameBorderRedStylesheet = "QFrame#frame {border: 1px solid rgb(224,30,55)}"; +static const char* kStrDisassemblyFrameBorderGreenStylesheet = "QFrame#frame {border: 1px solid rgb(18, 152, 0)}"; static const char* kStrDisassemblyFrameBorderPurpleStylesheet = "QFrame#frame {border: 1px solid rgb(128, 0, 128)}"; -static const char* kStrDisassemblyFrameBorderBlackStylesheet = "QFrame#frame {border: 1px solid black}"; +static const char* kStrDisassemblyFrameBorderBlackStylesheet = "QFrame#frame {border: 1px solid black}"; // Disassembly view frame selected. static const char* kStrDisassemblyFrameSelected = "selected"; @@ -646,13 +645,13 @@ static const char* kStrSettingsConfirmationApplicationSettings = "Application se #ifdef __linux static const char* kStrBuildViewFontFamily = "DejaVu Sans Mono"; #else -static const char* kStrBuildViewFontFamily = "Consolas"; +static const char* kStrBuildViewFontFamily = "Consolas"; #endif static const char* kStrBuildViewSettingsScrollarea = "settingsScrollArea"; static const char* kStrBuildViewSettingsScrollareaStylesheet = "QScrollArea#settingsScrollArea { background-color: transparent; }"; static const char* kStrBuildViewBuildSettingsWidgetStylesheetGreen = "#buildSettingsWidget { border: 1px solid rgb(18, 152, 0) }"; static const char* kStrBuildViewBuildSettingsWidgetStylesheetRed = "#buildSettingsWidget { border: 1px solid rgb(224, 30, 55); }"; -static const char* kStrBuildViewBuildSettingsWidgetStylesheetBlack = "#buildSettingsWidget { border: 1px solid black; }"; +static const char* kStrBuildViewBuildSettingsWidgetStylesheetBlack = "#buildSettingsWidget { border: 1px solid palette(text); }"; // *** BUILD VIEW FONT FAMILY - END *** @@ -676,4 +675,3 @@ static const char* kStrUpdatesResultsWindowTitle = "Available updates"; // *** CHECK FOR UPDATES DIALOG STRINGS - END *** #endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_RG_STRING_CONSTANTS_H_ - diff --git a/source/radeon_gpu_analyzer_gui/rg_syntax_highlighter.cpp b/source/radeon_gpu_analyzer_gui/rg_syntax_highlighter.cpp index 36e538b..b2841bb 100644 --- a/source/radeon_gpu_analyzer_gui/rg_syntax_highlighter.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_syntax_highlighter.cpp @@ -5,6 +5,10 @@ // Qt. #include +// QtCommon. +#include "qt_common/utils/qt_util.h" +#include "qt_common/utils/shared_isa_dictionary.h" + // Local. #include "radeon_gpu_analyzer_gui/qt/rg_syntax_highlighter.h" @@ -168,6 +172,17 @@ RgSyntaxHighlighter::Style RgSyntaxHighlighter::GetDefaultStyle() style.strings.setForeground(Qt::darkRed); style.preproc.setForeground(Qt::darkBlue); + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + // Dark mode needs a different set of syntax highlight colors. + style.keywords.setForeground(QColor(70, 150, 240)); + style.types.setForeground(QColor(70, 150, 240)); + style.functions.setForeground(QColor(210, 213, 164)); + style.comments.setForeground(QColor(106, 153, 62)); + style.strings.setForeground(QColor(211, 149, 106)); + style.preproc.setForeground(QColor(152, 217, 251)); + } + return style; } diff --git a/source/radeon_gpu_analyzer_gui/rg_target_gpus_dialog.cpp b/source/radeon_gpu_analyzer_gui/rg_target_gpus_dialog.cpp index 17baeb7..a076e7b 100644 --- a/source/radeon_gpu_analyzer_gui/rg_target_gpus_dialog.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_target_gpus_dialog.cpp @@ -32,7 +32,11 @@ class RgTableFilterProxyModel : public QSortFilterProxyModel { public: - RgTableFilterProxyModel(RgTargetGpusDialog* parent_dialog = nullptr) : QSortFilterProxyModel(parent_dialog), parent_Dialog(parent_dialog) {} + RgTableFilterProxyModel(RgTargetGpusDialog* parent_dialog = nullptr) + : QSortFilterProxyModel(parent_dialog) + , parent_Dialog(parent_dialog) + { + } virtual ~RgTableFilterProxyModel() = default; protected: @@ -74,9 +78,9 @@ bool RgTreeEventFilter::eventFilter(QObject* object, QEvent* event) return is_handled; } -RgTargetGpusDialog::RgTargetGpusDialog(const QString& selected_gpus, QWidget* parent) : - QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), - parent_(parent) +RgTargetGpusDialog::RgTargetGpusDialog(const QString& selected_gpus, QWidget* parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) + , parent_(parent) { ui_.setupUi(this); @@ -123,12 +127,10 @@ RgTargetGpusDialog::RgTargetGpusDialog(const QString& selected_gpus, QWidget* pa // Preprocess the gpu family names: since we get some family names // as a codename without the gfx notation, we would have to add the // gfx notation here again. - std::transform(selected_gpus_vector.begin(), selected_gpus_vector.end(), - selected_gpus_vector.begin(), [&](std::string& familyName) - { + std::transform(selected_gpus_vector.begin(), selected_gpus_vector.end(), selected_gpus_vector.begin(), [&](std::string& familyName) { std::stringstream fixed_name; - std::string gfx_notation; - bool hasGfxNotation = RgUtils::GetGfxNotation(familyName, gfx_notation); + std::string gfx_notation; + bool hasGfxNotation = RgUtils::GetGfxNotation(familyName, gfx_notation); if (hasGfxNotation && familyName.find("/") == std::string::npos) { fixed_name << gfx_notation << "/" << familyName; @@ -167,7 +169,7 @@ std::vector RgTargetGpusDialog::GetSelectedCapabilityGroups() const auto row_to_group_index_iter = table_row_index_to_group_index_.find(row_index); if (row_to_group_index_iter != table_row_index_to_group_index_.end()) { - int group_index = row_to_group_index_iter->second; + int group_index = row_to_group_index_iter->second; bool is_valid_index = (group_index >= 0 && group_index < capability_groups_.size()); assert(is_valid_index); if (is_valid_index) @@ -175,8 +177,8 @@ std::vector RgTargetGpusDialog::GetSelectedCapabilityGroups() const const CapabilityGroup& group_info = capability_groups_[group_index]; // Retrieve the compute capability string from the first row of the group. - std::string group_name = group_info.group_rows[0].compute_capability; - auto is_already_added_iter = std::find(selected_families.begin(), selected_families.end(), group_name); + std::string group_name = group_info.group_rows[0].compute_capability; + auto is_already_added_iter = std::find(selected_families.begin(), selected_families.end(), group_name); if (is_already_added_iter == selected_families.end()) { selected_families.push_back(group_name); @@ -199,12 +201,12 @@ void RgTargetGpusDialog::HandleItemChanged(QStandardItem* item) QModelIndex selected_item_index = item->index(); if (selected_item_index.isValid()) { - int selected_row = selected_item_index.row(); + int selected_row = selected_item_index.row(); auto group_index_iter = table_row_index_to_group_index_.find(selected_row); if (group_index_iter != table_row_index_to_group_index_.end()) { - int group_index = group_index_iter->second; - bool is_checked = (item->checkState() == Qt::Checked); + int group_index = group_index_iter->second; + bool is_checked = (item->checkState() == Qt::Checked); SetIsGroupChecked(group_index, is_checked); } @@ -212,7 +214,7 @@ void RgTargetGpusDialog::HandleItemChanged(QStandardItem* item) // Only allow the user to confirm their changes if there's at least one family selected. std::vector selected_families = GetSelectedCapabilityGroups(); - bool is_ok_enabled = !selected_families.empty(); + bool is_ok_enabled = !selected_families.empty(); // Update the enabledness of the dialog's OK button. ToggleOKButtonEnabled(is_ok_enabled); @@ -287,10 +289,10 @@ void RgTargetGpusDialog::HandleSearchTextChanged(const QString& search_text) void RgTargetGpusDialog::ComputeGroupColor(int group_index, QColor& color) const { // Use 25% saturation for a more muted color palette, but 100% value to maintain brightness. - static const int kBackgroundColorNumHueSteps = 10; + static const int kBackgroundColorNumHueSteps = 10; static const float kBackgroundColorHueStepIncrement = 1.0f / kBackgroundColorNumHueSteps; - static const float kBackgroundColorSaturation = 0.25f; - static const float kBackgroundColorValue = 1.0f; + static const float kBackgroundColorSaturation = 0.25f; + static const float kBackgroundColorValue = 1.0f; // If the number of groups exceeds the number of hue steps, reset the hue to the start of the color wheel. int color_group_index = group_index % kBackgroundColorNumHueSteps; @@ -298,6 +300,11 @@ void RgTargetGpusDialog::ComputeGroupColor(int group_index, QColor& color) const // Compute the group's color based on the group index vs. the total group count. float hue = color_group_index * kBackgroundColorHueStepIncrement; color.setHsvF(hue, kBackgroundColorSaturation, kBackgroundColorValue); + + if (QtCommon::QtUtils::ColorTheme::Get().GetColorTheme() == ColorThemeType::kColorThemeTypeDark) + { + color = color.darker(300); + } } void RgTargetGpusDialog::ConnectSignals() @@ -318,6 +325,10 @@ void RgTargetGpusDialog::ConnectSignals() is_connected = connect(this->ui_.cancelPushButton, &QPushButton::clicked, this, &RgTargetGpusDialog::HandleCancelButtonClicked); assert(is_connected); + is_connected = connect( + &QtCommon::QtUtils::ColorTheme::Get(), &QtCommon::QtUtils::ColorTheme::ColorThemeUpdated, this, &RgTargetGpusDialog::SetDefaultTableBackgroundColors); + assert(is_connected); + // Connect the tree's model to the check changed handler. ToggleItemCheckChangedHandler(true); } @@ -353,8 +364,8 @@ bool RgTargetGpusDialog::IsRowVisible(int row_index, const QModelIndex& source_p auto table_row_to_group_iter = table_row_index_to_group_index_.find(row_index); if (table_row_to_group_iter != table_row_index_to_group_index_.end()) { - int group_index = table_row_to_group_iter->second; - const CapabilityGroup& group_info = capability_groups_[group_index]; + int group_index = table_row_to_group_iter->second; + const CapabilityGroup& group_info = capability_groups_[group_index]; // Check if any of the cells associated with the group match the user's search string. for (const TableRow& current_row : group_info.group_rows) @@ -368,7 +379,6 @@ bool RgTargetGpusDialog::IsRowVisible(int row_index, const QModelIndex& source_p break; } } - } return is_filtered; @@ -441,7 +451,7 @@ std::string RgTargetGpusDialog::GetItemText(const QStandardItem* item) const void RgTargetGpusDialog::PopulateTableData(std::shared_ptr version_info, const std::string& mode) { // Create the GPU tree model, and fill it. - gpu_tree_model_ = new QStandardItemModel(0, ColumnType::kCount, this); + gpu_tree_model_ = new QStandardItemModel(0, ColumnType::kCount, this); QStandardItem* selected_checkbox = new QStandardItem(); selected_checkbox->setCheckable(true); @@ -460,11 +470,11 @@ void RgTargetGpusDialog::PopulateTableData(std::shared_ptr ver if (version_info != nullptr) { int current_row_index = 0; - int group_index = 0; + int group_index = 0; // Search the supported hardware data for the given mode's supported hardware list. auto current_mode_architectures_iter = version_info->gpu_architectures.find(mode); - bool is_mode_found = (current_mode_architectures_iter != version_info->gpu_architectures.end()); + bool is_mode_found = (current_mode_architectures_iter != version_info->gpu_architectures.end()); assert(is_mode_found); if (is_mode_found) { @@ -480,16 +490,16 @@ void RgTargetGpusDialog::PopulateTableData(std::shared_ptr ver const std::string& currentArchitecture = hardware_architecture.architecture_name; // Determine how many families are found within the architecture. - std::vector gpu_families = hardware_architecture.gpu_families; - int num_families_in_architecture = static_cast(gpu_families.size()); + std::vector gpu_families = hardware_architecture.gpu_families; + int num_families_in_architecture = static_cast(gpu_families.size()); // Set the gfx notation as prefix if applicable to the family name. // For example, "Tonga" would become "gfx802/Tonga". - for(int i = 0; i < num_families_in_architecture; i++) + for (int i = 0; i < num_families_in_architecture; i++) { - std::string gfx_notation; + std::string gfx_notation; std::stringstream family_name_revised; - bool has_gfx_notation = RgUtils::GetGfxNotation(gpu_families[i].family_name, gfx_notation); + bool has_gfx_notation = RgUtils::GetGfxNotation(gpu_families[i].family_name, gfx_notation); if (has_gfx_notation && !gfx_notation.empty()) { family_name_revised << gfx_notation << "/"; @@ -500,15 +510,16 @@ void RgTargetGpusDialog::PopulateTableData(std::shared_ptr ver // Sort the GPU families in reverse order so that for the new AMD // GPU naming scheme (gfxABCD) we will have the newer families on top. - std::sort(gpu_families.rbegin(), gpu_families.rend(), [&](RgGpuFamily familyA, - RgGpuFamily familyB) { return familyA.family_name < familyB.family_name; }); + std::sort(gpu_families.rbegin(), gpu_families.rend(), [&](RgGpuFamily familyA, RgGpuFamily familyB) { + return familyA.family_name < familyB.family_name; + }); // Step through each family within the architecture. for (int family_index = 0; family_index < num_families_in_architecture; family_index++) { // Create a copy of the family info and sort by product name. - RgGpuFamily family_sorted_by_product_name = gpu_families[family_index]; - const std::string& family_name = family_sorted_by_product_name.family_name; + RgGpuFamily family_sorted_by_product_name = gpu_families[family_index]; + const std::string& family_name = family_sorted_by_product_name.family_name; // Sort the product name column alphabetically. std::sort(family_sorted_by_product_name.product_names.begin(), family_sorted_by_product_name.product_names.end()); @@ -534,7 +545,7 @@ void RgTargetGpusDialog::PopulateTableData(std::shared_ptr ver checkbox_item->setCheckable(true); } - TableRow num_row = { current_row_index, currentArchitecture, product_name, family_name }; + TableRow num_row = {current_row_index, currentArchitecture, product_name, family_name}; capabilityGroup.group_rows.push_back(num_row); // Set the data for each column in the new row. @@ -594,7 +605,7 @@ void RgTargetGpusDialog::SetTableIndexData(int row, int column, const std::strin { // Generate an index and verify that it's valid. QModelIndex model_index = gpu_tree_model_->index(row, column); - bool is_valid = model_index.isValid(); + bool is_valid = model_index.isValid(); assert(is_valid); if (is_valid) { @@ -609,7 +620,7 @@ void RgTargetGpusDialog::SetTableBackgroundColor(int row, const QColor& backgrou for (int column_index = ColumnType::kSelectedCheckbox; column_index < ColumnType::kCount; ++column_index) { QModelIndex model_index = gpu_tree_model_->index(row, column_index); - bool is_valid = model_index.isValid(); + bool is_valid = model_index.isValid(); assert(is_valid); if (is_valid) { @@ -639,7 +650,7 @@ void RgTargetGpusDialog::ToggleRowChecked(const QModelIndex& source_model_index) if (source_item_model != nullptr) { QModelIndex checkbox_column_filtered_index = source_item_model->index(source_model_index.row(), ColumnType::kSelectedCheckbox); - bool is_filtered_index_valid = checkbox_column_filtered_index.isValid(); + bool is_filtered_index_valid = checkbox_column_filtered_index.isValid(); assert(is_filtered_index_valid); if (is_filtered_index_valid) { @@ -652,7 +663,7 @@ void RgTargetGpusDialog::ToggleRowChecked(const QModelIndex& source_model_index) if (clicked_item != nullptr) { // Determine the current check state for the row's checkbox item. - int group_index = group_index_iter->second; + int group_index = group_index_iter->second; bool check_state = (clicked_item->checkState() == Qt::Checked) ? true : false; // Toggle the checkbox for the entire group of products. diff --git a/source/radeon_gpu_analyzer_gui/rg_tree_widget.cpp b/source/radeon_gpu_analyzer_gui/rg_tree_widget.cpp index fc841bd..2468b63 100644 --- a/source/radeon_gpu_analyzer_gui/rg_tree_widget.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_tree_widget.cpp @@ -39,11 +39,10 @@ void RgTreeWidget::mouseMoveEvent(QMouseEvent* event) { setCursor(Qt::PointingHandCursor); - QColor light_blue(229, 243, 255); const int column_count = item->columnCount(); for (int column_number = 0; column_number < column_count; column_number++) { - item->setBackground(column_number, light_blue); + item->setBackground(column_number, qApp->palette().color(QPalette::Highlight)); } // Pass the event onto the base class. diff --git a/source/radeon_gpu_analyzer_gui/rg_utils.cpp b/source/radeon_gpu_analyzer_gui/rg_utils.cpp index 9d91194..a59f7b8 100644 --- a/source/radeon_gpu_analyzer_gui/rg_utils.cpp +++ b/source/radeon_gpu_analyzer_gui/rg_utils.cpp @@ -1461,19 +1461,6 @@ void RgUtils::StyleRepolish(QWidget* widget, bool repolish_children) } } -void RgUtils::SetBackgroundColor(QWidget* widget, const QColor& color) -{ - assert(widget != nullptr); - if (widget != nullptr) - { - // Set the background color. - QPalette palette = widget->palette(); - palette.setColor(QPalette::Window, color); - widget->setAutoFillBackground(true); - widget->setPalette(palette); - } -} - std::string RgUtils::TruncateString(const std::string& text, unsigned int num_front_chars, unsigned int num_back_chars, diff --git a/source/radeon_gpu_analyzer_gui/rg_utils.h b/source/radeon_gpu_analyzer_gui/rg_utils.h index 1b33a2f..78eacc6 100644 --- a/source/radeon_gpu_analyzer_gui/rg_utils.h +++ b/source/radeon_gpu_analyzer_gui/rg_utils.h @@ -109,9 +109,6 @@ class RgUtils // Re-polish the widget from it's style (this is useful for applying style changes after modifying a dynamic property). static void StyleRepolish(QWidget* widget, bool repolish_children = false); - // Set the background color for the given widget to the given color. - static void SetBackgroundColor(QWidget* widget, const QColor& color); - // *********** // Qt - END. // *********** diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_opencl.ui b/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_opencl.ui index 69338b6..75d3897 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_opencl.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_opencl.ui @@ -1,6 +1,6 @@ - RgBuildSettingsViewOpenCL + rgBuildSettingsViewOpenCL @@ -30,7 +30,7 @@ 0 - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 0 @@ -62,10 +62,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -211,10 +211,12 @@ - 75 true + + false + OpenCL options @@ -253,14 +255,14 @@ - + Enable MAD instructions - + Ignore the signedness of zeros @@ -293,41 +295,13 @@ - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 75 - true - - - - General - - - 0 - - - - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -437,10 +411,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -530,10 +504,12 @@ - 75 true + + false + Alternative compiler @@ -571,10 +547,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -585,7 +561,7 @@ - + Assume no NaN nor infinite @@ -626,10 +602,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -639,15 +615,45 @@ + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + true + + + + false + + + General + + + 0 + + + - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -673,10 +679,12 @@ - 75 true + + true + Settings command line @@ -688,10 +696,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -723,10 +731,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -752,10 +760,12 @@ - 75 true + + false + Additional clang options @@ -767,10 +777,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -799,7 +809,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_vulkan.ui b/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_vulkan.ui index 09cce0e..574ff73 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_vulkan.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_build_settings_view_vulkan.ui @@ -1,13 +1,13 @@ - RgBuildSettingsViewVulkan + rgBuildSettingsViewVulkan 0 0 1200 - 650 + 824 @@ -51,7 +51,7 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus Allow block offsets to follow HLSL rules works independently of source language. @@ -63,9 +63,9 @@ - - Custom output binary file name. - + + Custom output binary file name. + Name of output binary file @@ -94,10 +94,12 @@ - 75 true + + false + @@ -114,9 +116,9 @@ Enable Vulkan validation layers. - - background-color: white; - + + + Enable validation layers @@ -160,10 +162,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -192,10 +194,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -228,10 +230,12 @@ - 75 true + + false + @@ -272,10 +276,12 @@ - 75 true + + false + @@ -312,10 +318,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -341,10 +347,12 @@ - 75 true + + false + @@ -359,10 +367,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -451,10 +459,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -499,17 +507,17 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -561,10 +569,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -577,7 +585,7 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus Perform IO mapping in HLSL register space. @@ -612,7 +620,7 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus Generate debug information. @@ -625,7 +633,7 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus Automatically bind uniform variables without explicit bindings. @@ -673,10 +681,12 @@ - 75 true + + false + @@ -691,10 +701,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -726,10 +736,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -742,10 +752,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -765,13 +775,15 @@ - 75 true - - Settings for any custom output file names. - + + Settings for any custom output file names. + + + false + Output files @@ -808,7 +820,7 @@ glslangOptionsLineEdit compilerBinariesLineEdit compilerBrowseButton - outputFileBinaryNameLineEdit + outputFileBinaryNameLineEdit allOptionsTextEdit diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_editor_element.ui b/source/radeon_gpu_analyzer_gui/ui/rg_editor_element.ui index 37bb1c9..7388023 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_editor_element.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_editor_element.ui @@ -1,7 +1,7 @@ RgEditorElement - + 0 @@ -30,7 +30,7 @@ 0 - QLayout::SetNoConstraint + QLayout::SizeConstraint::SetNoConstraint 0 @@ -71,10 +71,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -93,15 +93,11 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus - - - :/icons/expand_file_item.svg:/icons/expand_file_item.svg - false @@ -113,7 +109,7 @@ - Qt::ClickFocus + Qt::FocusPolicy::ClickFocus @@ -126,10 +122,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -166,7 +162,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_find_text_widget.ui b/source/radeon_gpu_analyzer_gui/ui/rg_find_text_widget.ui index 73a47f9..00cc1f0 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_find_text_widget.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_find_text_widget.ui @@ -1,7 +1,7 @@ RgFindTextWidget - + 0 @@ -28,421 +28,6 @@ 58 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - Form @@ -631,7 +216,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_global_settings_view.ui b/source/radeon_gpu_analyzer_gui/ui/rg_global_settings_view.ui index 1baafb1..430c016 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_global_settings_view.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_global_settings_view.ui @@ -6,7 +6,7 @@ 0 0 - 1200 + 1138 777 @@ -52,125 +52,44 @@ 6 - - - - Log file location - - - - - - - - 0 - 0 - - + + 0 - 0 + 25 - - true - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed + + + true + - - - 20 - 5 - + + Disassembly view - + - - - - - 0 - 0 - - + + 0 - 0 + 25 - - - - - - - 0 - 0 - + + + true + - Default API on startup + General - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed - - - - 20 - 5 - - - - - - - - - - - 150 - 25 - - - - false - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - + + 30 @@ -182,24 +101,8 @@ - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed - - - - 20 - 5 - - - - - - + + 0 @@ -212,16 +115,45 @@ - General + Input files - - + + + + true + + + <system default> + + + true + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + - + - + 0 0 @@ -232,35 +164,42 @@ 25 - - false - - GLSL + Prompt on startup 0 - GLSL + Prompt on startup - HLSL + Binary Analysis + + + + + OpenCL + + + + + Vulkan - + Qt::Orientation::Horizontal - 50 + 40 20 @@ -268,37 +207,45 @@ - - + + + + + 0 + 25 + + + + + true + + - Font + Source code editor - - - - Associate file extensions with SPIR-V binary + + + + true - - + + - + 0 0 - - - 0 - 0 - + + Default API on startup - + @@ -311,15 +258,15 @@ - - + + - Associate file extensions with GLSL + Project file location - - + + Qt::Orientation::Vertical @@ -334,12 +281,84 @@ - - + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Fixed + + + + 20 + 5 + + + + + + + + Associate file extensions with GLSL + + + + + + + + 0 + 0 + + + + + 88 + 0 + + + + Columns + + + + + - + + + + 150 + 25 + + + + false + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + - + 0 0 @@ -350,42 +369,35 @@ 25 + + false + - Prompt on startup + GLSL 0 - Prompt on startup - - - - - Binary Analysis - - - - - OpenCL + GLSL - Vulkan + HLSL - + Qt::Orientation::Horizontal - 40 + 50 20 @@ -393,68 +405,8 @@ - - - - Associate file extensions with SPIR-V text - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - background-color: white; - - - Always use auto-generated project names - - - - - - - - 0 - 25 - - - - - true - - - - Disassembly view - - - - - - - true - - - <system default> - - - true - - - - - + + Qt::Orientation::Vertical @@ -469,48 +421,7 @@ - - - - - 0 - 25 - - - - - true - - - - Source code editor - - - - - - - Open include files with - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - @@ -526,7 +437,7 @@ - + Qt::Orientation::Vertical @@ -542,36 +453,23 @@ - - - - - 30 - 16777215 - - - - ... - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed + + + + + 0 + 0 + - + - 20 - 5 + 0 + 0 - + - + @@ -607,54 +505,124 @@ - + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Fixed + + + + 20 + 20 + + + + + Associate file extensions with HLSL - - + + + + Disassembly view columns + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Fixed + + + + 20 + 5 + + + + + + + + Associate file extensions with SPIR-V binary + + + + + + + Font size + + + + + + + Log file location + + + + + + + + 0 + 0 + + 0 25 - - - true - + + - Input files + Always use auto-generated project names - - + + - Project file location + Open include files with - - + + - Font size + Associate file extensions with SPIR-V text - - + + + + + 30 + 16777215 + + - Disassembly view columns + ... - - + + Qt::Orientation::Vertical @@ -664,43 +632,43 @@ 20 - 20 + 5 - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed + + + + + 0 + 0 + - + - 20 - 20 + 0 + 0 - + - - + + - + 0 0 - 88 + 0 0 - - Columns + + true @@ -717,10 +685,49 @@ - - - - true + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Fixed + + + + 20 + 20 + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Fixed + + + + 20 + 5 + + + + + + + + Font + + + + + + + Color Theme: Light diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_isa_disassembly_view.ui b/source/radeon_gpu_analyzer_gui/ui/rg_isa_disassembly_view.ui index 3ab24ee..c41f87e 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_isa_disassembly_view.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_isa_disassembly_view.ui @@ -1,13 +1,13 @@ RgIsaDisassemblyView - + 0 0 - 1009 - 759 + 644 + 621 @@ -41,7 +41,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 0 @@ -101,7 +101,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -130,7 +130,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -181,7 +181,7 @@ - Qt::LeftToRight + Qt::LayoutDirection::LeftToRight Full Kernel Name Label @@ -190,14 +190,14 @@ false - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - Qt::Horizontal + Qt::Orientation::Horizontal @@ -224,13 +224,13 @@ - border: 1px solid black; + - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -254,7 +254,7 @@ border: none; - Qt::Vertical + Qt::Orientation::Vertical 0 diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_main_window.ui b/source/radeon_gpu_analyzer_gui/ui/rg_main_window.ui index 009f5ef..6bac82f 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_main_window.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_main_window.ui @@ -1,7 +1,7 @@ RgMainWindow - + 0 @@ -79,12 +79,12 @@ 0 + + + START - - background-color: rgb(255, 255, 255); - 0 @@ -111,10 +111,7 @@ - QWidget#settingsTab -{ -background:white; -} + SETTINGS @@ -176,7 +173,7 @@ background:white; 0 0 800 - 31 + 22 diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_menu_build_settings_item.ui b/source/radeon_gpu_analyzer_gui/ui/rg_menu_build_settings_item.ui index dd7e443..02d5f16 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_menu_build_settings_item.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_menu_build_settings_item.ui @@ -1,6 +1,6 @@ - RgMenuBuildSettingsItem + rgMenuBuildSettingsItem @@ -51,12 +51,11 @@ - 50 false - Qt::NoFocus + Qt::FocusPolicy::NoFocus @@ -68,6 +67,9 @@ :/icons/gear_icon.svg:/icons/gear_icon.svg + + false + diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_menu_file_item_opencl.ui b/source/radeon_gpu_analyzer_gui/ui/rg_menu_file_item_opencl.ui index fbac7eb..5cfe015 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_menu_file_item_opencl.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_menu_file_item_opencl.ui @@ -1,6 +1,6 @@ - RgMenuFileItemOpenCL + rgMenuFileItemOpenCL @@ -134,7 +134,6 @@ - 75 true @@ -167,7 +166,7 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus @@ -187,7 +186,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -234,39 +233,13 @@ false - QTreeView -{ -background: rgb(246, 246, 246); -} - -QTreeView::item:hover -{ - /* Grey when hovering over an item.*/ - color: #000000; - background:#d3d3d3; -} - -QTreeView::item:selected:active -{ - /* Light yellow when the item is actively selected.*/ - color: #000000; - background:#ffffb2; -} - -QTreeView::item:selected:!active -{ - /* Light yellow when the item is selected but active.*/ - color: #000000; - background:#ffffb2; -} - - + - QAbstractScrollArea::AdjustToContents + QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers 11 diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_menu_pipeline_state_item.ui b/source/radeon_gpu_analyzer_gui/ui/rg_menu_pipeline_state_item.ui index 7acc9fc..3d4de09 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_menu_pipeline_state_item.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_menu_pipeline_state_item.ui @@ -1,6 +1,6 @@ - RgMenuPipelineStateItem + rgMenuPipelineStateItem @@ -51,12 +51,11 @@ - 50 false - Qt::NoFocus + Qt::FocusPolicy::NoFocus @@ -68,6 +67,9 @@ :/icons/state_settings_cube.svg:/icons/state_settings_cube.svg + + false + diff --git a/source/radeon_gpu_analyzer_gui/ui/rg_start_tab.ui b/source/radeon_gpu_analyzer_gui/ui/rg_start_tab.ui index 5198c79..0b6750c 100644 --- a/source/radeon_gpu_analyzer_gui/ui/rg_start_tab.ui +++ b/source/radeon_gpu_analyzer_gui/ui/rg_start_tab.ui @@ -52,7 +52,6 @@ 12 - 75 true @@ -64,10 +63,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -82,7 +81,6 @@ 12 - 75 true @@ -94,10 +92,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -129,10 +127,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -147,7 +145,6 @@ 12 - 75 true @@ -159,10 +156,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -172,7 +169,7 @@ - + @@ -185,7 +182,7 @@ 3 - QLayout::SetFixedSize + QLayout::SizeConstraint::SetFixedSize 0 @@ -202,7 +199,7 @@ - + false @@ -212,7 +209,7 @@ - + true @@ -230,10 +227,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -248,7 +245,6 @@ 12 - 75 true @@ -260,10 +256,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -290,21 +286,21 @@ 0 - + About RGA - + Help manual - + Getting started guide @@ -316,7 +312,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/source/utils/dx12/backend/main.cpp b/source/utils/dx12/backend/main.cpp index bd90957..43c22f8 100644 --- a/source/utils/dx12/backend/main.cpp +++ b/source/utils/dx12/backend/main.cpp @@ -42,24 +42,12 @@ static const char* kStrErrorNoDxrStateDescriptionFile = "Error: no DXR state des static const char* kStrInfoCompilingComputePipeline = "Compiling compute pipeline..."; static const char* kStrInfoCompilingGraphicsPipeline = "Compiling graphics pipeline..."; static const char* kStrInfoCompilingDxrPipeline = "Compiling ray tracing pipeline..."; -static const char* kStrInfoCompilingDxrShader = "Compiling ray tracing shader..."; // *** CONSTANTS - END *** // *** INTERNALLY LINKED UTILITIES - START *** -// Returns true if the user specified a DXR configuration. -static bool IsDxrConfig(const rga::RgDx12Config &config, bool& is_pipeline_mode, bool& is_shader_mode) -{ - const char* kStrModePipeline = "pipeline"; - const char* kStrModeShader = "shader"; - std::string mode_lower = rga::RgDx12Utils::ToLower(config.dxr_mode); - is_pipeline_mode = mode_lower.compare(kStrModePipeline) == 0; - is_shader_mode = !is_pipeline_mode && mode_lower.compare(kStrModeShader) == 0; - return (is_pipeline_mode || is_shader_mode); -} - // Validates the inputs, prints error messages as // necessary and also adjusts the configuration as necessary. // Returns true if valid, otherwise returns false. @@ -87,9 +75,7 @@ static bool IsInputValid(rga::RgDx12Config& config) } else { - bool is_dxr_pipeline = false; - bool is_dxr_shader = false; - bool is_dxr = IsDxrConfig(config, is_dxr_pipeline, is_dxr_shader); + bool is_dxr = config.is_config_dxr; if (is_dxr) { if (config.dxr_state_file.empty() && config.dxr_hlsl_input.empty()) @@ -314,24 +300,17 @@ int main(int argc, char* argv[]) cxxopts::value(config.rs_pso)) // DXR options. - ("mode", "Compilation mode (Pipeline or Shader).", - cxxopts::value(config.dxr_mode)) + ("dxr", "Set compilation mode as DXR. Default mode is DX12.", + cxxopts::value(config.is_config_dxr)) ("state-desc", "Full path to the DXR state description JSON file.", cxxopts::value(config.dxr_state_file)) - ("export", "The name of the export to target, could be a raygeneration shader " - "name in Pipeline mode or a shader name in Shader mode.", - cxxopts::value(config.dxrExport)) - ("dxr-isa", "Full path to DXR ISA disassembly output file.", - cxxopts::value(config.dxr_isa_output)) - ("dxr-stats", "Full path to DXR hardware usage statistics output file.", - cxxopts::value(config.dxr_statistics_output)) ("dxr-bin", "Full path to DXR pipeline binary output file.", cxxopts::value(config.dxr_binary_output)) ("dxr-hlsl-mapping", "HLSL->DXIL mapping (optional).", cxxopts::value(config.dxr_hlsl_mapping)) - ("output-metadata", "Full path to output metadata file.", + ("output-metadata", "Full path to output metadata file.", cxxopts::value(config.output_metadata)) - ("hlsl", "Full path to input HLSL file.", + ("hlsl", "Full path to input HLSL file.", cxxopts::value(config.dxr_hlsl_input)) // General options. @@ -361,9 +340,7 @@ int main(int argc, char* argv[]) if (is_input_valid) { // Check if this is a DXR or standard graphics or compute pipeline. - bool is_dxr_pipeline = false; - bool is_dxr_shader = false; - bool is_dxr = IsDxrConfig(config, is_dxr_pipeline, is_dxr_shader); + bool is_dxr = config.is_config_dxr; if (config.should_enable_debug_layer) { @@ -434,15 +411,8 @@ int main(int argc, char* argv[]) if (is_dxr) { #ifdef RGA_DXR_ENABLED - // DXR pipeline or shader. - if (is_dxr_pipeline) - { - std::cout << kStrInfoCompilingDxrPipeline << std::endl; - } - else - { - std::cout << kStrInfoCompilingDxrShader << std::endl; - } + // DXR pipeline. + std::cout << kStrInfoCompilingDxrPipeline << std::endl; is_ok = rgFrontend.CompileRayTracingPipeline(config, error_msg); #endif } diff --git a/source/utils/dx12/backend/rg_dx12_backend.cpp b/source/utils/dx12/backend/rg_dx12_backend.cpp index 3e4d81a..4d28d9f 100644 --- a/source/utils/dx12/backend/rg_dx12_backend.cpp +++ b/source/utils/dx12/backend/rg_dx12_backend.cpp @@ -463,16 +463,10 @@ namespace rga std::vector& binary, std::string& error_msg) const; - // Creates the state object and extracts the results for a single pipeline designated by the raygeneration shader name. - bool CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - std::vector>>>& raytracing_shader_stats, - std::vector>>& pipeline_binary, - std::vector& is_unified_mode, std::vector>>& indirect_shader_names, - std::string& error_msg) const; - - // Creates the state object and extracts the results for a single pipeline designated by the raygeneration shader name. - bool CreateStateObjectShader(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, const std::wstring& raygen_shader_name, - RgDx12ShaderResultsRayTracing& raytracing_shader_stats, std::vector& pipeline_binary, std::string& error_msg) const; + // Creates the state object and extracts the compiled code object binaries for a single pipeline designated by the raygeneration shader name. + bool CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, + std::vector>>& pipeline_binary, + std::string& error_msg) const; private: HMODULE LoadUMDLibrary(bool is_offline_session); @@ -745,12 +739,10 @@ namespace rga } #ifdef RGA_DXR_ENABLED + bool RgDx12Backend::Impl::CreateStateObject( const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - std::vector>>>& raytracing_shader_stats, std::vector>>& pipeline_binaries, - std::vector& is_unified_mode, - std::vector>>& indirect_shader_names, std::string& error_msg) const { assert(amd_shader_analyzer_ext_ != nullptr); @@ -771,289 +763,42 @@ namespace rga ret = (SUCCEEDED(hr)); if (ret) { - // Allocate enough elements to store the flags for all generated pipelines. - is_unified_mode.resize(pipeline_count); - - bool is_indirect_mode = false; for (uint32_t pipeline_index = 0; pipeline_index < pipeline_count; ++pipeline_index) { - // Tracking the shader names for the current pipeline. - std::shared_ptr> pipeline_shader_names = std::make_shared>(); - std::shared_ptr>> stats = - std::make_shared>>(); - - // Check if the pipeline was compiled in Unified or Indirect mode. - hr = amd_shader_analyzer_ext_->IsRayTracingPipelineIndirect(*pipeline_handle, pipeline_index, &is_indirect_mode); - is_unified_mode[pipeline_index] = !is_indirect_mode; - assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) + bool is_binary_extraction_supported = (pipeline_count > 0); + if (is_binary_extraction_supported) { - if (is_unified_mode[pipeline_index]) + // Extract the pipeline binary. + // Retrieve the buffer size. + uint32_t buffer_size = 0; + hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary(*pipeline_handle, pipeline_index, nullptr, &buffer_size); + assert(buffer_size > 0); + assert(SUCCEEDED(hr)); + if (buffer_size > 0 && SUCCEEDED(hr)) { - // Retrieve shader name. - size_t name_bytes = 0; - const uint32_t kShaderIndex = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderName( - *pipeline_handle, pipeline_index, kShaderIndex, &name_bytes, nullptr); + // Get the contents. + std::shared_ptr> binary = std::make_shared>(); + binary->resize(buffer_size); + hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary(*pipeline_handle, pipeline_index, binary->data(), &buffer_size); assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) + assert(!binary->empty()); + if (binary->empty()) { - std::wstring curr_shader_name_wide; - curr_shader_name_wide.resize(name_bytes); - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderName( - *pipeline_handle, pipeline_index, kShaderIndex, &name_bytes, (wchar_t*)curr_shader_name_wide.data()); - if (!curr_shader_name_wide.empty()) - { - // Convert the export name to non-wide string. - std::string raygen_shader_name_as_str = RgDx12Utils::wstrToStr(curr_shader_name_wide); - - // Track the raygeneration shader name. - pipeline_shader_names->push_back(raygen_shader_name_as_str); - - // Retrieve results for this pipeline. - std::shared_ptr curr_item = std::make_shared(); - stats->push_back(curr_item); - - // Retrieve the disassembly for the pipeline. - size_t diassembly_bytes = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineIsaDisassembly( - *pipeline_handle, curr_shader_name_wide.c_str(), nullptr, &diassembly_bytes); - assert(SUCCEEDED(hr)); - ret = (SUCCEEDED(hr)); - if (ret && diassembly_bytes > 0) - { - curr_item->disassembly = new char[diassembly_bytes]{}; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineIsaDisassembly( - *pipeline_handle, curr_shader_name_wide.c_str(), curr_item->disassembly, &diassembly_bytes); - assert(SUCCEEDED(hr)); - assert(curr_item->disassembly != nullptr); - if (!SUCCEEDED(hr) || curr_item->disassembly == nullptr) - { - std::stringstream msg; - msg << kStrErrorDisassemblyContentsExtractionFailure << kStrErrorPipelineIdentifiedByRaygenShaderName - << raygen_shader_name_as_str; - error_msg.append(msg.str()); - ret = false; - } - } - else - { - std::stringstream msg; - std::string shader_name_str = RgDx12Utils::wstrToStr(curr_shader_name_wide); - msg << kStrErrorDisassemblySizeExtractionFailure << kStrErrorPipelineIdentifiedByRaygenShaderName - << shader_name_str; - msg << kStrHintWrongShaderName1 << kStrHintWrongShaderName2Raygen; - error_msg.append(msg.str()); - ret = false; - } - - if (ret) - { - // Retrieve the statistics. - AmdExtD3DShaderStatsRayTracing rt_stats_driver{}; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineStats( - *pipeline_handle, curr_shader_name_wide.c_str(), &rt_stats_driver); - assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) - { - ExtractRayTracingStats(*curr_item, rt_stats_driver); - } - else - { - std::stringstream msg; - msg << kStrErrorStatisticsExtractionFailure << kStrErrorPipelineIdentifiedByRaygenShaderName - << raygen_shader_name_as_str; - error_msg.append(msg.str()); - ret = false; - } - - bool is_binary_extraction_supported = (pipeline_count > 0); - if (is_binary_extraction_supported) - { - // Extract the pipeline binary. - // Retrieve the buffer size. - uint32_t buffer_size = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary( - *pipeline_handle, pipeline_index, nullptr, &buffer_size); - assert(buffer_size > 0); - assert(SUCCEEDED(hr)); - if (buffer_size > 0 && SUCCEEDED(hr)) - { - // Get the contents. - std::shared_ptr> binary = std::make_shared>(); - binary->resize(buffer_size); - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary( - *pipeline_handle, pipeline_index, binary->data(), &buffer_size); - assert(SUCCEEDED(hr)); - assert(!binary->empty()); - if (binary->empty()) - { - std::stringstream msg; - msg << kStrErrorPipelineBinaryExtractionFailure << kStrErrorPipelineIdentifiedByRaygenShaderName - << raygen_shader_name_as_str; - } - - // Track the pipeline binary. - pipeline_binaries.push_back(binary); - } - else - { - std::stringstream msg; - msg << kStrErrorPipelineBinarySizeQueryFailure << kStrErrorPipelineIdentifiedByRaygenShaderName - << raygen_shader_name_as_str; - } - } - } - } + std::stringstream msg; + msg << kStrErrorPipelineBinaryExtractionFailure << kStrErrorPipelineIdentifiedByIndexPipelineBinary << pipeline_index << "\n"; + error_msg.append(msg.str()); } + + // Track the pipeline binary. + pipeline_binaries.push_back(binary); } else { - // The driver used Indirect compilation. - // Check how many shaders were created for this pipeline. - uint32_t shader_count = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderCount(*pipeline_handle, pipeline_index, &shader_count); - assert(shader_count > 0); - for (uint32_t shader_index = 0; shader_index < shader_count; shader_index++) - { - // Retrieve shader name. - size_t name_bytes = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderName( - *pipeline_handle, pipeline_index, shader_index, &name_bytes, nullptr); - assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) - { - std::wstring curr_shader_name_wide; - curr_shader_name_wide.resize(name_bytes); - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderName( - *pipeline_handle, pipeline_index, shader_index, &name_bytes, (wchar_t*)curr_shader_name_wide.data()); - if (!curr_shader_name_wide.empty()) - { - // Convert the shader name to non-wide string. - std::string curr_shader_name_as_str = RgDx12Utils::wstrToStr(curr_shader_name_wide); - pipeline_shader_names->push_back(curr_shader_name_as_str); - - // Retrieve shader disassembly. - std::shared_ptr curr_results = std::make_shared(); - size_t diassembly_bytes = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingShaderIsaDisassembly( - *pipeline_handle, curr_shader_name_wide.c_str(), nullptr, &diassembly_bytes); - assert(SUCCEEDED(hr)); - ret = (SUCCEEDED(hr)); - if (ret && diassembly_bytes > 0) - { - curr_results->disassembly = new char[diassembly_bytes]{}; - hr = amd_shader_analyzer_ext_->GetRayTracingShaderIsaDisassembly( - *pipeline_handle, curr_shader_name_wide.c_str(), curr_results->disassembly, &diassembly_bytes); - assert(SUCCEEDED(hr)); - assert(curr_results->disassembly != nullptr); - if (!SUCCEEDED(hr) || curr_results->disassembly == nullptr) - { - std::stringstream msg; - msg << kStrErrorDisassemblyContentsExtractionFailure - << kStrErrorDisassemblyContentsExtractionFailurePiplineNumber << pipeline_index << " " - << kStrErrorPerShaderName << curr_shader_name_wide.c_str(); - error_msg.append(msg.str()); - ret = false; - } - } - else - { - std::stringstream msg; - msg << kStrErrorDisassemblySizeExtractionFailure << kStrErrorDisassemblyContentsExtractionFailurePiplineNumber - << pipeline_index << " " << kStrErrorPerShaderName << curr_shader_name_wide.c_str(); - error_msg.append(msg.str()); - ret = false; - } - - // Retrieve the statistics. - AmdExtD3DShaderStatsRayTracing rt_stats_driver{}; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineStats( - *pipeline_handle, curr_shader_name_wide.c_str(), &rt_stats_driver); - assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) - { - ExtractRayTracingStats(*curr_results, rt_stats_driver); - } - else - { - std::stringstream msg; - msg << kStrErrorStatisticsExtractionFailure << kStrErrorDisassemblyContentsExtractionFailurePiplineNumber - << pipeline_index << " " << kStrErrorPerShaderName << curr_shader_name_wide.c_str(); - error_msg.append(msg.str()); - ret = false; - } - - // Track the current results. - stats->push_back(curr_results); - } - else - { - std::stringstream msg; - msg << kStrErrorDxrEmptyShaderName << shader_index; - error_msg.append(msg.str()); - ret = false; - } - } - else - { - std::stringstream msg; - msg << kStrErrorDxrFailedToRetrieveShaderName << shader_index << " " << kStrErrorPipelineIdentifiedByIndex - << pipeline_index; - error_msg.append(msg.str()); - ret = false; - } - } - - bool is_binary_extraction_supported = (pipeline_count > 0); - if (is_binary_extraction_supported) - { - // Retrieve the buffer size. - uint32_t buffer_size = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary(*pipeline_handle, pipeline_index, nullptr, &buffer_size); - assert(buffer_size > 0); - assert(SUCCEEDED(hr)); - if (buffer_size > 0 && SUCCEEDED(hr)) - { - // Get the contents. - std::shared_ptr> binary = std::make_shared>(); - binary->resize(buffer_size); - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineElfBinary( - *pipeline_handle, pipeline_index, binary->data(), &buffer_size); - assert(SUCCEEDED(hr)); - assert(!binary->empty()); - if (!binary->empty()) - { - pipeline_binaries.push_back(binary); - } - else - { - std::stringstream msg; - msg << kStrErrorPipelineBinaryExtractionFailure << kStrErrorPipelineIdentifiedByIndexPipelineBinary - << pipeline_index; - } - } - else - { - std::stringstream msg; - msg << kStrErrorPipelineBinarySizeQueryFailure << kStrErrorPipelineIdentifiedByIndexPipelineBinary << pipeline_index; - } - } + std::stringstream msg; + msg << kStrErrorPipelineBinarySizeQueryFailure << kStrErrorPipelineIdentifiedByIndexPipelineBinary << pipeline_index << "\n"; + error_msg.append(msg.str()); } } - else - { - std::stringstream msg; - msg << kStrErrorDxrFailedToCheckPipelineCompilationType << pipeline_index; - error_msg.append(msg.str()); - ret = false; - } - - // Track the shader names. - indirect_shader_names.push_back(pipeline_shader_names); - - // Track the results of the current indirect pipeline. - raytracing_shader_stats.push_back(stats); } } } @@ -1068,88 +813,6 @@ namespace rga return ret; } - bool RgDx12Backend::Impl::CreateStateObjectShader(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - const std::wstring& shader_name, RgDx12ShaderResultsRayTracing& shader_stats, std::vector&, std::string& error_msg) const - { - assert(amd_shader_analyzer_ext_ != nullptr); - bool ret = amd_shader_analyzer_ext_ != nullptr; - if (ret) - { - AmdExtD3DPipelineHandle* pipeline_handle = new AmdExtD3DPipelineHandle{}; - ID3D12StateObject* dxr_state_object = nullptr; - HRESULT hr = amd_shader_analyzer_ext_->CreateStateObject(ray_tracing_state_object, - IID_PPV_ARGS(&dxr_state_object), pipeline_handle); - assert(SUCCEEDED(hr)); - ret = (SUCCEEDED(hr)); - if (ret) - { - // Convert the shader name to std::string for presentation purposes. - std::string shader_name_std_str = RgDx12Utils::wstrToStr(shader_name); - - // Retrieve the disassembly for the pipeline. - size_t diassembly_bytes = 0; - hr = amd_shader_analyzer_ext_->GetRayTracingShaderIsaDisassembly(*pipeline_handle, - shader_name.c_str(), nullptr, &diassembly_bytes); - assert(SUCCEEDED(hr)); - ret = (SUCCEEDED(hr)); - if (ret && diassembly_bytes > 0) - { - shader_stats.disassembly = new char[diassembly_bytes] {}; - hr = amd_shader_analyzer_ext_->GetRayTracingShaderIsaDisassembly(*pipeline_handle, - shader_name.c_str(), shader_stats.disassembly, &diassembly_bytes); - assert(SUCCEEDED(hr)); - assert(shader_stats.disassembly != nullptr); - if (!SUCCEEDED(hr) || shader_stats.disassembly == nullptr) - { - std::stringstream msg; - msg << kStrErrorDisassemblyContentsExtractionFailure << - kStrErrorPerShaderName << shader_name_std_str.c_str(); - error_msg.append(msg.str()); - ret = false; - } - } - else - { - std::stringstream msg; - msg << kStrErrorDisassemblySizeExtractionFailure << - kStrErrorPerShaderName << shader_name_std_str.c_str(); - msg << kStrHintWrongShaderName1 << kStrHintWrongShaderName2; - error_msg.append(msg.str()); - ret = false; - } - - // Retrieve the statistics. - if (ret) - { - AmdExtD3DShaderStatsRayTracing rt_stats_driver{}; - hr = amd_shader_analyzer_ext_->GetRayTracingPipelineShaderStats(*pipeline_handle, - shader_name.c_str(), &rt_stats_driver); - assert(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) - { - ExtractRayTracingStats(shader_stats, rt_stats_driver); - } - else - { - std::stringstream msg; - msg << kStrErrorStatisticsExtractionFailure << - kStrErrorPerShaderName << shader_name_std_str.c_str(); - error_msg.append(msg.str()); - ret = false; - } - } - } - else - { - std::stringstream msg; - msg << kStrErrorDxrFailedToCreateStateObject << std::endl << kStrHintDebugOutput; - error_msg.append(msg.str()); - ret = false; - } - } - - return ret; - } #endif bool RgDx12Backend::CompileComputePipeline(const RgDx12Config config, const D3D12_COMPUTE_PIPELINE_STATE_DESC* compute_pso, @@ -1168,29 +831,16 @@ namespace rga } #ifdef RGA_DXR_ENABLED - bool RgDx12Backend::CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - std::vector>>>& raytracing_shader_stats, - std::vector>>& pipeline_binary, std::vector& is_unified_mode, - std::vector< std::shared_ptr>>& indirect_shader_names, - std::string& error_msg) const - { - bool ret = false; - assert(impl_ != nullptr); - if (impl_ != nullptr) - { - ret = impl_->CreateStateObject(ray_tracing_state_object, raytracing_shader_stats, pipeline_binary, is_unified_mode, indirect_shader_names, error_msg); - } - return ret; - } - bool RgDx12Backend::CreateStateObjectShader(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, const std::wstring& raygen_shader_name, - RgDx12ShaderResultsRayTracing& raytracing_shader_stats, std::vector& pipeline_binary, std::string& error_msg) const + bool RgDx12Backend::CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, + std::vector>>& pipeline_binary, + std::string& error_msg) const { bool ret = false; assert(impl_ != nullptr); if (impl_ != nullptr) { - ret = impl_->CreateStateObjectShader(ray_tracing_state_object, raygen_shader_name, raytracing_shader_stats, pipeline_binary, error_msg); + ret = impl_->CreateStateObject(ray_tracing_state_object, pipeline_binary, error_msg); } return ret; } diff --git a/source/utils/dx12/backend/rg_dx12_backend.h b/source/utils/dx12/backend/rg_dx12_backend.h index 63bd26c..47610ab 100644 --- a/source/utils/dx12/backend/rg_dx12_backend.h +++ b/source/utils/dx12/backend/rg_dx12_backend.h @@ -130,29 +130,16 @@ namespace rga RgDx12ThreadGroupSize& thread_group_size, std::vector& pipeline_binary, std::string& error_msg) const; -#ifdef RGA_DXR_ENABLED - // Compile all ray tracing pipelines to generate the disassembly and compiler resource usage info, - // and extract the results for all pipelines (each pipeline is designated by the raygeneration shader name). - // ray_tracing_state_object should contain all required data for the DXR State Object creation. - // Any error messages would be set into error_msg. - // Returns true on success, false otherwise. - bool CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - std::vector>>>& raytracing_shader_stats, - std::vector>>& pipeline_binary, - std::vector& is_unified_mode, - std::vector>>& indirect_shader_names, - std::string& error_msg) const; - // Compile a ray tracing shader to generate the disassembly and compiler resource usage info, - // and extract the results for a single pipeline (designated by the raygeneration shader name). +#ifdef RGA_DXR_ENABLED + // Compile all ray tracing pipelines to generate the compiled code object binaries + // for all pipelines (each pipeline is designated by the raygeneration shader name). // ray_tracing_state_object should contain all required data for the DXR State Object creation. // Any error messages would be set into error_msg. // Returns true on success, false otherwise. - bool CreateStateObjectShader(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, - const std::wstring& shader_name, - RgDx12ShaderResultsRayTracing& shader_stats, - std::vector& pipeline_binary, - std::string& error_msg) const; + bool CreateStateObject(const D3D12_STATE_OBJECT_DESC* ray_tracing_state_object, + std::vector>>& pipeline_binary, + std::string& error_msg) const; #endif private: diff --git a/source/utils/dx12/backend/rg_dx12_data_types.h b/source/utils/dx12/backend/rg_dx12_data_types.h index dd83885..d0084f4 100644 --- a/source/utils/dx12/backend/rg_dx12_data_types.h +++ b/source/utils/dx12/backend/rg_dx12_data_types.h @@ -77,14 +77,8 @@ namespace rga // Full path to the file that describes the pipeline state. std::string rs_pso; - // DXR compilation mode (Pipeline or Shader). - std::string dxr_mode; - - // DXR ISA disassembly output file. - std::string dxr_isa_output; - - // DXR statistics output file. - std::string dxr_statistics_output; + // Compilation mode (DXR or DX12 (default)). + bool is_config_dxr = false; // DXR binary output file. std::string dxr_binary_output; @@ -92,9 +86,6 @@ namespace rga // Full path to the DXR state description file. std::string dxr_state_file; - // DXR export (raygeneration shader name in Pipeline mode or shader name in Shader mode). - std::string dxrExport; - // Full path to the pipeline binary output file. std::string pipeline_binary; @@ -266,27 +257,10 @@ namespace rga RgDx12DxrPipelineConfig pipeline_config; }; - // The results per DXR shader. - struct RgDxrShaderResults - { - std::string export_name; - std::string isa_disassembly; - std::string stats; - }; - struct RgDxrPipelineResults { - // Pipeline name is either a raygeneration shader name or an index (in All mode). - std::string pipeline_name; - // Full path to pipeline binary output file. std::string pipeline_binary; - - // Results for all of the pipeline's shaders. - std::vector results; - - // True if pipeline was compiled in unified mode, false otherwise. - bool isUnified = true; }; // *** DXR-SPECIFIC TYPES - END *** diff --git a/source/utils/dx12/backend/rg_dx12_factory.cpp b/source/utils/dx12/backend/rg_dx12_factory.cpp index 9eab065..fe5b66b 100644 --- a/source/utils/dx12/backend/rg_dx12_factory.cpp +++ b/source/utils/dx12/backend/rg_dx12_factory.cpp @@ -142,31 +142,4 @@ namespace rga } } - void RgDx12Factory::DestroyDxilLibrarySubobject(D3D12_STATE_SUBOBJECT*& dxil_library_subobject) - { - if (dxil_library_subobject != nullptr) - { - if (dxil_library_subobject->pDesc != nullptr) - { - D3D12_DXIL_LIBRARY_DESC* desc = (D3D12_DXIL_LIBRARY_DESC*)(dxil_library_subobject->pDesc); - desc->DXILLibrary.BytecodeLength = 0; - delete[] desc->DXILLibrary.pShaderBytecode; - desc->DXILLibrary.pShaderBytecode = nullptr; - for (uint32_t i = 0; i < desc->NumExports; i++) - { - desc->pExports[i]; - delete[] desc->pExports[i].Name; - desc->pExports[i].Name = nullptr; - delete[] desc->pExports[i].ExportToRename; - desc->pExports[i].ExportToRename = nullptr; - } - delete[] desc->pExports; - desc->pExports = nullptr; - } - - delete dxil_library_subobject; - dxil_library_subobject = nullptr; - } - } - } diff --git a/source/utils/dx12/backend/rg_dx12_factory.h b/source/utils/dx12/backend/rg_dx12_factory.h index ac28ba3..71d9862 100644 --- a/source/utils/dx12/backend/rg_dx12_factory.h +++ b/source/utils/dx12/backend/rg_dx12_factory.h @@ -47,8 +47,5 @@ namespace rga // Destroy a hit group subobject that was created by this factory. static void DestroyHitGroupSubobject(D3D12_STATE_SUBOBJECT*& hit_group_subobject); - - // Destroy a DXIL library subobject that was created by this factory. - static void DestroyDxilLibrarySubobject(D3D12_STATE_SUBOBJECT*& dxil_library_subobject); }; } diff --git a/source/utils/dx12/backend/rg_dx12_frontend.cpp b/source/utils/dx12/backend/rg_dx12_frontend.cpp index f26c51e..7df2248 100644 --- a/source/utils/dx12/backend/rg_dx12_frontend.cpp +++ b/source/utils/dx12/backend/rg_dx12_frontend.cpp @@ -71,21 +71,21 @@ namespace rga static const char* kStrErrorFailedToWriteOutputFile1 = "Error: failed to write "; static const char* kStrErrorFailedToWriteOutputFile2 = " file to "; static const char* kStrErrorFailedToWriteOutputFile3 = "make sure that the path is valid."; - static const char* kStrErrorFailedToExtractRaytracingDisassembly = "Error: failed to extract disassembly."; - static const char* kStrErrorFailedToExtractRaytracingStatistics = "Error: failed to extract hardware resource usage statistics."; - static const char* kStrErrorFailedToExtractRaytracingBinary = "Error: failed to extract pipeline binary."; + //static const char* kStrErrorFailedToExtractRaytracingDisassembly = "Error: failed to extract disassembly."; + //static const char* kStrErrorFailedToExtractRaytracingStatistics = "Error: failed to extract hardware resource usage statistics."; + //static const char* kStrErrorFailedToExtractRaytracingBinary = "Error: failed to extract pipeline binary."; static const char* kStrErrorFailedToCreateComputePipeline = "Error: compute pipeline state creation failed. "; - static const char* kStrErrorDxrShaderModeCompilationFailed = "Error: DXR shader mode compilation failed."; + //static const char* kStrErrorDxrShaderModeCompilationFailed = "Error: DXR shader mode compilation failed."; static const char* kStrErrorDxrFailedToReadHlslToDxilMappingFile1 = "Error: failed to read "; static const char* kStrErrorDxrFailedToParseHlslToDxilMappingFile1 = "Error: failed to parse "; static const char* kStrErrorDxrdHlslToDxilMappingFile2 = "HLSL->DXIL mapping file."; static const char* kStrErrorAmdDisplayAdapterNotFound = "Error: could not find an AMD display adapter on the system. Consider adding --offline to the rga command to use the AMD driver (amdxc64.dll) that is bundled with the tool."; - static const char* kStrErrorDxrFailedToRetrievePipelineShaderName = "Error: failed to retrieve shader name for shader #"; + //static const char* kStrErrorDxrFailedToRetrievePipelineShaderName = "Error: failed to retrieve shader name for shader #"; // Warnings. - static const char* kStrWarningBinaryExtractionNotSupportedInIndirectMode = "Warning: pipeline binary extraction (-b option) is not supported when driver performs Indirect compilation."; - static const char* kStrWarningBinaryExtractionNotSupportedMultiplePipelines1 = "Warning: pipeline binary extraction skipped for pipeline #"; - static const char* kStrWarningBinaryExtractionNotSupportedMultiplePipelines2 = " - there is currently no support for pipeline binary extraction when multiple pipelines are generated."; + //static const char* kStrWarningBinaryExtractionNotSupportedInIndirectMode = "Warning: pipeline binary extraction (-b option) is not supported when driver performs Indirect compilation."; + //static const char* kStrWarningBinaryExtractionNotSupportedMultiplePipelines1 = "Warning: pipeline binary extraction skipped for pipeline #"; + //static const char* kStrWarningBinaryExtractionNotSupportedMultiplePipelines2 = " - there is currently no support for pipeline binary extraction when multiple pipelines are generated."; // Info. static const char* kStrInfoExtractComputeShaderDisassemblyAmdil = "Extracting compute shader AMDIL disassembly..."; @@ -105,18 +105,8 @@ namespace rga static const char* kStrInfoExtractGraphicsPipelineBinarySuccess = "Graphics pipeline binary extracted successfully."; static const char* kStrInfoExtractGraphicsShaderStatsSuccess = " shader statistics extracted successfully."; static const char* kStrInfoExtractGraphicsShaderDisassemblySuccess = " shader disassembly extracted successfully."; - static const char* kStrInfoExtractRayTracingDisassemblySuccess = "Disassembly extracted successfully."; - static const char* kStrInfoExtractRayTracingStatisticsSuccess = "Hardware resource usage statistics extracted successfully."; static const char* kStrInfoExtractRayTracingBinarySuccess = "Pipeline binary extracted successfully."; - static const char* kStrInfoExtractRayTracingStatsShader = "Extracting statistics for shader "; - static const char* kStrInfoExtractRayTracingPipelineBinaryByRaygen = "Extracting pipeline binary for pipeline associated with raygeneration shader "; - static const char* kStrInfoExtractRayTracingDisassemblyPipelineByRaygen = "Extracting disassembly for pipeline associated with raygeneration shader "; - static const char* kStrInfoExtractRayTracingResourceUsagePipelineByRaygen = "Extracting hardware resource usage for pipeline associated with raygeneration shader "; - static const char* kStrInfoExtractRayTracingPipelineBinaryByIndex1 = "Extracting pipeline binary for pipeline #"; - static const char* kStrInfoExtractRayTracingDisassemblyPipelineByIndex1 = "Extracting disassembly for pipeline #"; - static const char* kStrInfoExtractRayTracingResourceUsagePipelineByIndex1 = "Extracting hardware resource usage for pipeline #"; - static const char* kStrInfoExtractRayTracingResultByIndex2 = " for shader "; - static const char* kStrInfoExtractRayTracingDisassemblyShader = "Extracting disassembly for shader "; + static const char* kStrInfoExtractRayTracingPipelineBinaryByIndex1 = "Extracting pipeline binary for pipeline "; static const char* kStrInfoCompilingRootSignatureFromHlsl1 = "Compiling root signature defined in HLSL file "; static const char* kStrInfoCompilingRootSignatureFromHlsl2 = " in macro named "; static const char* kStrHintRootSignatureFailure = "Hint: this failure could be due to a missing or incompatible root signature.\n" @@ -124,15 +114,10 @@ namespace rga "with the macro name, or use the --rs-macro option.\n2. If your root signature is precompiled into a binary, please use the --rs-bin " "option with the full path to the binary file as an argument."; static const char* kStrHintUseDebugLayer = "To facilitate troubleshooting, we recommend enabling the --debug-layer option when running RGA."; - static const char* kStrInfoDxrPipelineCompiledUnified = "Pipeline compiled in Unified mode, expect a single uber shader in the output."; - static const char* kStrInfoDxrPipelineCompiledIndirect1 = "Pipeline compiled in Indirect mode, expect "; - static const char* kStrInfoDxrPipelineCompiledIndirect2 = " shaders in the output."; static const char* kStrInfoDxrPipelineCompilationGenerated1 = "Compilation generated "; - static const char* kStrInfoDxrPipelineCompilationGeneratedMultiplePipelines2 = " pipelines."; - static const char* kStrInfoDxrPipelineCompilationGeneratedSinglePipeline2 = " pipeline."; - static const char* kStrInfoDxrPipelineTypeReport1 = "Pipeline #"; - static const char* kStrInfoDxrPipelineTypeReport2 = " associated with raygeneration shader "; - + static const char* kStrInfoDxrPipelineCompilationGeneratedMultiplePipelines2 = " pipeline binaries."; + static const char* kStrInfoDxrPipelineCompilationGeneratedSinglePipeline2 = " pipeline binary."; + // *** CONSTANTS - END *** // *** STATICALLY-LINKED UTITILIES - START *** @@ -1542,11 +1527,6 @@ namespace rga { // Assume pipeline mode by default, unless user specified shader mode explicitly. D3D12_STATE_OBJECT_TYPE stateObjectType = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; - std::string modeLower = RgDx12Utils::ToLower(config.dxr_mode); - if (modeLower.compare("shader") == 0) - { - stateObjectType = D3D12_STATE_OBJECT_TYPE_COLLECTION; - } // Create the State Object descriptor, based upon which the state object would be created. CD3DX12_STATE_OBJECT_DESC dxr_state_desc(stateObjectType); @@ -1634,419 +1614,57 @@ namespace rga // Track the results. std::vector results_pipeline_mode; - const char* kStrModeNameShader = "shader"; - const char* kOutputFilenameSuffixUnified = "unified"; - std::wstring dxr_export_wide = RgDx12Utils::strToWstr(config.dxrExport); - std::string export_lower = RgDx12Utils::ToLower(config.dxrExport); - std::wstring dxr_export_wide_lower = RgDx12Utils::strToWstr(config.dxrExport); - bool is_shader_mode = modeLower.compare(kStrModeNameShader) == 0; - if (is_shader_mode) - { - std::vector> rs; - std::vector pipeline_binary; - bool is_unified_mode = true; - std::vector indirect_shader_names; - - // Compile and extract the results for a single shader. - std::shared_ptr raytracing_shader_stats = std::make_shared(); - ret = backend_.CreateStateObjectShader(dxr_state_desc, dxr_export_wide, *raytracing_shader_stats, pipeline_binary, error_msg); - assert(ret); - if (ret) - { - rs.push_back(raytracing_shader_stats); - } - else - { - if (error_msg.empty()) - { - std::cerr << kStrErrorDxrShaderModeCompilationFailed << std::endl; - } - } + // Pipeline mode: compile and extract the results for all generated pipelines. + // Per-pipeline binary. + std::vector>> pipeline_binaries; - - if (ret) - { - RgDxrPipelineResults pipeline_results; - pipeline_results.isUnified = is_unified_mode; - - // If we are in Pipeline (non All) mode, we would use the export name as the name of the pipeline. - pipeline_results.pipeline_name = "null"; - - uint32_t i = 0; - for (const auto& curr_results : rs) - { - // If we are in Unified mode, pipeline name is identical to export name (raygeneration shader name). - RgDxrShaderResults shader_results_tracking; - if (is_unified_mode || is_shader_mode) - { - shader_results_tracking.export_name = config.dxrExport; - } - else - { - assert(i < indirect_shader_names.size()); - if (i < indirect_shader_names.size()) - { - shader_results_tracking.export_name = indirect_shader_names[i]; - } - } - - assert(is_unified_mode || i < indirect_shader_names.size()); - if (!config.dxr_isa_output.empty() && curr_results->disassembly != nullptr) - { - // Save output files and report to user: disassembly. - if (is_shader_mode || is_unified_mode) - { - std::cout << (!is_shader_mode ? kStrInfoExtractRayTracingDisassemblyPipelineByRaygen : kStrInfoExtractRayTracingDisassemblyShader) - << config.dxrExport << "..." << std::endl; - } - else - { - std::cout << kStrInfoExtractRayTracingDisassemblyShader << "#" << (i + 1) << ": " << indirect_shader_names[i] << "..." << std::endl; - } - - std::string output_filename_fixed = config.dxr_isa_output; - if (!is_shader_mode) - { - output_filename_fixed = GenerateSpecificFileName(output_filename_fixed, (is_unified_mode ? kOutputFilenameSuffixUnified : indirect_shader_names[i])); - } - - bool is_disassembly_saved = RgDx12Utils::WriteTextFile(output_filename_fixed, curr_results->disassembly); - std::cout << (is_disassembly_saved ? kStrInfoExtractRayTracingDisassemblySuccess : - kStrErrorFailedToExtractRaytracingDisassembly) << std::endl; - assert(is_disassembly_saved); - ret = ret && is_disassembly_saved; - if (is_disassembly_saved) - { - shader_results_tracking.isa_disassembly = output_filename_fixed; - } - } - - if (!config.dxr_statistics_output.empty()) - { - // Save output files and report to user: statistics. - if (is_shader_mode) - { - std::cout << kStrInfoExtractRayTracingStatsShader << config.dxrExport << "..." << std::endl; - } - else - { - std::cout << kStrInfoExtractRayTracingStatsShader << "#" << (i + 1) << ": " << - indirect_shader_names[i] << "..." << std::endl; - } - - std::string output_filename_fixed = config.dxr_statistics_output; - if (!is_shader_mode) - { - output_filename_fixed = GenerateSpecificFileName(output_filename_fixed, (is_unified_mode ? kOutputFilenameSuffixUnified : indirect_shader_names[i])); - } - - bool is_statistics_saved = SerializeDx12StatsRayTracing(*curr_results, output_filename_fixed); - std::cout << (is_statistics_saved ? kStrInfoExtractRayTracingStatisticsSuccess : - kStrErrorFailedToExtractRaytracingStatistics) << std::endl; - assert(is_statistics_saved); - ret = ret && is_statistics_saved; - if (is_statistics_saved) - { - shader_results_tracking.stats = output_filename_fixed; - } - } - - // Track the current results. - pipeline_results.results.push_back(shader_results_tracking); - - // Increment the index for the current result. - ++i; - } - - // Pipeline binaries extraction is not supported in shader mode. - if (!is_shader_mode && is_unified_mode && !config.dxr_binary_output.empty()) - { - // Save output files and report to user: binaries. - std::cout << kStrInfoExtractRayTracingPipelineBinaryByRaygen << config.dxrExport << "..." << std::endl; - std::string output_filename_fixed = config.dxr_binary_output; - output_filename_fixed = GenerateSpecificFileName(output_filename_fixed, (is_unified_mode ? kOutputFilenameSuffixUnified : "")); - bool is_binary_saved = RgDx12Utils::WriteBinaryFile(output_filename_fixed, pipeline_binary); - std::cout << (is_binary_saved ? kStrInfoExtractRayTracingBinarySuccess : - kStrErrorFailedToExtractRaytracingBinary) << std::endl; - assert(is_binary_saved); - ret = ret && is_binary_saved; - if (is_binary_saved) - { - pipeline_results.pipeline_binary = output_filename_fixed; - } - } - - // Track the pipeline results. - results_pipeline_mode.push_back(pipeline_results); - } - } - else + // Compile. + ret = backend_.CreateStateObject(dxr_state_desc, pipeline_binaries, error_msg); + assert(ret); + if (ret) { - // Pipeline mode: compile and extract the results for all generated pipelines. - // Per-pipeline results. - std::vector>>> rs; - - // Per-pipeline binary. - std::vector>> pipeline_binaries; - - // Per-pipeline flag that specifies whether the pipeline was compiled in Unified mode. - std::vector is_unified; - - // Container for the raygeneration shader name for each generated pipeline. - std::vector>> raygeneration_shader_names; - - // Compile. - ret = backend_.CreateStateObject(dxr_state_desc, rs, pipeline_binaries, - is_unified, raygeneration_shader_names, error_msg); - assert(ret); - assert(!rs.empty()); - if (ret && !rs.empty()) + // For each pipeline, let's extract the results. + for (uint32_t pipeline_index = 0; pipeline_index < pipeline_binaries.size(); pipeline_index++) { - // Notify the user about the number of pipelines that were generated. - std::cout << kStrInfoDxrPipelineCompilationGenerated1 << rs.size() << - (rs.size() == 1 ? kStrInfoDxrPipelineCompilationGeneratedSinglePipeline2 : - kStrInfoDxrPipelineCompilationGeneratedMultiplePipelines2) << std::endl; + // Output metadata. + RgDxrPipelineResults curr_pipeline_results_metadata; - // For each pipeline, let's extract the results. - for (uint32_t pipeline_index = 0; pipeline_index < rs.size(); pipeline_index++) + // Binary files: only if required by user and only once per pipeline. + if (!config.dxr_binary_output.empty()) { - // Running number to identify the current pipeline in Indirect mode. - const std::string pipeline_index_display_name = std::to_string(pipeline_index + 1); - - // The shader names for the current pipeline. In case we are in Unified mode, there will - // be only a single shader name (the raygeneration shader). - std::shared_ptr> pipeline_shader_names = raygeneration_shader_names[pipeline_index]; - const auto& curr_raygeneration_shader_names = *pipeline_shader_names; - - // The raygeneration shader name for this pipeline (essentially, the pipeline identifier). - // We already have in hand the vector that holds the raygeneration shader name for the current pipeline - // so we will take the first (and only) element. - const char* curr_raygeneration_shader_name = curr_raygeneration_shader_names[0].data(); - - // The results for the current pipeline. - const auto& curr_results = rs[pipeline_index]; - - // Report the type of compilation (Unified/Indirect) to the user for the current pipeline. - std::cout << kStrInfoDxrPipelineTypeReport1 << (pipeline_index + 1); - if (is_unified[pipeline_index]) - { - std::cout << kStrInfoDxrPipelineTypeReport2 << - curr_raygeneration_shader_name; - } - std::cout << ": " << std::endl; - - if (is_unified[pipeline_index]) + assert(pipeline_index < pipeline_binaries.size()); + if (pipeline_index < pipeline_binaries.size()) { - // Unified mode - expect a single shader in output. - assert(curr_results->size() == 1); - std::cout << kStrInfoDxrPipelineCompiledUnified << std::endl; - } - else - { - // Indirect mode - expect N shaders in output. - assert(curr_results->size() >= 1); - std::cout << kStrInfoDxrPipelineCompiledIndirect1 << curr_results->size() << - kStrInfoDxrPipelineCompiledIndirect2 << std::endl; - } - - // Output metadata. - RgDxrPipelineResults curr_pipeline_results_metadata; - if (is_unified[pipeline_index]) - { - // Since this pipeline was compiled in Unified mode, shader name is pipeline name. - curr_pipeline_results_metadata.pipeline_name = curr_raygeneration_shader_name; - curr_pipeline_results_metadata.isUnified = true; - } - else - { - // In Indirect mode we don't have the name of the raygeneration shader, just an index. - curr_pipeline_results_metadata.pipeline_name = pipeline_index_display_name; - curr_pipeline_results_metadata.isUnified = false; - } - - // Go through pipeline's shaders. - for (uint32_t shader_index = 0; shader_index < rs[pipeline_index]->size(); shader_index++) - { - // Metadata to track the output files for this shader. - RgDxrShaderResults curr_shader_results_metadata; - - // Track the export name. - if (is_unified[pipeline_index]) - { - // In unified mode, this is the raygeneration shader name. - curr_shader_results_metadata.export_name = curr_raygeneration_shader_name; - } - else + // Running number to identify the current pipeline in Indirect mode. + const std::string pipeline_index_display_name = std::to_string(pipeline_index + 1); + + // Generate an index-specific file name. + std::string bin_output_filename = + GenerateSpecificFileName(config.dxr_binary_output, pipeline_index_display_name); + assert(!bin_output_filename.empty()); + if (!bin_output_filename.empty()) { - // In indirect mode, this is the name of the current shader. - assert(shader_index < curr_raygeneration_shader_names.size()); - if (shader_index < curr_raygeneration_shader_names.size()) + bool is_binary_saved = + RgDx12Utils::WriteBinaryFile(bin_output_filename, *pipeline_binaries[pipeline_index]); + ret = ret && is_binary_saved; + assert(is_binary_saved); + if (is_binary_saved) { - curr_shader_results_metadata.export_name = curr_raygeneration_shader_names[shader_index].data(); + curr_pipeline_results_metadata.pipeline_binary = bin_output_filename; } else { - std::cout << kStrErrorDxrFailedToRetrievePipelineShaderName << - (shader_index + 1) << "." << std::endl; + std::cout << kStrErrorFailedToWriteOutputFile1 << "binary" << kStrErrorFailedToWriteOutputFile2 + << bin_output_filename << kStrErrorFailedToWriteOutputFile3 << std::endl; } } - - // Build a suffix for this shader's output files. - std::stringstream shader_output_file_suffix_stream; - if (is_unified[pipeline_index]) - { - shader_output_file_suffix_stream << curr_shader_results_metadata.export_name.c_str() << "_"; - shader_output_file_suffix_stream << kOutputFilenameSuffixUnified; - } - else - { - shader_output_file_suffix_stream << pipeline_index_display_name << "_" << - curr_shader_results_metadata.export_name.c_str(); - } - const std::string shader_output_file_suffix = shader_output_file_suffix_stream.str().c_str(); - - // ISA files. - if (!config.dxr_isa_output.empty()) - { - // Generate an index-specific file name. - std::string isa_output_filename = GenerateSpecificFileName(config.dxr_isa_output, shader_output_file_suffix); - assert(!isa_output_filename.empty()); - if (!isa_output_filename.empty()) - { - // Save per-pipeline disassembly. - if (is_unified[pipeline_index]) - { - std::cout << kStrInfoExtractRayTracingDisassemblyPipelineByRaygen << curr_shader_results_metadata.export_name; - } - else - { - std::cout << kStrInfoExtractRayTracingDisassemblyPipelineByIndex1 << pipeline_index_display_name << - kStrInfoExtractRayTracingResultByIndex2 << curr_shader_results_metadata.export_name; - } - std::cout << "..." << std::endl; - - bool is_disassembly_saved = RgDx12Utils::WriteTextFile(isa_output_filename, (*curr_results)[shader_index]->disassembly); - ret = ret && is_disassembly_saved; - assert(is_disassembly_saved); - if (is_disassembly_saved) - { - curr_shader_results_metadata.isa_disassembly = isa_output_filename; - std::cout << kStrInfoExtractRayTracingDisassemblySuccess << std::endl; - } - else - { - std::cerr << kStrErrorFailedToWriteOutputFile1 << "disassembly" << - kStrErrorFailedToWriteOutputFile2 << isa_output_filename << - kStrErrorFailedToWriteOutputFile3 << std::endl; - } - } - } - - // Statistics files. - if (!config.dxr_statistics_output.empty()) - { - // Generate an index-specific file name. - std::string stats_output_filename = GenerateSpecificFileName(config.dxr_statistics_output, - shader_output_file_suffix); - assert(!stats_output_filename.empty()); - if (!stats_output_filename.empty()) - { - // Save per-pipeline statistics. - if (is_unified[pipeline_index]) - { - std::cout << kStrInfoExtractRayTracingResourceUsagePipelineByRaygen << - curr_shader_results_metadata.export_name; - } - else - { - std::cout << kStrInfoExtractRayTracingResourceUsagePipelineByIndex1 << pipeline_index_display_name << - kStrInfoExtractRayTracingResultByIndex2 << curr_shader_results_metadata.export_name; - } - std::cout << "..." << std::endl; - - bool is_statistics_saved = SerializeDx12StatsRayTracing((*(*curr_results)[shader_index]), stats_output_filename); - assert(is_statistics_saved); - ret = ret && is_statistics_saved; - if (is_statistics_saved) - { - curr_shader_results_metadata.stats = stats_output_filename; - std::cout << kStrInfoExtractRayTracingStatisticsSuccess << std::endl; - } - else - { - std::cerr << kStrErrorFailedToWriteOutputFile1 << "statistics" << - kStrErrorFailedToWriteOutputFile2 << stats_output_filename << - kStrErrorFailedToWriteOutputFile3 << std::endl; - } - } - } - - // Binary files: only if required by user and only once per pipeline. - if (!config.dxr_binary_output.empty() && (shader_index == 0)) - { - assert(pipeline_index < pipeline_binaries.size()); - if (pipeline_index < pipeline_binaries.size()) - { - // Generate an index-specific file name. - std::string bin_output_filename = GenerateSpecificFileName(config.dxr_binary_output, - (is_unified[pipeline_index] ? curr_raygeneration_shader_name : pipeline_index_display_name)); - assert(!bin_output_filename.empty()); - if (!bin_output_filename.empty()) - { - // Save per-pipeline binary. - if (is_unified[pipeline_index]) - { - std::cout << kStrInfoExtractRayTracingPipelineBinaryByRaygen << - curr_raygeneration_shader_name; - } - else - { - std::cout << kStrInfoExtractRayTracingPipelineBinaryByIndex1 << pipeline_index_display_name; - } - std::cout << "..." << std::endl; - - bool is_binary_saved = RgDx12Utils::WriteBinaryFile(bin_output_filename, *pipeline_binaries[pipeline_index]); - ret = ret && is_binary_saved; - assert(is_binary_saved); - if (is_binary_saved) - { - curr_pipeline_results_metadata.pipeline_binary = bin_output_filename; - std::cout << kStrInfoExtractRayTracingBinarySuccess << std::endl; - } - else - { - std::cout << kStrErrorFailedToWriteOutputFile1 << "binary" << - kStrErrorFailedToWriteOutputFile2 << bin_output_filename << - kStrErrorFailedToWriteOutputFile3 << std::endl; - } - } - } - else - { - bool is_multi_pipeline = (rs.size() > 1); - if(!is_multi_pipeline) - { - // Pipeline generation is supported for a single pipeline. - std::cerr << kStrErrorNoPipelineBinaryGeneratedForIndex << pipeline_index_display_name << std::endl; - } - else - { - // Pipeline generation is currently not supported by the driver for multiple pipelines. - std::cerr << kStrWarningBinaryExtractionNotSupportedMultiplePipelines1 << - pipeline_index_display_name << kStrWarningBinaryExtractionNotSupportedMultiplePipelines2 << std::endl; - } - } - } - - // Track current shader's results in the pipeline output metadata container. - curr_pipeline_results_metadata.results.push_back(curr_shader_results_metadata); } - - // Track the current pipeline's results. - results_pipeline_mode.push_back(curr_pipeline_results_metadata); } + + // Track the current pipeline's results. + results_pipeline_mode.push_back(curr_pipeline_results_metadata); } - } + } // Output metadata file. if (!config.output_metadata.empty()) @@ -2072,11 +1690,5 @@ namespace rga return ret; } - - bool rgDx12Frontend::CompileRayTracingShader(const RgDx12Config&, std::string&) const - { - bool ret = false; - return ret; - } #endif } \ No newline at end of file diff --git a/source/utils/dx12/backend/rg_dx12_frontend.h b/source/utils/dx12/backend/rg_dx12_frontend.h index 41808b2..96796fa 100644 --- a/source/utils/dx12/backend/rg_dx12_frontend.h +++ b/source/utils/dx12/backend/rg_dx12_frontend.h @@ -39,9 +39,6 @@ namespace rga #ifdef RGA_DXR_ENABLED // Compile ray tracing pipeline. bool CompileRayTracingPipeline(const RgDx12Config& config, std::string& error_msg) const; - - // Compile ray tracing shader. - bool CompileRayTracingShader(const RgDx12Config& config, std::string& error_msg) const; #endif private: diff --git a/source/utils/dx12/backend/rg_dxr_output_metadata.cpp b/source/utils/dx12/backend/rg_dxr_output_metadata.cpp index d2ca96d..ea0c5ff 100644 --- a/source/utils/dx12/backend/rg_dxr_output_metadata.cpp +++ b/source/utils/dx12/backend/rg_dxr_output_metadata.cpp @@ -14,21 +14,11 @@ // Json. #include "json/json-3.11.3/single_include/nlohmann/json.hpp" -using namespace rga; - // Constants: JSON elements. -static const char* kDxrOutputMetadataJsonElemSchemaVersion = "SchemaVersion"; +static const char* kDxrOutputMetadataJsonElemSchemaVersion = "SchemaVersion"; static const char* kDxrOutputMetadataJsonElemSchemaVersionDefault = "1.0"; -static const char* kDxrOutputMetadataJsonElemPipelines = "Pipelines"; -static const char* kDxrOutputMetadataJsonElemName = "Name"; -static const char* kDxrOutputMetadataJsonElemCompilationMode = "CompilationMode"; -static const char* kDxrOutputMetadataJsonElemCompilationModeUnified = "Unified"; -static const char* kDxrOutputMetadataJsonElemCompilationModeIndirect = "Indirect"; -static const char* kDxrOutputMetadataJsonElemShaders = "Shaders"; -static const char* kDxrOutputMetadataJsonElemExport = "Export"; -static const char* kDxrOutputMetadataJsonElemIsa = "ISA"; -static const char* kDxrOutputMetadataJsonElemStats = "Stats"; -static const char* kDxrOutputMetadataJsonPipelineBinary = "PipelineBinary"; +static const char* kDxrOutputMetadataJsonElemPipelines = "Pipelines"; +static const char* kDxrOutputMetadataJsonPipelineBinary = "PipelineBinary"; // Constants: error messages. static const char* kDxrOutputMetadataErrorFailedToWriteFile = "Error: failed to write JSON output metadata file."; @@ -45,23 +35,6 @@ bool rga::RgDxrOutputMetadata::WriteOutputMetadata(const std::string& json_filen structure[kDxrOutputMetadataJsonElemSchemaVersion] = kDxrOutputMetadataJsonElemSchemaVersionDefault; for (uint32_t pipeline_index = 0; pipeline_index < pipeline_results.size(); pipeline_index++) { - // Pipeline name. - structure[kDxrOutputMetadataJsonElemPipelines][pipeline_index][kDxrOutputMetadataJsonElemName] = pipeline_results[pipeline_index].pipeline_name; - - // Pipeline compilation mode. - structure[kDxrOutputMetadataJsonElemPipelines][pipeline_index][kDxrOutputMetadataJsonElemCompilationMode] = - (pipeline_results[pipeline_index].isUnified ? kDxrOutputMetadataJsonElemCompilationModeUnified : kDxrOutputMetadataJsonElemCompilationModeIndirect); - - for (uint32_t shader_index = 0; shader_index < pipeline_results[pipeline_index].results.size(); shader_index++) - { - // Shader element. - const auto& curr_shader_results = pipeline_results[pipeline_index].results[shader_index]; - structure[kDxrOutputMetadataJsonElemPipelines][pipeline_index][kDxrOutputMetadataJsonElemShaders][shader_index] = - { {kDxrOutputMetadataJsonElemExport, curr_shader_results.export_name}, - {kDxrOutputMetadataJsonElemIsa,curr_shader_results.isa_disassembly}, - { kDxrOutputMetadataJsonElemStats, curr_shader_results.stats} }; - } - // Pipeline binary. structure[kDxrOutputMetadataJsonElemPipelines][pipeline_index][kDxrOutputMetadataJsonPipelineBinary] = pipeline_results[pipeline_index].pipeline_binary; } @@ -114,44 +87,10 @@ bool rga::RgDxrOutputMetadata::ReadOutputMetadata(const std::string& json_filena { RgDxrPipelineResults curr_pipeline_result; - // Compilation mode. - std::string pipeline_compilation_mode = pipeline[kDxrOutputMetadataJsonElemCompilationMode]; - curr_pipeline_result.isUnified = (pipeline_compilation_mode.compare(kDxrOutputMetadataJsonElemCompilationModeUnified) == 0); - - // Name. - std::string pipeline_name = pipeline[kDxrOutputMetadataJsonElemName]; - curr_pipeline_result.pipeline_name = pipeline_name; - // Binary. std::string pipeline_binary_path = pipeline[kDxrOutputMetadataJsonPipelineBinary]; curr_pipeline_result.pipeline_binary = pipeline_binary_path; - // Shaders. - auto shaders_elem_iter = pipeline.find(kDxrOutputMetadataJsonElemShaders); - if (shaders_elem_iter != pipeline.end() && pipeline[kDxrOutputMetadataJsonElemShaders] != nullptr) - { - auto shaders_element = pipeline[kDxrOutputMetadataJsonElemShaders]; - for (const auto& shader : shaders_element) - { - RgDxrShaderResults curr_shader_results; - - // Exports. - std::string export_name = shader[kDxrOutputMetadataJsonElemExport]; - curr_shader_results.export_name = export_name; - - // ISA. - std::string isa_file = shader[kDxrOutputMetadataJsonElemIsa]; - curr_shader_results.isa_disassembly = isa_file; - - // STATS. - std::string stats_file = shader[kDxrOutputMetadataJsonElemStats]; - curr_shader_results.stats = stats_file; - - // Track shader results. - curr_pipeline_result.results.push_back(curr_shader_results); - } - } - // Track pipeline results. pipeline_results.push_back(curr_pipeline_result); }